2017-03-27 51 views
10

我正在繪製我的未定形多邊形地圖的中心的圓。該圈被放置在該國大部分地區的中心。但對於「挪威」多邊形形狀,返回中心點是錯誤的。縮放/縮放頁面後,您可以清楚地看到區別。查找地圖的未定形多邊形的中心點

enter image description here

我用這個計算器的解決方案: link

我下面這裏的代碼。 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 };    
     } 

我已存儲的方向路徑數據陣列收集並用於計算中心點。

Fiddle link

能否請你告訴我,有什麼錯我的代碼

+3

您正在計算多邊形的[質心](https://en.wikipedia.org/wiki/Centroid),該多邊形不能保證位於凹多邊形(如挪威)的表面內。你可能想要實現某種[Point On Surface算法](http://gis.stackexchange.com/questions/76498/how-is-st-pointonsurface-calculated) – antonio

+1

不幸的是,該文章中描述的算法贏得了' t在這裏工作,因爲OP的路徑由兩個獨立的子路徑組成。並且通過中心的水平線會錯過兩個子路徑:/它需要被修改。 –

+0

有沒有其他的算法或解決方案來實現這個..? – Bharathi

回答

2

您可以實現Polylabel。這是一個由Mapbox的人設計的算法,用於在多邊形的中心顯示標籤,無論其形狀如何

+0

關於這種算法的介紹可以在這裏找到:https://www.mapbox.com/blog/polygon-center/ – alpadev

+0

嗨,我知道這個「Polylabel」算法已經..但他們已經使用JavaScript第三方插件。在我的來源中,我無法使用第三方插件 – Bharathi

0

我認爲你的代碼的問題是你正在試圖找到形狀的質心, 2D形狀的質量中心。多邊形內的區域將找到該區域的中心。如果您試圖平衡該點的面積,那麼這將會使用滿,因爲點周圍的質量分佈將是均勻的。

但是你只需要用圓圈覆蓋這個區域,所以你只需要找到彼此距離最遠的兩個點並圍繞這些點畫一個圓。

因此,循環遍歷所有點找到最遠的一對,找到這兩點之間的點(avg(x1,x2),avg(y1,y2)),然後在那裏繪製一個圓直徑作爲這些點之間的距離。