In Javascript.
I have a map of the world that is 1024 x 1024px - It is a spherical Mercator projection.
Im looking to convert long/lat to x,y for this map. I have a bunch of coordinates that I need to overlay on top of it.
Calculating longitude was very easy, and I am doing it like so:
pos.x = ((long + 180)/ 360) * 1024;
I just need to same for lat --> y
I looked around a saw a lot of reference to openlayers, but didn't see such a conversion.
To boil it down:
var mercator = function(lat, lng) {
return [lng, Math.log( (Math.sin(lat) + 1.0) / Math.cos(lat)) ] ;
};
Lat and long must be expressed in radians of course.
You can find the corresponding formulas in this wikipedia article: Mercator Projection.
Related
I am doing a Javascript application that requires the movement of a certain element in a real world map, in frames.
For each frame, i have the following positions in latitude and longitude for the element, for example for frame 0:
- Latitude: 49.011213
- Longitude: 8.422885
For frame 1:
- Latitude: 49.01121
- Longitude: 8.422887
Frame (Frame 0) needs to be point (0,0) and I want the following ones to be converted to XY Coordinates as well.
Basically, I need a Javascript script that receives the latitude and longitude of a frame and returns the position (x,y) for that frame (in relation to frame 0 with position (0,0)).
I've tried the following but it doesn't work:
function convertSphericalToCartesian(latitude, longitude)
{
// Convert from Degrees to Radians
let latRad = latitude * (Math.PI)/180;
let lonRad = longitude * (Math.PI)/180;
let earthRadius = 6367; // Radius in km
let posX = earthRadius * Math.cos(latRad) * Math.cos(lonRad);
let posY = earthRadius * Math.cos(latRad) * Math.sin(lonRad);
return {x: posX, y: posY};
}
Do you know a better formula for this? Thank you very much.
Any conversion you do will introduce error, since you're trying to map the surface of a sphere to rectangular coordinates. You haven't mentioned what you're doing with this information - the mention of "frames" makes me think of animation or a game involving moving things on a map. If that's the case, then your calculations are going to be closely tied to the map you're using.
In general, the question is: how far apart are your coordinates likely to be?
For small distances, up to a few miles or kilometers, you're probably just fine treating the lat/lon as x/y coordinates. For example, the coordinates you've given in your example are literally only feet apart - don't bother with complicated calculations. And again, how you draw something on a given map at those coordinates depends very much on the map you're using.
For larger distances, the curvature of the Earth becomes important and the map projection you're working with will make a big difference in how those coordinates are calculated. For example, this question discusses the calculations for a Mercator projection.
I am using the Web Mercator to transform longitudes and latitudes to x and y coordinates. However, when I want to inverse this problem the built-in atan() (or Math.atan()) function of JavaScript (and p5.js) gives me trouble. The Web Mercator and the calculated inverse are given below.
formulas
Then, for an example y position in my grid, I have code similar to:
//Sample code for transforming y coordinate to latitude using Web Mercator
//map size: 128x128 -> c_map = 128, zoom level: 1
var ypos = 100;
var c_map = 128;
var temp = PI*(1- ypos/(pow(2, 1)*c_map);
temp = atan(exp(temp) * 180/PI);
lat = 2*(180 / PI)*(temp - PI / 4);
However, this gives me false values for the y coordinate since JavaScript computes the tangent and arctangent in radians.
I have tried several configurations of first transforming the exponent to radians (is the exponent in degrees?) and then transforming the result back to degrees, but to no avail. The y coordinates are given relative to the point [0,0].
What kind of radian/degree transformation do I need to apply where in order to get correct values of my y coordinate?
Hi to all i'm developing a map with raphael.js as they do in here : http://raphaeljs.com/world/
the problem is that i'm using a custom svg world map so they function getXY() obviously wont return the correct x,y of a lat,lng.
How can i calculate the x and y of a given lat/lng knowing the map width/height and the rapport froma point and his coordinates (x:1104.73=lng:42.998604)(y:559.25=lat:9.424553).
they use this code:
cx: lon * 2.6938 + 465.4
y: lat * -2.6938 + 227.066
but i cant figure out what is 2.6938 and the other two numbers.
I've also used this math here:
int x = (int) ((MAP_WIDTH/360.0) * (180 + lon));
int y = (int) ((MAP_HEIGHT/180.0) * (90 - lat));
But i cant get it works,anibody can help me?
The formula to use depends on what projection (Equirectangular, Robinson, Miller, Lambert, Mercator, or other one) is used by your map. More on projections here http://en.wikipedia.org/wiki/Map_projection
You will not find any help if you don't know what is the projection for your "custom svg world map"
Cheers
I have trying to get Latitude and Longitude of a Point.
But While transforming it's not returning the correct LonLat. It's big number that is not a lonlat point for sure.
I have tried for some solutions but didn't get result.
What else could be failing?
JS Code I have Tried
map = createMap("deviceMap");
var fromProjection = new OpenLayers.Projection("EPSG:4326");
var toProjection = new OpenLayers.Projection("EPSG:900913");
map.events.register('click', map, function handleMapClick(e) {
lonLat = self.map.getLonLatFromViewPortPx(e.xy).
transform(map.getProjectionObject(), toProjection);
prompt("",lonLat);
});
Finally got answer
map.events.register('click', map, function handleMapClick(e) {
var toProjection = new OpenLayers.Projection("EPSG:4326");
var lonLat = map.getLonLatFromPixel(e.xy).
transform(map.getProjectionObject(), toProjection);
});
EPSG:4326
should refer to WGS 84,
has decimal degree values
EPSG:900913
refers to WGS84 Web Mercator
has metric values, it is x/y axis coordinate system, so "high numbers" are expected
If I understand you right, you should have in variable lonLat a high number.
"LonLat" in OpenLayers does not mean, it will be only longitude/latitude, see documentation here:
lon {Number} The x-axis coordinate in map units. If your map is in a
geographic projection, this will be the Longitude. Otherwise, it will
be the x coordinate of the map location in your map units.
lat {Number} The y-axis coordinate in map units. If your map is in a
geographic projection, this will be the Latitude. Otherwise, it will
be the y coordinate of the map location in your map units.
So if you want to get a real LonLat coordinates, you should not convert it (and use EPSG:4326) or convert it to the other coordinate system, not EPSG:900913.
By the way, OpenLayers started to use 900918 (numeric equivalent to GOOGlE), It was define by Mr. Christopher Schmidt, firstly it was not accepted by European Petroleum Survey Group (EPSG). Then EPSG changed their mind and gave them number: 3857 - WGS84 Pseudo-Mercator.
I have polyline in my map. I want to know the pixel (screen) xy-coordinates, when user clicks the polyline. Click event only returns the LatLng object, so does anyone have a clue how to get the pixel coordinates from latLng?
I would appreciate very much if someone could help me!
If you have the LatLng object, you can use the google map projection object to transform it into tile coordinates and then into pixel coordinates:
For the docs on the projection class:
https://developers.google.com/maps/documentation/javascript/reference#Projection
Google's example explaining how to transform a LatLng into a pixel coordinate:
https://developers.google.com/maps/documentation/javascript/examples/map-coordinates?csw=1
There's one catch. The above will give you the pixel coordinates inside google's map div (which you may want depending on your needs). If you want the pixels relative to the top left corner of the screen, there's one more step. You need to do the same projection on the the viewport's top left corner and subtract the two. This will give you the pixel coordinates of the LatLng point.
The code I finally used looked like this (note that "latLng" is an input):
var numTiles = 1 << map.getZoom();
var projection = map.getProjection();
var worldCoordinate = projection.fromLatLngToPoint(latLng);
var pixelCoordinate = new google.maps.Point(
worldCoordinate.x * numTiles,
worldCoordinate.y * numTiles);
var topLeft = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var topLeftWorldCoordinate = projection.fromLatLngToPoint(topLeft);
var topLeftPixelCoordinate = new google.maps.Point(
topLeftWorldCoordinate.x * numTiles,
topLeftWorldCoordinate.y * numTiles);
return new google.maps.Point(
pixelCoordinate.x - topLeftPixelCoordinate.x,
pixelCoordinate.y - topLeftPixelCoordinate.y
)