从纬度,经度转换为x,y

use*_*rld 21 mapping geometry gps

我想将GPS位置(纬度,经度)转换为x,y坐标.我找到了许多关于这个主题的链接并应用了它,但它没有给我正确的答案!

我按照这些步骤来测试答案:(1)首先,我采取两个位置并使用地图计算它们之间的距离.(2)然后将两个位置转换为x,y坐标.(3)然后再次计算x,y坐标中两点之间的距离,看它是否在点(1)给出了相同的结果.

我发现以下解决方案之一,但它没有给我正确的答案!

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);
Run Code Online (Sandbox Code Playgroud)

我也试过这个链接,但仍然不能与我合作!

任何帮助如何从(纬度,经度)转换为(x,y)?

谢谢,

MvG*_*MvG 43

没有确切的解决方案

从球体到平面没有等距映射.将lat/lon坐标从球体转换为平面中的x/y坐标时,您无法希望此操作将保留所有长度.你必须接受某种变形.确实存在许多不同的地图投影,这可以在长度,角度和区域的保留之间实现不同的折衷.对于地球表面的小部分,横向墨卡托很常见.您可能听说过UTM.但还有更多.

您引用的公式计算x/y/z,即3D空间中的点.但即便如此,你也无法自动获得正确的距离.球体表面上两点之间的最短距离将通过该球体,而地球上的距离大部分是表面之后的测地长度.所以他们会更长.

小区域的近似

如果要绘制的地球表面部分相对较小,则可以使用非常简单的近似值.您可以简单地使用水平轴x来表示经度λ,垂直轴y来表示纬度φ.但是,它们之间的比例不应该是1:1.相反,你应该使用COS(φ 0)的长宽比,其中φ 0表示接近你的地图的中心纬度.此外,要从角度(以弧度测量)转换为长度,您需要乘以地球的半径(在此模型中假定为球体).

  • X = - [R λCOS(φ 0)
  • ÿ = - [R φ

这是简单的equirectangular投影.在大多数情况下,你就可以计算COS(φ 0)只有一次,这使得大量的点真的很便宜的后续计算.

  • @ alsadi90:无论是以度数还是以弧度为单位测量角度,只会影响地图的大小而不影响地形.您必须确保正确计算余弦,在大多数编程语言中,这意味着使用弧度.对于φ0,我建议您简单地取纬度的下限和上限之间的平均值.但对于这样的小地图,从该区域内取任何纬度可能会运作得很好. (2认同)

小智 5

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:

在此处输入图片说明

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 = 6.371;     //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");
Run Code Online (Sandbox Code Playgroud)

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

PS: I'm applying the converted positions to an html element whose id is "point-to-project". In order to use this piece of code on your project you shall create this element (styled as position absolute) or change the "usage" block.

  • 有一个错误:地球半径以公里为单位是“6371”,而不是“6.371”(在 JS 中略大于 6)。当然,在这么小的区域内,它并没有太大变化,但未来的读者应该注意这一点。 (2认同)