Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiPolygon with holes #378

Open
mcasamayorpolo opened this issue Sep 14, 2021 · 10 comments
Open

MultiPolygon with holes #378

mcasamayorpolo opened this issue Sep 14, 2021 · 10 comments
Labels

Comments

@mcasamayorpolo
Copy link

mcasamayorpolo commented Sep 14, 2021

There is an issue with the multipolygons that have holes. When I use a geojson that has a MultiPolygon feature with holes, the Feature Service that I get has the MultiPolygon feature with all of its rings clockwise. Theoretically, as the Esri documentation says, a hole has to be counter-clockwise. So the feature obtained is not correct.

I have checked the geojson and it is right as you can see at the following image:

image

The MultiPolygon feature is the following:

{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-102.75393999999825,
19.786959999999674
],
[
-102.75420999999827,
19.78647999999966
],
[
-102.75396999999825,
19.786189999999657
],
[
-102.75380999999825,
19.78611999999966
],
[
-102.75299999999825,
19.78610999999966
],
[
-102.75261999999826,
19.78629999999966
],
[
-102.75240999999825,
19.786249999999665
],
[
-102.75214999999827,
19.786319999999662
],
[
-102.75199999999828,
19.786249999999665
],
[
-102.75164999999826,
19.786499999999663
],
[
-102.75161999999827,
19.786619999999665
],
[
-102.75158999999826,
19.787079999999666
],
[
-102.75143999999827,
19.787469999999654
],
[
-102.75143999999827,
19.788379999999666
],
[
-102.75194999999825,
19.78768999999966
],
[
-102.75228999999825,
19.787459999999665
],
[
-102.75269999999827,
19.78741999999966
],
[
-102.75393999999825,
19.786959999999674
]
],
[
[
-102.75219999999825,
19.786499999999663
],
[
-102.75218999999827,
19.786989999999665
],
[
-102.75172999999826,
19.786959999999674
],
[
-102.75172999999826,
19.786499999999663
],
[
-102.75219999999825,
19.786499999999663
]
]
]
]
}
}

Thank you in advance for your help. :)

@rgwozdz
Copy link
Member

rgwozdz commented Aug 8, 2022

@mcasamayorpolo - sorry, I don't understand what you are asking for in this issue. Can you clarify?

@mtrcn
Copy link

mtrcn commented Jan 20, 2023

I am also able to produce the same issue, the problem is related to GeoJSON to ArcGIS JSON conversion.

https://github.com/terraformer-js/terraformer/blob/df0e9d296c028a9cf8d0db9d83dc772a97c644ac/packages/arcgis/src/helpers.js#L17-L29

doesn't return the correct value for some cases, I asked ChatGPT to fix this algorithm and it produces following code;

function ringIsClockwise(ringToTest) {
    var area = 0;
    for (var i = 0; i < ringToTest.length; i++) {
        var j = (i + 1) % ringToTest.length;
        area += ringToTest[i][0] * ringToTest[j][1];
        area -= ringToTest[j][0] * ringToTest[i][1];
    }
    return area > 0;
}

This works well and solved my problem.

ChatGPT explains the algorithm as below;

The algorithm calculates the signed area of the polygon using a modified version of the "shoelace theorem" also known as "Gauss's area formula".
The shoelace theorem states that the area of a closed polygon can be calculated by taking the sum of the product of the x-coordinates of a point
with the y-coordinate of the point following it, and subtracting the sum of the product of the y-coordinates of a point with the x-coordinate of
the point following it.
The function loops through each pair of consecutive coordinates in the polygon and applies the shoelace theorem by adding the product of the current
x-coordinate and the following y-coordinate to a running "area" total, and subtracting the product of the following x-coordinate and the current
y-coordinate. The loop starts at the last point and ends at the first point, this is why the loop variable is (i + 1) % coordinates.length this
way the last point coordinates will be used to calculate the area with the first point coordinates.
At the end of the loop, the function checks whether the area is greater than zero. If it is, the coordinates are in clockwise order;
if it is not, the coordinates are in counter-clockwise order.
It's important to note that this algorithm will only work for polygons with a valid shape and orientation, that is, the first and
last point of the coordinates array should be the same and the polygon should not have any hole.

