2014-04-14 63 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,並從最終結果中減去它。