rgeo-activerecord 6.1.0 → 7.0.1
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.
- checksums.yaml +4 -4
- data/History.md +23 -0
- data/README.md +56 -28
- data/lib/rgeo/active_record/arel_spatial_queries.rb +17 -23
- data/lib/rgeo/active_record/geometry_mixin.rb +10 -0
- data/lib/rgeo/active_record/spatial_factory_store.rb +52 -12
- data/lib/rgeo/active_record/version.rb +1 -1
- metadata +28 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32e44e9ec5d1c3416c4acddd27a1abbf2eb1e7d60e1d3bffa32576b16c1c1cc7
|
4
|
+
data.tar.gz: 109a5c4b94e7a770ec55125ac19f810441c19cd97ba1a580c90114025d0a8dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe3abd106906d2e1882f3bd23e19f6d31d75df521ea5f00f5024070590739cf478b2acc8cad400f4c6908f879b29dfad94076d53dcec87268bdd25898147a81e
|
7
|
+
data.tar.gz: 461b289050ed2a49013609ec71a06e3e1326fad4464e62adb06808e7ec6415cb140889afef68ebbad27c3ec664c65270b0a922f4063bdc7c853c0c48b2ce86d6
|
data/History.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
### 7.0.1 / 2021-02-23
|
2
|
+
|
3
|
+
* Fix malformed Arel queries using `as` (ugisozols)
|
4
|
+
|
5
|
+
### 7.0.0 / 2020-12-15
|
6
|
+
|
7
|
+
* Update visit_* methods and Arel interface to support RGeo features.
|
8
|
+
* Rework SpatialFactoryStore to support hierarchical matches and fallbacks.
|
9
|
+
|
10
|
+
### 6.2.2 / 2020-11-20
|
11
|
+
|
12
|
+
* Removed `Arel::Visitor::DepthFirst` for ActiveRecord 6.1 compatibility (kamipo)
|
13
|
+
|
14
|
+
### 6.2.1 / 2019-07-01
|
15
|
+
|
16
|
+
* Include GeometryMixin in Cartesian modules (#52, andreasknoepfle)
|
17
|
+
|
18
|
+
|
19
|
+
### 6.2.0 / 2019-05-09
|
20
|
+
|
21
|
+
* Allow ActiveRecord 6.0 (#50, corneverbruggen)
|
22
|
+
|
23
|
+
|
1
24
|
### 6.1.0 / 2018-12-01
|
2
25
|
|
3
26
|
* Allow rgeo 2.0
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
## RGeo::ActiveRecord
|
2
2
|
|
3
|
-
[](https://rubygems.org/gems/rgeo-activerecord)
|
4
|
+
[](https://github.com/rgeo/rgeo-activerecord/actions?query=workflow%3A%22Tests%22)
|
5
5
|
[](https://codeclimate.com/github/rgeo/rgeo-activerecord)
|
6
6
|
|
7
|
-
RGeo::ActiveRecord is an optional [RGeo](http://github.com/
|
7
|
+
RGeo::ActiveRecord is an optional [RGeo](http://github.com/rgeo/rgeo) module
|
8
8
|
providing spatial extensions for ActiveRecord, as well as a set of helpers for
|
9
9
|
writing spatial ActiveRecord adapters based on RGeo.
|
10
10
|
|
@@ -28,9 +28,12 @@ Gemfile:
|
|
28
28
|
```ruby
|
29
29
|
gem 'rgeo-activerecord'
|
30
30
|
```
|
31
|
-
Version `6.1` supports ActiveRecord 5.0, 5.1, and 5.2 with `rgeo` 1.0+.
|
32
31
|
|
33
|
-
Version `6.
|
32
|
+
Version `6.2+` supports ActiveRecord 5.x and 6.x with `rgeo` 1.0+
|
33
|
+
|
34
|
+
Version `6.1` supports ActiveRecord 5.x and 6.0 with `rgeo` 1.0+.
|
35
|
+
|
36
|
+
Version `6.0` supports ActiveRecord 5.x with `rgeo` 1.x.
|
34
37
|
|
35
38
|
Version `5.0` supports ActiveRecord 5.0 and 5.1, with `rgeo` 0.6.
|
36
39
|
|
@@ -40,32 +43,28 @@ Version `1.1.0` supports ActiveRecord 4.0 and 4.1
|
|
40
43
|
|
41
44
|
Version `0.6.0` supports earlier versions of ruby and ActiveRecord:
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
- Ruby 1.8.7 or later
|
47
|
+
- ActiveRecord 3.0.3 - 3.2.x
|
48
|
+
- rgeo 0.3.20 or later
|
49
|
+
- arel 2.0.6 or later
|
47
50
|
|
48
51
|
### Spatial Factories for Columns
|
49
52
|
|
50
|
-
|
51
|
-
are no longer tied to their database column in ActiveRecord 4.2.
|
53
|
+
**_This is an introduction. More details are available in the [wiki entry](https://github.com/rgeo/rgeo-activerecord/wiki/Spatial-Factory-Store)._**
|
52
54
|
|
53
|
-
Register spatial factories in the `SpatialFactoryStore` singleton class. Each spatial
|
54
|
-
in your
|
55
|
-
a factory matching the properties of its type. For example, you can set a different
|
56
|
-
spatial factory for point types, or for types matching a specific SRID, or having
|
55
|
+
Register spatial factories in the `SpatialFactoryStore` singleton class to parse spatial data. Each spatial column
|
56
|
+
in your models will use the `SpatialFactoryStore` to parse the stored WKB into an RGeo Feature. The factory from the `SpatialFactoryStore` is chosen based on metadata from the spatial column and the attributes with which the factory was registered to the store. For example, you can set a factory for point types, for types matching a specific SRID, having
|
57
57
|
a Z coordinate, or any combination of attributes.
|
58
58
|
|
59
|
-
The supported keys when registering a spatial type are listed here with their
|
60
|
-
and other allowed values:
|
59
|
+
The supported keys when registering a spatial type are listed here with their expected values:
|
61
60
|
|
62
61
|
```
|
63
|
-
geo_type:
|
64
|
-
|
65
|
-
has_m:
|
66
|
-
has_z:
|
67
|
-
sql_type:
|
68
|
-
srid:
|
62
|
+
geo_type: string # geometry, point, polygon, line_string, geometry_collection,
|
63
|
+
# multi_line_string, multi_point, multi_polygon
|
64
|
+
has_m: boolean # true, false
|
65
|
+
has_z: boolean # true, false
|
66
|
+
sql_type: string # geometry, geography
|
67
|
+
srid: int # (any valid SRID)
|
69
68
|
```
|
70
69
|
|
71
70
|
The default factories are `RGeo::Geographic.spherical_factory` for
|
@@ -73,7 +72,7 @@ geographic types, and `RGeo::Cartesian.preferred_factory` for geometric types.
|
|
73
72
|
|
74
73
|
Here is an example setup:
|
75
74
|
|
76
|
-
```
|
75
|
+
```rb
|
77
76
|
RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
|
78
77
|
# By default, use the GEOS implementation for spatial columns.
|
79
78
|
config.default = RGeo::Geos.factory_generator
|
@@ -83,6 +82,33 @@ RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
|
|
83
82
|
end
|
84
83
|
```
|
85
84
|
|
85
|
+
_NOTE: `rgeo_factory_generator` and related methods were removed in version 4.0, since column types
|
86
|
+
are no longer tied to their database column in ActiveRecord 4.2._
|
87
|
+
|
88
|
+
### Spatial Queries
|
89
|
+
|
90
|
+
RGeo-ActiveRecord provides an Arel interface to use functions commonly found in spatial databases. The interface also allows for the creation of your own spatial functions if they are not defined.
|
91
|
+
|
92
|
+
Here is an example using `st_contains`:
|
93
|
+
|
94
|
+
```rb
|
95
|
+
point = RGeo::Geos.factory(srid: 0).point(1,1)
|
96
|
+
|
97
|
+
buildings = Building.arel_table
|
98
|
+
containing_buiildings = Building.where(buildings[:geom].st_contains(point))
|
99
|
+
```
|
100
|
+
|
101
|
+
or using the `Arel.spatial` node:
|
102
|
+
|
103
|
+
```rb
|
104
|
+
point = "SRID=0;POINT(1,1)"
|
105
|
+
|
106
|
+
buildings = Building.arel_table
|
107
|
+
containing_buiildings = Building.where(buildings[:geom].st_contains(Arel.spatial(point)))
|
108
|
+
```
|
109
|
+
|
110
|
+
_Note: If you pass a WKT representation into an st_function, you should prepend the string with SRID=your_srid, otherwise the database will assume SRID=0 which may cause errors on certain operations._
|
111
|
+
|
86
112
|
### RGeo Dependency
|
87
113
|
|
88
114
|
See the README for the [rgeo](https://github.com/rgeo/rgeo) gem, a dependency, for further
|
@@ -107,15 +133,17 @@ http://groups.google.com/group/rgeo-users
|
|
107
133
|
### Acknowledgments
|
108
134
|
|
109
135
|
[Daniel Azuma](http://www.daniel-azuma.com) created RGeo.
|
110
|
-
[Tee Parham](http://twitter.com/teeparham) is
|
136
|
+
[Tee Parham](http://twitter.com/teeparham) is a former maintainer.
|
137
|
+
[Keith Doggett](http://www.github.com/keithdoggett) is a current maintainer.
|
138
|
+
[Ulysse Buonomo](http://www.github.com/BuonOmo) is a current maintainer.
|
111
139
|
|
112
140
|
Development is supported by:
|
113
141
|
|
114
|
-
|
115
|
-
|
142
|
+
- [Klaxit](https://www.klaxit.com)
|
143
|
+
- Goldfish Ads
|
116
144
|
|
117
145
|
### License
|
118
146
|
|
119
|
-
Copyright
|
147
|
+
Copyright 2020 Daniel Azuma, Tee Parham
|
120
148
|
|
121
149
|
https://github.com/rgeo/rgeo-activerecord/blob/master/LICENSE.txt
|
@@ -24,16 +24,18 @@ module RGeo
|
|
24
24
|
|
25
25
|
def visit_RGeo_ActiveRecord_SpatialNamedFunction(node, collector)
|
26
26
|
name = st_func(node.name)
|
27
|
-
exprs = []
|
28
|
-
node.expressions.each_with_index do |expr, index|
|
29
|
-
exprs << (node.spatial_argument?(index) ? visit_in_spatial_context(expr, collector) : visit(expr, collector))
|
30
|
-
end
|
31
27
|
collector << name
|
32
28
|
collector << "("
|
33
29
|
collector << "DISTINCT " if node.distinct
|
34
|
-
|
30
|
+
node.expressions.each_with_index do |expr, index|
|
31
|
+
node.spatial_argument?(index) ? visit_in_spatial_context(expr, collector) : visit(expr, collector)
|
32
|
+
collector << ", " unless index == node.expressions.size - 1
|
33
|
+
end
|
35
34
|
collector << ")"
|
36
|
-
|
35
|
+
if node.alias
|
36
|
+
collector << " AS "
|
37
|
+
visit node.alias, collector
|
38
|
+
end
|
37
39
|
collector
|
38
40
|
end
|
39
41
|
|
@@ -41,13 +43,15 @@ module RGeo
|
|
41
43
|
# The node must be a string (in which case it is treated as WKT),
|
42
44
|
# an RGeo feature, or a spatial attribute.
|
43
45
|
def visit_in_spatial_context(node, collector)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
collector <<
|
49
|
-
|
50
|
-
|
46
|
+
if node.is_a?(String)
|
47
|
+
collector << "#{st_func('ST_GeomFromText')}(#{quote(node)})"
|
48
|
+
elsif node.is_a?(RGeo::Feature::Instance)
|
49
|
+
srid = node.srid
|
50
|
+
collector << "#{st_func('ST_GeomFromText')}(#{quote(node.to_s)}, #{srid})"
|
51
|
+
elsif node.is_a?(RGeo::Cartesian::BoundingBox)
|
52
|
+
geom = node.to_geometry
|
53
|
+
srid = geom.srid
|
54
|
+
collector << "#{st_func('ST_GeomFromText')}(#{quote(geom.to_s)}, #{srid})"
|
51
55
|
else
|
52
56
|
visit(node, collector)
|
53
57
|
end
|
@@ -86,16 +90,6 @@ module RGeo
|
|
86
90
|
alias :visit_RGeo_Cartesian_BoundingBox :visit_String
|
87
91
|
end
|
88
92
|
|
89
|
-
Arel::Visitors::DepthFirst.class_eval do
|
90
|
-
alias :visit_RGeo_Feature_Instance :terminal
|
91
|
-
alias :visit_RGeo_Cartesian_BoundingBox :terminal
|
92
|
-
end
|
93
|
-
|
94
|
-
Arel::Visitors::ToSql.class_eval do
|
95
|
-
alias :visit_RGeo_Feature_Instance :visit_String
|
96
|
-
alias :visit_RGeo_Cartesian_BoundingBox :visit_String
|
97
|
-
end
|
98
|
-
|
99
93
|
# A NamedFunction subclass that keeps track of the spatial-ness of
|
100
94
|
# the arguments and return values, so that it can provide context to
|
101
95
|
# visitors that want to interpret syntax differently when dealing with
|
@@ -82,6 +82,16 @@ module RGeo
|
|
82
82
|
Geos::ZMMultiPolygonImpl,
|
83
83
|
Geos::ZMPointImpl,
|
84
84
|
Geos::ZMPolygonImpl,
|
85
|
+
|
86
|
+
Cartesian::GeometryCollectionImpl,
|
87
|
+
Cartesian::LinearRingImpl,
|
88
|
+
Cartesian::LineImpl,
|
89
|
+
Cartesian::LineStringImpl,
|
90
|
+
Cartesian::MultiLineStringImpl,
|
91
|
+
Cartesian::MultiPointImpl,
|
92
|
+
Cartesian::MultiPolygonImpl,
|
93
|
+
Cartesian::PointImpl,
|
94
|
+
Cartesian::PolygonImpl
|
85
95
|
].each { |klass| klass.include(GeometryMixin) }
|
86
96
|
|
87
97
|
if RGeo::Geos.capi_supported?
|
@@ -4,16 +4,17 @@ module RGeo
|
|
4
4
|
module ActiveRecord
|
5
5
|
class SpatialFactoryStore
|
6
6
|
include Singleton
|
7
|
+
Entry = Struct.new(:attrs, :factory)
|
7
8
|
|
8
9
|
attr_accessor :registry
|
9
10
|
|
10
11
|
def initialize
|
11
|
-
@registry =
|
12
|
+
@registry = []
|
12
13
|
@default = nil
|
13
14
|
end
|
14
15
|
|
15
16
|
def register(factory, attrs = {})
|
16
|
-
registry
|
17
|
+
registry.push(Entry.new(filter_attrs(attrs), factory))
|
17
18
|
end
|
18
19
|
|
19
20
|
def default(attrs = {})
|
@@ -25,11 +26,11 @@ module RGeo
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def factory(attrs)
|
28
|
-
|
29
|
+
closest_factory(attrs) || default(attrs)
|
29
30
|
end
|
30
31
|
|
31
32
|
def clear
|
32
|
-
@registry =
|
33
|
+
@registry = []
|
33
34
|
end
|
34
35
|
|
35
36
|
private
|
@@ -50,14 +51,53 @@ module RGeo
|
|
50
51
|
}
|
51
52
|
end
|
52
53
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
def filter_attrs(attrs)
|
55
|
+
attrs.slice(:geo_type, :has_m, :has_z, :sql_type, :srid)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Match attrs to the closest equal to or less specific factory
|
60
|
+
#
|
61
|
+
# That means that attrs can at most be matched to an Entry with the same
|
62
|
+
# number of keys as it. But could match with a factory with only 1 key
|
63
|
+
# in its attrs.
|
64
|
+
#
|
65
|
+
# Examples:
|
66
|
+
# attrs = {sql_type: "geometry" }, entry_attrs = {sql_type: "geometry", geo_type: "point"}
|
67
|
+
# is not a match because the entry is more specific than attrs
|
68
|
+
#
|
69
|
+
# attrs = {sql_type: "geometry", geo_type: "point"}, entry_attrs = {sql_type: "geometry"}
|
70
|
+
# is a match because the entry is less specific than attrs and would be the fallback for all "geometry" types
|
71
|
+
#
|
72
|
+
# attrs = {sql_type: "geometry", geo_type: "point"}, entry_attrs = {sql_type: "geometry", geo_type: "linestring"}
|
73
|
+
# is not a match because there are mismatched keys
|
74
|
+
#
|
75
|
+
# If there is no match, nil is returned
|
76
|
+
def closest_factory(attrs)
|
77
|
+
max_matches = 0
|
78
|
+
registry.reduce(nil) do |selected_fac, entry|
|
79
|
+
cmp = cmp_attrs(attrs, entry.attrs)
|
80
|
+
if cmp > max_matches
|
81
|
+
max_matches = cmp
|
82
|
+
entry.factory
|
83
|
+
else
|
84
|
+
selected_fac
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Returns number of common key/values
|
91
|
+
# or -1 if oth is bigger than attrs, or they have a mismatched key/value pair
|
92
|
+
def cmp_attrs(attrs, oth)
|
93
|
+
return -1 if oth.size > attrs.size
|
94
|
+
matches = 0
|
95
|
+
attrs.each do |k, v|
|
96
|
+
next if oth[k].nil?
|
97
|
+
return -1 unless v == oth[k]
|
98
|
+
matches += 1
|
99
|
+
end
|
100
|
+
matches
|
61
101
|
end
|
62
102
|
end
|
63
103
|
end
|
metadata
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgeo-activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Daniel Azuma
|
7
|
+
- Daniel Azuma
|
8
|
+
- Tee Parham
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-02-23 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activerecord
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - "
|
18
|
+
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
20
|
version: '5.0'
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- - "
|
25
|
+
- - ">="
|
25
26
|
- !ruby/object:Gem::Version
|
26
27
|
version: '5.0'
|
27
28
|
- !ruby/object:Gem::Dependency
|
@@ -122,10 +123,27 @@ dependencies:
|
|
122
123
|
- - ">="
|
123
124
|
- !ruby/object:Gem::Version
|
124
125
|
version: 1.0.0
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: simplecov
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 0.20.0
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 0.20.0
|
125
140
|
description: RGeo is a geospatial data library for Ruby. RGeo::ActiveRecord is an
|
126
141
|
optional RGeo module providing some spatial extensions to ActiveRecord, as well
|
127
142
|
as common tools used by RGeo-based spatial adapters.
|
128
|
-
email:
|
143
|
+
email:
|
144
|
+
- dazuma@gmail.com
|
145
|
+
- parhameter@gmail.com
|
146
|
+
- kfdoggett@gmail.com
|
129
147
|
executables: []
|
130
148
|
extensions: []
|
131
149
|
extra_rdoc_files: []
|
@@ -142,7 +160,8 @@ files:
|
|
142
160
|
- lib/rgeo/active_record/spatial_factory_store.rb
|
143
161
|
- lib/rgeo/active_record/version.rb
|
144
162
|
homepage: https://github.com/rgeo/rgeo-activerecord
|
145
|
-
licenses:
|
163
|
+
licenses:
|
164
|
+
- BSD-3-Clause
|
146
165
|
metadata: {}
|
147
166
|
post_install_message:
|
148
167
|
rdoc_options: []
|
@@ -152,15 +171,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
171
|
requirements:
|
153
172
|
- - ">="
|
154
173
|
- !ruby/object:Gem::Version
|
155
|
-
version: 2.
|
174
|
+
version: 2.5.0
|
156
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
176
|
requirements:
|
158
177
|
- - ">="
|
159
178
|
- !ruby/object:Gem::Version
|
160
179
|
version: '0'
|
161
180
|
requirements: []
|
162
|
-
|
163
|
-
rubygems_version: 2.7.8
|
181
|
+
rubygems_version: 3.0.8
|
164
182
|
signing_key:
|
165
183
|
specification_version: 4
|
166
184
|
summary: An RGeo module providing spatial extensions to ActiveRecord.
|