Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create RGeo polygon in Ruby from WKT when the polygon has errors

I'm working with a MySQL database with polygons stored in WKT format. Many polygons in the database have duplicate points (e.g. in the below example, the point -122.323502 47.600959 is repeated three times).

When attempting to call RGeo::Cartesian::Factory.parse_wkt() on these polygons, the result is nil.

How can I create RGeo objects from these polygons, without modifying the polygon data.

poly = "MULTIPOLYGON(((-122.362163 47.618641,-122.344621 47.592555,-122.332017 47.592458,-122.32748 47.59241,-122.326109 47.592652,-122.324738 47.592895,-122.323147 47.593478,-122.321412 47.59411,-122.320826 47.594984,-122.320669 47.596296,-122.321149 47.598627,-122.323502 47.600959,-122.323502 47.600959,-122.323502 47.600959,-122.324071 47.601688,-122.320757 47.601688,-122.32073 47.604262,-122.320767 47.607663,-122.320746 47.609703,-122.320723 47.611938,-122.320714 47.612812,-122.320772 47.614075,-122.320799 47.618495,-122.362163 47.618641)))"

parsed_poly = RGeo::Cartesian::Factory.new().parse_wkt(poly)

=>nil
like image 336
Jesse Rundle Avatar asked Mar 18 '13 21:03

Jesse Rundle


2 Answers

Try this:

RGeo::Geos.factory(:srid => 4326).parse_wkt(wkt_string)
like image 107
boulder_ruby Avatar answered Nov 08 '22 14:11

boulder_ruby


polygon = RGeo::Geographic.spherical_factory.parse_wkt(params[:polygon])

works for me! I am using rails + mysql

First I tried to create the place record in Rails like this:

@place = Place.new(params)

Btw, my place table is like this:

`polygon` polygon DEFAULT NULL,
`latlon` point DEFAULT NULL,

So first I tried to do everything in Model and hope rgeo will automatically change polygon and latlon from text to geometry and save in mysql like a charm. And It did work at latlon as it is a Point Type. Here is what I add to place.rb

self.rgeo_factory_generator = RGeo::Geos.method(:factory)
set_rgeo_factory_for_column(:latlon, RGeo::Geographic.spherical_factory)
set_rgeo_factory_for_column(:polygon, RGeo::Geographic.spherical_factory)

Unfortunately, Polygon type does not work.

And I found this on rgeo/reographic/interface.rb

This implementation does not implement some of the more advanced geometric operations. In particular:

  • Relational operators such as Feature::Geometry#intersects? are not implemented for most types.
  • Relational constructors such as Feature::Geometry#union are not implemented for most types.
  • Buffer, convex hull, and envelope calculations are not implemented for most types. Boundaries are available except for GeometryCollection.
  • Length calculations are available, but areas are not. Distances are available only between points.
  • Equality and simplicity evaluation are implemented for some but not all types.
  • Assertions for polygons and multipolygons are not implemented.

OK. So I need to do it myself. I tried the following but not work.

polygon = RGeo::Geographic.spherical_factory.parse_wkt(params[:polygon])
params[:polygon] = polygon
@place = Place.new(place_params)
@place.save

But this worked!

polygon = RGeo::Geographic.spherical_factory.parse_wkt(params[:polygon])
@place.polygon = polygon
@place.save

I think maybe ActiveRecord cannot deal with both other type and polygon object at the same time!

like image 1
arthur bryant Avatar answered Nov 08 '22 13:11

arthur bryant