nofxx-postgis_adapter 0.1.2

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.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2008-12-10
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Spatial Adapter Copyright (c) 2006 Guilhem Vellut <guilhem.vellut+georuby@gmail.com>
2
+ PostGis Adapter Functions (c) 2008 Marcos Piccinini <nofxx>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,36 @@
1
+ History.txt
2
+ MIT-LICENSE
3
+ Manifest.txt
4
+ README.markdown
5
+ Rakefile
6
+ init.rb
7
+ install.rb
8
+ lib/postgis_adapter.rb
9
+ lib/postgis_adapter/acts_as_geom.rb
10
+ lib/postgis_adapter/common_spatial_adapter.rb
11
+ lib/postgis_functions.rb
12
+ lib/postgis_functions/bbox.rb
13
+ lib/postgis_functions/class.rb
14
+ lib/postgis_functions/common.rb
15
+ lib/postgis_functions/linestring.rb
16
+ lib/postgis_functions/point.rb
17
+ lib/postgis_functions/polygon.rb
18
+ postgis_adapter.gemspec
19
+ rails/init.rb
20
+ script/console
21
+ script/destroy
22
+ script/generate
23
+ spec/acts_as_geom_spec.rb
24
+ spec/common_spatial_adapter_spec.rb
25
+ spec/db/database_postgis.yml
26
+ spec/db/models_postgis.rb
27
+ spec/db/schema_postgis.rb
28
+ spec/postgis_adapter_spec.rb
29
+ spec/postgis_functions/bbox_spec.rb
30
+ spec/postgis_functions/linestring_spec.rb
31
+ spec/postgis_functions/point_spec.rb
32
+ spec/postgis_functions/polygon_spec.rb
33
+ spec/postgis_functions_spec.rb
34
+ spec/spec.opts
35
+ spec/spec_helper.rb
36
+ uninstall.rb
data/README.markdown ADDED
@@ -0,0 +1,301 @@
1
+ Postgis Adapter
2
+ ===============
3
+
4
+ A plugin for ActiveRecord which manages the PostGIS geometric columns
5
+ in a transparent way (that is like the other base data type columns).
6
+ It also provides a way to manage these columns in migrations.
7
+
8
+ This fork adds handy methods to make geometrical calculations on postgis.
9
+
10
+ [Postgis Manual](http://postgis.refractions.net/documentation/manual-svn)
11
+
12
+ *PostGIS and Rails 2+ only*.
13
+
14
+
15
+ Install
16
+ -------
17
+
18
+ If you are using Spatial Adapter, *remove it first*.
19
+
20
+ ### Dependencies
21
+
22
+ - georuby
23
+ - postgres 8.3+
24
+ - postgis 1.3+
25
+
26
+ ### As gem:
27
+
28
+ sudo gem sources --add http://gems.github.com
29
+ sudo gem install nofxx-postgis_adapter
30
+
31
+ config.gem "nofxx-postgis_adapter", :lib => "postgis_adapter", :source => "http://gems.github.com"
32
+
33
+ ### As plugin:
34
+
35
+ script/plugin install git://github.com/nofxx/postgis_adapter.git
36
+
37
+
38
+ How to Use
39
+ ----------
40
+
41
+ Geometric columns in your ActiveRecord models now appear just like
42
+ any other column of other basic data types. They can also be dumped
43
+ in ruby schema mode and loaded in migrations the same way as columns
44
+ of basic types.
45
+
46
+
47
+ ### Model
48
+
49
+ class TablePoint < ActiveRecord::Base
50
+ end
51
+
52
+ That was easy! As you see, there is no need to declare a column as geometric.
53
+ The plugin will get this information by itself.
54
+
55
+ Here is an example of PostGIS row creation and access, using the
56
+ model and the table defined above :
57
+
58
+ pt = TablePoint.new(:data => "Hello!",:geom => Point.from_x_y(1,2))
59
+ pt.save
60
+ pt = TablePoint.first
61
+ puts pt.geom.x
62
+ => 1
63
+
64
+
65
+ PostGIS Functions
66
+ -----------------
67
+
68
+ Here are this fork additions. To use it:
69
+
70
+
71
+ class Street < ActiveRecord::Base
72
+ acts_as_geom :line
73
+ end
74
+
75
+ ...
76
+
77
+ @place = Poi.new( :data => **Point** )
78
+ @park = Park.new( :area => **Polygon** )
79
+ @street = Street.new( :line => **LineString** )
80
+
81
+
82
+ ### Play!
83
+
84
+ @place.inside?(@park)
85
+ => true
86
+
87
+ @place.in_bounds?(@park, 0.5) # margin
88
+ => false
89
+
90
+ @place.outside?(@park)
91
+
92
+ @street.crosses?(@park)
93
+
94
+ @area.contains?(@place)
95
+
96
+ Polygons:
97
+
98
+ @park.area
99
+ => 1345
100
+
101
+ @park.contains?(@point)
102
+ => true
103
+
104
+ @park.overlaps?(@other_park)
105
+ => false
106
+
107
+ Line Strings:
108
+
109
+ @street_east.intersects?(@street_west)
110
+ => false
111
+
112
+ @street_central.length
113
+ => 4508.53636
114
+
115
+ @street_central.length(:miles)
116
+ => 2.81798593
117
+
118
+ @street.length_spheroid
119
+ => 4.40853636
120
+
121
+
122
+ ### And for classes:
123
+
124
+ City.close_to(@point)
125
+ => [Array of cities in order by distance...
126
+
127
+ Street.close_to(@point)
128
+ => [Array streets in order by distance...
129
+
130
+ Country.contain(@point)
131
+ => The Conutry that contains the point
132
+
133
+ Areas.contains(@point)
134
+ => [Array of areas contains the point...
135
+
136
+
137
+ ### BBox Support
138
+
139
+ @area.strictly_left_of? @point
140
+
141
+ @area.overlaps_or_above? @street
142
+
143
+ ...
144
+
145
+ completely_contained_by?
146
+ completely_contains?
147
+ overlaps_or_above?
148
+ overlaps_or_below?
149
+ overlaps_or_left_of?
150
+ overlaps_or_right_of?
151
+ strictly_above?
152
+ strictly_below?
153
+ strictly_left_of?
154
+ strictly_right_of?
155
+ interacts_with?
156
+ binary_equal?
157
+ same_as?
158
+
159
+
160
+ Or use a (almost) postgis like notation:
161
+
162
+ @area.bbox "<<", @point
163
+
164
+ @area.bbox "|>>", @point
165
+
166
+ @area.bbox "@", @park
167
+
168
+
169
+ ### Warning
170
+
171
+ *To be fixed:*
172
+
173
+ This only supports one geom column per model. Still looking for the best way to
174
+ implement a multi geom.
175
+
176
+ http://nofxx.lighthouseapp.com/projects/20712/tickets/3-multiple-geoms-in-model
177
+
178
+ ### Wiki
179
+
180
+ Check out the [wiki pages](http://github.com/nofxx/postgis_adapter/wikis).
181
+ For all functions.
182
+
183
+
184
+ ### Find_by
185
+
186
+ find_by_*column* has been redefined when column is of a geometric type.
187
+ Instead of using the Rails default '=' operator, for which I can't see
188
+ a definition for MySql spatial datatypes and which performs a bounding
189
+ box equality test in PostGIS, it uses a bounding box intersection:
190
+ && in PostGIS and MBRIntersects in MySQL, which can both make use
191
+ of a spatial index if one is present to speed up the queries.
192
+ You could use this query, for example, if you need to display data
193
+ from the database: You would want only the geometries which are in
194
+ the screen rectangle and you could use a bounding box query for that.
195
+ Since this is a common case, it is the default. You have 2 ways to use
196
+ the find_by_*geom_column*: Either by passing a geometric object directly,
197
+ or passing an array with the 2 opposite corners of a bounding box
198
+ (with 2 or 3 coordinates depending of the dimension of the data).
199
+
200
+ Park.find_by_geom(LineString.from_coordinates([[1.4,5.6],[2.7,8.9],[1.6,5.6]]))
201
+
202
+ or
203
+
204
+ Park.find_by_geom([[3,5.6],[19.98,5.9]])
205
+
206
+ In PostGIS, since you can only use operations with geometries with the same SRID, you can add a third element representing the SRID of the bounding box to the array. It is by default set to -1:
207
+
208
+ Park.find_by_geom([[3,5.6],[19.98,5.9],123])
209
+
210
+
211
+ Database Tools
212
+ --------------
213
+
214
+ ### Migrations
215
+
216
+ Here is an example of code for the creation of a table with a
217
+ geometric column in PostGIS, along with the addition of a spatial
218
+ index on the column :
219
+
220
+ ActiveRecord::Schema.define do
221
+ create_table :places do |t|
222
+ t.string :name
223
+ t.point :geom, :srid => 123, :with_z => true, :null => false
224
+
225
+ t.timestamps
226
+ end
227
+ add_index :table_points, :geom, :spatial=>true
228
+ end
229
+
230
+
231
+ ### Fixtures
232
+
233
+ If you use fixtures for your unit tests, at some point,
234
+ you will want to input a geometry. You could transform your
235
+ geometries to a form suitable for YAML yourself everytime but
236
+ the spatial adapter provides a method to do it for you: +to_yaml+.
237
+ It works for both MySQL and PostGIS (although the string returned
238
+ is different for each database). You would use it like this, if
239
+ the geometric column is a point:
240
+
241
+ fixture:
242
+ id: 1
243
+ data: HELLO
244
+ geom: <%= Point.from_x_y(123.5,321.9).to_yaml %>
245
+
246
+
247
+ Geometric data types
248
+ --------------------
249
+
250
+ Ruby geometric datatypes are currently made available only through
251
+ the GeoRuby library (http://georuby.rubyforge.org): This is where the
252
+ *Point.from_x_y* in the example above comes from. It is a goal
253
+ of a future release of the Spatial Adapter to support additional
254
+ geometric datatype libraries, such as Ruby/GEOS, as long as they
255
+ can support reading and writing of EWKB.
256
+
257
+
258
+ Warning
259
+ -------
260
+
261
+ - Since ActiveRecord seems to keep only the string values directly
262
+ returned from the database, it translates from these to the correct
263
+ types everytime an attribute is read, which is probably ok for simple
264
+ types, but might be less than efficient for geometries, since the EWKB
265
+ string has to be parsed everytime. Also it means you cannot modify the
266
+ geometry object returned from an attribute directly :
267
+
268
+ place = Place.first
269
+ place.the_geom.y=123456.7
270
+
271
+ - Since the translation to a geometry is performed everytime the_geom
272
+ is read, the change to y will not be saved! You would have to do
273
+ something like this :
274
+
275
+ place = Place.first
276
+ the_geom = place.the_geom
277
+ the_geom.y=123456.7
278
+ place.the_geom = the_geom
279
+
280
+
281
+ License
282
+ -------
283
+
284
+ Spatial Adapter for Rails is released under the MIT license.
285
+ PostGis Adapter is released under the MIT license.
286
+
287
+
288
+ Support
289
+ -------
290
+
291
+ Tested using rails 2.2.2 / postgresql 8.3.5 / postgis 1.3.3 / linux / osx
292
+
293
+ Any questions, enhancement proposals, bug notifications or corrections:
294
+
295
+ ### PostGis Adapter
296
+
297
+ [Project Tracker](http://nofxx.lighthouseapp.com/projects/20712-postgis_adapter)
298
+
299
+ ### SpatialAdapter
300
+
301
+ guilhem.vellut+georuby@gmail.com.
data/Rakefile ADDED
@@ -0,0 +1,107 @@
1
+ #$:.unshift(File.join(File.dirname(__FILE__) ,'../../gems/georuby/lib/'))
2
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
3
+ require 'rake'
4
+ require 'spec/rake/spectask'
5
+ require 'rake/rdoctask'
6
+ require 'active_record'
7
+ require 'active_record/connection_adapters/postgresql_adapter'
8
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
9
+ require File.dirname(__FILE__) + '/lib/postgis_adapter'
10
+
11
+ # Generate all the Rake tasks
12
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)PostgisAdapter::VERSION
13
+ $hoe = Hoe.new('postgis_adapter', PostgisAdapter::VERSION) do |p|
14
+ p.developer('Marcos Piccinini', 'x@nofxx.com')
15
+ p.summary = "Postgis Adapter for Activer Record"
16
+ p.description = "Postgis Adapter for Activer Record"
17
+ p.url = "http://github.com/nofxx/postgis_adapter"
18
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
19
+ # p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
20
+ p.rubyforge_name = "postgis_adapter" # TODO this is default value
21
+ p.extra_deps = [
22
+ ['activerecord','>= 2.0.2'],
23
+ ]
24
+ p.extra_dev_deps = [
25
+ ['newgem', ">= #{::Newgem::VERSION}"]
26
+ ]
27
+
28
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
29
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
30
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
31
+ p.rsync_args = '-av --delete --ignore-errors'
32
+ end
33
+
34
+ require 'newgem/tasks' # load /tasks/*.rake
35
+ Dir['tasks/**/*.rake'].each { |t| load t }
36
+
37
+ # TODO - want other tests/tasks run by default? Add them to the list
38
+ # task :default => [:spec, :features]
39
+
40
+
41
+ desc 'Default: run specs.'
42
+ task :default => :spec
43
+
44
+ #desc 'Run the specs'
45
+ #Spec::Rake::SpecTask.new(:spec) do |t|
46
+ # t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
47
+ # t.spec_files = FileList['spec/**/*_spec.rb']
48
+ #end
49
+
50
+ desc "Run all specs"
51
+ Spec::Rake::SpecTask.new do |t|
52
+ t.spec_files = FileList['spec/*_spec.rb']
53
+ t.spec_opts = ['--options', 'spec/spec.opts']
54
+ unless ENV['NO_RCOV']
55
+ t.rcov = true
56
+ t.rcov_dir = 'coverage'
57
+ t.rcov_opts = ['--html', '--exclude', "\.autotest,schema.rb,init.rb,\.gitignore,spec\/spec_helper.rb,spec\/db/*,#{ENV['GEM_HOME']}"]
58
+ end
59
+ end
60
+
61
+ desc "Look for TODO and FIXME tags in the code"
62
+ task :todo do
63
+ egrep /(FIXME|TODO|TBD)/
64
+ end
65
+
66
+ namespace :db do
67
+ task :migrate do
68
+ load('spec/db/schema_postgis.rb')
69
+ end
70
+ end
71
+
72
+ desc "Generate the documentation"
73
+ Rake::RDocTask::new do |rdoc|
74
+ rdoc.rdoc_dir = 'doc/'
75
+ rdoc.title = "PostGIS Adapter for Rails Documentation"
76
+ rdoc.options << '--line-numbers' << '--inline-source'
77
+ rdoc.rdoc_files.include('README.markdown')
78
+ rdoc.rdoc_files.include('lib/**/*.rb')
79
+ end
80
+
81
+ # From Rspec Rakefile
82
+ #
83
+ def egrep(pattern)
84
+ Dir['**/*.rb'].each do |fn|
85
+ count = 0
86
+ open(fn) do |f|
87
+ while line = f.gets
88
+ count += 1
89
+ if line =~ pattern
90
+ puts "#{fn}:#{count}:#{line}"
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ desc "verify_committed, verify_rcov, post_news, release"
98
+ task :complete_release => [:verify_committed, :post_news, :release]
99
+
100
+ desc "Verifies that there is no uncommitted code"
101
+ task :verify_committed do
102
+ IO.popen('git status') do |io|
103
+ io.each_line do |line|
104
+ raise "\n!!! Do a git commit first !!!\n\n" if line =~ /^#\s*modified:/
105
+ end
106
+ end
107
+ end