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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (89)

我想将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);

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

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

谢谢,

提问于
用户回答回答于

没有确切的解决方案

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

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

小区域的近似

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

  • X = - [R ķCOS(PHI 0)
  • ÿ = - [R ž

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

用户回答回答于

由于此页面显示在谷歌之上,而我搜索同样的问题,我想提供一个更实际的答案。MVG的答案是正确的,但相当理论化。

我已经在javascript中为fitbit离子绘制了一个跟踪绘图应用程序。下面的代码是我如何解决这个问题。

//LOCATION PROVIDER
index.js
var gpsFix = false;
var circumferenceAtLat = 0;
function locationSuccess(pos){
  if(!gpsFix){
    gpsFix = true;
    circumferenceAtLat = Math.cos(pos.coords.latitude*0.01745329251)*111305;
  }
  pos.x:Math.round(pos.coords.longitude*circumferenceAtLat),
  pos.y:Math.round(pos.coords.latitude*110919), 
  plotTrack(pos);
}

plotting.js

plotTrack(position){

let x = Math.round((this.segments[i].start.x - this.bounds.minX)*this.scale);
let y = Math.round(this.bounds.maxY - this.segments[i].start.y)*this.scale; //heights needs to be inverted

//redraw?
let redraw = false;

//x or y bounds?
 if(position.x>this.bounds.maxX){
   this.bounds.maxX = (position.x-this.bounds.minX)*1.1+this.bounds.minX; //increase by 10%
   redraw = true;
 }
 if(position.x<this.bounds.minX){
   this.bounds.minX = this.bounds.maxX-(this.bounds.maxX-position.x)*1.1;
    redraw = true;
 };
 if(position.y>this.bounds.maxY){
   this.bounds.maxY = (position.y-this.bounds.minY)*1.1+this.bounds.minY; //increase by 10%
    redraw = true;
 }
 if(position.y<this.bounds.minY){
   this.bounds.minY = this.bounds.maxY-(this.bounds.maxY-position.y)*1.1;
    redraw = true;
 }
 if(redraw){
   reDraw();
 }
}


function reDraw(){

let xScale = device.screen.width / (this.bounds.maxX-this.bounds.minX);
let yScale = device.screen.height / (this.bounds.maxY-this.bounds.minY); 
if(xScale<yScale) this.scale = xScale; 
else this.scale = yScale;

//Loop trough your object to redraw all of them
}

扫码关注云+社区

领取腾讯云代金券