Skip to content

Commit

Permalink
proper rgeo .to_geo for lines and polygons, with specs
Browse files Browse the repository at this point in the history
  • Loading branch information
tagliala committed May 28, 2013
1 parent 2529ba6 commit 1b67def
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 34 deletions.
15 changes: 9 additions & 6 deletions lib/mongoid_geospatial/wrappers/rgeo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ module Mongoid
module Geospatial

class Point

def to_geo
RGeo::Geographic.spherical_factory.point x, y
end
Expand All @@ -25,23 +24,27 @@ def self.mongoize(obj)
end
end

class GeometryField
private
def points
self.map do |pair|
RGeo::Geographic.spherical_factory.point(*pair)
end
end
end

class Line < GeometryField
def to_geo
RGeo::Geographic.spherical_factory.line_string self
RGeo::Geographic.spherical_factory.line_string points
end

end

class Polygon < GeometryField
def to_geo
points = self.map do |pair|
RGeo::Geographic.spherical_factory.point *pair
end
ring = RGeo::Geographic.spherical_factory.linear_ring points
RGeo::Geographic.spherical_factory.polygon ring
end

end
end
end
114 changes: 86 additions & 28 deletions spec/mongoid_geospatial/wrappers/rgeo_spec.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,119 @@
require "spec_helper"

describe Mongoid::Geospatial::Point do
describe "RGeo Wrapper" do

before(:all) do
Mongoid::Geospatial.send(:remove_const, 'Point')
Mongoid::Geospatial.send(:remove_const, 'Polygon')
Mongoid::Geospatial.send(:remove_const, 'Line')

load "#{File.dirname(__FILE__)}/../../../lib/mongoid_geospatial/fields/point.rb"
load "#{File.dirname(__FILE__)}/../../../lib/mongoid_geospatial/fields/polygon.rb"
load "#{File.dirname(__FILE__)}/../../../lib/mongoid_geospatial/fields/line.rb"

Object.send(:remove_const, 'Bar')
load "#{File.dirname(__FILE__)}/../../models/bar.rb"

Object.send(:remove_const, 'Farm')
load "#{File.dirname(__FILE__)}/../../models/farm.rb"

Object.send(:remove_const, 'River')
load "#{File.dirname(__FILE__)}/../../models/river.rb"
end

it "should not inferfer with mongoid" do
Bar.create!(name: "Moe's")
Bar.count.should eql(1)
describe Mongoid::Geospatial::Point do
it "should not inferfer with mongoid" do
Bar.create!(name: "Moe's")
Bar.count.should eql(1)
end

it "should not respond to distance before loading external" do
bar = Bar.create!(location: [5,5])
bar.location.should_not respond_to(:distance)
end
end

it "should not respond to distance before loading external" do
bar = Bar.create!(location: [5,5])
bar.location.should_not respond_to(:distance)
describe Mongoid::Geospatial::Polygon do
it "should not inferfer with mongoid" do
Farm.create!(name: "Springfield Nuclear Power Plant")
Farm.count.should eql(1)
end

it "should not respond to to_geo before loading external" do
farm = Farm.create!(area: [[5,5],[6,5],[6,6],[5,6]])
farm.area.should_not respond_to(:to_geo)
end
end

describe Mongoid::Geospatial::Line do
it "should not inferfer with mongoid" do
River.create!(name: "Mississippi")
River.count.should eql(1)
end

it "should not respond to to_geo before loading external" do
river = River.create!(source: [[5,5],[6,5],[6,6],[5,6]])
river.source.should_not respond_to(:to_geo)
end
end

describe "queryable" do

before do
Mongoid::Geospatial.use_rgeo
Bar.create_indexes
Farm.create_indexes
River.create_indexes
end

describe "(de)mongoize" do

it "should mongoize array" do
geom = Bar.new(location: [10, -9]).location
geom.class.should eql(Mongoid::Geospatial::Point)
geom.to_geo.class.should eql(RGeo::Geographic::SphericalPointImpl)
geom.x.should be_within(0.1).of(10)
geom.to_geo.y.should be_within(0.1).of(-9)
end
describe Mongoid::Geospatial::Point do
it "should mongoize array" do
geom = Bar.new(location: [10, -9]).location
geom.class.should eql(Mongoid::Geospatial::Point)
geom.to_geo.class.should eql(RGeo::Geographic::SphericalPointImpl)
geom.x.should be_within(0.1).of(10)
geom.to_geo.y.should be_within(0.1).of(-9)
end

it "should mongoize hash" do
geom = Bar.new(location: {x: 10, y: -9}).location
geom.class.should eql(Mongoid::Geospatial::Point)
geom.to_geo.class.should eql(RGeo::Geographic::SphericalPointImpl)
end
it "should mongoize hash" do
geom = Bar.new(location: {x: 10, y: -9}).location
geom.class.should eql(Mongoid::Geospatial::Point)
geom.to_geo.class.should eql(RGeo::Geographic::SphericalPointImpl)
end

it "should accept an RGeo object" do
point = RGeo::Geographic.spherical_factory.point 1, 2
bar = Bar.create!(location: point)
bar.location.x.should be_within(0.1).of(1)
bar.location.y.should be_within(0.1).of(2)
it "should accept an RGeo object" do
point = RGeo::Geographic.spherical_factory.point 1, 2
bar = Bar.create!(location: point)
bar.location.x.should be_within(0.1).of(1)
bar.location.y.should be_within(0.1).of(2)
end

it "should calculate 3d distances by default" do
bar = Bar.create! location: [-73.77694444, 40.63861111 ]
bar2 = Bar.create! location: [-118.40, 33.94] #,:unit=>:mi, :spherical => true)
bar.location.distance(bar2.location).to_i.should be_within(1).of(3978262)
end
end

it "should calculate 3d distances by default" do
bar = Bar.create! location: [-73.77694444, 40.63861111 ]
bar2 = Bar.create! location: [-118.40, 33.94] #,:unit=>:mi, :spherical => true)
bar.location.distance(bar2.location).to_i.should be_within(1).of(3978262)
describe Mongoid::Geospatial::Polygon do
it "should mongoize array" do
geom = Farm.create!(area: [[5,5],[6,5],[6,6],[5,6]]).area
geom.class.should eql(Mongoid::Geospatial::Polygon)
geom.to_geo.class.should eql(RGeo::Geographic::SphericalPolygonImpl)
geom.to_geo.to_s.should eq "POLYGON ((5.0 5.0, 6.0 5.0, 6.0 6.0, 5.0 6.0, 5.0 5.0))"
end
end

describe Mongoid::Geospatial::Line do
it "should mongoize array" do
geom = River.create!(source: [[5,5],[6,5],[6,6],[5,6]]).source
geom.class.should eql(Mongoid::Geospatial::Line)
geom.to_geo.class.should eql(RGeo::Geographic::SphericalLineStringImpl)
geom.to_geo.to_s.should eq "LINESTRING (5.0 5.0, 6.0 5.0, 6.0 6.0, 5.0 6.0)"
end
end
end
end
end

0 comments on commit 1b67def

Please sign in to comment.