nofxx-postgis_adapter 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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