mapshaper icon indicating copy to clipboard operation
mapshaper copied to clipboard

Preventing incorrect topology on simplification

Open vedinerd opened this issue 4 years ago • 4 comments

Hi -- I've recently run into an issue that I've tried to illustrate here. It's not exactly a bug, and instead simplification producing "incorrect" topology for nested polygons, and I wanted to see if any users had run into the same issue or had a work around. If you look at the two attached screen shots, you can see the topology as three shapes, one a multipolygon with a single hole, another polygon that is exactly the same shape and in the same position as that hole, and a polygon adjacent to the multipolygon. All shapes share common edges (these are zip code "boundaries"). When simplifying beyond a certain point (simplify the attached geojson down to below 15% or so (with "prevent shape removal" on), the polygon that was previously contained entirely inside the multipolygon is now outside it along with the hole in the multipolygon. Note that in the "before" image the tiny polygon is inside the "left" polygon (with a corresponding hole in the outer shape), and after it is inside the "right" one.

Running the "clean" algorithm on the resulting layer restores a logical topology (no more hole outside the perimeter), but it also completely removes the smaller nested polygon, since it now entirely overlaps with the adjacent polygon, which had no hole. A feature that would help in this situation would be if the simplification algorithm could "preserve topology" beyond keeping the borders the same, and instead optionally rollback or prevent simplification that caused holes to travel outside their perimeters, which should have the desired effect here I think. Or perhaps someone knows if this can be accomplished with a more sophisticated use of the command line? Thank you!

sample.zip

before

after

vedinerd avatar Dec 24 '19 22:12 vedinerd

As you discovered, mapshaper doesn't support this kind of topology preservation.

This kind of topology change hasn't been a problem in my own work. I tend to use fairly light simplification -- simplified lines might only diverge from the original lines by a few pixels at most, if I'm making a map for the web. The kind of topology change that you're talking about would probably be too small relative to the display resolution of the map to be visible, if it occurred.

This issue may be important to other mapshaper users, so I'm going to leave this issue open for discussion, instead of closing as "wontfix". A related problem is to make sure that line simplification doesn't change the location of points in a second layer relative to the lines in the simplified layer.

mbloch avatar Dec 25 '19 06:12 mbloch

Hi -- thank you for the response, and for the very useful tool. I am able to apply some custom post-processing to address these issues in the output topology, but would definitely be interested in further discussion from anyone.

vedinerd avatar Dec 26 '19 03:12 vedinerd

I think there is no option to represent your "inner-shape-A" relation to the hole of the "outer-shape-B". At least not in GeoJSON. Such relations "shapeA to holeInShapeB" is a meta information outside of the GeoJSON spec, I am not sure about the other supported formats but as far as i know this kind of relation is not included in other specs, so mapshaper should not care about it IMHO (out of scope).

But mapshaper should take care about MultiPolygon (holes of a shape): If a holeInShapeB "leaves" the shapeB due to "oversimplification", then the hole should be dropped from the MultiPolygon. I think this is required to comply with the OGC simple features spec. I did not tested it explicitly but i think it was already implemented in the last month by @mbloch (at least since 0.4.149, maybe even earlyer).

So custom post-processing is required. @vedinerd how do your post-processing code look like? How do you implement the relation? Checking hole-Polygon is equal to shape-Polygon, expecting that both are 100% polygon-equal and each hole-Polygon has a (global) unique shape (at least within its MultiPolygon shape; parent), or do you use its position in the coordinates-list as an ID to establish a relation-link (custom meta data)?

Maybe mapshaper can output some additional simplification details (logs), like "hey on file A.geojson i dropped a hole (list position = ID or polygon-coordinates that represent the original hole as a 'unique ID'), due to aggressive simplication settings." in a machine readable format enabled by a new command line option "-logfile simplification.log", so that your post-processing code can consume it and is easyer to read/maintain in the end.

christian-weiss avatar Jan 11 '20 13:01 christian-weiss

Hi Christian — agreed. This information appears to be outside the GeoJSON spec. It would be helpful for my particular case if Mapshaper could optionally detect and prevent simplification on topology segments when they resulted in this behavior, but Mapshaper’s existing behavior is completely reasonable. In my case it is sufficient to know when this happens and include information (in my case, a US zip code) about the “lost” shape in the properties section of the closest retained shape in GeoJSON. I do this by comparing the pre- and post-simplification GeoJSON using C#, so completely outside Mapshaper. This solves my business problem well enough, but unfortunately isn't really generalizable to the broader issue.

vedinerd avatar Jan 13 '20 14:01 vedinerd