Project lat/long to pixels - javascript

I´m making an app for smartwatches, where I need to draw the track user is currently using. The track consists of lat/long pairs.
So far I´ve tried many functions, but with this one below I got most consistent results yet there are tracks, that got deformed, like squashed or the route was shifted.
function transformToPixels(lat, lon){
var westLongitude = boundingBox[1].toDegrees()[1];
var eastLongitude = boundingBox[0].toDegrees()[1];
var northLatitude = boundingBox[1].toDegrees()[0];
var southLatitude = boundingBox[0].toDegrees()[0];
var longitudeDiff = eastLongitude - westLongitude;
var latitudeDiff = northLatitude - southLatitude;
var xPixel = (((eastLongitude - lon) / (longitudeDiff).toDouble()) * DISPLAY_WIDTH).toNumber();
var yPixel = (((northLatitude - lat) / (latitudeDiff).toDouble()) * DISPLAY_HEIGHT).toNumber();
var result = new [2];
result[1] = xPixel - 3; //had to try/error these numbers to fit the line on the display
result[0] = yPixel + 25; //had to try/error these numbers to fit the line on the display
return result;
}
Here is the route drawn on phone from lat/long pairs:
And here is drawn on the smartwatch by projecting the same lat/long to X,Y pixels:
Then there is another route:
And here is drawn on the smartwatch by projecting the same lat/long to X,Y pixels:
Here are the GeoJsons from which I get the lat/long pairs.
This one is working fine: https://pastebin.com/1vx8S98V
This one gets deformed: https://pastebin.com/4Mt4MpEq
I don´t need meter-perfect conversion, but the shape of the route shouldn´t be changed.

Related

amcharts - how to set lat/lon in mappolygon?

Basically, I just want to plot a circle, at a user defined lat/lon with a radius of X km.
So I realize looking through documentation, I can't change the lat/lons of the mappolygons that are already loaded through the geodata, but I guess I'm not quite sure how to create a new map polygon with a specified lat/lon or if I can even do that!
My code is set up so that everytime the user clicks somewhere a marker is plotted or replotted accordingly, the location of the marker is where I would like to plot the center of the circle. I get that using the getCircle function I need to do the whole km2deg for the third variable, but I'm more concerned with the location right now. Any help would be great!
https://codepen.io/kbreezy/pen/wLRrPq
below is my onclick method of the code.
chart.seriesContainer.events.on("hit", function(ev) {
var lp = $("#chartdiv").data("point");
var coords = chart.svgPointToGeo(ev.svgPoint);
if (lp) {
lp.latitude = coords.latitude;
lp.longitude = coords.longitude;
} else {
var marker = imageSeries.mapImages.create();
marker.latitude = coords.latitude;
marker.longitude = coords.longitude;
}
$("#chartdiv").data("point", marker);
var circleSeries = chart.series.push(new am4maps.MapPolygonSeries())
var circleTemplate = circleSeries.mapPolygons.template;
circleTemplate.fill = am4core.color("#bf7569");
circleTemplate.strokeOpacity = 1;
circleTemplate.fillOpacity = 0.75;
var polygon = circleSeries.mapPolygons.create();
var mapPolygon = polygonSeries.getPolygonById("DE");
mapPolygon.setPropertyValue('latitude', coords.latitude);
mapPolygon.setPropertyValue('longitude', coords.longitude);
polygon.latitude = coords.latitude;
polygon.longitude = coords.longitude;
polygon.multiPolygon = am4maps.getCircle(mapPolygon.visualLongitude, mapPolygon.visualLatitude, 5);
//polygon.multiPolygon = am4maps.getCircle(coords.latitude, coords.longitude, 5);
});
MapPolygon does not have some latitude/longitude where you could "move" it. It's multipolygon must contain coordinates of the area you want to show. So when you pass longitude/latitude to the getCircle method, it returns multiPolygon around that point.
I modified your pen where to show the concept: https://codepen.io/team/amcharts/pen/ydrLZw
polygon.multiPolygon = am4maps.getCircle(coords.longitude, coords.latitude, 5);

2D Array Not Translating to D3 Map Coordinates

