geos-extensions 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -94,6 +94,15 @@ We've also included some Rails integration for PostGIS, including:
94
94
  :limit => 10
95
95
  )
96
96
 
97
- We wrote this code for Rails 2.3 and are currently testing on Rails
98
- 3, but it appears that everything is working as expected and is
99
- working with Arel. (Things are looking good so far!)
97
+ === Running ActiveRecord Tests
98
+
99
+ ActiveRecord unit tests can be run by setting the TEST_ACTIVERECORD
100
+ environment variable when running `rake test`. The test database name
101
+ is geos_extensions_unit_tests and requires PostGIS to be installed. The
102
+ test scripts will try to find your postgis.sql and spatial_ref_sys.sql
103
+ files, but if it needs a hint, set the POSTGIS_PATH environment variable
104
+ to the directory the files are in to create the database properly. You
105
+ can also set the database up manually before running the tests -- just
106
+ make sure the database has PostGIS installed with the spatial_ref_sys
107
+ table populated and you'll be fine.
108
+
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ begin
12
12
  require 'jeweler'
13
13
  Jeweler::Tasks.new do |gem|
14
14
  gem.name = "geos-extensions"
15
- gem.version = "0.0.3"
15
+ gem.version = "0.0.4"
16
16
  gem.summary = "Extensions for the GEOS library."
17
17
  gem.description = gem.summary
18
18
  gem.email = "code@zoocasa.com"
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{geos-extensions}
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["J Smith"]
12
- s.date = %q{2011-02-24}
12
+ s.date = %q{2011-02-27}
13
13
  s.description = %q{Extensions for the GEOS library.}
14
14
  s.email = %q{code@zoocasa.com}
15
15
  s.extra_rdoc_files = [
@@ -29,6 +29,9 @@ Gem::Specification.new do |s|
29
29
  "lib/geos_helper.rb",
30
30
  "lib/google_maps.rb",
31
31
  "lib/google_maps/polyline_encoder.rb",
32
+ "test/fixtures/foos.yml",
33
+ "test/geometry_columns_test.rb",
34
+ "test/geospatial_scopes_test.rb",
32
35
  "test/reader_test.rb",
33
36
  "test/test_helper.rb",
34
37
  "test/writer_test.rb"
@@ -38,6 +41,8 @@ Gem::Specification.new do |s|
38
41
  s.rubygems_version = %q{1.5.2}
39
42
  s.summary = %q{Extensions for the GEOS library.}
40
43
  s.test_files = [
44
+ "test/geometry_columns_test.rb",
45
+ "test/geospatial_scopes_test.rb",
41
46
  "test/reader_test.rb",
42
47
  "test/test_helper.rb",
43
48
  "test/writer_test.rb"
@@ -20,7 +20,7 @@ module ActiveRecord
20
20
  "Geometry column load for #{table_name}"
21
21
  )
22
22
 
23
- returning(PostgreSQLGeometryColumn.new(c.name)) do |g|
23
+ PostgreSQLGeometryColumn.new(c.name).tap do |g|
24
24
  # since we're too stupid at the moment to understand
25
25
  # PostgreSQL schemas, let's just go with this:
26
26
  if res.ntuples == 1
@@ -50,7 +50,7 @@ module Geos
50
50
  # as we'll assume the SRID of the column to be whatever the SRID of
51
51
  # the geometry is.
52
52
  module GeospatialScopes
53
- SCOPE_METHOD = if Rails.version >= '3.0'
53
+ SCOPE_METHOD = if ::ActiveRecord::VERSION::MAJOR >= 3
54
54
  'scope'
55
55
  else
56
56
  'named_scope'
@@ -83,13 +83,21 @@ module Geos
83
83
  :use_index => true
84
84
  }.merge(args.extract_options!)
85
85
 
86
- geom = Geos.read(args.first)
87
- column_name = ::ActiveRecord::Base.connection.quote_table_name(options[:column])
86
+ column_name = self.connection.quote_table_name(options[:column])
88
87
  column_srid = self.srid_for(options[:column])
89
- geom_srid = if geom.srid == 0
88
+
89
+ geom = if args.first.is_a?(String) && args.first =~ /^SRID=default;/
90
+ args.first.sub(/default/, (column_srid || -1).to_s)
91
+ else
92
+ args.first
93
+ end
94
+
95
+ geos = Geos.read(geom)
96
+
97
+ geom_srid = if geos.srid == 0
90
98
  -1
91
99
  else
