rgeo 1.1.2 → 2.0.0
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/ext/geos_c_impl/extconf.rb +5 -3
- data/ext/geos_c_impl/factory.c +4 -4
- data/ext/geos_c_impl/geometry.c +1 -1
- data/lib/rgeo.rb +2 -4
- data/lib/rgeo/cartesian.rb +6 -16
- data/lib/rgeo/cartesian/analysis.rb +22 -20
- data/lib/rgeo/cartesian/bounding_box.rb +83 -79
- data/lib/rgeo/cartesian/calculations.rb +40 -38
- data/lib/rgeo/cartesian/factory.rb +134 -169
- data/lib/rgeo/cartesian/feature_classes.rb +2 -18
- data/lib/rgeo/cartesian/feature_methods.rb +37 -39
- data/lib/rgeo/cartesian/interface.rb +11 -9
- data/lib/rgeo/coord_sys.rb +9 -8
- data/lib/rgeo/coord_sys/cs/entities.rb +345 -303
- data/lib/rgeo/coord_sys/cs/factories.rb +30 -28
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +128 -126
- data/lib/rgeo/coord_sys/srs_database/{interface.rb → entry.rb} +26 -32
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +19 -17
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +21 -19
- data/lib/rgeo/error.rb +3 -1
- data/lib/rgeo/feature.rb +23 -34
- data/lib/rgeo/feature/curve.rb +2 -0
- data/lib/rgeo/feature/factory.rb +15 -13
- data/lib/rgeo/feature/factory_generator.rb +7 -5
- data/lib/rgeo/feature/geometry.rb +31 -29
- data/lib/rgeo/feature/geometry_collection.rb +6 -4
- data/lib/rgeo/feature/line.rb +2 -0
- data/lib/rgeo/feature/line_string.rb +3 -1
- data/lib/rgeo/feature/linear_ring.rb +2 -0
- data/lib/rgeo/feature/multi_curve.rb +2 -0
- data/lib/rgeo/feature/multi_line_string.rb +2 -0
- data/lib/rgeo/feature/multi_point.rb +2 -0
- data/lib/rgeo/feature/multi_polygon.rb +2 -0
- data/lib/rgeo/feature/multi_surface.rb +2 -0
- data/lib/rgeo/feature/point.rb +2 -0
- data/lib/rgeo/feature/polygon.rb +3 -1
- data/lib/rgeo/feature/surface.rb +2 -0
- data/lib/rgeo/feature/types.rb +107 -103
- data/lib/rgeo/geographic.rb +17 -27
- data/lib/rgeo/geographic/factory.rb +154 -199
- data/lib/rgeo/geographic/interface.rb +141 -137
- data/lib/rgeo/geographic/proj4_projector.rb +28 -23
- data/lib/rgeo/geographic/projected_feature_classes.rb +2 -18
- data/lib/rgeo/geographic/projected_feature_methods.rb +59 -49
- data/lib/rgeo/geographic/projected_window.rb +4 -2
- data/lib/rgeo/geographic/simple_mercator_projector.rb +41 -39
- data/lib/rgeo/geographic/spherical_feature_classes.rb +2 -18
- data/lib/rgeo/geographic/spherical_feature_methods.rb +67 -67
- data/lib/rgeo/geographic/spherical_math.rb +81 -87
- data/lib/rgeo/geos.rb +23 -34
- data/lib/rgeo/geos/capi_factory.rb +106 -135
- data/lib/rgeo/geos/capi_feature_classes.rb +19 -37
- data/lib/rgeo/geos/ffi_factory.rb +276 -297
- data/lib/rgeo/geos/ffi_feature_classes.rb +2 -20
- data/lib/rgeo/geos/ffi_feature_methods.rb +170 -166
- data/lib/rgeo/geos/interface.rb +25 -23
- data/lib/rgeo/geos/utils.rb +47 -39
- data/lib/rgeo/geos/zm_factory.rb +171 -185
- data/lib/rgeo/geos/zm_feature_classes.rb +2 -20
- data/lib/rgeo/geos/zm_feature_methods.rb +76 -72
- data/lib/rgeo/impl_helper.rb +1 -11
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +72 -75
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +21 -23
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +57 -49
- data/lib/rgeo/impl_helper/basic_point_methods.rb +29 -25
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +31 -27
- data/lib/rgeo/impl_helper/math.rb +2 -0
- data/lib/rgeo/impl_helper/utils.rb +9 -15
- data/lib/rgeo/version.rb +3 -1
- data/lib/rgeo/wkrep.rb +20 -30
- data/lib/rgeo/wkrep/wkb_generator.rb +87 -84
- data/lib/rgeo/wkrep/wkb_parser.rb +93 -93
- data/lib/rgeo/wkrep/wkt_generator.rb +67 -63
- data/lib/rgeo/wkrep/wkt_parser.rb +172 -168
- metadata +17 -32
- data/lib/rgeo/feature/mixins.rb +0 -143
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# GeometryCollection feature interface
|
@@ -31,7 +33,7 @@ module RGeo
|
|
31
33
|
include Geometry
|
32
34
|
extend Type
|
33
35
|
|
34
|
-
include
|
36
|
+
include Enumerable
|
35
37
|
|
36
38
|
# === SFS 1.1 Description
|
37
39
|
#
|
@@ -56,7 +58,7 @@ module RGeo
|
|
56
58
|
# Also note that this method is different from GeometryCollection#[]
|
57
59
|
# in that it does not support negative indexes.
|
58
60
|
|
59
|
-
def geometry_n(
|
61
|
+
def geometry_n(n)
|
60
62
|
raise Error::UnsupportedOperation, "Method GeometryCollection#geometry_n not defined."
|
61
63
|
end
|
62
64
|
|
@@ -76,7 +78,7 @@ module RGeo
|
|
76
78
|
# the same way Ruby's array indexing works. Hence, geometry_n(-1)
|
77
79
|
# returns nil, where [-1] returns the last element of the collection.
|
78
80
|
|
79
|
-
def [](
|
81
|
+
def [](n)
|
80
82
|
raise Error::UnsupportedOperation, "Method GeometryCollection#[] not defined."
|
81
83
|
end
|
82
84
|
|
@@ -93,7 +95,7 @@ module RGeo
|
|
93
95
|
# Note that all GeometryCollection implementations must also
|
94
96
|
# include the Enumerable mixin.
|
95
97
|
|
96
|
-
def each(&
|
98
|
+
def each(&block)
|
97
99
|
raise Error::UnsupportedOperation, "Method GeometryCollection#each not defined."
|
98
100
|
end
|
99
101
|
end
|
data/lib/rgeo/feature/line.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# LineString feature interface
|
@@ -45,7 +47,7 @@ module RGeo
|
|
45
47
|
# if the given N is out of range. N is zero-based.
|
46
48
|
# Does not support negative indexes.
|
47
49
|
|
48
|
-
def point_n(
|
50
|
+
def point_n(n)
|
49
51
|
raise Error::UnsupportedOperation, "Method LineString#point_n not defined."
|
50
52
|
end
|
51
53
|
|
data/lib/rgeo/feature/point.rb
CHANGED
data/lib/rgeo/feature/polygon.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# Polygon feature interface
|
@@ -82,7 +84,7 @@ module RGeo
|
|
82
84
|
# if the given N is out of range. N is zero-based.
|
83
85
|
# Does not support negative indexes.
|
84
86
|
|
85
|
-
def interior_ring_n(
|
87
|
+
def interior_ring_n(n)
|
86
88
|
raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined."
|
87
89
|
end
|
88
90
|
|
data/lib/rgeo/feature/surface.rb
CHANGED
data/lib/rgeo/feature/types.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# Feature type management and casting
|
@@ -56,17 +58,17 @@ module RGeo
|
|
56
58
|
# Note that feature objects need not actually include this module.
|
57
59
|
# Therefore, the is_a? method will generally not work.
|
58
60
|
|
59
|
-
def check_type(
|
60
|
-
|
61
|
-
|
61
|
+
def check_type(rhs)
|
62
|
+
rhs = rhs.geometry_type if rhs.is_a?(Feature::Instance)
|
63
|
+
rhs.is_a?(Type) && (rhs == self || rhs.include?(self))
|
62
64
|
end
|
63
65
|
alias === check_type
|
64
66
|
|
65
67
|
# Returns true if this type is the same type or a subtype of the
|
66
68
|
# given type.
|
67
69
|
|
68
|
-
def subtype_of?(
|
69
|
-
self ==
|
70
|
+
def subtype_of?(type)
|
71
|
+
self == type || include?(type)
|
70
72
|
end
|
71
73
|
|
72
74
|
# Returns the supertype of this type. The supertype of Geometry
|
@@ -78,8 +80,8 @@ module RGeo
|
|
78
80
|
|
79
81
|
# Iterates over the known immediate subtypes of this type.
|
80
82
|
|
81
|
-
def each_immediate_subtype(&
|
82
|
-
@subtypes
|
83
|
+
def each_immediate_subtype(&block)
|
84
|
+
@subtypes&.each(&block)
|
83
85
|
end
|
84
86
|
|
85
87
|
# Returns the OpenGIS type name of this type. For example:
|
@@ -91,14 +93,14 @@ module RGeo
|
|
91
93
|
end
|
92
94
|
alias to_s type_name
|
93
95
|
|
94
|
-
def
|
95
|
-
(@subtypes ||= []) <<
|
96
|
+
def add_subtype(type) # :nodoc:
|
97
|
+
(@subtypes ||= []) << type
|
96
98
|
end
|
97
99
|
|
98
|
-
def self.extended(
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
def self.extended(type) # :nodoc:
|
101
|
+
supertype = type.included_modules.find { |m| m.is_a?(self) }
|
102
|
+
type.instance_variable_set(:@supertype, supertype)
|
103
|
+
supertype&.add_subtype(type)
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
@@ -155,124 +157,126 @@ module RGeo
|
|
155
157
|
# casting behavior by defining the override_cast method. See
|
156
158
|
# RGeo::Feature::Factory#override_cast for more details.
|
157
159
|
|
158
|
-
def cast(
|
160
|
+
def cast(obj, *params)
|
159
161
|
# Interpret params
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
case
|
162
|
+
factory = obj.factory
|
163
|
+
type = obj.geometry_type
|
164
|
+
opts = {}
|
165
|
+
params.each do |param|
|
166
|
+
case param
|
165
167
|
when Factory::Instance
|
166
|
-
|
168
|
+
opts[:factory] = param
|
167
169
|
when Type
|
168
|
-
|
169
|
-
when
|
170
|
-
|
171
|
-
when
|
172
|
-
|
170
|
+
opts[:type] = param
|
171
|
+
when Symbol
|
172
|
+
opts[param] = true
|
173
|
+
when Hash
|
174
|
+
opts.merge!(param)
|
173
175
|
end
|
174
176
|
end
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
177
|
+
force_new = opts[:force_new]
|
178
|
+
keep_subtype = opts[:keep_subtype]
|
179
|
+
project = opts[:project]
|
180
|
+
nfactory = opts.delete(:factory) || factory
|
181
|
+
ntype = opts.delete(:type) || type
|
180
182
|
|
181
183
|
# Let the factory override
|
182
|
-
if
|
183
|
-
|
184
|
-
return
|
184
|
+
if nfactory.respond_to?(:override_cast)
|
185
|
+
override = nfactory.override_cast(obj, ntype, opts)
|
186
|
+
return override unless override == false
|
185
187
|
end
|
186
188
|
|
187
189
|
# Default algorithm
|
188
|
-
|
189
|
-
if
|
190
|
+
ntype = type if keep_subtype && type.include?(ntype)
|
191
|
+
if ntype == type
|
190
192
|
# Types are the same
|
191
|
-
if
|
192
|
-
|
193
|
+
if nfactory == factory
|
194
|
+
force_new ? obj.dup : obj
|
193
195
|
else
|
194
|
-
if
|
195
|
-
|
196
|
-
if
|
197
|
-
|
198
|
-
|
196
|
+
if type == Point
|
197
|
+
proj = nproj = nil
|
198
|
+
if project
|
199
|
+
proj = factory.proj4
|
200
|
+
nproj = nfactory.proj4
|
199
201
|
end
|
200
|
-
|
201
|
-
|
202
|
-
if
|
203
|
-
|
204
|
-
|
202
|
+
hasz = factory.property(:has_z_coordinate)
|
203
|
+
nhasz = nfactory.property(:has_z_coordinate)
|
204
|
+
if proj && nproj && CoordSys.check!(:proj4)
|
205
|
+
coords = CoordSys::Proj4.transform_coords(proj, nproj, obj.x, obj.y, hasz ? obj.z : nil)
|
206
|
+
coords << (hasz ? obj.z : 0.0) if nhasz && coords.size < 3
|
205
207
|
else
|
206
|
-
|
207
|
-
|
208
|
+
coords = [obj.x, obj.y]
|
209
|
+
coords << (hasz ? obj.z : 0.0) if nhasz
|
208
210
|
end
|
209
|
-
|
210
|
-
|
211
|
-
elsif
|
212
|
-
|
213
|
-
elsif
|
214
|
-
|
215
|
-
elsif
|
216
|
-
|
217
|
-
elsif
|
218
|
-
|
219
|
-
|
220
|
-
elsif
|
221
|
-
|
222
|
-
elsif
|
223
|
-
|
224
|
-
elsif
|
225
|
-
|
226
|
-
elsif
|
227
|
-
|
211
|
+
coords << (factory.property(:has_m_coordinate) ? obj.m : 0.0) if nfactory.property(:has_m_coordinate)
|
212
|
+
nfactory.point(*coords)
|
213
|
+
elsif type == Line
|
214
|
+
nfactory.line(cast(obj.start_point, nfactory, opts), cast(obj.end_point, nfactory, opts))
|
215
|
+
elsif type == LinearRing
|
216
|
+
nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) })
|
217
|
+
elsif type == LineString
|
218
|
+
nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) })
|
219
|
+
elsif type == Polygon
|
220
|
+
nfactory.polygon(cast(obj.exterior_ring, nfactory, opts),
|
221
|
+
obj.interior_rings.map { |r| cast(r, nfactory, opts) })
|
222
|
+
elsif type == MultiPoint
|
223
|
+
nfactory.multi_point(obj.map { |g| cast(g, nfactory, opts) })
|
224
|
+
elsif type == MultiLineString
|
225
|
+
nfactory.multi_line_string(obj.map { |g| cast(g, nfactory, opts) })
|
226
|
+
elsif type == MultiPolygon
|
227
|
+
nfactory.multi_polygon(obj.map { |g| cast(g, nfactory, opts) })
|
228
|
+
elsif type == GeometryCollection
|
229
|
+
nfactory.collection(obj.map { |g| cast(g, nfactory, opts) })
|
228
230
|
end
|
229
231
|
end
|
230
232
|
else
|
231
233
|
# Types are different
|
232
|
-
if
|
233
|
-
(
|
234
|
-
|
235
|
-
if
|
236
|
-
cast(
|
234
|
+
if ntype == Point && (type == MultiPoint || type == GeometryCollection) ||
|
235
|
+
(ntype == Line || ntype == LineString || ntype == LinearRing) && (type == MultiLineString || type == GeometryCollection) ||
|
236
|
+
ntype == Polygon && (type == MultiPolygon || type == GeometryCollection)
|
237
|
+
if obj.num_geometries == 1
|
238
|
+
cast(obj.geometry_n(0), nfactory, ntype, opts)
|
237
239
|
end
|
238
|
-
elsif
|
239
|
-
|
240
|
-
elsif
|
241
|
-
if
|
242
|
-
|
240
|
+
elsif ntype == Point
|
241
|
+
raise(Error::InvalidGeometry, "Cannot cast to Point")
|
242
|
+
elsif ntype == Line
|
243
|
+
if type == LineString && obj.num_points == 2
|
244
|
+
nfactory.line(cast(obj.point_n(0), nfactory, opts), cast(obj.point_n(1), nfactory, opts))
|
243
245
|
end
|
244
|
-
elsif
|
245
|
-
if
|
246
|
-
|
246
|
+
elsif ntype == LinearRing
|
247
|
+
if type == LineString
|
248
|
+
nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) })
|
247
249
|
end
|
248
|
-
elsif
|
249
|
-
if
|
250
|
-
|
250
|
+
elsif ntype == LineString
|
251
|
+
if type == Line || type == LinearRing
|
252
|
+
nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) })
|
251
253
|
end
|
252
|
-
elsif
|
253
|
-
if
|
254
|
-
|
255
|
-
elsif
|
256
|
-
|
254
|
+
elsif ntype == MultiPoint
|
255
|
+
if type == Point
|
256
|
+
nfactory.multi_point([cast(obj, nfactory, opts)])
|
257
|
+
elsif type == GeometryCollection
|
258
|
+
nfactory.multi_point(obj.map { |p| cast(p, nfactory, opts) })
|
257
259
|
end
|
258
|
-
elsif
|
259
|
-
if
|
260
|
-
|
261
|
-
elsif
|
262
|
-
|
260
|
+
elsif ntype == MultiLineString
|
261
|
+
if type == Line || type == LinearRing || type == LineString
|
262
|
+
nfactory.multi_line_string([cast(obj, nfactory, opts)])
|
263
|
+
elsif type == GeometryCollection
|
264
|
+
nfactory.multi_line_string(obj.map { |p| cast(p, nfactory, opts) })
|
263
265
|
end
|
264
|
-
elsif
|
265
|
-
if
|
266
|
-
|
267
|
-
elsif
|
268
|
-
|
266
|
+
elsif ntype == MultiPolygon
|
267
|
+
if type == Polygon
|
268
|
+
nfactory.multi_polygon([cast(obj, nfactory, opts)])
|
269
|
+
elsif type == GeometryCollection
|
270
|
+
nfactory.multi_polygon(obj.map { |p| cast(p, nfactory, opts) })
|
269
271
|
end
|
270
|
-
elsif
|
271
|
-
if
|
272
|
-
|
272
|
+
elsif ntype == GeometryCollection
|
273
|
+
if type == MultiPoint || type == MultiLineString || type == MultiPolygon
|
274
|
+
nfactory.collection(obj.map { |p| cast(p, nfactory, opts) })
|
273
275
|
else
|
274
|
-
|
276
|
+
nfactory.collection([cast(obj, nfactory, opts)])
|
275
277
|
end
|
278
|
+
else
|
279
|
+
raise(RGeo::Error::InvalidGeometry, "Undefined type cast from #{type.name} to #{ntype.name}")
|
276
280
|
end
|
277
281
|
end
|
278
282
|
end
|
data/lib/rgeo/geographic.rb
CHANGED
@@ -1,33 +1,23 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The Geographic module includes a suite of
|
4
|
+
# implementations with one common feature: they represent geographic
|
5
|
+
# latitude/longitude coordinates measured in degrees. The "x"
|
6
|
+
# coordinate corresponds to longitude, and the "y" coordinate to
|
7
|
+
# latitude. Thus, coordinates are often expressed in reverse
|
8
|
+
# (i.e. long-lat) order. e.g.
|
2
9
|
#
|
3
|
-
#
|
10
|
+
# location = geographic_factory.point(long, lat)
|
4
11
|
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# (i.e. long-lat) order. e.g.
|
14
|
-
#
|
15
|
-
# location = geographic_factory.point(long, lat)
|
16
|
-
#
|
17
|
-
# Some geographic implementations include a secondary factory that
|
18
|
-
# represents a projection. For these implementations, you can quickly
|
19
|
-
# transform data between lat/long coordinates and the projected
|
20
|
-
# coordinate system, and most calculations are done in the projected
|
21
|
-
# coordinate system. For implementations that do not include this
|
22
|
-
# secondary projection factory, calculations are done on the sphereoid.
|
23
|
-
# See the various class methods of Geographic for more information on
|
24
|
-
# the behaviors of the factories they generate.
|
25
|
-
|
26
|
-
module Geographic
|
27
|
-
end
|
28
|
-
end
|
12
|
+
# Some geographic implementations include a secondary factory that
|
13
|
+
# represents a projection. For these implementations, you can quickly
|
14
|
+
# transform data between lat/long coordinates and the projected
|
15
|
+
# coordinate system, and most calculations are done in the projected
|
16
|
+
# coordinate system. For implementations that do not include this
|
17
|
+
# secondary projection factory, calculations are done on the sphereoid.
|
18
|
+
# See the various class methods of Geographic for more information on
|
19
|
+
# the behaviors of the factories they generate.
|
29
20
|
|
30
|
-
# Implementation files.
|
31
21
|
require "rgeo/geographic/factory"
|
32
22
|
require "rgeo/geographic/projected_window"
|
33
23
|
require "rgeo/geographic/interface"
|