Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find center point of the unshaped polygon for map

I am drawing circle in the center of my unshaped polygon maps. The circle is placed in the center for most of the country. But for "Norway" polygon shape, the return center point is wrong. You can see the difference clearly, after zooming/scaling the page.

enter image description here

I used this stackoverflow solution : link

My code below here. 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 have stored the direction path data in array collection and used to calculate center point.

Fiddle link

Could you please tell me that what wrong with my code

like image 456
Bharathi Avatar asked Mar 27 '17 08:03

Bharathi


1 Answers

You could implement Polylabel. It's an algorithm made by the guys from Mapbox designed to display a label in the center of a polygon, regardless of its shape

like image 181
alpadev Avatar answered Oct 26 '22 01:10

alpadev