2017-03-27 1 views
10

Je dessine un cercle au centre de mes cartes de polygones non tracées. Le cercle est placé au centre pour la majeure partie du pays. Mais pour la forme de polygone "Norvège", le centre de retour est faux. Vous pouvez voir la différence clairement, après avoir zoomé/mis à l'échelle la page.Trouve le point central du polygone non façonné pour la carte

enter image description here

J'utilise cette solution stackoverflow: link

Mon code ci-dessous ici. SVG:

<svg xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; z-index: 0; float: left; background: transparent; height: 500px; width: 500px; margin-top: 0px; margin-left: 0px;"> 
<path class="mapShape" stroke="#FFFFFF" stroke-width="0.25" fill="#ffff00" d="M289.61881571694846,107.44341140465033,293.96308112495205,110.5369251340838,292.1742152937817,111.64028258514635,293.69594267913214,114.17588213225122,291.33275072129567,115.75640079550517,290.21101327644885,116.115304587361,290.79940687634996,113.34302402649551,289.01707237203874,111.73064813415773,286.86058614336986,113.10652807111005,286.17946205663384,116.00897875925767,284.8551099335093,117.71420145300249,283.3639577705983,116.78716653168755,281.5503303156214,116.97787478097227,280.0068557650149,114.91879878457861,279.17443456817995,115.95395481299134,278.3128736053582,116.11389849530838,278.1091105619184,118.63382135713674,275.4914839478672,118.02707970555407,275.1238635503685,120.11785014900434,273.7901091874799,120.10529402219055,272.87321137841224,122.7050543288587,271.48390485080984,126.60600357598904,269.3273468493182,131.3173178164711,269.8332017031975,132.42411528484843,269.3498835156233,133.6909765856373,267.9721324124638,133.63667113556374,267.07023512332535,136.56637255563933,267.1556447822521,140.55669253761528,268.04325927968785,142.03410132622142,267.5838414420485,145.3716436133896,266.42815545209885,147.26315676671453,265.8157897294402,148.82368555076928,264.88410671891126,147.16092140518467,262.1416671663106,150.27022727262624,260.28992834251846,150.88797751378152,258.3692158361812,149.54060413568916,257.8725479035983,146.63056295282385,257.4334417747625,140.05376745248705,258.71236170116373,138.13152704055724,262.3797376189663,135.55992732652805,265.12181830745385,132.29324106111955,267.6643705490366,127.68026976914571,271.0015914827522,120.85619046583638,273.32767689129025,118.04298816880565,277.1444838258035,113.13815447740048,280.19224496586196,111.35745222872376,282.47741986550216,111.5754647031133,284.5924214026924,108.10819671605745,287.12506899475255,108.29698566394183ZM284.83905555555555,72.19815552139636,281.7365555555555,74.85366572152822,279.28612499999997,73.35699077101634,280.24459722222224,71.66044868206447,279.40541666666667,69.508641420061,282.28369444444445,68.1303212868272,282.8351944444444,70.69457195193213ZM275.84976388888896,58.9806663889022,280.42198611111115,64.57567572395904,276.92690277777774,67.37974197318883,276.1551666666667,72.37724133868834,274.9366805555556,73.61091608778322,274.2752777777778,78.81637965917018,272.6015972222222,79.05316716888755,269.61470833333334,75.26524507138704,270.87438888888886,72.97467771855085,268.79249999999996,71.06094914643477,266.0865416666667,65.20265086315597,265.0062916666667,59.363240232610856,268.7927361111111,56.545993503156645,269.5535,59.301357483657114,271.5316944444445,59.193568518861454,272.0590972222222,56.500983977896404,274.0984027777777,56.221878380253195ZM285.84392411084985,53.30414066139549,288.5659801818243,56.17728511117262,286.50645903652526,60.397046089088526,282.4784246850189,61.291565425339506,278.3822061520165,60.0221846103223,278.1350923237096,57.880800099653854,276.14203281216373,57.74271786397911,274.62224329302427,54.037937230381914,278.9111000819593,51.69790103414376,280.92770107932694,53.71698527072119,282.3322952181492,51.194805998985345Z" stroke-linejoin="round" stroke-linecap="square" nodeValue="#E0E0E0"></path> 
<circle fill="#FE0000" cx="271.7692623673869" cy="128.99711033923683" fill-opacity="1" r="1"></circle> 
</svg> 

JavaScript:

