Найти центральную точку неформованного многоугольника для карты

Я рисую круг в центре моих неформованных многоугольных карт. Круг расположен в центре для большей части страны. Но для формы "многоугольник" в Норвегии "точка возврата" неверна. Вы можете четко видеть разницу, после масштабирования/масштабирования страницы.

введите описание изображения здесь

Я использовал это решение stackoverflow: ссылка

Мой код ниже. 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 };             
        }

Я сохранил данные о пути пути в массиве и использовал для вычисления центральной точки.

Ссылка на скрипт

Не могли бы вы рассказать мне, что случилось с моим кодом

Ответ 1

Вы можете реализовать Polylabel. Это алгоритм, сделанный ребятами из Mapbox, предназначенный для отображения метки в центре многоугольника, независимо от его формы.

Ответ 2

Я думаю, что проблема с вашим кодом заключается в том, что вы пытаетесь найти центроид формы, который является центром масс для 2D-фигур. Которая берет область внутри полигона, находит центр этой области. Что будет полезно, если вы попытаетесь сбалансировать область на этой точке, потому что распределение массы вокруг точки будет четным.

Но вам просто нужно покрыть область кругом, так что вам просто нужно найти две точки, которые наиболее далеки друг от друга и нарисовать круг вокруг этих точек.

Таким образом, петля через все точки найдет самую дальнюю пару, найдите точку между этими двумя точками (avg (x1, x2), avg (y1, y2)) и нарисуйте круг с диаметром в качестве расстояния между этими точками.