2014-04-14 37 views
1

正如话题所述,我有一个多边形并且想要计算质心(质心)。我使用地理坐标,将它们转换为像素坐标系,使用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

不,我不认为这是你描述的情况。我会在[链接​​](http://www.pic-upload.de/view-22911875/wrong-centroid.png.html)上传一张照片。正如你所看到的质心不正确。我知道我投射在一个平原上,这样做时出现错误,但这是一个相当小的区域,错误不应该那么好。有趣的是,如果我让三角形变小,错误会变得更大。 – pakrom

回答

0

我认为你的计算有一个舍入误差是由于像素和纬度/多头之间的转换 - 有没有必要做这个 - 你可以用纬度/多头直接工作。

您可以添加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,并从最终结果中减去它。