The 2D array I created is not accepted by D3.js as coordinates (The map example I'm using is at http://bl.ocks.org/phil-pedruco/6522279.)
Here are the facts:
1.) The JSON input I am supplied with is a string of latitude and longitude (e.g. "37.3879 -134.96376").
2.) The output required is a 2D array that must be in this form [[lat,long],[lat,long],...].
3.) console.log(typeof(lat)); returns that the lat and long values are indeed numbers (not strings)
4.) console.log("Coordinates: " + JSON.stringify(points)); returns [[37.3879,-134.96376],[13.5,-45],...] - which appears to be in the correct form, yet no points are displayed on the map
5.) If I hardcode the values in the array the points are displayed.
var points = [];
//var dotSpot = [[1.4440, 32.442], [12.222, 4.893]];
window.onload = function () {
getJSON();
}
function getJSON(supplierID) {
//retrieves JSON perfectly
//calls make() with Supplier data
}
function make(jdata) {
for (var i = 0; i < jdata.length; i++) {
//Splits string by space
var temp = jdata[i].latLong.split(/[ ,]+/)
//Converts lat and long strings to floats
var lat = parseFloat(temp[0]);
var long = parseFloat(temp[1]);
console.log(typeof(lat));
//Add "curr" coordinates array to "points" array
var curr = new Array(lat, long);
points.push(curr);
}
console.log("Coordinates: " + JSON.stringify(points));
}
You have specified your coordinates to be [latitude, longitude]. However, unlike many other applications D3 uses coordinates with longitude as the first value followed by latitude. From the docs:
The point must be specified as a two-element array [longitude, latitude] in degrees.
Changing you data accordingly should yield the desired rendering:
var curr = new Array(long, lat); // instead of new Array(lat, long)
points.push(curr);

How to get map.getBounds() as a list of 4 floats?

I'd like to get the coordinates of map bounds as a list of 4 floats (i.e. two points in latitude/longitude coordinates).
This (Google maps undocumented feature) used to work until a few days ago:
var b = map.getBounds();
var bounds = [b.H.H, b.H.j, b.j.j, b.j.H];
It doesn't work anymore. How to get these 4 floats ?
function getRectFromBounds(bounds) {
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
return [ne.lat(), ne.lng(), sw.lat(), sw.lng()];
};
var rect = getRectFromBounds(map.getBounds());
you can extend LatLngBounds and create a utility function to return this array, something like map.getBounds().toRect()

How do I enlarge LatLngBounds box using LatLng data

I get the current bounds of a google map by calling:
map.getBounds()
This will return LatLngBounds. For example:
((-26.574013562724005, -1.5375947819336488), (-25.230016040794602, 3.735842718066351))
Is it possible to get the the new LatLng points if I want to increase the map bounds by a percentage (e.g. 1%) around the centre of the map.
I have tried multiplying every coordinate by 1.01 but this shifts the map and does not increase the bounds.
I want to use the increased box size to start caching markers, in order to save calls to the server when the user pans or zooms out.
The image below will explain better what needs to happen:
Based on markerclusterer getExtendedBounds function you could use this one:
function getExtendedBounds(map, overlay) {
//With _mapBoundsEnlargePixels we add some extra space surrounding the map
//change this value until you get the desired size
var _mapBoundsEnlargePixels = 500;
var projection = overlay.getProjection();
var bounds = angular.copy(map.getBounds());
// Turn the bounds into latlng.
var tr = new google.maps.LatLng(bounds.getNorthEast().lat(),
bounds.getNorthEast().lng());
var bl = new google.maps.LatLng(bounds.getSouthWest().lat(),
bounds.getSouthWest().lng());
// Convert the points to pixels and extend out
var trPix = projection.fromLatLngToDivPixel(tr);
trPix.x = trPix.x + _mapBoundsEnlargePixels;
trPix.y = trPix.y - _mapBoundsEnlargePixels;
var blPix = projection.fromLatLngToDivPixel(bl);
blPix.x = blPix.x - _mapBoundsEnlargePixels;
blPix.y = blPix.y + _mapBoundsEnlargePixels;
// Convert the pixel points back to LatLng
var ne = projection.fromDivPixelToLatLng(trPix);
var sw = projection.fromDivPixelToLatLng(blPix);
// Extend the bounds to contain the new bounds.
bounds.extend(ne);
bounds.extend(sw);
return bounds;
}

Drawing images from an array

I'm currently working on drawing up a tilemap using a set of images loaded inn to an array.
I've defined a tile as an object like this:
function tile(gfx){
this.tile = gfx;
this.drawSelf = function(x,y)
this.tile.x = x;
this.tile.y = y;
}
Then I filled up an array with several tile objects which through the debugger displays correctly.
Now when I start drawing up the images using this code:
for (var x = 0; x < mapArray.length; x++){
xN = 183 + (50*x);
mapArray[x].drawSelf(xN, 134);
gameStage.addChild(mapArray[x].tile);
mapArray[x].tile.visible = true;
}
The problem is that all the "objects" in the array recive the same x and y coords. So what i suspect is that every single object in the array referes to each other.
What I'm trying to do is create a 20x10 map of tiles. And I need to be able to refer to each tile as a single object.
Shout out if I'm not making sense.
If you create all the tiles like this :
var gfx = new ...
for (...) {
mapArray[x].tile = new tile(gfx);
}
Then all of them share the same gfx object.
You should change your initialization like this :
for (...) {
var gfx = new ...
mapArray[x].tile = new tile(gfx);
}

Categories