@rgwozdz
Copy link
Member

rgwozdz commented Jan 20, 2023

Ok, issue should probably be posted to terraformer.

@rgwozdz
Copy link
Member

rgwozdz commented Jan 20, 2023

@mtrcn - I can open the issue at terraformer, but I don't have any specifics of instances when the existing code fails. You that it

doesn't return the correct value for some cases

Can you provide those cases so we can test?

@mtrcn
Copy link

mtrcn commented Jan 21, 2023

@rgwozdz Here is a fiddle you can see difference; https://jsfiddle.net/mtrcn/gdzq8jco/4/

@rgwozdz
Copy link
Member

rgwozdz commented Jan 22, 2023

@mtrcn - I tested the ChatGPT function using a very simple clockwise-ring:

const clockwiseRing = [
    [0, 0], // lower left
    [0, 1], // upper left
    [1, 1], // upper right
    [1, 0], // lower right
    [0, 0]  // lower left
]

When I give it this clockwise ring, it returns false (due to negative area), which according to the ChatGPT explanation , is suppose to indicate "the coordinates are in counter-clockwise order." However, as noted, the simple ring was constructed in clockwise-order.

Any thoughts? Maybe I a overlooking something obvious. Here is a runkit, demoing the code with this ring: https://runkit.com/rgwozdz/63cb2c2638ecaa00086581e6

@mtrcn
Copy link

mtrcn commented Jan 23, 2023

Maybe it is because Latitude is Y and Longitude is X in geospatial?

In this case;
image

Does it make sense?

@rgwozdz
Copy link
Member

rgwozdz commented Jan 23, 2023

Geospatial coordinate pairs need to be ordered like [x, y], where x is the west-east axis (e.g. longitude) and y is the south-north axis (e.g. latitude). It's possible that this code has it backwards. As you note, if you switch the x's and y's the function returns true, but when you switch the coordinates, you're producing a counter-clockwise ring.

I think the ChatGPT function is not giving the right result. I looked at the ring in your fiddle, and it too looks like it is a clockwise ring, but the ChatGPT function returns false. The existing function from terraformer returns true which is the right result, since the ring provided is actually clockwise.

I am not doubting that you and the original poster are having some kind of issue, but and I am wondering if the source of the problem is not with the ringIsClockwise function , but rather, in how it is applied. @mcasamayorpolo noted that the ring representing the hole "should be counter-clockwise". So perhaps the issue is that terraformer sees clockwise rings representing holes, but does not reverse them?

@rgwozdz
Copy link
Member

rgwozdz commented Jan 23, 2023

I've tested the terraformer code and at least with the GeoJSON I am using, it appears to be functioning as expected. @mtrcn are you able to share the specific multipolygon GeoJSON that koop uses to produce the ArcGIS JSON (with clockwise-holes)? So far I cannot reproduce.

@mtrcn
Copy link

mtrcn commented Jan 23, 2023

Hi @rgwozdz, thanks for your all effort, here is the GeoJSON I'm using for testing;

