Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert from latitude, longitude to x, y

I want to convert GPS location (latitude, longitude) into x,y coordinates. I found many links about this topic and applied it, but it doesn't give me the correct answer!

I am following these steps to test the answer: (1) firstly, i take two positions and calculate the distance between them using maps. (2) then convert the two positions into x,y coordinates. (3) then again calculate distance between the two points in the x,y coordinates and see if it give me the same result in point(1) or not.

one of the solution i found the following, but it doesn't give me correct answer!

latitude = Math.PI * latitude / 180; longitude = Math.PI * longitude / 180;  // adjust position by radians latitude -= 1.570795765134; // subtract 90 degrees (in radians)  // and switch z and y  xPos = (app.radius) * Math.sin(latitude) * Math.cos(longitude); zPos = (app.radius) * Math.sin(latitude) * Math.sin(longitude); yPos = (app.radius) * Math.cos(latitude); 

also i tried this link but still not work with me well!

any help how to convert from(latitude, longitude) to (x,y) ?

Thanks,

like image 229
userInThisWorld Avatar asked Apr 28 '13 19:04

userInThisWorld


People also ask

How do you convert latitude and longitude to XY coordinates?

latitude = Math. PI * latitude / 180; longitude = Math. PI * longitude / 180; // adjust position by radians latitude -= 1.570795765134; // subtract 90 degrees (in radians) // and switch z and y xPos = (app. radius) * Math.

Is latitude or longitude X or Y?

Even though geographic coordinates are angular units, ArcSDE stores and treats them as if they are planar. In this case, longitude values are considered the x-coordinate, while latitude values are the y-coordinate.


2 Answers

No exact solution exists

There is no isometric map from the sphere to the plane. When you convert lat/lon coordinates from the sphere to x/y coordinates in the plane, you cannot hope that all lengths will be preserved by this operation. You have to accept some kind of deformation. Many different map projections do exist, which can achieve different compromises between preservations of lengths, angles and areas. For smallish parts of earth's surface, transverse Mercator is quite common. You might have heard about UTM. But there are many more.

The formulas you quote compute x/y/z, i.e. a point in 3D space. But even there you'd not get correct distances automatically. The shortest distance between two points on the surface of the sphere would go through that sphere, whereas distances on the earth are mostly geodesic lengths following the surface. So they will be longer.

Approximation for small areas

If the part of the surface of the earth which you want to draw is relatively small, then you can use a very simple approximation. You can simply use the horizontal axis x to denote longitude λ, the vertical axis y to denote latitude φ. The ratio between these should not be 1:1, though. Instead you should use cos(φ0) as the aspect ratio, where φ0 denotes a latitude close to the center of your map. Furthermore, to convert from angles (measured in radians) to lengths, you multiply by the radius of the earth (which in this model is assumed to be a sphere).

  • x = r λ cos(φ0)
  • y = r φ

This is simple equirectangular projection. In most cases, you'll be able to compute cos(φ0) only once, which makes subsequent computations of large numbers of points really cheap.

like image 126
MvG Avatar answered Oct 30 '22 15:10

MvG


I want to share with you how I managed the problem. I've used the equirectangular projection just like @MvG said, but this method gives you X and Y positions related to the globe (or the entire map), this means that you get global positions. In my case, I wanted to convert coordinates in a small area (about 500m square), so I related the projection point to another 2 points, getting the global positions and relating to local (on screen) positions, just like this:

First, I choose 2 points (top-left and bottom-right) around the area where I want to project, just like this picture:

enter image description here

Once I have the global reference area in lat and lng, I do the same for screen positions. The objects containing this data are shown below.

//top-left reference point var p0 = {     scrX: 23.69,        // Minimum X position on screen     scrY: -0.5,         // Minimum Y position on screen     lat: -22.814895,    // Latitude     lng: -47.072892     // Longitude }  //bottom-right reference point var p1 = {     scrX: 276,          // Maximum X position on screen     scrY: 178.9,        // Maximum Y position on screen     lat: -22.816419,    // Latitude     lng: -47.070563     // Longitude }  var radius = 6371;      //Earth Radius in Km  //## Now I can calculate the global X and Y for each reference point ##\\  // This function converts lat and lng coordinates to GLOBAL X and Y positions function latlngToGlobalXY(lat, lng){     //Calculates x based on cos of average of the latitudes     let x = radius*lng*Math.cos((p0.lat + p1.lat)/2);     //Calculates y based on latitude     let y = radius*lat;     return {x: x, y: y} }  // Calculate global X and Y for top-left reference point p0.pos = latlngToGlobalXY(p0.lat, p0.lng); // Calculate global X and Y for bottom-right reference point p1.pos = latlngToGlobalXY(p1.lat, p1.lng);  /* * This gives me the X and Y in relation to map for the 2 reference points. * Now we have the global AND screen areas and then we can relate both for the projection point. */  // This function converts lat and lng coordinates to SCREEN X and Y positions function latlngToScreenXY(lat, lng){     //Calculate global X and Y for projection point     let pos = latlngToGlobalXY(lat, lng);     //Calculate the percentage of Global X position in relation to total global width     pos.perX = ((pos.x-p0.pos.x)/(p1.pos.x - p0.pos.x));     //Calculate the percentage of Global Y position in relation to total global height     pos.perY = ((pos.y-p0.pos.y)/(p1.pos.y - p0.pos.y));      //Returns the screen position based on reference points     return {         x: p0.scrX + (p1.scrX - p0.scrX)*pos.perX,         y: p0.scrY + (p1.scrY - p0.scrY)*pos.perY     } }  //# The usage is like this #\\  var pos = latlngToScreenXY(-22.815319, -47.071718); $point = $("#point-to-project"); $point.css("left", pos.x+"em"); $point.css("top", pos.y+"em"); 

As you can see, I made this in javascript, but the calculations can be translated to any language.

P.S. I'm applying the converted positions to an HTML element whose id is "point-to-project". To use this piece of code on your project, you shall create this element (styled as position absolute) or change the "usage" block.

like image 33
allexrm Avatar answered Oct 30 '22 14:10

allexrm