Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cookpad/armg
Add MySQL geometry type to Active Record.
https://github.com/cookpad/armg
activerecord geometry hacktoberfest mysql rails rails5 ruby
Last synced: 10 days ago
JSON representation
Add MySQL geometry type to Active Record.
- Host: GitHub
- URL: https://github.com/cookpad/armg
- Owner: cookpad
- License: mit
- Created: 2017-08-10T09:55:41.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-03-07T15:19:11.000Z (over 1 year ago)
- Last Synced: 2024-10-29T14:15:24.712Z (19 days ago)
- Topics: activerecord, geometry, hacktoberfest, mysql, rails, rails5, ruby
- Language: Ruby
- Homepage:
- Size: 75.2 KB
- Stars: 18
- Watchers: 5
- Forks: 13
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Armg
Add MySQL geometry type to Active Record.
[![Gem Version](https://badge.fury.io/rb/armg.svg)](https://badge.fury.io/rb/armg)
[![Build Status](https://github.com/cookpad/armg/workflows/test/badge.svg?branch=master)](https://github.com/cookpad/armg/actions)## Installation
Add this line to your application's Gemfile:
```ruby
gem 'armg'
```And then execute:
$ bundle
Or install it yourself as:
$ gem install armg
## Usage
```ruby
require 'active_record'
require 'armg'ActiveRecord::Base.establish_connection(adapter: 'mysql2', database: 'my_db')
ActiveRecord::Migration.create_table :geoms, options: 'ENGINE=MyISAM' do |t|
t.geometry 'location', null: false
t.index ['location'], name: 'idx_location', type: :spatial
endclass Geom < ActiveRecord::Base; end
wkt_parser = RGeo::WKRep::WKTParser.new(nil, support_ewkt: true)
point = wkt_parser.parse('SRID=4326;Point(-122.1 47.3)')
Geom.create!(location: point)Geom.first
#=> #>
```## Using WKT
```ruby
Armg.deserializer = Armg::WktDeserializer.new
Armg.serializer = Armg::WktSerializer.newGeom.create!(location: 'Point(-122.1 47.3)')
Geom.first
#=> #
```## Using custom deserializer
```ruby
class CustomDeserializer
def initialize
factory = RGeo::Geographic.spherical_factory(srid: 0)
@wkb_parser = RGeo::WKRep::WKBParser.new(factory, support_ewkb: true)
enddef deserialize(wkb)
wkb_without_srid = wkb.b.slice(4..-1)
@wkb_parser.parse(wkb_without_srid)
end
endArmg.deserializer = CustomDeserializer.new
Geom.take
#=> #>
```## Using custom serializer
```ruby
class CustomSerializer
def initialize
@wkt_parser = RGeo::WKRep::WKTParser.new(nil, support_ewkt: true)
@wkb_generator = RGeo::WKRep::WKBGenerator.new(type_format: :ewkb, little_endian: true)
enddef serialize(value)
if value.is_a?(String)
value = @wkt_parser.parse(value)
endsrid = "\x00\x00\x00\x00"
srid + @wkb_generator.generate(value)
end
endArmg.serializer = CustomSerializer.new
Geom.create!(id: 4, location: 'Point(-122.1 47.3)')
```## Running tests
```sh
docker-compose up -d
bundle install
bundle exec appraisal install
bundle exec appraisal ar61 rake
# bundle exec appraisal ar60 rake
# ARMG_TEST_MYSQL_PORT=10057 bundle exec appraisal ar61 rake # MySQL 5.7
# ARMG_TEST_MYSQL_PORT=10057 ARMG_TEST_MYSQL_ENGINE=InnoDB bundle exec appraisal ar61 rake
```## Using with [Ridgepole](https://github.com/winebarrel/ridgepole)
You need to extend the TableDefinition class.
```ruby
# ridgepole-geo.rb
module TableDefinitionExtForGeometry
def geometry(*args)
options = args.extract_options!
column_names = args
column_names.each { |name| column(name, :geometry, options) }
end
end
Ridgepole::DSLParser::TableDefinition.prepend(TableDefinitionExtForGeometry)module DiffExtForGeometry
def normalize_index_options!(opts)
super
opts.delete(:length) if opts[:type] == :spatial
end
end
Ridgepole::Diff.prepend(DiffExtForGeometry)
``````sh
$ ridgepole -c 'mysql2://[email protected]:10057/armg_test' -r armg -e > Schemafile$ cat Schemafile
# Export Schema
create_table "geoms", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.geometry "location", null: false
t.string "name"
t.index ["location"], name: "idx_location", length: 32, type: :spatial
t.index ["name"], name: "idx_name", length: 10
end$ ridgepole -c 'mysql2://[email protected]:10057/armg_test' -r armg,ridgepole-geo -a
Apply `Schemafile`
No change
```## Limitation on MySQL 8.0
At the moment, armg gem supports only SRIDs with long-lat axis order in MySQL 8.0.
e.g. SRID=3857 (WGS 84 / Pseudo-Mercator -- Spherical Mercator, Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI)That is, armg does not support SRIDs with lat-long axis order.
e.g. SRID=4326 (WGS 84 -- WGS84 - World Geodetic System 1984, used in GPS)## Related links
* [rgeo/rgeo: Geospatial data library for Ruby](https://github.com/rgeo/rgeo)
* [MySQL :: MySQL 5.7 Reference Manual :: 11.5.3 Supported Spatial Data Formats](https://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html)