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 and right hand rule #782

Closed
FitzCarraldo-it opened this issue Nov 14, 2022 · 9 comments
Closed

MultiPolygon and right hand rule #782

FitzCarraldo-it opened this issue Nov 14, 2022 · 9 comments

Comments

@FitzCarraldo-it
Copy link

Hi,

Thank you for your work. I have an issue about multipolygon. I create some map with multipoly last week, but now if i try to do the same thing i get the right hand rule error and i don see anything. So i load the old file and i get the same error but i can see and edit the multipolygon. I miss something?

@chriswhong
Copy link
Contributor

Any way you can share the file? What did you use to create the geojson with Multipolygons?

@FitzCarraldo-it
Copy link
Author

FitzCarraldo-it commented Nov 14, 2022

Hi Chris,

I used geojson.io for the geojson creation; starting from a single polygon i change type from polygon to multipolygon and then i've placed the second poly array. No problem. But today when i try to do the same, i've got this error:

image

This is the whole GeoJSON:

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": "01", "name": "spara", "cap": [ "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" ] }, "geometry": { "coordinates": [ [ [ [ 10.054115864565517, 42.26090627280195 ], [ 10.054115864565517, 41.36139362268415 ], [ 10.936127216436944, 41.36139362268415 ], [ 10.936127216436944, 42.26090627280195 ], [ 10.054115864565517, 42.26090627280195 ] ], [ [ 11.732750376967573, 42.07091206517259 ], [ 12.746113089809938, 42.014470439676046 ], [ 12.594475367391851, 41.496275845578 ], [ 11.843562558734305, 41.49592342463356 ], [ 11.732750376967573, 42.07091206517259 ] ], [ [ 10.39092142845297, 40.935511886112124 ], [ 10.39092142845297, 40.13363469371467 ], [ 11.155195061855636, 40.13363469371467 ], [ 11.155195061855636, 40.935511886112124 ], [ 10.39092142845297, 40.935511886112124 ] ] ] ], "type": "MultiPolygon" } } ] }

I also used https://mapstertech.github.io/mapster-right-hand-rule-fixer/ to parse point in the correct order. And it works. I'not a programmer but i understand that right hand rule stand for the point order if a polygon it's inside or outside the other poly in the multipolygon array. So i try to do that but it'doesn't work

@kuanb
Copy link

kuanb commented Nov 14, 2022

@chriswhong I think this is going to come up more often. There's new GeoJSON spec that came out in July about winding order of polygons (counter-clockwise). A variety of tools do not conform with that (esp. older versions) and will output clockwise-winding-ordered GeoJSON. The result is that the above situation the OP shared will occur.

An example of this is something I found w/ mercantile, where it outputs the wrong winding order which will get rejected from geojson.io now: mapbox/mercantile#148

@kuanb
Copy link

kuanb commented Nov 15, 2022

image

@FitzCarraldo-it you can visualize the 2 polygons you have that are in the wrong winding order (as in the above image). A script to generate the above is shared below.

In the image, polygons A and B have their polygons in clockwise order whereas C has its in counter-clockwise order, which is correct. As a result, both A and B need to be reversed to become valid GeoJSON.

Script:

import json
from shapely.geometry import Point, Polygon, box

# this is the OP's original MultiPolygon FeatureCollection
example_gj = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": "01", "name": "spara", "cap": [ "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" ] }, "geometry": { "coordinates": [ [ [ [ 10.054115864565517, 42.26090627280195 ], [ 10.054115864565517, 41.36139362268415 ], [ 10.936127216436944, 41.36139362268415 ], [ 10.936127216436944, 42.26090627280195 ], [ 10.054115864565517, 42.26090627280195 ] ], [ [ 11.732750376967573, 42.07091206517259 ], [ 12.746113089809938, 42.014470439676046 ], [ 12.594475367391851, 41.496275845578 ], [ 11.843562558734305, 41.49592342463356 ], [ 11.732750376967573, 42.07091206517259 ] ], [ [ 10.39092142845297, 40.935511886112124 ], [ 10.39092142845297, 40.13363469371467 ], [ 11.155195061855636, 40.13363469371467 ], [ 11.155195061855636, 40.935511886112124 ], [ 10.39092142845297, 40.935511886112124 ] ] ] ], "type": "MultiPolygon" } } ] }

fc = {
  "type": "FeatureCollection",
  "features": []
}
for feat in example_gj["features"]:
    for cs in feat["geometry"]["coordinates"][0]:
        as_poly = Polygon(cs)
        gi = as_poly.__geo_interface__
        cs = gi["coordinates"][0]
        cs_r = list(reversed(cs))
        
        fc["features"].append({
            "type": "Feature",
            "properties": {
                "stroke-width": 0.3
            },
            "geometry": {
                "coordinates": cs_r,
                "type": "LineString"
            }
        })

        for c, hex_col in zip(cs_r[:4], ["#e9507d", "#f38b83", "#fcd384", "#edfbe6"]):
            buffered = Point(c).buffer(0.01)
            as_box = box(*buffered.bounds)
            coords = as_box.exterior.coords.xy
            xs = list(coords[0])
            ys = list(coords[1])
            p = Polygon(list(zip(xs, ys)))
            feat = {
                "type": "Feature",
                "properties": {
                    "fill": hex_col,
                    "fill-opacity": 0.8,
                    "stroke-width": "0"
                }
            }
            feat["geometry"] = p.__geo_interface__
            fc["features"].append(feat)
    
print(json.dumps(fc))

@chriswhong
Copy link
Contributor

chriswhong commented Nov 15, 2022

The error is showing up because geojsonhint was upgraded in #735, looks like the prior version 0.3.4 was from 2014 and did not include this rule.

However, geojson.io has always been using geojson-rewind, which will set the counterclockwise winding order for any polygon drawn in the app. This was also updated recently but to my knowledge the previous version was also doing the same.

In any case, I think geojson.io is working as expected and showing an error/not rendering invalid geojson in the code editor.

@FitzCarraldo-it FYI the sample geojson data you provided includes coordinates for three polygons that do not intersect, but they are nested in the geojson as only one polygon with an exterior ring and two interior rings. If all three were drawn in geojson.io, they would be counterclockwise, but placing them where they are in the geojson means it expects the 2nd and 3rd to be clockwise because they are inner rings.

"geometry": {
                "coordinates": [ // array to hold all of the polygons in this MultiPolygon
                    [ // first Polygon
                        [ // outer ring
                            ... 
                        ],
                        [ // first inner ring (your 2nd polygon)
                            ...
                        ],
                        [ // second inner ring (your 3rd polygon)
                            ...
                        ]
                    ]
                    // your 2nd and 3rd polygons should be here where they are treated as Polygons in the MultiPolygon
                ],
                "type": "MultiPolygon"
            }

@FitzCarraldo-it
Copy link
Author

Thank you for the answer. I still have issue but i understand the question. I use map for my Einstein Analytics exam and i find that what works on geojson.io doesn't in Analytics and viceversa.I think i must investigate geojson implementation in Salesforce!!!

@chriswhong
Copy link
Contributor

Thanks for raising this! Closing as there is no immediate action to take.

@chriswhong
Copy link
Contributor

Hi, based on some other discussions it was determined that the right hand rule should be a warning instead of an error. This was implemented in #786, so you should be able to use the geojson you were trying earlier now.

@FitzCarraldo-it
Copy link
Author

Him Chris. Tank you for the info!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants