计算多个纬度/经度坐标对的中心点
给定一组纬度和经度点,如何计算该组中心点(也称为将视图集中在所有点上的点)的纬度和经度?
编辑:我使用过的Python解决方案:
Convert lat/lon (must be in radians) to Cartesian coordinates for each location.
X = cos(lat) * cos(lon)
Y = cos(lat) * sin(lon)
Z = sin(lat)
Compute average x, y and z coordinates.
x = (x1 + x2 + ... + xn) / n
y = (y1 + y2 + ... + yn) / n
z = (z1 + z2 + ... + zn) / n
Convert average x, y, z coordinate to latitude and longitude.
Lon = atan2(y, x)
Hyp = sqrt(x * x + y * y)
Lat = atan2(z, hyp)
Given a set of latitude and longitude points, how can I calculate the latitude and longitude of the center point of that set (aka a point that would center a view on all points)?
EDIT: Python solution I've used:
Convert lat/lon (must be in radians) to Cartesian coordinates for each location.
X = cos(lat) * cos(lon)
Y = cos(lat) * sin(lon)
Z = sin(lat)
Compute average x, y and z coordinates.
x = (x1 + x2 + ... + xn) / n
y = (y1 + y2 + ... + yn) / n
z = (z1 + z2 + ... + zn) / n
Convert average x, y, z coordinate to latitude and longitude.
Lon = atan2(y, x)
Hyp = sqrt(x * x + y * y)
Lat = atan2(z, hyp)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
我用 JavaScript 完成了这个任务,如下所示
I did this task in javascript like below
Dart/Flutter 计算多个经纬度坐标对的中心点
Dart/Flutter Calculate the center point of multiple latitude/longitude coordinate pairs
如果您希望所有点在图像中可见,您需要纬度和经度的极值,并确保您的视图包含具有您想要的任何边框的这些值。
(从 Alnitak 的回答来看,如何计算极值可能有点问题,但如果它们在环绕的经度两侧各有几度,那么你就可以决定并采取正确的范围。)
如果你不想扭曲这些点所在的任何地图,然后调整边界框的纵横比,使其适合您分配给视图的任何像素,但仍包含极值。
要使点保持在某个任意缩放级别的中心,请计算“刚好适合”上述点的边界框的中心,并将该点保留为中心点。
If you want all points to be visible in the image, you'd want the extrema in latitude and longitude and make sure that your view includes those values with whatever border you want.
(From Alnitak's answer, how you calculate the extrema may be a little problematic, but if they're a few degrees on either side of the longitude that wraps around, then you'll call the shot and take the right range.)
If you don't want to distort whatever map that these points are on, then adjust the bounding box's aspect ratio so that it fits whatever pixels you've allocated to the view but still includes the extrema.
To keep the points centered at some arbitrary zooming level, calculate the center of the bounding box that "just fits" the points as above, and keep that point as the center point.
为了感谢这个线程,以下是我在 Ruby 中实现的一点贡献,希望能为某人节省几分钟的宝贵时间:
As an appreciation for this thread, here is my little contribution with the implementation in Ruby, hoping that I will save someone a few minutes from their precious time:
我使用从 www.geomidpoint.com 获得的公式并编写了以下 C++ 实现。 array 和 geocoords 是我自己的类,其功能应该是不言自明的。
I used a formula that I got from www.geomidpoint.com and wrote the following C++ implementation. The
array
andgeocoords
are my own classes whose functionality should be self-explanatory.斯卡拉版本:
Scala version:
我发现这篇文章非常有用,所以这里是 PHP 的解决方案。我已经成功地使用了这个,只是想节省其他开发人员一些时间。
I found this post very useful so here is the solution in PHP. I've been using this successfully and just wanted to save another dev some time.
原始函数的 Javascript 版本
Javascript version of the original function
为了可能节省某人一两分钟,这里是在 Objective-C 而不是 python 中使用的解决方案。此版本采用包含 MKMapCoords 的 NSValues 的 NSArray,这是在我的实现中调用的:
In the interest of possibly saving someone a minute or two, here is the solution that was used in Objective-C instead of python. This version takes an NSArray of NSValues that contain MKMapCoordinates, which was called for in my implementation:
非常好的解决方案,正是我的 swift 项目所需要的,所以这里有一个 swift 端口。谢谢&这还有一个游乐场项目:
https://github.com/ppoh71/playgounds/tree/master/centerLocationPoint.playground
very nice solutions, just what i needed for my swift project, so here's a swift port. thanks & here's also a playground project:
https://github.com/ppoh71/playgounds/tree/master/centerLocationPoint.playground
Java版本,如果有人需要的话。常量定义为静态,不会对其进行两次计算。
Java Version if anyone needs it. Constants defined static to not calculate them twice.
Dart 实现 Flutter 来查找多个纬度、经度的中心点。
导入数学包
纬度和经度列表
Dart Implementation for Flutter to find Center point for Multiple Latitude, Longitude.
import math package
Latitude and Longitude List
如果您有兴趣获得一个非常简化的点“中心”(例如,简单地将地图居中到 gmaps 多边形的中心),那么这里有一个对我有用的基本方法。
这将返回多边形中心的中间纬度/经度坐标。
If you are interested in obtaining a very simplified 'center' of the points (for example, to simply center a map to the center of your gmaps polygon), then here's a basic approach that worked for me.
This returns the middle lat/lng coordinate for the center of a polygon.
在 Django 中,这是微不足道的(并且实际上有效,我遇到了许多解决方案无法正确返回纬度负值的问题)。
例如,假设您正在使用 django-geopostcodes (我是作者)。
point
是一个 DjangoPoint
实例,可用于执行诸如检索距该中心点 10 公里范围内的所有对象等操作;将其更改为原始 Python 很简单;
Django 正在使用 GEOS - 更多详细信息请参见 https:// docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/
In Django this is trivial (and actually works, I had issues with a number of the solutions not correctly returning negatives for latitude).
For instance, let's say you are using django-geopostcodes (of which I am the author).
point
is a DjangoPoint
instance that can then be used to do things such as retrieve all objects that are within 10km of that centre point;Changing this to raw Python is trivial;
Under the hood Django is using GEOS - more details at https://docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/
这是基于 @Yodacheese 使用 Google Maps api 的 C# 答案的 Android 版本:
在应用程序 build.gradle 中添加:
Here is the Android version based on @Yodacheese's C# answer using Google Maps api:
in app build.gradle add:
其中许多答案只是一种奇怪方法的变体,这种方法没有找到包含所有点的边界框的真正中心。相反,它找到大多数点的中心(某种加权中心)。如果您想要所有点的真实中心,而不管聚类和权重如何,您可以获得边界框并轻松找到这 4 个角的中心。如果您不关心地球曲率因素,您可以使用像(C# 代码)这样简单的方法:
So many of these answers are just variations on an odd approach that doesn't find the true center of the bounding box that comprises all the points. Rather it finds the center of most points (a weighted center of sorts). If you want the true center of all points regardless of clustering and weights, you can get the bounding box and easily find the center of those 4 corners. If you aren't concerned about factoring in earth curvature, you can get away with something as simple as (C# code):
这是寻找中心点的 python 版本。
lat1 和 lon1 是纬度和经度列表。
它将重新调整中心点的纬度和经度。
Here is the python Version for finding center point.
The lat1 and lon1 are latitude and longitude lists.
it will retuen the latitude and longitude of center point.
这与加权平均问题相同,其中所有权重都相同,并且有两个维度。
求中心纬度的所有纬度的平均值和中心经度的所有经度的平均值。
买者自负:这是一个近距离近似值,当由于地球曲率而与平均值的偏差超过几英里时,误差将变得难以控制。请记住,纬度和经度是度数(不是真正的网格)。
This is is the same as a weighted average problem where all the weights are the same, and there are two dimensions.
Find the average of all latitudes for your center latitude and the average of all longitudes for the center longitude.
Caveat Emptor: This is a close distance approximation and the error will become unruly when the deviations from the mean are more than a few miles due to the curvature of the Earth. Remember that latitudes and longitudes are degrees (not really a grid).
如果您想考虑正在使用的椭球体,您可以找到公式
这里http://www.ordnancesurvey.co.uk/oswebsite/gps/ docs/A_Guide_to_Cooperative_Systems_in_Great_Britain.pdf
参见附件 B
该文档包含很多内容其他有用的东西
B
If you wish to take into account the ellipsoid being used you can find the formulae
here http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf
see Annexe B
The document contains lots of other useful stuff
B
PHP 中的对象外。给定坐标对数组,返回中心。
取自#4 的想法
Out of object in PHP. Given array of coordinate pairs, returns center.
Taken idea from #4
谢谢!这是 OP 使用度的解决方案的 C# 版本。它利用系统。 Device.Location.GeoCooperative 类
Thanks! Here is a C# version of OP's solutions using degrees. It utilises the System.Device.Location.GeoCoordinate class
当它们从 359' 回绕到 0' 时,仅对它们进行平均的简单方法会出现带有角度的奇怪边缘情况。
关于SO的更早的问题 询问如何求一组罗盘角度的平均值。
针对球面坐标推荐的方法的扩展是:
The simple approach of just averaging them has weird edge cases with angles when they wrap from 359' back to 0'.
A much earlier question on SO asked about finding the average of a set of compass angles.
An expansion of the approach recommended there for spherical coordinates would be:
非常有用的帖子!我已经在 JavaScript 中实现了这个,这是我的代码。我已经成功地使用了这个。
Very useful post! I've implemented this in JavaScript, hereby my code. I've used this successfully.