var path = "289.61881571694846,107.44341140465033,293.96308112495205,110.5369251340838,292.1742152937817,111.64028258514635,293.69594267913214,114.17588213225122,291.33275072129566,115.75640079550517,290.21101327644885,116.115304587361,290.79940687634996,113.34302402649551,289.01707237203874,111.73064813415773,286.86058614336985,113.10652807111005,286.17946205663383,116.00897875925767,284.8551099335093,117.71420145300249,283.3639577705983,116.78716653168754,281.5503303156214,116.97787478097227,280.0068557650149,114.91879878457861,279.17443456817994,115.95395481299134,278.3128736053582,116.11389849530837,278.1091105619184,118.63382135713674,275.4914839478672,118.02707970555407,275.1238635503685,120.11785014900434,273.7901091874799,120.10529402219055,272.87321137841223,122.7050543288587,271.48390485080983,126.60600357598903,269.3273468493182,131.3173178164711,269.8332017031975,132.42411528484843,269.3498835156233,133.6909765856373,267.9721324124638,133.63667113556374,267.07023512332534,136.56637255563933,267.1556447822521,140.55669253761528,268.04325927968784,142.03410132622142,267.5838414420485,145.3716436133896,266.42815545209885,147.26315676671453,265.8157897294402,148.82368555076928,264.88410671891125,147.16092140518467,262.1416671663106,150.27022727262624,260.28992834251846,150.88797751378152,258.3692158361812,149.54060413568916,257.8725479035983,146.63056295282385,257.4334417747625,140.05376745248705,258.71236170116373,138.13152704055724,262.3797376189663,135.55992732652805,265.12181830745385,132.29324106111954,267.6643705490366,127.68026976914571,271.0015914827522,120.85619046583638,273.32767689129025,118.04298816880565,277.1444838258035,113.13815447740047,280.19224496586196,111.35745222872376,282.47741986550215,111.5754647031133,284.5924214026924,108.10819671605745,287.12506899475255,108.29698566394182" 
     var stringData = path.split(","); 
     var length = stringData.length; 
     var data = [], obj; 

     for (var i = 0; i < length; i = i + 2) { 
      obj = { x: parseFloat(stringData[i]), y: parseFloat(stringData[i + 1]) }; 
      data.push(obj); 
     } 

     var centerPoint = _findMidPointofPoylgon(data); 
     alert("cx: " + centerPoint.x + "cy: " + centerPoint.y); 

    //Return the centerX and centerY of the unshape polygon 
     function _findMidPointofPoylgon (points) { 
      var x = 0, 
      y = 0, 
      i, min = 0, 
      j, 
      f, 
      point1, 
      point2; 
      var max = points.length; 
      var area = function() { 
       var area = 0, 
        i, 
        j, 
        point1, 
        point2; 

       for (i = 0, j = max - 1; i < max; j = i, i++) { 
        point1 = points[i]; 
        point2 = points[j]; 
        area += point1.x * point2.y; 
        area -= point1.y * point2.x; 
       } 
       area /= 2; 

       return area; 
      }; 
      for (i = 0, j = max - 1; i < max; j = i, i++) { 
       point1 = points[i]; 
       point2 = points[j]; 
       f = point1.x * point2.y - point2.x * point1.y; 
       x += (point1.x + point2.x) * f; 
       y += (point1.y + point2.y) * f; 
      } 

      f = area() * 6; 
      var xSum = x/f, ySum = y/f; 

      return { x: xSum, y: ySum };    
     } 

I ont stocké les données de trajectoire de direction dans la collecte de matrice et utilisés pour calculer le point central.

Fiddle link

Pourriez-vous s'il vous plaît me dire que ce ne va pas avec mon code

+3

Vous calculez [le centroïde] (https://en.wikipedia.org/wiki/Centroid) du polygone qui n'est pas garanti à l'intérieur de la surface sur des polygones concaves (comme la Norvège). Vous voudrez peut-être implémenter une sorte d'algorithme [Point On Surface] (http://gis.stackexchange.com/questions/76498/how-is-st-pointonsurface-calculated) – antonio

+1

Malheureusement, l'algorithme décrit dans cet article a gagné ' Je travaille ici parce que le chemin de l'OP consiste en deux sous-chemins séparés. Et une ligne horizontale à travers le centre manquerait les deux sous-chemins:/Il faudrait le modifier. –

+0

Existe-t-il d'autres algorithmes ou solutions pour y parvenir? – Bharathi

Répondre

2

Vous pourriez mettre en œuvre Polylabel. C'est un algorithme fait par les gars de Mapbox conçu pour afficher une étiquette au centre d'un polygone, quelle que soit sa forme

+0

Une introduction sur cet algorithme peut être trouvée ici: https://www.mapbox.com/blog/polygon-center/ – alpadev

+0

Salut, je connais déjà cet algorithme "Polylabel". Mais JavaScript a utilisé un plugin tiers. Dans ma source, je ne peux pas utiliser un plugin tiers – Bharathi

0

Je pense que le problème avec votre code est que vous essayez de trouver le centroïde de la forme qui est le centre de masse pour les formes 2D. Ce qui prend la zone à l'intérieur du polygone trouve le centre de cette zone. Ce qui sera utile si vous essayez d'équilibrer la zone sur ce point, car la distribution de masse autour du point sera égale.

Mais vous avez juste besoin de couvrir la zone avec un cercle, donc il vous suffit de trouver les deux points les plus éloignés les uns des autres et dessinez un cercle autour de ces points. Donc, boucle par tous les points trouver la paire la plus éloignée, trouver le point entre ces deux points (avg (x1, x2), avg (y1, y2)), et dessiner un cercle avec le diamètre de la distance entre ces points .