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

d3.geo.path doesn't handle zero-area polygons correctly #2025

Closed
stvno opened this issue Sep 18, 2014 · 6 comments
Closed

d3.geo.path doesn't handle zero-area polygons correctly #2025

stvno opened this issue Sep 18, 2014 · 6 comments
Assignees
Labels
bug Something isn’t working
Milestone

Comments

@stvno
Copy link

stvno commented Sep 18, 2014

d3.geo.path sometimes renders polygons where all points are in a straight line (so no inside) as an "infinite" area with a line shaped "hole". The polygons are created by TileStache from a postgis database and served as topojson. The polygons start out as valid RHR geometries and are turned into lines due to the shift from floating point space to integer space; see the drawing below.
example

If the order of the last three points in the topojson is changed the feature is drawn correctly. I've setup a page showing the difference here: http://research.geodan.nl/sites/vectortiling/test/faultytile.html

Is there a correct clockwise order for points on a line? If so it might be that TileStache is wrong here serving the points in the wrong order, but following the above drawing the points are in a valid order. I would think that if a polygon has an area of 0, the order of points doesn't matter and D3 shouldn't try to create an infinite area with a zero area hole in it.

@jasondavies jasondavies self-assigned this Sep 18, 2014
@jasondavies
Copy link
Contributor

Currently, “degenerate” polygons such as these cause problems for D3, because their winding orders are ambiguous and we need to improve the robustness of our winding order algorithm. I guess the most practical thing would be to treat such polygons as lines, rather than ignoring them completely.

@jasondavies jasondavies added the bug Something isn’t working label Sep 18, 2014
stvno added a commit to stvno/edugis-new that referenced this issue Sep 18, 2014
stvno added a commit to stvno/d3 that referenced this issue Sep 18, 2014
A fix for d3 issue d3#2025 not sure if it is fully backwards compatible, but the basic premises is that a point cannot be in a 0 area polygon. Putting the if statement there doesn't seem to impact performance, but I haven't done any serious benchmarking.
@stvno
Copy link
Author

stvno commented Sep 18, 2014

I've been fiddling a bit and I discovered that the function d3_geo_pointInPolygon(point, polygon) returns 'true' where IMHO that is wrong, if you have a zero-area polygon there can't be a point inside. So I added a simple check whether or not the polygon had an area of zero. This solves this issue for me, but since I don't fully understand what the clipStartInside is supposed to mean, nor the other uses of pointInPolygon it might break other things.

You can check the fix here: https://github.com/stvno/d3/blob/master/src/geo/point-in-polygon.js

@mbostock
Copy link
Member

if you have a zero-area polygon there can't be a point inside

As Jason alluded to, I believe the problem here is an ambiguity between a degenerate clockwise zero-area polygon (where the winding order is interpreted as intended) and a degenerate counterclockwise whole-sphere polygon (where the winding order is unintentionally inverted).

@jasondavies
Copy link
Contributor

Exactly. But for such degenerate zero-area polygons, I think it would make more sense to interpret them as always being clockwise. After all, if you really need a whole-sphere geometry, you would simply use {type: "Sphere"}.

@mbostock
Copy link
Member

Agreed.

@mbostock
Copy link
Member

mbostock commented May 5, 2016

Fixed in 3.5.17; see #2784 by @lukasappelhans.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn’t working
Development

No branches or pull requests

3 participants