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

Possible bug found in geoContains (MultiPolygon) #187

Closed
jake-unl opened this issue Feb 12, 2020 · 2 comments
Closed

Possible bug found in geoContains (MultiPolygon) #187

jake-unl opened this issue Feb 12, 2020 · 2 comments

Comments

@jake-unl
Copy link

jake-unl commented Feb 12, 2020

Hi,
I am getting incorrect results for Multipolygon contains, which seem to be related to earthly hemispheres...

I have reduced my problem to a code example at the bottom. I began with an array of Multipolygons, and have systematically cut it back to two triangular "nations", one in the northern and one in the southern hemisphere.

I am getting inexplicable behaviour with the one situated in the southern hemisphere, and I can't understand what exactly could be going wrong.
I also added a quick sanity check below, which uses the single polygon contains method provided by d3-polygon.

I ran the below code using:

npm i d3-geo d3-polygon && node testd3.js

If you have any further questions, please feel free to contact me, or point out my ignorance 😄🥇

Thanks in advance
jake

Note these versions:
d3-polygon: 1.0.6
d3-geo: 1.11.9

const polyg = require('d3-polygon')

const sou_geometry = {
  type: "MultiPolygon",
  coordinates: [
    [
      [
        [
          112.699751,
          -25.5887378
        ],
        [
          113.2041132,
          -26.6077496
        ],
        [
          119.1896561,
          -27.123542
        ],
        [
          112.699751,
          -25.5887378
        ]
      ]
    ]
  ]
}

const nor_geometry = {
  type: "MultiPolygon",
  coordinates: [
    [
      [
        [
          112.699751,
          25.5887378
        ],
        [
          113.2041132,
          26.6077496
        ],
        [
          119.1896561,
          27.123542
        ],
        [
          112.699751,
          25.5887378
        ]
      ]
    ]
  ]
}
  

let southhemi = [113.45, -26.22]
let northhemi = [113.45, 26.22]
console.log(geo.geoContains(sou_geometry, southhemi)) 
console.log(geo.geoContains(nor_geometry, northhemi))
console.log(polyg.polygonContains(sou_geometry.coordinates[0][0], southhemi)) 
console.log(polyg.polygonContains(nor_geometry.coordinates[0][0], northhemi))```
@Fil
Copy link
Member

Fil commented Feb 12, 2020

While planar polygons are not ambiguous re: what is inside and what is outside, for spherical polygons there must be a rule. In D3 the rule is that polygons are defined as "clockwise". A better metaphor than the "clock" is that, if you walk along the border, "inside" the polygon is under your right foot (see #138 (comment) for a great picture of myself trying out geoContains in a special suit).

It appears that your southern geometry is running in the "wrong" winding order, which means that the surface it occupies is "all the globe except the small triangle". You can verify this by computing d3.geoArea(geometry): it's almost equal to the globe's surface (4π).

@Fil Fil closed this as completed Feb 12, 2020
@jake-unl
Copy link
Author

Ohhhh! Thank you so much for your response Fil, you've really helped my understanding here.
This is now very clear. 😃

Thanks!

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

No branches or pull requests

2 participants