geos-extensions 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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