92
- geom.srid
100
+ geos.srid
93
101
  end
94
102
 
95
103
  function = if options[:use_index]
@@ -111,7 +119,7 @@ module Geos
111
119
  {
112
120
  :conditions => [
113
121
  conditions,
114
- geom.to_ewkb
122
+ geos.to_ewkb
115
123
  ]
116
124
  }
117
125
  }
@@ -1,9 +1,8 @@
1
1
 
2
2
  require File.join(File.dirname(__FILE__), *%w{ geos_extensions })
3
3
 
4
- if defined?(Rails)
4
+ if defined?(ActiveRecord)
5
5
  require File.join(GEOS_EXTENSIONS_BASE, *%w{ active_record_extensions connection_adapters postgresql_adapter })
6
6
  require File.join(GEOS_EXTENSIONS_BASE, *%w{ active_record_extensions geometry_columns })
7
7
  require File.join(GEOS_EXTENSIONS_BASE, *%w{ active_record_extensions geospatial_scopes })
8
8
  end
9
-
@@ -16,7 +16,7 @@ module Geos
16
16
  autoload :ActiveRecord, File.join(GEOS_EXTENSIONS_BASE, 'active_record_extensions')
17
17
  autoload :GoogleMaps, File.join(GEOS_EXTENSIONS_BASE, 'google_maps')
18
18
 
19
- REGEXP_WKT = /^(?:SRID=([0-9]+);)?(\s*[PLMCG].+)/i
19
+ REGEXP_WKT = /^(?:SRID=(-?[0-9]+);)?(\s*[PLMCG].+)/i
20
20
  REGEXP_WKB_HEX = /^[A-Fa-f0-9\s]+$/
21
21
  REGEXP_G_LAT_LNG_BOUNDS = /^
