javascript - Nokia Here Maps calculating the centroid of a polygon (e.g triangle) generates wrong results -


as topic says have polygon , want calculate center of mass (centroid). take geo-coordinates, transform them pixel cooridinates use formula found on http://en.wikipedia.org/wiki/centroid , transform the calculated pixels geo-coordinates.

the result seems wrong (i can't post pictures). relevant code snippet is:

    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;              (var = 0; < 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 

i reckon calculation has rounding error due switching between pixels , lat/longs - there no need - can work lat/longs directly.

you can add getcentroid() method polygon class shown:

 nokia.maps.map.polygon.prototype.getcentroid = function (arg) {     var signedarea = 0,       len = this.path.getlength(),       centroidlongitude = 0,       centroidlatitude = 0;       (i=0; < len; i++){       var = this.path.get(i),       b = this.path.get( + 1 < len ? + 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);   }; 

you can call polygon.getcentroid() (e.g. add marker) follows:

 map.objects.add(new nokia.maps.map.marker(polygon.getcentroid())); 

note, may still edge effects of polygon crosses 180th meridian.(use isidl()method check) . in case may need add 360 each latitude prior making calculations, , substract final result.


Comments

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -