Ben G
Ben G

Reputation: 128

Point belonging to which Polygon

I'm trying to find out which Region (Polygon) a certain point resides in.

I'm trying to follow Daniel Azuma's RubyConf2012 Geospatial analysis screencast. The following code always returns nil:

 Region.where{st_contains(poly, Point.last.coords)}.first

Here's my Region class:

 class Region < ActiveRecord::Base
attr_accessible :poly, :name, :multi

has_many :points

GEOFACTORY = RGeo::Geographic.simple_mercator_factory
set_rgeo_factory_for_column(:poly, GEOFACTORY.projection_factory)


def self.load

path = File.join(Rails.root, 'lib/tasks/uk/districts')
factory = GEOFACTORY
RGeo::Shapefile::Reader::open(path, :factory => factory) do |file|
    file.each do |record|
        name = record['NAME']
        region = Region.where(:name => name).first ||
         record.geometry.projection.each do |poly|
         Region.create(:name => name, :poly => poly)

        end
    end
end
end

Points class:

class Point < ActiveRecord::Base
attr_accessible :coords

belongs_to :region

def self.find_region
  region = Region.where{st_contains(poly, Point.last.coords)}.first
  puts region
end

end

Upvotes: 2

Views: 1009

Answers (1)

boulder_ruby
boulder_ruby

Reputation: 39695

So first of all, you say your query returns nil. Well, that's not true. The first method on your query results returns nil. Your query returned an empty array. i.e. it didn't throw an error but did not yield any results. in rgeo when a method returns nil that normally means something else.

you need to make sure both the region and the point data came from the same projections. Its possible if not likely that your points are geographic (lonlat) coordinates. PostGIS can only do spatial joins on flat planes. If you formatted geographic coords as geographic types (using things like the RGeo::Geographic factories), trying to do a spatial join w/ a geographic shape for a projected (flat) data column should throw an error. But if you didn't, and generated the Point instances with Cartesian or Geometric types, throwing the geographic points into the method is surely going to return []. After all, 32, -81 are points on a geometric projection too.

Its also possible that the last point is simply not inside of a region shape

Upvotes: 2

Related Questions