22
22
  \(
@@ -0,0 +1,16 @@
1
+ ---
2
+ one:
3
+ id: 1
4
+ name: "one"
5
+ the_geom: 'POINT(0 0)'
6
+ the_other_geom: 'SRID=4326; POINT(10 10)'
7
+ two:
8
+ id: 2
9
+ name: "two"
10
+ the_geom: 'POINT(10 10)'
11
+ the_other_geom: 'SRID=4326; POINT(20 20)'
12
+ three:
13
+ id: 3
14
+ name: "three"
15
+ the_geom: 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5))'
16
+ the_other_geom: 'SRID=4326; POLYGON((5 5, 5 10, 10 10, 10 5, 5 5))'
@@ -0,0 +1,150 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ if ENV['TEST_ACTIVERECORD']
6
+ class GeometryColumnsTests < ActiveRecord::TestCase
7
+ include TestHelper
8
+ include ActiveRecord::TestFixtures
9
+
10
+ self.fixture_path = File.join(File.dirname(__FILE__), 'fixtures')
11
+ fixtures :foos
12
+
13
+ def test_geometry_columns_detected
14
+ assert_equal(2, Foo.geometry_columns.length)
15
+
16
+ Foo.geometry_columns.each do |column|
17
+ assert_kind_of(ActiveRecord::ConnectionAdapters::PostgreSQLGeometryColumn, column)
18
+ end
19
+ end
20
+
21
+ def test_srid_for
22
+ assert_equal(-1, Foo.srid_for(:the_geom))
23
+ assert_equal(4326, Foo.srid_for(:the_other_geom))
24
+ end
25
+
26
+ def test_coord_dimension_for
27
+ assert_equal(2, Foo.coord_dimension_for(:the_geom))
28
+ assert_equal(2, Foo.coord_dimension_for(:the_other_geom))
29
+ end
30
+
31
+ def test_geometry_column_by_name
32
+ assert_kind_of(ActiveRecord::ConnectionAdapters::PostgreSQLGeometryColumn, Foo.geometry_column_by_name(:the_geom))
33
+ assert_kind_of(ActiveRecord::ConnectionAdapters::PostgreSQLGeometryColumn, Foo.geometry_column_by_name(:the_other_geom))
34
+ end
35
+
36
+ def test_accessors
37
+ foo = Foo.find(1)
38
+
39
+ Geos::ActiveRecord::GeometryColumns::GEOMETRY_COLUMN_OUTPUT_FORMATS.each do |format|
40
+ assert(foo.respond_to?("the_geom_#{format}"))
41
+ assert(foo.respond_to?("the_other_geom_#{format}"))
42
+ end
43
+ end
44
+
45
+ def test_without_accessor
46
+ foo = Foo.find(1)
47
+ assert_kind_of(String, foo.the_geom)
48
+ end
49
+
50
+ def test_geos_accessor
51
+ foo = Foo.find(1)
52
+ assert_kind_of(Geos::Point, foo.the_geom_geos)
53
+ end
54
+
55
+ def test_wkt_accessor
56
+ foo = Foo.find(1)
57
+ assert_kind_of(String, foo.the_geom_wkt)
58
+ assert_match(/^POINT\s*\(0\.0+\s+0\.0+\)$/, foo.the_geom_wkt)
59
+ end
60
+
61
+ def test_wkb_accessor
62
+ foo = Foo.find(1)
63
+ assert_kind_of(String, foo.the_geom_wkb)
64
+ assert_match(/^[A-F0-9]+$/, foo.the_geom_wkb)
65
+ end
66
+
67
+ def test_ewkt_accessor
68
+ foo = Foo.find(1)
69
+ assert_kind_of(String, foo.the_geom_ewkt)
70
+ assert_match(/^SRID=\d+;POINT\s*\(0\.0+\s+0\.0+\)$/, foo.the_geom_ewkt)
71
+ end
72
+
73
+ def test_ewkb_accessor
74
+ foo = Foo.find(1)
75
+ assert_kind_of(String, foo.the_geom_ewkb)
76
+ assert(/^[A-F0-9]+$/, foo.the_geom_wkb)
77
+ end
78
+
79
+ def test_wkb_bin_accessor
80
+ foo = Foo.find(1)
81
+ assert_kind_of(String, foo.the_geom_wkb_bin)
82
+ end
83
+
84
+ def test_ewkb_bin_accessor
85
+ foo = Foo.find(1)
86
+ assert_kind_of(String, foo.the_geom_ewkb_bin)
87
+ end
88
+
89
+ def test_geos_create
90
+ foo = Foo.create!(
91
+ :name => 'test_geos_create',
92
+ :the_geom => Geos.read(POINT_WKT)
93
+ )
94
+
95
+ foo.reload
96
+ assert_saneness_of_point(foo.the_geom_geos)
97
+ end
98
+
99
+ def test_wkt_create
100
+ foo = Foo.create!(
101
+ :name => 'test_wkt_create',
102
+ :the_geom => POINT_WKT
103
+ )
104
+
105
+ foo.reload
106
+ assert_saneness_of_point(foo.the_geom_geos)
107
+ end
108
+
109
+ def test_wkb_create
110
+ foo = Foo.create!(
111
+ :name => 'test_wkb_create',
112
+ :the_geom => POINT_WKB
113
+ )
114
+
115
+ foo.reload
116
+ assert_saneness_of_point(foo.the_geom_geos)
117
+ end
118
+
119
+ def test_ewkt_create_with_srid_4326
120
+ foo = Foo.create!(
121
+ :name => 'test_ewkt_create_with_srid_4326',
122
+ :the_other_geom => POINT_EWKT
123
+ )
124
+
125
+ foo.reload
126
+ assert_saneness_of_point(foo.the_other_geom_geos)
127
+ end
128
+
129
+ def test_ewkt_create_with_srid_default
130
+ foo = Foo.create!(
131
+ :name => 'test_ewkt_create_with_srid_default',
132
+ :the_other_geom => POINT_EWKT_WITH_DEFAULT
133
+ )
134
+
135
+ foo.reload
136
+ assert_saneness_of_point(foo.the_other_geom_geos)
137
+ foo.the_other_geom_geos
138
+ end
139
+
140
+ def test_ewkb_create
141
+ foo = Foo.create!(
142
+ :name => 'test_ewkb_create',
143
+ :the_other_geom => POINT_EWKB
144
+ )
145
+
146
+ foo.reload
147
+ assert_saneness_of_point(foo.the_other_geom_geos)
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,88 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ if ENV['TEST_ACTIVERECORD']
6
+ class GeospatialScopesTests < ActiveRecord::TestCase
7
+ include TestHelper
8
+ include ActiveRecord::TestFixtures
9
+
10
+ self.fixture_path = File.join(File.dirname(__FILE__), 'fixtures')
11
+ fixtures :foos
12
+
13
+ def tester(method, args, ids = [])
14
+ geoms = Foo.send(method, *Array(args)).all
15
+ assert_equal(ids.sort, geoms.collect(&:id).sort)
16
+ end
17
+
18
+ def test_contains
19
+ tester(:st_contains, 'POINT(3 3)', [ 3 ])
20
+ end
21
+
22
+ def test_containsproperly
23
+ tester(:st_containsproperly, 'LINESTRING(-4 -4, 4 4)', [ 3 ])
24
+ end
25
+
26
+ def test_covers
27
+ tester(:st_covers, 'LINESTRING(-4 -4, 4 4)', [ 3 ])
28
+ end
29
+
30
+ def test_coveredby
31
+ tester(:st_coveredby, 'POLYGON((-6 -6, -6 6, 6 6, 6 -6, -6 -6))', [ 1, 3 ])
32
+ end
33
+
34
+ def test_crosses
35
+ tester(:st_crosses, 'LINESTRING(-6 -6, 4 4)', [ 3 ])
36
+ end
37
+
38
+ def test_disjoint
39
+ tester(:st_disjoint, 'POINT(100 100)', [ 1, 2, 3 ])
40
+ end
41
+
42
+ def test_equal
43
+ tester(:st_equals, 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5))', [ 3 ])
44
+ end
45
+
46
+ def test_intersects
47
+ tester(:st_intersects, 'LINESTRING(-5 -5, 10 10)', [ 1, 2, 3 ])
48
+ end
49
+
50
+ def test_orderingequals
51
+ tester(:st_orderingequals, 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5))', [ 3 ])
52
+ end
53
+
54
+ def test_overlaps
55
+ tester(:st_overlaps, 'POLYGON((-6 -6, -5 0, 0 0, 0 -5, -6 -6))', [ 3 ])
56
+ end
57
+
58
+ def test_touches
59
+ tester(:st_touches, 'POLYGON((-5 -5, -5 -10, -10 -10, -10 -5, -5 -5))', [ 3 ])
60
+ end
61
+
62
+ def test_within
63
+ tester(:st_within, 'POLYGON((-5 -5, 5 10, 20 20, 10 5, -5 -5))', [ 1, 2 ])
64
+ end
65
+
66
+ def test_dwithin
67
+ tester(:st_dwithin, [ 'POINT(5 5)', 10 ], [ 1, 2, 3 ])
68
+ end
69
+
70
+ def test_with_column
71
+ assert_equal([1, 2, 3], Foo.st_disjoint('POINT(100 100)', :column => :the_other_geom).all.collect(&:id).sort)
72
+ end
73
+
74
+ def test_with_srid_switching
75
+ assert_equal([1, 2, 3], Foo.st_disjoint('SRID=4326; POINT(100 100)').all.collect(&:id).sort)
76
+ end
77
+
78
+ def test_with_srid_default
79
+ assert_equal([1, 2, 3], Foo.st_disjoint('SRID=default; POINT(100 100)').all.collect(&:id).sort)
80
+ assert_equal([3], Foo.st_contains('SRID=default; POINT(-3 -3)').all.collect(&:id).sort)
81
+ end
82
+
83
+ def test_with_srid_transform
84
+ assert_equal([1, 2, 3], Foo.st_disjoint('SRID=4269; POINT(100 100)', :column => :the_other_geom).all.collect(&:id).sort)
85
+ assert_equal([3], Foo.st_contains('SRID=4269; POINT(7 7)', :column => :the_other_geom).all.collect(&:id).sort)
86
+ end
87
+ end
88
+ end
@@ -1,6 +1,26 @@
1
1
 
