谷歌地图android中一组经纬度点的中心
Posted
技术标签:
【中文标题】谷歌地图android中一组经纬度点的中心【英文标题】:Center of a cluster of latitude and longitude points in Google map android 【发布时间】:2016-04-21 20:57:28 【问题描述】:我正在尝试在 android 中获取形状的中心。形状是在地图上手工绘制的。我有所有的坐标,但平均值比我想象的要复杂。我想在平均纬度和经度上绘制一个标记。
我尝试过分别将纬度和经度相加,然后除以点数。这并没有给出正确的答案。标记似乎总是落后于绘图人物。我也尝试过使用该实现,但它给出了相同的答案,之前的 SO 问题,Calculate the center point of multiple latitude/longitude coordinate pairs
我一直在使用的代码:
private void calculateFreeHandPolygonParameters()
double xValues = 0;
double yValues = 0;
double zValues = 0;
int count = 0;
// linesForPolygon a list of the lines in the polygon
for(Polyline line : linesForPolygon)
for (LatLng point : line.getPoints())
xValues += Math.cos(Math.toRadians(point.latitude)) * Math.cos(Math.toRadians(point.longitude));
yValues += Math.cos(Math.toRadians(point.latitude)) * Math.sin(Math.toRadians(point.longitude));
zValues += Math.sin(Math.toRadians(point.latitude));
count++;
double meanX = xValues/count;
double meanY = yValues/count;
double meanZ = zValues/count;
double centralLongitude = Math.atan2(meanY, meanX);
double centralSquareRoot = Math.sqrt(Math.pow(meanX, 2) + Math.pow(meanX, 2) + Math.pow(meanX, 2));
double centralLatitude = Math.atan2(meanZ, centralSquareRoot);
double latitude = Math.toDegrees(centralLatitude);
double longitude = Math.toDegrees(centralLongitude);
Log.i("MAPS", "Freehand Parameters: x mean -> " + latitude + " y mean -> " + longitude);
testMarker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.title("Polygon center")
.snippet("lat: " + latitude + " long: " + longitude));
【问题讨论】:
您描述的方法应该有效,除非经度靠近国际日期变更线,或者位置靠近两极。也许你应该分享你的代码。 【参考方案1】:这是我的质心代码:
public class PolygonCentroid
private List<GeoPoint> points;
private int pointsSize;
public PolygonCentroid(List<GeoPoint> points)
this.points = points;
this.pointsSize = points.size();
protected double polygonArea()
double area = 0;
for (int i = 0, j; i < pointsSize; i++)
j = (i + 1) % pointsSize;
area += points.get(i).getLongitude() * points.get(j).getLatitude();
area -= points.get(i).getLatitude() * points.get(j).getLongitude();
area /= 2.0;
return area;
public GeoPoint centroid()
double cx = 0, cy = 0;
double factor;
for (int i = 0, j; i < pointsSize; i++)
j = (i + 1) % pointsSize;
factor = (points.get(i).getLongitude() * points.get(j).getLatitude() - points.get(j).getLongitude() * points.get(i).getLatitude());
cx += (points.get(i).getLongitude() + points.get(j).getLongitude()) * factor;
cy += (points.get(i).getLatitude() + points.get(j).getLatitude()) * factor;
double A = polygonArea();
factor = 1.0 / (6.0 * A);
cx *= factor;
cy *= factor;
return new GeoPoint(cy, cx);
另外,请注意质心可以在多边形之外:
Full source code 和 usage。
【讨论】:
此方法有效,但仅适用于第一次迭代。我还没有弄清楚为什么如果我绘制另一个多边形它不起作用。标记落后于我的代码的先前版本。 别忘了像我一样重置坐标列表。 >"marker trails behind" 我想您应该注意Z-ordering,如果您想始终在顶部显示一些叠加层。【参考方案2】:-
您实际上需要计算所谓的 CENTROID。这不是一件小事,看这里:
http://www.spatialanalysisonline.com/html/index.html?centroids_and_centers.htm
注意所谓的GREAT CIRCLE,在飞机地图上回忆飞行计划......因此,如果距离相对较大,您需要记住这种现象。
这是一道经典的GIS问题,在你理解了算法的伪代码之后,就是简单的编码任务了……试试gis.stackexchange.com
【讨论】:
我一直使用的代码怎么不起作用?像我所做的那样计算平均值非常有意义吗?您提供的链接中的第一种方法是我最初尝试过的,但也一直落后。需要计算面积的方法会变得异常复杂 是的,这种算法的底层代码确实很复杂......通常使用gis库来完成这种任务,或者如果使用postgis存储在数据库中的位置,那么postgis就有这个还有一种查询方法。以上是关于谷歌地图android中一组经纬度点的中心的主要内容,如果未能解决你的问题,请参考以下文章
应用启动时在 android 谷歌地图中获取当前位置(纬度,经度)
如何将谷歌地图标记的纬度和经度发送到 Firebase - android? [关闭]