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
Post a Comment