2
2
  require 'rubygems'
3
3
  require 'test/unit'
4
+
5
+ if ENV['TEST_ACTIVERECORD']
6
+ ACTIVERECORD_GEM_VERSION = ENV['ACTIVERECORD_GEM_VERSION'] || '~> 3.0.3'
7
+ gem 'activerecord', ACTIVERECORD_GEM_VERSION
8
+
9
+ POSTGIS_PATHS = [
10
+ ENV['POSTGIS_PATH'],
11
+ '/opt/local/share/postgresql*/contrib/postgis-*',
12
+ '/usr/share/postgresql*/contrib/postgis-*',
13
+ '/usr/pgsql-*/share/contrib/postgis-*',
14
+ ].compact
15
+
16
+ puts "Testing against ActiveRecord #{Gem.loaded_specs['activerecord'].version.to_s}"
17
+ require 'active_support'
18
+ require 'active_support/core_ext/module/aliasing'
19
+ require 'active_record'
20
+ require 'active_record/fixtures'
21
+ require 'logger'
22
+ end
23
+
4
24
  require File.join(File.dirname(__FILE__), %w{ .. lib geos_extensions })
5
25
 
6
26
  puts "Ruby version #{RUBY_VERSION} - #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}"
@@ -9,9 +29,71 @@ if defined?(Geos::FFIGeos)
9
29
  puts "Using #{Geos::FFIGeos.geos_library_paths.join(', ')}"