{"type":"Feature","gid":"id","properties":{"id":1},"geometry":{"type":"MultiPolygon","coordinates":[[[[-1.1458276270764451,50.86695669563779],[-1.146082137848927,50.867029004863504],[-1.1467471764264463,50.8672010402532],[-1.1467601119069546,50.867193041407496],[-1.1468520235930826,50.86721808313518],[-1.1471843217783801,50.86730854884652],[-1.147627037905677,50.86742239131639],[-1.1476479576040517,50.86744412638625],[-1.1476720202397306,50.86748054240546],[-1.147702279651506,50.86753561842779],[-1.1477130074278277,50.86757076804909],[-1.1477287467251598,50.867642824089494],[-1.1477726200700293,50.8678086089786],[-1.1478113182208678,50.86794647887966],[-1.1478241012829886,50.868024808174106],[-1.1478340262085895,50.868104015869264],[-1.1478582699613291,50.86825526920926],[-1.1479082219068242,50.86847456594397],[-1.1478275305487189,50.869092440537095],[-1.1481636465204201,50.869111790478385],[-1.1486440056637715,50.869128812801875],[-1.1489479587494469,50.869154685719764],[-1.1496455413324682,50.86926791485879],[-1.1504524442447135,50.86953739646806],[-1.1507571999589497,50.869813359382654],[-1.1512887025021117,50.87024980960727],[-1.1509080745152451,50.87032815215525],[-1.1511124183412456,50.87083995401236],[-1.151157416058643,50.87159730555806],[-1.1510259379127197,50.87266091571782],[-1.150577522960531,50.87264751603134],[-1.149825314861844,50.87259810682087],[-1.148550852393479,50.87248405293367],[-1.1467842380971076,50.872119680313396],[-1.1452317258679066,50.87202383540937],[-1.1451006786255031,50.87247236034532],[-1.1460602606857588,50.87286465399389],[-1.146406529571501,50.87291449986568],[-1.146690130385671,50.872886157078106],[-1.147151755993088,50.87276110606707],[-1.1475309912394134,50.872760495213804],[-1.1477887938966953,50.87297529042077],[-1.147977664873692,50.87316254569202],[-1.1486268082637148,50.87329908413931],[-1.1493233644072507,50.872885094531156],[-1.1511586922513584,50.87303583960293],[-1.1511388876658295,50.8730901379223],[-1.1510475434957714,50.87340871226961],[-1.1509963419084022,50.873582886974155],[-1.1509043619108978,50.873826817716285],[-1.15089513650576,50.87394347499366],[-1.1508882631376727,50.87400889137028],[-1.1508808066180691,50.874075112841794],[-1.1508428295021964,50.87431143279419],[-1.1508034456482459,50.874489352439845],[-1.1507630849712496,50.874487354784385],[-1.150143320940672,50.874496363079544],[-1.1491832281403136,50.874421779584964],[-1.1488208006624325,50.87437858306577],[-1.148770445011307,50.87479728341234],[-1.1485970802597265,50.87493120201542],[-1.148275650699465,50.874982931328276],[-1.147722433306623,50.87485722955888],[-1.1472350322550702,50.87463737819595],[-1.146788881841812,50.874498935278524],[-1.146150963726033,50.87433205296874],[-1.1454477268966297,50.87423227954874],[-1.1448711848736624,50.874214540716906],[-1.144502825933482,50.87449572630135],[-1.1441361950099773,50.87468229569644],[-1.1438346402132773,50.87481526753671],[-1.143665223435948,50.874732916059926],[-1.1432076300424199,50.87405364385196],[-1.1430836673598896,50.87382292282314],[-1.1428973538365494,50.87349711624419],[-1.14277364343579,50.873252878077665],[-1.1425386601732828,50.87325115261487],[-1.1421561258129802,50.87314019632712],[-1.1417957002771533,50.87298884628922],[-1.1412638852582933,50.87286327107439],[-1.140795165078639,50.872792231387706],[-1.1404541206829322,50.87274916617857],[-1.139771038848903,50.87271709908819],[-1.1388969460562581,50.872616028038486],[-1.1377265351162305,50.87236406013227],[-1.1367458952538156,50.87224866737954],[-1.136252829195651,50.872339648566395],[-1.1362210913017337,50.87211518404683],[-1.135996817274869,50.872099527577845],[-1.1355105558456788,50.87205880118646],[-1.1347544888802275,50.872012360570594],[-1.1332141960070858,50.871856138918425],[-1.1320851442821893,50.871831044056265],[-1.1304696675609471,50.8717744709452],[-1.1305129126551423,50.871342258443086],[-1.1307708419861195,50.87103973474718],[-1.1308683682905805,50.87084368549098],[-1.130767564656271,50.87058489915685],[-1.1304885370125841,50.87060231304328],[-1.1300844090952162,50.870641999760615],[-1.1300287551413517,50.87059540693927],[-1.1297054006795784,50.87090834854331],[-1.1295910214672447,50.871379014534945],[-1.1294630490166166,50.871634239338626],[-1.1281164605389522,50.87147568226873],[-1.1280421106897216,50.872113118418255],[-1.1245905505824039,50.8717620973902],[-1.1242134071427556,50.8718483744881],[-1.1223371190127513,50.87193267299143],[-1.1210805052477588,50.87198262377961],[-1.1191031782037728,50.871511983430175],[-1.1173209000790147,50.87112353552252],[-1.1160084691611647,50.87086810026431],[-1.1147816788305491,50.87073860499679],[-1.112391701514941,50.87053018163575],[-1.1104077409376816,50.87026168771982],[-1.1091381239649771,50.870148978193086],[-1.1069049090264038,50.8695694348575],[-1.1043847759811558,50.86880943677879],[-1.1022908413911707,50.86785774222244],[-1.1000431087270286,50.86667092140091],[-1.0980257651333745,50.8654078686649],[-1.0962003093253168,50.86402550264874],[-1.095395932516585,50.86424712735796],[-1.0921530923286837,50.8643738579683],[-1.0898534122777832,50.86434329449877],[-1.0869552391287178,50.864232054431],[-1.0857148663002985,50.86416965641816],[-1.084697551294818,50.864100448473664],[-1.0826173847144251,50.86409678025199],[-1.0817976659136397,50.86407767710068],[-1.0812493784494703,50.8634784104446],[-1.080274657777629,50.86320490564613],[-1.0798789165262577,50.86298659149758],[-1.0795396859584547,50.862945942174726],[-1.079315962090112,50.86313405586364],[-1.0789354869997676,50.86315637272153],[-1.0780625630832557,50.86380772807742],[-1.0764873881836132,50.86355476541785],[-1.0745717498008334,50.86332440022499],[-1.0721339035456399,50.863203781744936],[-1.0702894886088827,50.863416962159555],[-1.0701691276715812,50.86242863425466],[-1.0697304211007437,50.862361846023816],[-1.0683520454813884,50.8622749030067],[-1.0662876356575135,50.86148623650491],[-1.0645311043334915,50.86130761274314],[-1.064212404997051,50.86124176526988],[-1.0641815150672675,50.86178583732533],[-1.0635476339416632,50.86247697679918],[-1.0624646750433964,50.86262018857623],[-1.0624497512878035,50.86236689653348],[-1.0615108452740905,50.862308718290485],[-1.061270866034288,50.86230678887744],[-1.0612865442197976,50.86252211101099],[-1.0607022690206813,50.86273260757636],[-1.0594031305402043,50.86268417159662],[-1.058383863411255,50.86257763065163],[-1.0580251000501122,50.86254668102195],[-1.0579623265046427,50.86253356584283],[-1.0534782625390857,50.86253951631178],[-1.0526304558004105,50.862530515383824],[-1.0522410918512126,50.86236213310048],[-1.0526491149862496,50.86023366321614],[-1.0527052607168834,50.86008247129336],[-1.0526789821203972,50.85989870800915],[-1.0528429329692062,50.85970383013304],[-1.0530566197977813,50.859522013596525],[-1.0532922228165473,50.85924543573668],[-1.0532964503716211,50.85903660279923],[-1.053252606650214,50.85873244044264],[-1.0533072111955735,50.85850502793256],[-1.0536199668785269,50.857874633863624],[-1.053687381969062,50.857508080154965],[-1.0540211462945104,50.85682722090544],[-1.0541655974706807,50.85660686503382],[-1.0543143963656414,50.856171348722924],[-1.0544229317663492,50.85582917681011],[-1.0542913099316242,50.85541319065047],[-1.0543433320305426,50.855234845130234],[-1.0544408674066121,50.855109049336015],[-1.0557098603844586,50.85515413282899],[-1.055777180037514,50.85515716294449],[-1.055830939419847,50.854791607132526],[-1.0562218261834369,50.854806996258525],[-1.0563553103637269,50.8538903253627],[-1.0563935566032698,50.85372923696852],[-1.061332946101742,50.853982673302156],[-1.0617655957041408,50.854346921681845],[-1.0621485171702207,50.85469811078616],[-1.0620888300224538,50.856178688256854],[-1.0627069219835161,50.85627226304865],[-1.0648997460540917,50.856125286673546],[-1.065143115190125,50.85645635973131],[-1.0914557794791468,50.85934139705621],[-1.1134778314626392,50.86347901527792],[-1.1398689856219928,50.86646647359779],[-1.1458276270764451,50.86695669563779]],[[-1.1208396290476963,50.86601969316992],[-1.1208902304998725,50.865665523339004],[-1.1208121454906856,50.86566917358514],[-1.1200916664599065,50.865689062818056],[-1.1198133337441387,50.865598354708474],[-1.1194716464461498,50.865605667429605],[-1.1194788879126325,50.866089567593264],[-1.1203592168686085,50.86638579781731],[-1.1208396290476963,50.86601969316992]],[[-1.1057815910029771,50.864915258742826],[-1.106111337311161,50.864238350984046],[-1.1070064672174438,50.86436772177988],[-1.1068018685295866,50.86400582492666],[-1.10692669879736,50.86375360929379],[-1.1069295996398094,50.8636017282192],[-1.1065517930188953,50.86348491031179],[-1.1056140156632353,50.863363803548076],[-1.1030975400773135,50.863167277618295],[-1.1006818111651366,50.86293349831517],[-1.1010382933032379,50.86308557254265],[-1.100870391565552,50.86357993228715],[-1.1037543952556506,50.86462125792398],[-1.1057815910029771,50.864915258742826]],[[-1.0832327203297656,50.859492307746315],[-1.0814026711346654,50.8589842379901],[-1.0809902960528983,50.859613921245746],[-1.080716149896603,50.86033330280413],[-1.0818678098381245,50.86076009853181],[-1.0830651947129315,50.86089609568395],[-1.0837841247374402,50.8609523743399],[-1.0840873153641857,50.8607901917811],[-1.0840587233253145,50.8602076722058],[-1.0837464493255218,50.85981280611163],[-1.0832327203297656,50.859492307746315]],[[-1.0602826676148331,50.85907188480929],[-1.0604203174485525,50.85894007705747],[-1.0605531993580064,50.8590455795923],[-1.0610244166659146,50.85873607040809],[-1.0610844075976922,50.85873655291581],[-1.0611307340645955,50.858670467649645],[-1.0611030254994012,50.858556318088155],[-1.0606094419480523,50.85848588949324],[-1.0607330440282081,50.85830649855775],[-1.0602252283899805,50.858197978540154],[-1.0598098810775205,50.85796677892542],[-1.0593918650720053,50.857868472041964],[-1.0590932558162987,50.85779960780554],[-1.0587149794071713,50.85870797853575],[-1.0590576328541192,50.85882466849411],[-1.0602826676148331,50.85907188480929]],[[-1.1175280408923756,50.86656120796448],[-1.1176377790685248,50.867274884543505],[-1.1202730373995302,50.86722422908629],[-1.120191473121325,50.86657017109778],[-1.1192417197820375,50.86653330824639],[-1.1175280408923756,50.86656120796448]],[[-1.1228322132815551,50.867137826223676],[-1.122839259394593,50.86788213020376],[-1.1225885554206514,50.868110435870214],[-1.1206892627832472,50.86802189187849],[-1.1198685380821223,50.86798600591296],[-1.1196780210657862,50.868133079668304],[-1.1200943876308156,50.8684555142932],[-1.1196306596381018,50.868778740530985],[-1.1194032469249116,50.86963838242282],[-1.1195937601020507,50.87011505034213],[-1.120776852384466,50.87022792255686],[-1.1207579980261642,50.87060648092955],[-1.1212968912849226,50.87065509022348],[-1.1222150152905996,50.870506061223246],[-1.1238333268553264,50.8699390289725],[-1.1245417630083192,50.869706727686385],[-1.1266763491634724,50.86976726718184],[-1.128080165108591,50.87000052343977],[-1.12920941058227,50.870012664239],[-1.1293397996450563,50.86962751119813],[-1.129359719318242,50.869345491092886],[-1.1291774675667263,50.869096768374305],[-1.1288816996237834,50.86891882400605],[-1.128711575018335,50.868876999496045],[-1.1284982271494215,50.86886188850996],[-1.1278586872560388,50.868789521466134],[-1.127756174597751,50.86855894395781],[-1.127633059257604,50.86828765824624],[-1.127702182469902,50.868017807927885],[-1.1277062174460992,50.867801545000624],[-1.1276883880440498,50.86761215511898],[-1.1281168378449342,50.86754776401222],[-1.128332699610201,50.8674277106324],[-1.1282703854834686,50.86733261749207],[-1.1280155870085844,50.867249604623716],[-1.1273750608355548,50.86723130031265],[-1.1259663596953817,50.86716669008158],[-1.1243880548825875,50.86703319857279],[-1.1228322132815551,50.867137826223676]],[[-1.137896826317601,50.86921217142837],[-1.1379128906030842,50.86949955380375],[-1.1385704685352438,50.86946385232279],[-1.1390184890421493,50.86920692966092],[-1.1387011352003749,50.86903898940184],[-1.1386867343824154,50.86895101422815],[-1.1382068780861736,50.868906918228774],[-1.137896826317601,50.86921217142837]],[[-1.1345628748098433,50.870041330984066],[-1.1351726464542524,50.87069929174819],[-1.1365130721155559,50.87052263794276],[-1.13635587063008,50.87023155416118],[-1.1359796211353321,50.869782665964635],[-1.1355135485177708,50.869584303046075],[-1.1349898022523306,50.869799454171606],[-1.1345628748098433,50.870041330984066]],[[-1.143833011553012,50.87052995360502],[-1.1434482673740132,50.870540649386854],[-1.1430318547169016,50.87053083485627],[-1.1428902951190074,50.87096914110348],[-1.1421653824236593,50.87088946608759],[-1.142164335630577,50.87123755542387],[-1.1419691149667424,50.87168898399126],[-1.1417474969750034,50.87212332010108],[-1.1420794148402253,50.872372468931026],[-1.1423651326617,50.872519889946545],[-1.1425995544246452,50.872552027444996],[-1.142946868982599,50.87254443911189],[-1.143056404773731,50.87239654173942],[-1.1431063263357104,50.87229552062941],[-1.1434312874493497,50.8723418395361],[-1.1434897059859797,50.87206852229653],[-1.1432722368878172,50.87198581677157],[-1.1434878794195724,50.87158522919554],[-1.1438291038964836,50.871618148581284],[-1.1440448636721525,50.8712108019591],[-1.1453781472132367,50.871318575989534],[-1.145720114985387,50.87072627306897],[-1.1448261062713287,50.87054737002645],[-1.143833011553012,50.87052995360502]],[[-1.1184482595215177,50.86968129800728],[-1.1182553007921614,50.86952947472919],[-1.1170636075306715,50.86987317953588],[-1.1169590850183502,50.870436725761245],[-1.1170355262047151,50.87089397150446],[-1.1172791602472338,50.87100348368534],[-1.1182023992940522,50.87104354683985],[-1.118211523690735,50.87072279118366],[-1.1184482595215177,50.86968129800728]],[[-1.1146938541090254,50.86890848397346],[-1.115179818676874,50.867412217722],[-1.1135593316872785,50.86747418040742],[-1.1114473480308031,50.86746555116444],[-1.1110531192045408,50.86783382565094],[-1.1105260181602992,50.869017889867656],[-1.1114852903702246,50.86917370426985],[-1.1119591182817576,50.86893969354374],[-1.112698286701842,50.86894531346134],[-1.1146938541090254,50.86890848397346]]]]}}

If I use the terraformer's clockwise function I'm getting these results;
image

image

Holes are filled with dark blue polygons at different scales.

@rgwozdz rgwozdz added the bug label Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants