Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/rgeo/activerecord-spatialite-adapter

ActiveRecord connection adapter for SpatiaLite, based on sqlite3 and rgeo
https://github.com/rgeo/activerecord-spatialite-adapter

Last synced: about 1 month ago
JSON representation

ActiveRecord connection adapter for SpatiaLite, based on sqlite3 and rgeo

Lists

README

        

== SpatiaLite \ActiveRecord Adapter

The SpatiaLite \ActiveRecord Adapter is an \ActiveRecord connection
adapter based on the standard sqlite3 adapter. It extends the standard
adapter to provide support for spatial extensions using SpatiaLite, using
the {RGeo}[http://github.com/dazuma/rgeo] library to represent spatial
data in Ruby. Like the standard sqlite3 adapter, this adapter requires
the sqlite3-ruby gem.

== What This Adapter Provides

=== Spatial Migrations

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 spatial index, set
the :spatial option to true.

Examples:

create_table :my_spatial_table do |t|
t.column :latlon, :point # or t.point :latlon
t.line_string :path
t.geometry :shape
end
change_table :my_spatial_table do |t|
t.index :latlon, :spatial => true
end

=== Spatial Attributes

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.

Spatial objects in RGeo are tied to a factory that specifies the
coordinate system as well as other behaviors of the object. You must
therefore specify a factory for each spatial column (attribute) in your
\ActiveRecord class. You can either set an explicit factory for a specific
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 at least the :srid
option, which will be provided based on the column's specified SRID. Note
that the spatialite adapter does not currently support Z or M coordinates,
as it's unclear to me whether SpatiaLite itself supports them. 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 MySpatialTable < 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 = MySpatialTable.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

=== Spatial Queries

You can create simple queries based on objective equality in the same way
you would on a scalar column:

rec = MySpatialTable.where(:latlon => RGeo::Geos.factory.point(-122, 47)).first

You can also use WKT:

rec = MySpatialTable.where(:latlon => 'POINT(-122 47)').first

The adapter also provides experimental support for more complex queries
such as radius searches. However, these extensions require Arel 2.1
(which is scheduled for release with Rails 3.1). We do not have these
documented yet, and the syntax is subject to change. For now, you should
write more complex queries in SQL.

== Installation And Configuration

=== Installing The Adapter Gem

This adapter has the following requirements:

* Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred.
* sqlite 3.7.3 or later.
* SpatiaLite 3.0 or later. Version 2.3 may work but is not officially
supported.
* sqlite3 gem 1.3.5 or later.
* \ActiveRecord 3.0.3 or later. Earlier versions will not work.
Should be compatible with Rails versions through 3.2.x.
* rgeo gem 0.3.7 or later.
* rgeo-activerecord gem 0.4.3 or later.

Note: if you are running Mac OS X, the OS-provided copy of sqlite3 may
not support extensions. You should install an alternate copy of sqlite3
(for example, using MacPorts or Homebrew) reinstall the gem using:

gem install sqlite3 -- --with-sqlite3-dir=/path/to/alternate/sqlite3

Install this adapter as a gem:

gem install activerecord-spatialite-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-spatialite-adapter",
to your Gemfile, and then request the adapter name "spatialite" in
your database connection configuration (which, for a Rails application,
is in the config/database.yml file). The other database connection
configuration parameters are the same as for the stock sqlite3 adapter,
with the exception of one additional parameter, libspatialite,
which should be set to the full path to the libspatialite shared library,
if it is not installed in a standard place (such as /usr/local or
/opt/local).

Generally, you can create a new Rails application using:

rails new my_app --database=sqlite3

...and then change the adapter names to "spatialite" and add an
appropriate libspatialite setting.

Next, the SpatiaLite adapter includes a special railtie that provides
support for SpatiaLite 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 'active_record/connection_adapters/spatialite_adapter/railtie'

Note that this railtie must load after the ActiveRecord railtie. That is,
the above require command should appear after require 'rails/all'.

=== Dealing with SpatiaLite Definitions

SpatiaLite adds many objects (meta-information tables, functions,
triggers, etc.) to a Sqlite3 database. These objects are required to
maintain the spatial elements of the database, but they can be a hassle
when managing the database with Rails. Following are some tips and
gotchas that you may encounter.

Make sure you include the correct libspatialite setting in your
database.yml config file, especially for your production environments.

SpatiaLite databases need to be initialized by executing the SpatiaLite
initialization script or by calling the InitSpatialMetaData() function.
The rake db:create task will do this for you when it creates a database.
Thus, when setting up a new application, you should make sure you call
rake db:create or otherwise cause the SpatiaLite initialization to
occur, before you attempt to run your first migration. Failure to do so
will result in errors during the migration.

Dumping a SpatiaLite database as SQL will cause a bunch of internal tables
and triggers to be included in your dump. These are the actual SpatiaLite
implementation objects used to enforce spatial constraints and implement
spatial indexes. Unfortunately, not only is this a bit unsightly, but not
everything is dumped here: for example, for each spatial column, there
should be a row in the geometry_columns table, and those will be missing
in the SQL structure dump. As a result, loading from the SQL structure
dump will not properly reproduce your database schema. Because of this, we
highly recommend that you leave config.active_record.schema_format set to
:ruby for now, so that schema dumps are done in the Ruby format.

== Additional Information

=== Known bugs and limitations

The spatialite adapter works in principle, but there are a few known holes
in the functionality. Notably, things that require the alter_table
mechanism may not function properly, because the current sqlite3
implementation doesn't properly preserve triggers. This means, among
other things, removing columns in tables with spatial information can
cause the remaining spatial columns to fail. However, most simple things
work, including creating tables with geometric columns, adding geometric
columns to existing tables, and creating and removing spatial R*tree
indexes. Note that this adapter is not yet well tested.

=== Development and support

Documentation is available at http://dazuma.github.com/activerecord-spatialite-adapter/rdoc

Source code is hosted on Github at http://github.com/dazuma/activerecord-spatialite-adapter

Contributions are welcome. Fork the project on Github.

Report bugs on Github issues at http://github.org/dazuma/activerecord-spatialite-adapter/issues

Support available on the rgeo-users google group at http://groups.google.com/group/rgeo-users

Contact the author at dazuma at gmail dot com.

=== Acknowledgments

The SpatiaLite Adapter and its supporting libraries (including RGeo) are
written by Daniel Azuma (http://www.daniel-azuma.com).

Development is supported by Pirq. (http://www.pirq.com).

=== License

Copyright 2010-2012 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.