== PostGIS \ActiveRecord Adapter The PostGIS \ActiveRecord Adapter is an \ActiveRecord connection adapter based on the standard postgresql adapter. It extends the standard adapter to provide support for the spatial extensions provided by PostGIS, using the {RGeo}[http://github.com/dazuma/rgeo] library to represent spatial data in Ruby. Like the standard postgresql adapter, this adapter requires the pg gem. === What This Adapter Provides First, this adapter extends the migration syntax to support creating spatial columns and indexes. To create a spatial column, use the :geometry type, or any of the OGC spatial types such as :point or :line_string. To create a geography column, set the :geographic option to true when creating the column. To create a spatial index, set the :spatial option to true when creating the index. Examples: create_table :spatial_table do |t| t.column :shape, :geometry # or t.geometry :shape t.line_string :path t.column :latlon, :point, :geographic => true end change_table :spatial_table do |t| t.index :latlon, :spatial => true end When this adapter is in use, spatial attributes in your \ActiveRecord objects will have RGeo geometry values. You can set spatial attributes either to RGeo geometry objects, or to strings in WKT (well-known text) format, which the adapter will automatically convert to geometry objects. To specify the RGeo geometry factory, you can either set an explicit factory for a column, or provide a factory generator that will yield the appropriate factory for the table's spatial columns based on their types. For the former, call the set_rgeo_factory_for_column class method on your \ActiveRecord class. For the latter, set the rgeo_factory_generator class attribute. This generator should understand the usual :srid, :has_z_coordinate, and :has_m_coordinate options. It will also be passed a :geographic option indicating whether the column is a geography column. The set_rgeo_factory_for_column and rgeo_factory_generator methods are actually implemented and documented in the "rgeo-activerecord" gem. Examples, given the spatial table defined above: class SpatialTable < ActiveRecord::Base # By default, use the GEOS implementation for spatial columns. self.rgeo_factory_generator = RGeo::Geos.method(:factory) # But use a geographic implementation for the :latlon column. set_rgeo_factory_for_column(:latlon, RGeo::Geographic.spherical_factory) end Now you can interact with the data using the RGeo types: rec = SpatialTable.new rec.latlon = 'POINT(-122 47)' # You can set by feature object or WKT. loc = rec.latlon # Accessing always returns a feature object, in # this case, a geographic that understands latitude. loc.latitude # => 47 rec.shape = loc # the factory for the :shape column is GEOS, so the # value will be cast from geographic to GEOS. RGeo::Geos.is_geos?(rec.shape) # => true You can create simple queries based on spatial equality in the same way you would on a scalar column: rec = SpatialTable.where(:latlon => RGeo::Geos.factory.point(-122, 47)).first You can also use WKT: rec = SpatialTable.where(:latlon => 'POINT(-122 47)').first Other types of queries (e.g. radius searches) currently must be written in SQL. We are investigating writing a set of Arel extensions for constructing arbitrary spatial queries. However, these extensions will probably require Rails 3.1. === Installing The Adapter Gem This adapter has the following requirements: * Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred. * PostGIS 1.5 or later. * \ActiveRecord 3.0.3 or later. Earlier versions will not work. * rgeo gem 0.2.4 or later. * rgeo-activerecord gem 0.2.2 or later. * pg gem 0.10 or later. Install this adapter as a gem: gem install activerecord-postgis-adapter See the README for the "rgeo" gem, a required dependency, for further installation information. === Setting Up The Adapter To use this adapter, add this gem, "activerecord-postgis-adapter", to your Gemfile, and then request the adapter name "postgis" in your database connection configuration (which, for a Rails application, is in the config/database.yml file). Furthermore, the PostGIS adapter includes a special railtie that provides support for PostGIS databases in ActiveRecord's rake tasks. This railtie is required in order to run, e.g., rake test. To install this railtie, you should add this line to your config/application.rb: require 'rgeo/active_record/postgis_adapter/railtie' Note that this railtie must load after the ActiveRecord railtie. That is, the above require command should appear after require 'rails/all'. Besides the adapter name "postgis", most of the other database connection configuration parameters are the same as for the stock postgresql adapter. However, there are a few special parameters you may want to set. The script_dir parameter provides the path to the directory containing the SQL scripts for PostGIS installation. i.e. this could be /usr/local/share/contrib/postgis-1.5. This directory should contain the files postgis.sql and spatial_ref_sys.sql. It is used by the db:create rake task to add the PostGIS types, functions, and tables to a newly created database. If you do not provide this parameter, you will need to add these objects to the database manually. Generally, therefore, this parameter is required at least for the test database, which is usually automatically created by the rake tasks. Because PostGIS adds many objects to the database, you may encounter a few issues when running Rails rake tasks that manage databases. Specifically: * Dumping the structure as sql (rake db:structure:dump) may include all the PostGIS definitions as well, cluttering your SQL dump. * Rake tasks that automatically create the test database (e.g. rake test) may emit a number of errors because PostGIS definitions are being added twice to the database: once on creation, and again because they are showing up in the SQL dump that ActiveRecord uses to copy the schema. Because of these issues, it is recommended that you include the schema name "postgis" in the schema_search_path parameter. The PostGIS adapter treats this schema name as special, in that: * The db:create rake task will automatically create the "postgis" schema, and will create all the PostGIS objects in that schema. * Dumping the structure as sql will omit objects in the "postgis" schema. As a result, the PostGIS definitions will no longer appear in the SQL dump file, effectively eliminating the above issues. === Known bugs and limitations A few minor holes still exist in this adapter. Notably, using \ActiveRecord to list indexes doesn't properly identify GiST (spatial) indexes as such. This adapter is also not yet well tested. === Development and support Documentation is available at http://virtuoso.rubyforge.org/activerecord-postgis-adapter/README_rdoc.html Source code is hosted on Github at http://github.com/dazuma/activerecord-postgis-adapter Contributions are welcome. Fork the project on Github. Report bugs on Github issues at http://github.org/dazuma/activerecord-postgis-adapter/issues Contact the author at dazuma at gmail dot com. === Acknowledgments RGeo is written by Daniel Azuma (http://www.daniel-azuma.com). Development of RGeo is sponsored by GeoPage, Inc. (http://www.geopage.com). This adapter implementation owes some debt to the spatial_adapter plugin (http://github.com/fragility/spatial_adapter). Although we made some different design decisions for this adapter, studying the spatial_adapter source gave us a head start on the implementation. === License Copyright 2010 Daniel Azuma All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder, nor the names of any other contributors to this software, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.