1

I am using Ruby on Rails and PostGIS to store GeoJSON map data in a model called, "Map". When I save an object loaded successfully with a simple GeoJSON feature I get the error, "NoMethodError: undefined method `factory' for #".

See below for examples, setup, what I've tried, and links to resources.

Example 1 (using Rails console)

irb(main):007:0> feature = '{ "type": "Feature", "properties": {  "name": "Coors Field",  "amenity": "Baseball Stadium",  "popupContent": "This is where the Rockies play!" }, "geometry": {  "type": "Point",  "coordinates": [-104.99404, 39.75621] }}'
=> "{ \"type\": \"Feature\", \"properties\": {  \"name\": \"Coors Field\",  \"amenity\": \"Baseball Stadium\",  \"popupContent\": \"This is where the Rockies play!\" }, \"geometry\": {  \"type\": \"Point\",  \"coordinates\": [-104.99404, 39.75621] }}"

irb(main):008:0> geom_feature = RGeo::GeoJSON.decode(feature)
=> #<RGeo::GeoJSON::Feature:0x304e48c id=nil geom="POINT (-104.99404 39.75621)">

irb(main):009:0> Map.create(name: 'demo', geometry: geom_feature)
   (0.9ms)  BEGIN
   (0.6ms)  ROLLBACK
NoMethodError: undefined method `factory' for #<RGeo::GeoJSON::Feature:0x000000000609c918>
  from (irb):9

Setup

  • Rails 5.1.4
  • PostGIS 9.6
  • Docker DB src: kartoza/postgis:9.6-2.4
  • Docker web src: ruby 2.3.5

Files

config/initializers/rgeo.rb

RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config| 
  config.default = RGeo::Geographic.spherical_factory(srid: 4326) 
end

Gemfile

# Mapping
gem 'activerecord-postgis-adapter'
gem 'rgeo'
gem 'rgeo-geojson'
# need this? found on random post - willing to try anything
gem 'rgeo-activerecord'

db/migrate/20182039293939_create_maps.rb

create_table :maps do |t|
  t.string :name
  t.st_polygon :polygon
  t.geometry :geometry
  t.multi_polygon :multi_polygon
  t.references :mappable, polymorphic: true, index: true

  t.timestamps
end

Sources

Among others I've gone through the following sources without any luck:

Daniel Azuma's original post about setup from 2011

StackOverflow post that talks about why part of that is obsolete 2015-06-26

  • Note the comment below the accepted answer that clarifies how to set a default spherical factory for everything - which is fine for me and what I did above.

Github issue response that doesn't seem relevant given that this is already a single feature

More recent and active Github activerecord-postgis-adaptor response that hit on all points above

Suggests that despite not using Geos the install needs to be wrestled with 2015

  • I'm still messing with this option despite it not seeming relevant
  • Tried and had no effect (see below)

Attempts

I also tried installing Geos but this made no difference.

In container:

apt install libgeos-dev
gem uninstall rgeo && gem install rgeo

In Rails Console: (after restart)

irb(main):001:0> RGeo::Geos.supported?
=> true

Attempt and outcome same as above (Example 1)

2 Answers2

1

You need to use the geometry of the feature (call Feature#geometry):

json = '{ "type": "Feature", "properties": { "name": "Coors Field",  "amenity": "Baseball Stadium", "popupContent": "This is where the Rockies play!" }, "geometry": { "type": "Point",  "coordinates": [-104.99404, 39.75621] }}'

feature = RGeo::GeoJSON.decode(json)

Map.create(name: 'demo', geometry: feature.geometry)
tee
  • 4,149
  • 1
  • 32
  • 44
0

Thanks, tee.

I build on your example to show what worked for me. The only difference lies on the last line, where rgeo needs you to inform the feature's index.

json = '{ "type": "Feature", "properties": { "name": "Coors Field",  "amenity": "Baseball Stadium", "popupContent": "This is where the Rockies play!" }, "geometry": { "type": "Point",  "coordinates": [-104.99404, 39.75621] }}'

feature = RGeo::GeoJSON.decode(json)

Map.create(name: 'demo', geometry: feature[0].geometry)