正如主题所说,我有一个多边形,想要计算质心(质心)。我使用地理坐标,将它们转换为像素cooridinates,使用http://en.wikipedia.org/wiki/Centroid上的公式,并将计算的像素转换回地理坐标。
结果似乎错了(我无法发布图片)。相关的代码段是:
this.drawPolygonCenter = function (mapService, coords) {
var sumY = 0;
var sumX = 0;
var partialSum = 0;
var sum = 0;
var cm = mapService.getCurrentMapReference();
var points = [];
coords.forEach(function (c, idx) {
points.push(cm.geoToPixel(c));
console.log("x: " + points[idx].x + " y: " + points[idx].y);
});
var n = points.length;
for (var i = 0; i < n - 1; i++) {
partialSum = points[i].x * points[i + 1].y - points[i + 1].x * points[i].y;
sum += partialSum;
sumX += (points[i].x + points[i + 1].x) * partialSum;
sumY += (points[i].y + points[i + 1].y) * partialSum;
}
var area = 0.5 * sum;
var div = 6 * area;
var x1 = sumX / div;
var y1 = sumY / div;
console.log("Centroid: x= " + x1 + " y= " + y1); // debug
var pinLocation = cm.pixelToGeo(Math.ceil(x1), Math.ceil(y1));
var pin = this.createCenterPin(pinLocation);
cm.objects.add(new nokia.maps.map.StandardMarker(pinLocation)); // debug
答案 0 :(得分:0)
我认为你的计算有一个舍入错误是由于像素和纬度/长度之间的切换 - 没有必要这样做 - 你可以直接使用lat / longs。
您可以向getCentroid()
类添加Polygon
方法,如下所示:
nokia.maps.map.Polygon.prototype.getCentroid = function (arg) {
var signedArea = 0,
len = this.path.getLength(),
centroidLongitude = 0,
centroidLatitude = 0;
for (i=0; i < len; i++){
var a = this.path.get(i),
b = this.path.get( i + 1 < len ? i + 1 : 0);
signedArea +=
((a.longitude * b.latitude) - (b.longitude * a.latitude));
centroidLongitude += (a.longitude + b.longitude) *
((a.longitude * b.latitude) - (b.longitude * a.latitude));
centroidLatitude += (a.latitude + b.latitude) *
((a.longitude * b.latitude) - (b.longitude * a.latitude));
}
signedArea = signedArea /2;
centroidLongitude = centroidLongitude/ (6 * signedArea);
centroidLatitude = centroidLatitude/ (6 * signedArea);
return new nokia.maps.geo.Coordinate(centroidLatitude, centroidLongitude);
};
您可以按如下方式致电polygon.getCentroid()
(例如添加标记):
map.objects.add(new nokia.maps.map.Marker(polygon.getCentroid()));
注意,您可能仍会得到Polygon
穿过第180个子午线的一些边缘效果。(使用isIDL()
方法检查)。在这种情况下,您可能需要在进行计算之前向每个纬度添加360,并从最终结果中减去它。