计算新的经度,从旧的纬度+ n米
Posted
技术标签:
【中文标题】计算新的经度,从旧的纬度+ n米【英文标题】:Calculating new longitude, latitude from old + n meters 【发布时间】:2011-09-19 20:35:37 【问题描述】:我想根据坐标和距离(以米为单位)创建 2 个新经度和 2 个新纬度,我想在某个点周围创建一个漂亮的边界框。它适用于城市的一部分,最大 ±1500 米。因此,我认为不必考虑地球的曲率。
所以我有 50.0452345
(x) 和 4.3242234
(y) 我想知道 x + 500 米,x - 500 米,y - 500 米,y + 500 米
我发现了很多算法,但几乎所有算法似乎都处理点之间的距离。
【问题讨论】:
gis.stackexchange.com/questions/25877/… 【参考方案1】:每经度的公里数约为
(pi/180) * r_earth * cos(theta*pi/180)
其中theta
是以度为单位的纬度,r_earth
约为 6378 公里。
每个纬度的公里数在所有位置都大致相同,大约
(pi/180) * r_earth = 111 km / degree
所以你可以这样做:
new_latitude = latitude + (dy / r_earth) * (180 / pi);
new_longitude = longitude + (dx / r_earth) * (180 / pi) / cos(latitude * pi/180);
只要dx
和dy
与地球的半径相比很小,并且您不会离两极太近。
【讨论】:
要从度数转换为弧度,你乘以 py 并除以 180。但你写cos(latitude*180/pi)
@josch:很好。下次尝试更正答案,而不是简单地提出更正。许多人只是简单地从 *** 复制和粘贴代码,认为它是正确的并且可以使用。
好的,方向是什么?我的意思是如果我想添加 50 米,它将添加到哪里?右、左、上还是下?
地球不是完美的球形,因此“半径”使用单个值是一个近似值。***说“从表面上的点到中心的距离从 6,353 公里到 6,384 公里”。它还说“将地球建模为球体的几种不同方法,每种方法的平均半径为 6,371 公里”,这表明了你的价值。确实,如果这种修正在您的应用程序中很重要,那么无论如何您都应该使用更好的算法。
对于任何不确定 r_earth 变量应该以米为单位并且应该等于大约 6371000.0【参考方案2】:
接受的答案是完全正确且有效的。我做了一些调整,变成了这样:
double meters = 50;
// number of km per degree = ~111km (111.32 in google maps, but range varies
between 110.567km at the equator and 111.699km at the poles)
// 1km in degree = 1 / 111.32km = 0.0089
// 1m in degree = 0.0089 / 1000 = 0.0000089
double coef = meters * 0.0000089;
double new_lat = my_lat + coef;
// pi / 180 = 0.018
double new_long = my_long + coef / Math.cos(my_lat * 0.018);
希望这也有帮助。
【讨论】:
0.0000089
?尽量避免使用幻数,没有人会理解这一点。
代码中地球直径和圆周率数字的缩写。不是魔法。
如果没有人知道如何复制这个数字,这仍然很神奇。你为什么不把完整的计算放到你的代码中?
谷歌地图中的 1 度等于 111.32 公里。 1 度 = 111.32 公里。 1KM 度数 = 1 / 111.32 = 0.008983。 1M 度数 = 0.000008983。
你应该在你的答案中发表评论,把它放在 cmets 是没有帮助的。【参考方案3】:
对于纬度做:
var earth = 6378.137, //radius of the earth in kilometer
pi = Math.PI,
m = (1 / ((2 * pi / 360) * earth)) / 1000; //1 meter in degree
var new_latitude = latitude + (your_meters * m);
对于经度:
var earth = 6378.137, //radius of the earth in kilometer
pi = Math.PI,
cos = Math.cos,
m = (1 / ((2 * pi / 360) * earth)) / 1000; //1 meter in degree
var new_longitude = longitude + (your_meters * m) / cos(latitude * (pi / 180));
变量your_meters
可以包含正值或负值。
【讨论】:
非常感谢,解决了我的问题。但我想说,如果你能添加一些关于这些位的更多解释性信息,尤其是m
以及那里发生的事情,那就更好了。【参考方案4】:
你签出了吗:How do I find the lat/long that is x km north of a given lat/long?
这些计算充其量是烦人的,我已经完成了很多。半正弦公式将成为您的朋友。
一些参考:http://www.movable-type.co.uk/scripts/latlong.html
【讨论】:
如果你在一个很小的区域工作,只做 latitude-0.09 和 longtitude-0.0148 得到大约一平方公里的区域真的很糟糕吗? 我会说这还不错。该级别的平方公里不会被地球的曲率扭曲 - 只要您处理的纬度/经度是十进制的。 @BenjaminUdinktenCate 这将在阿姆斯特丹工作,但在世界其他地方会不准确。执行“longitude-0.0148”只会让你在赤道处走大约 0.16 公里。【参考方案5】:我不得不花费大约两个小时来通过@nibot 制定解决方案,我只需要一种方法来根据其中心点和宽度/高度(或半径)(以公里为单位)创建一个边界框:
我不完全理解数学/地理上的解决方案。 我调整了解决方案(通过尝试和错误)以获得四个坐标:
北:
private static Position FromKmToNPosition(Position p, double km)
double r_earth = 6378;
var pi = Math.PI;
var new_latitude = p.Lat + (km / r_earth) * (180 / pi);
return new Position(new_latitude, p.Long);
东:
private static Position FromKmToEPosition(Position p, double km)
double r_earth = 6378;
var pi = Math.PI;
var new_longitude = p.Long + (km / r_earth) * (180 / pi) / Math.Cos(p.Lat * pi / 180);
return new Position(p.Lat, new_longitude);
南:
private static Position FromKmToSPosition(Position p, double km)
double r_earth = 6378;
var pi = Math.PI;
var new_latitude = p.Lat - (km / r_earth) * (180 / pi);
return new Position(new_latitude, p.Long);
西部:
private static Position FromKmToWPosition(Position p, double km)
double r_earth = 6378;
var pi = Math.PI;
var new_longitude = p.Long - (km / r_earth) * (180 / pi) / Math.Cos(p.Lat * pi / 180);
return new Position(p.Lat, new_longitude);
【讨论】:
【参考方案6】:如果您不必非常精确,那么:每 10000 米大约是纬度和经度的 0.1。 例如,我想从我的数据库中加载 point_A 周围 3000 米的位置:
double newMeter = 3000 * 0.1 / 10000;
double lat1 = point_A.latitude - newMeter;
double lat2 = point_A.latitude + newMeter;
double lon1 = point_A.longitude - newMeter;
double lon1 = point_A.longitude + newMeter;
Cursor c = mDb.rawQuery("select * from TABLE1 where lat >= " + lat1 + " and lat <= " + lat2 + " and lon >= " + lon1 + " and lon <= " + lon2 + " order by id", null);
【讨论】:
【参考方案7】:工作 Python 代码将坐标偏移 10 米。
def add_blur(lat, long):
meters = 10
blur_factor = meters * 0.000006279
new_lat = lat + blur_factor
new_long = long + blur_factor / math.cos(lat * 0.018)
return new_lat, new_long
【讨论】:
您使用的幻数0.00006279
会导致巨大的偏移。将其替换为 this 的值:earth_radius_in_km = 6378.137 coeff = (1 / ((2 * math.pi / 360) * earth_radius_in_km)) / 1000 blur_factor = meters * coeff # depending on the north, south use - or + on meters
通过应用此更改,我的偏移量从 36 米缩小到 10 厘米左右!【参考方案8】:
public double MeterToDegree(double meters, double latitude)
return meters / (111.32 * 1000 * Math.Cos(latitude * (Math.PI / 180)));
【讨论】:
【参考方案9】:参见 Google 地图官方文档(下面的链接),因为他们在简单/简单的地图上解决了国家/地区距离问题:)
我推荐这个解决方案来轻松/简单地解决边界问题,您可以知道您正在解决哪个区域的边界问题(不推荐在全球范围内)
注意:
纬线从西向东延伸,标记一个点的南北位置。纬线称为平行线,总共有 180 度的纬度。每个纬度之间的距离约为 69 英里(110 公里)。
距离赤道越远,经度之间的距离越小。赤道经度之间的距离与纬度相同,大约为 69 英里(110 公里)。在北纬 45 度或南纬 45 度处,两者之间的距离约为 49 英里(79 公里)。当子午线在该点汇聚时,两极的经度之间的距离为零。
Original source 1 Original source 2
Official Google Maps Documentation: Code Example: Autocomplete Restricted to Multiple Countries
查看他们的代码部分,他们如何解决距离中心 + 10 公里 +/- 0.1 度的问题
function initMap(): void
const map = new google.maps.Map(
document.getElementById("map") as HTMLElement,
center: lat: 50.064192, lng: -130.605469 ,
zoom: 3,
);
const card = document.getElementById("pac-card") as HTMLElement;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
const center = lat: 50.064192, lng: -130.605469 ;
// Create a bounding box with sides ~10km away from the center point
const defaultBounds =
north: center.lat + 0.1,
south: center.lat - 0.1,
east: center.lng + 0.1,
west: center.lng - 0.1,
;
const input = document.getElementById("pac-input") as HTMLInputElement;
const options =
bounds: defaultBounds,
componentRestrictions: country: "us" ,
fields: ["address_components", "geometry", "icon", "name"],
origin: center,
strictBounds: false,
types: ["establishment"],
;
【讨论】:
【参考方案10】:这就是我在 VBA 中所做的,似乎对我有用。计算单位是英尺而不是米
Public Function CalcLong(OrigLong As Double, OrigLat As Double, DirLong As String, DirLat As String, DistLong As Double, DistLat As Double)
Dim FT As Double
Dim NewLong, NewLat As Double
FT = 1 / ((2 * WorksheetFunction.Pi / 360) * 20902230.971129)
If DirLong = "W" Then
NewLat = CalcLat(OrigLong, OrigLat, DirLong, DirLat, DistLong, DistLat)
NewLong = OrigLong - ((FT * DistLong) / Cos(NewLat * (WorksheetFunction.Pi / 180)))
CalcLong = NewLong
Else
NewLong = OrigLong + ((FT * DistLong) / Math.Cos(CalcLat(OrigLong, OrigLat, DirLong, DirLat, DistLong, DistLat) * (WorksheetFunction.Pi / 180)))
CalcLong = NewLong
End If
End Function
Public Function CalcLat(OrigLong As Double, OrigLat As Double, DirLong As String, DirLat As String, DistLong As Double, DistLat As Double) As Double
Dim FT As Double
Dim NewLat As Double
FT = 1 / ((2 * WorksheetFunction.Pi / 360) * 20902230.971129)
If DirLat = "S" Then
NewLat = (OrigLat - (FT * DistLat))
CalcLat = NewLat
Else
NewLat = (OrigLat + (FT * DistLat))
CalcLat = NewLat
End If
End Function
【讨论】:
【参考方案11】:为了完整起见发布此方法。
“按原样”使用此方法:
在任一轴上将任意(纬度、经度)点移动给定的米数。通过定义的米移动任意点的 Python 方法。
def translate_latlong(lat,long,lat_translation_meters,long_translation_meters):
''' method to move any lat,long point by provided meters in lat and long direction.
params :
lat,long: lattitude and longitude in degrees as decimal values, e.g. 37.43609517497065, -122.17226450150885
lat_translation_meters: movement of point in meters in lattitude direction.
positive value: up move, negative value: down move
long_translation_meters: movement of point in meters in longitude direction.
positive value: left move, negative value: right move
'''
earth_radius = 6378.137
#Calculate top, which is lat_translation_meters above
m_lat = (1 / ((2 * math.pi / 360) * earth_radius)) / 1000;
lat_new = lat + (lat_translation_meters * m_lat)
#Calculate right, which is long_translation_meters right
m_long = (1 / ((2 * math.pi / 360) * earth_radius)) / 1000; # 1 meter in degree
long_new = long + (long_translation_meters * m_long) / math.cos(latitude * (math.pi / 180));
return lat_new,long_new
【讨论】:
【参考方案12】:var meters = 50;
var coef = meters * 0.0000089;
var new_lat = map.getCenter().lat.apply() + coef;
var new_long = map.getCenter().lng.apply() + coef / Math.cos(new_lat * 0.018);
map.setCenter(lat:new_lat, lng:new_long);
【讨论】:
请在您的回答中添加一些解释。 如果您想将地图对象移动到当前地图中心附近约 50 米处,那么您可以使用此代码与 +,- 数字替换 +50以上是关于计算新的经度,从旧的纬度+ n米的主要内容,如果未能解决你的问题,请参考以下文章
给定 GPS 的地理位置,如何在给定的 x 米半径内找到纬度和经度