10
30
  end
11
31
 
32
+ if ENV['TEST_ACTIVERECORD']
33
+ ActiveRecord::Base.logger = Logger.new("debug.log")
34
+ ActiveRecord::Base.configurations = {
35
+ 'arunit' => {
36
+ :adapter => 'postgresql',
37
+ :database => 'geos_extensions_unit_tests',
38
+ :min_messages => 'warning',
39
+ :schema_search_path => 'public'
40
+ }
41
+ }
42
+
43
+ ActiveRecord::Base.establish_connection 'arunit'
44
+ ARBC = ActiveRecord::Base.connection
45
+
46
+ puts "Checking for PostGIS install"
47
+ 2.times do
48
+ begin
49
+ if postgis_version = ARBC.query('SELECT postgis_version()').to_s
50
+ puts "PostGIS info from postgis_version(): #{postgis_version}"
51
+ break
52
+ end
53
+ rescue ActiveRecord::StatementInvalid
54
+ puts "Trying to install PostGIS. If this doesn't work, you'll have to do this manually!"
55
+
56
+ plpgsql = ARBC.query(%{SELECT count(*) FROM pg_language WHERE lanname = 'plpgsql'}).to_s
57
+ if plpgsql == '0'
58
+ ARBC.execute(%{CREATE LANGUAGE plpgsql})
59
+ end
60
+
61
+ %w{
62
+ postgis.sql
63
+ spatial_ref_sys.sql
64
+ }.each do |file|
65
+ if !(found = Dir.glob(POSTGIS_PATHS).collect { |path|
66
+ File.join(path, file)
67
+ }.first)
68
+ puts "ERROR: Couldn't find #{file}. Try setting the POSTGIS_PATH to give us a hint!"
69
+ exit
70
+ else
71
+ ARBC.execute(File.read(found))
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ if !ARBC.table_exists?('foos')
78
+ ActiveRecord::Migration.create_table(:foos) do |t|
79
+ t.text :name
80
+ end
81
+
82
+ ARBC.execute(%{SELECT AddGeometryColumn('public', 'foos', 'the_geom', -1, 'GEOMETRY', 2)})
83
+ ARBC.execute(%{SELECT AddGeometryColumn('public', 'foos', 'the_other_geom', 4326, 'GEOMETRY', 2)})
84
+ end
85
+
86
+ class Foo < ActiveRecord::Base
87
+ include Geos::ActiveRecord::GeometryColumns
88
+ include Geos::ActiveRecord::GeospatialScopes
89
+ create_geometry_column_accessors!
90
+ end
91
+ end
92
+
12
93
  module TestHelper
13
94
  POINT_WKT = 'POINT(10 10.01)'
14
95
  POINT_EWKT = 'SRID=4326; POINT(10 10.01)'
96
+ POINT_EWKT_WITH_DEFAULT = 'SRID=default; POINT(10 10.01)'
15
97
  POINT_WKB = "0101000000000000000000244085EB51B81E052440"
16
98
  POINT_WKB_BIN = "\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40"
17
99
  POINT_EWKB = "0101000020E6100000000000000000244085EB51B81E052440"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geos-extensions
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - J Smith
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-24 00:00:00 -05:00
18
+ date: 2011-02-27 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -41,6 +41,9 @@ files:
41
41
  - lib/geos_helper.rb
42
42
  - lib/google_maps.rb
43
43
  - lib/google_maps/polyline_encoder.rb
44
+ - test/fixtures/foos.yml
45
+ - test/geometry_columns_test.rb
46
+ - test/geospatial_scopes_test.rb
44
47
  - test/reader_test.rb
45
48
  - test/test_helper.rb
46
49
  - test/writer_test.rb
@@ -79,6 +82,8 @@ signing_key:
79
82
  specification_version: 3
80
83
  summary: Extensions for the GEOS library.
81
84
  test_files:
85
+ - test/geometry_columns_test.rb
86
+ - test/geospatial_scopes_test.rb
82
87
  - test/reader_test.rb
83
88
  - test/test_helper.rb
84
89
  - test/writer_test.rb