earnold
earnold

Reputation: 1462

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!

Upvotes: 0

Views: 371

Answers (1)

AJ_
AJ_

Reputation: 38

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

Upvotes: 1

Related Questions