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

Fail to decode polygons with overlapping areas #33

Open
aelesbao opened this issue Jul 4, 2017 · 3 comments · May be fixed by #47
Open

Fail to decode polygons with overlapping areas #33

aelesbao opened this issue Jul 4, 2017 · 3 comments · May be fixed by #47

Comments

@aelesbao
Copy link

aelesbao commented Jul 4, 2017

I've noticed a problem when trying to decode areas with "bowtie" like shapes:

geojson = '{"type":"Polygon","coordinates":[[[40.1605224609375,50.48547354578499],[41.890869140625,49.75642885858046],[41.8963623046875,50.447011182312195],[40.1495361328125,50.025387620270244],[40.1605224609375,50.48547354578499]]]}'
polygon = RGeo::GeoJSON.decode(geojson, json_parser: :json)
# => returns nil

And, as you can see here, this is a valid Geo JSON Polygon.

Debugging the code, we could check that lib/rgeo/geo_json/coder.rb @ line 246 calls

ring = @geo_factory.linear_ring(points)

Which actually raises an RGeo::Error::InvalidGeometry: LinearRing failed ring test and returns nil.

Version tested: 0.4.3

@vitorreis
Copy link

+1 here

stadia pushed a commit to stadia/activerecord-mysql2rgeo-adapter that referenced this issue Mar 4, 2019
Hitting an issue like rgeo/rgeo-geojson#33 where we are getting "LinearRing failed ring test (RGeo::Error::InvalidGeometry)" for a valid polygon.  Added rescue from RGeo::Error::InvalidGeometry
@gydroperit
Copy link

+1 Version 2.1.1 problem still exists

@BuonOmo
Copy link
Member

BuonOmo commented Nov 4, 2020

I could indeed reproduce this issue by forcing the simple_factory (the geos based one does not reproduce).

geojson = '{"type":"Polygon","coordinates":[[[40.1605224609375,50.48547354578499],[41.890869140625,49.75642885858046],[41.8963623046875,50.447011182312195],[40.1495361328125,50.025387620270244],[40.1605224609375,50.48547354578499]]]}'
polygon = RGeo::GeoJSON.decode(geojson, geo_factory: RGeo::Cartesian.simple_factory)

With that said, it looks like a geojson accepts complex polygons (https://tools.ietf.org/html/rfc7946#section-3.1.6). Hence we may considere setting uses_lenient_assertions for the coder geo_factory. This would make the polygon not compliant with OGC as mentioned in rgeo. However, I don't know yet enough about RGeo's codebase to make that decision globally. @keithdoggett what is your opinion on that one ?

Locally, a quick fix is:

geojson = <<~JSON
{
  "type":"Polygon",
  "coordinates": [[
    [40.1605224609375,50.48547354578499],
    [41.890869140625,49.75642885858046],
    [41.8963623046875,50.447011182312195],
    [40.1495361328125,50.025387620270244],
    [40.1605224609375,50.48547354578499]
  ]]
}
JSON
polygon = RGeo::GeoJSON.decode(geojson, geo_factory: RGeo::Cartesian.simple_factory(uses_lenient_assertions: true))

puts polygon

And for convenience:

# in some init file
GEOJSON_CODER = RGeo::GeoJSON.coder(geo_factory: RGeo::Cartesian.simple_factory(uses_lenient_assertions: true))

# later
geojson = <<~JSON
{
  "type":"Polygon",
  "coordinates": [[
    [40.1605224609375,50.48547354578499],
    [41.890869140625,49.75642885858046],
    [41.8963623046875,50.447011182312195],
    [40.1495361328125,50.025387620270244],
    [40.1605224609375,50.48547354578499]
  ]]
}
JSON
GEOJSON_CODER.decode(geojson)

This might as well be a bit related with rgeo/rgeo#228, since it depends on the is_simple? method. However, the fact that geos is giving varying behaviors for the is_simple? method is already tracked in rgeo/rgeo#218.

EDIT: sorry for the quick close/reopen, but I think we may be able to handle this issue here

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

Successfully merging a pull request may close this issue.

4 participants