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表示接近你的地图的中心纬度.此外,要从角度(以弧度测量)转换为长度,您需要乘以地球的半径(在此模型中假定为球体).
这是简单的equirectangular投影.在大多数情况下,你就可以计算COS(φ 0)只有一次,这使得大量的点真的很便宜的后续计算.
小智 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.