Gps 从纬度、经度转换为x、y
我想将GPS位置(纬度、经度)转换为x、y坐标。 我找到了很多关于这个主题的链接并应用了它,但它并没有给我正确的答案Gps 从纬度、经度转换为x、y,gps,mapping,geometry,Gps,Mapping,Geometry,我想将GPS位置(纬度、经度)转换为x、y坐标。 我找到了很多关于这个主题的链接并应用了它,但它并没有给我正确的答案 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
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);
我按照以下步骤测试答案:
(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)有什么帮助吗
谢谢,不存在精确的解决方案
从球体到平面没有等轴测贴图。将球体中的纬度/经度坐标转换为平面中的x/y坐标时,不能指望此操作会保留所有长度。你必须接受某种变形。确实存在许多不同的地图投影,它们可以在保留长度、角度和面积之间实现不同的折衷。对于地球表面很小的部分来说,这是很常见的。你可能听说过。但是有
您引用的公式计算x/y/z,即三维空间中的一个点。但即使在那里,你也无法自动获得正确的距离。球体表面上两点之间的最短距离将穿过该球体,而地球上的距离主要是曲面后的测地线长度。所以它们会更长
小面积近似
如果要绘制的地球表面部分相对较小,则可以使用非常简单的近似值。您可以简单地使用横轴x表示经度λ,纵轴y表示纬度φ。不过,两者之间的比例不应为1:1。相反,您应该使用cos(φ0)作为纵横比,其中φ0表示靠近地图中心的纬度。此外,要将角度(以弧度为单位)转换为长度,您需要乘以地球的半径(在此模型中,地球被假定为球体)
- x=rλcos(φ0)
- y=rφ
这很简单。在大多数情况下,您只能计算cos(φ0)一次,这使得后续大量点的计算非常便宜。由于在我搜索同一问题时,此页面显示在google顶部,因此我想提供更实用的答案。MVG的答案是正确的,但在理论上是合理的 我用javascript为fitbit ionic制作了一个轨迹绘制应用程序。下面的代码是我如何解决这个问题的
//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
}
plotTrack(位置){
设x=Math.round((this.segments[i].start.x-this.bounds.minX)*this.scale);
设y=Math.round(this.bounds.maxY-this.segments[i].start.y)*this.scale;//需要反转高度
//重画?
让重画=假;
//x或y边界?
if(position.x>this.bounds.maxX){
this.bounds.maxX=(position.x-this.bounds.minX)*1.1+this.bounds.minX;//增加10%
重画=真;
}
if(position.xthis.bounds.maxY){
this.bounds.maxY=(position.y-this.bounds.minY)*1.1+this.bounds.minY;//增加10%
重画=真;
}
如果(position.y我想和大家分享我是如何处理这个问题的。我使用了@MvG所说的等矩形投影,但这种方法给出了与地球(或整个地图)相关的X和y位置,这意味着你得到了全局位置。在我的例子中,我想在一个小区域(大约500平方米)内转换坐标,因此我将投影点与另外2个点关联,获得全局位置并与局部(屏幕上)位置关联,如下所示:
首先,我在要投影的区域周围选择2个点(左上角和右下角),如下图所示:
一旦在lat和lng中有了全局参考区域,我就对屏幕位置进行了相同的操作。包含此数据的对象如下所示
//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");
如您所见,我是用javascript编写的,但是计算可以翻译成任何语言
PS:我正在将转换后的位置应用于id为“指向项目”的html元素。为了在项目中使用这段代码,您应创建此元素(样式为绝对位置)或更改“用法”块。最好转换为utm坐标,并将其视为x和y
import utm
u = utm.from_latlon(12.917091, 77.573586)
结果将是(779260.6231566061429369.8665238516,43,'p')
前两个可以视为x,y坐标,43P是UTM区域,对于小区域(宽度高达668公里)可以忽略该区域。为了完整性,我想添加我的@allexrm代码的python改编版本,它运行得非常好。再次感谢
radius = 6371 #Earth Radius in KM
class referencePoint:
def __init__(self, scrX, scrY, lat, lng):
self.scrX = scrX
self.scrY = scrY
self.lat = lat
self.lng = lng
# Calculate global X and Y for top-left reference point
p0 = referencePoint(0, 0, 52.526470, 13.403215)
# Calculate global X and Y for bottom-right reference point
p1 = referencePoint(2244, 2060, 52.525035, 13.405809)
# This function converts lat and lng coordinates to GLOBAL X and Y positions
def latlngToGlobalXY(lat, lng):
# Calculates x based on cos of average of the latitudes
x = radius*lng*math.cos((p0.lat + p1.lat)/2)
# Calculates y based on latitude
y = radius*lat
return {'x': x, 'y': y}
# This function converts lat and lng coordinates to SCREEN X and Y positions
def latlngToScreenXY(lat, lng):
# Calculate global X and Y for projection point
pos = latlngToGlobalXY(lat, lng)
# Calculate the percentage of Global X position in relation to total global width
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
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)*perX,
'y': p0.scrY + (p1.scrY - p0.scrY)*perY
}
pos = latlngToScreenXY(52.525607, 13.404572);
位置['x]和位置['y]包含lat和lng的平移x&y坐标(52.525607,13.404572)
我希望这对任何像我这样的人都有帮助,他们可以正确地解决将lat lng转换为本地参考坐标系的问题
Best谢谢@MvG,我不参与这些主题,我只需要在地图上画点,这些点之间的距离不超过50米,有没有简单的方法?@alsadi90:我更新了我的答案,为您的用例描述了一个简单的近似值。谢谢,但我有以下问题:这里λ和φ的弧度?还有关于φ0,如果我的面积接近50mx50m@alsadi90:以度或弧度测量角度只会影响贴图的大小,而不会影响贴图的形状。必须确保正确计算余弦,这在大多数编程语言中意味着使用弧度。例如₀ 我建议你只需取纬度下限和上限之间的平均值。但是对于这样小的地图,从该区域内取任何纬度都可能很好。谢谢你的帮助