rubygeojsonkmlwgs84rgeo

Issue with RGeo / GeoJSON / LinearRing failed ring test / EPSG 3857 vs EPSG: 4326


My overall goal is to answer, "Does this point intersect with this geojson object"

I am attempting to do this with the following code:

boundaries = {...} # geojson object
point = RGeo::Geographic.simple_mercator_factory.point(input_longitude, input_lat)
# this is the line that throws an error: 
feature_collection = RGeo::GeoJSON.decode(boundaries, geo_factory: RGeo::Geographic.simple_mercator_factory)
feature_collection.each do |feature|
  if feature.geometry.intersects?(point)
    return true
  end
end

For a particular geojson object, this blows up with the error: LinearRing failed ring test (RGeo::Error::InvalidGeometry)

However, if I switch to a similar, but slightly different factory, the code works:

# slightly different factory 
factory = RGeo::Geographic.projected_factory(projection_proj4: "EPSG:4326", projection_srid: 4326)
boundaries = {...} # geojson object
point = factory.point(input_longitude, input_lat)
# no error this time! 
feature_collection = RGeo::GeoJSON.decode(boundaries, geo_factory: factory)
feature_collection.each do |feature|
  if feature.geometry.intersects?(point)
    return true
  end
end

Does anyone have an idea of why this may be? Is my geojson invalid? Am I using the wrong factory to convert geojson to a Geometry?

From the documentation simple_mercator_factory should support both projection.

One hunch I have is that the geojson was perhaps incorrectly created from an original KMZ file?

Any guidance is greatly appreciated!


Solution

  • UPDATE: 2021-11-05

    I have created a pull request to get this fixed. See #278.

    ORIGINAL POST

    I've had the same issue and I have created the following monkey patch. I was going to put in a pull request about fixing this, but it they are in the progress of revamping the gem, so I wanted to wait.

    I pulled this from my project, so it should work as a drop in replacement.

    # Monkey patch for issues with lenient assertions for RGeo.
    #
    # /lib/extensions/rgeo/factory.rb
    #
    # ruby '2.5.3'
    # gem 'rails', '5.2.4.6'
    # gem 'rgeo', '2.1.1'
    #
    # This will allow:
    #   factory = RGeo::Geographic.simple_mercator_factory(uses_lenient_assertions: true, lenient_multi_polygon_assertions: true)
    #   factory.set_property(:uses_lenient_assertions, true)
    #
    module RGeo
      module Geographic
        class Factory
          def set_property(prop, value)
            case prop
              when :has_z_coordinate
                @support_z = value
              when :has_m_coordinate
                @support_m = value
              when :uses_lenient_assertions
                @lenient_assertions = value
              when :buffer_resolution
                @buffer_resolution = value
              when :is_geographic
                value
            end
          end
        end
      end
    end