Repository: rgeo/rgeo (Ruby)

Issue:
 RGeo::Geographic.simple_mercator_factory ignores lenient flags
I am having an issue with the classic `LinearRing failed ring test` when I use a simple mercator factory.  I've noticed that several of the closed issues on this topic suggest setting one of the possible lenient flags, i.e. `lenient_multi_polygon_assertions: true, uses_lenient_assertions:true`

However, this did not solve my issue. Looking under the hood, it seems as if [the factor method does not pass along these options](https://github.com/rgeo/rgeo/blob/v2.3.0/lib/rgeo/geographic/interface.rb#L216). 

Is this a deliberate design choice? And if so, could anyone point me in the direction of getting a more lenient behavior with a simple mercator projection & a potentially self-intersecting multipolygon?




Discussion:
I've posted more details about a related issue on stackoverflow if that is helpful: https://stackoverflow.com/questions/69827860/issue-with-rgeo-geojson-linearring-failed-ring-test-epsg-3857-vs-epsg-432
@earnold 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. 

```ruby
# 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
```

I hope this helps!

(I'll also post on the S.O. question as well)
@thestelz Awesome! Thank you. This is helpful.
@earnold thanks for the bug report. I'm able to reproduce this behavior and thanks @thestelz for the fix. We are getting rid of this behavior in version 3, but I suppose it would be worthwhile to get a patch for this in the meantime.

@thestelz if you want to open a PR that would be appreciated, otherwise I may have time to get to this next week.
@keithdoggett Is there a public read map for v3? I'm starting to use this gem in more and more of my current project. I'd love to know more about its direction, and potentially see if there are places I could help out. 
@keithdoggett I'll see if I can get to it. We are in the progress of moving all of our projects to docker, so I'll see if I can squeeze in some time to fix that (I might need some help with that, but I'll put that all in a pull request).

@earnold I think everything so far can be found in #247.
@earnold the issue mentioned above is the roadmap and any issues tagged with 3.0 have more of a description about what needs to be done. Any help is appreciated thanks!



Patch:
diff --git a/lib/rgeo/geographic/interface.rb b/lib/rgeo/geographic/interface.rb
index ba11386d..7a89ceeb 100644
--- a/lib/rgeo/geographic/interface.rb
+++ b/lib/rgeo/geographic/interface.rb
@@ -222,7 +222,8 @@ def simple_mercator_factory(opts = {})
           wkt_generator: opts[:wkt_generator],
           wkb_generator: opts[:wkb_generator],
           has_z_coordinate: opts[:has_z_coordinate],
-          has_m_coordinate: opts[:has_m_coordinate])
+          has_m_coordinate: opts[:has_m_coordinate],
+          uses_lenient_assertions: opts[:uses_lenient_assertions])
         projector = Geographic::SimpleMercatorProjector.new(factory,
           buffer_resolution: opts[:buffer_resolution],
           lenient_multi_polygon_assertions: opts[:lenient_multi_polygon_assertions],


Test patch:
diff --git a/test/simple_mercator/factory_test.rb b/test/simple_mercator/factory_test.rb
index 7d62078c..18396053 100644
--- a/test/simple_mercator/factory_test.rb
+++ b/test/simple_mercator/factory_test.rb
@@ -15,4 +15,25 @@ def setup
     @factory = RGeo::Geographic.simple_mercator_factory
     @srid = 4326
   end
+
+  def test_has_uses_lenient_assertions
+    factory = RGeo::Geographic.simple_mercator_factory(uses_lenient_assertions: true)
+
+    assert_equal(true, factory.property(:uses_lenient_assertions))
+  end
+
+  def test_ring_has_lenient_assertions
+    ring = lambda do |factory|
+      factory.linear_ring([
+                            factory.point(0, 0),
+                            factory.point(1, 1),
+                            factory.point(0, 1),
+                            factory.point(1, 0)
+                          ])
+    end
+
+    assert_raises { ring.call RGeo::Geographic.simple_mercator_factory }
+
+    ring.call RGeo::Geographic.simple_mercator_factory(uses_lenient_assertions: true)
+  end
 end