rgeo 2.3.1 → 3.0.0.pre.rc.2
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/.yardopts +6 -0
- data/README.md +11 -10
- data/ext/geos_c_impl/analysis.c +8 -6
- data/ext/geos_c_impl/analysis.h +1 -3
- data/ext/geos_c_impl/errors.c +10 -8
- data/ext/geos_c_impl/errors.h +7 -3
- data/ext/geos_c_impl/extconf.rb +3 -0
- data/ext/geos_c_impl/factory.c +273 -202
- data/ext/geos_c_impl/factory.h +51 -63
- data/ext/geos_c_impl/geometry.c +124 -22
- data/ext/geos_c_impl/geometry.h +8 -3
- data/ext/geos_c_impl/geometry_collection.c +81 -185
- data/ext/geos_c_impl/geometry_collection.h +1 -14
- data/ext/geos_c_impl/globals.c +91 -0
- data/ext/geos_c_impl/globals.h +45 -0
- data/ext/geos_c_impl/line_string.c +28 -29
- data/ext/geos_c_impl/line_string.h +1 -3
- data/ext/geos_c_impl/main.c +10 -9
- data/ext/geos_c_impl/point.c +9 -8
- data/ext/geos_c_impl/point.h +1 -3
- data/ext/geos_c_impl/polygon.c +43 -72
- data/ext/geos_c_impl/polygon.h +1 -3
- data/ext/geos_c_impl/preface.h +12 -0
- data/ext/geos_c_impl/ruby_more.c +65 -0
- data/ext/geos_c_impl/ruby_more.h +16 -0
- data/lib/rgeo/cartesian/calculations.rb +54 -17
- data/lib/rgeo/cartesian/factory.rb +6 -14
- data/lib/rgeo/cartesian/feature_classes.rb +68 -46
- data/lib/rgeo/cartesian/feature_methods.rb +67 -20
- data/lib/rgeo/cartesian/interface.rb +0 -36
- data/lib/rgeo/cartesian/planar_graph.rb +379 -0
- data/lib/rgeo/cartesian/sweepline_intersector.rb +149 -0
- data/lib/rgeo/cartesian/valid_op.rb +71 -0
- data/lib/rgeo/cartesian.rb +3 -0
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +6 -6
- data/lib/rgeo/coord_sys.rb +0 -11
- data/lib/rgeo/error.rb +15 -0
- data/lib/rgeo/feature/factory_generator.rb +0 -3
- data/lib/rgeo/feature/geometry.rb +107 -28
- data/lib/rgeo/feature/geometry_collection.rb +13 -5
- data/lib/rgeo/feature/line_string.rb +3 -3
- data/lib/rgeo/feature/multi_surface.rb +3 -3
- data/lib/rgeo/feature/point.rb +4 -4
- data/lib/rgeo/feature/surface.rb +3 -3
- data/lib/rgeo/geographic/factory.rb +6 -7
- data/lib/rgeo/geographic/interface.rb +6 -49
- data/lib/rgeo/geographic/proj4_projector.rb +0 -2
- data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
- data/lib/rgeo/geographic/projected_feature_methods.rb +67 -28
- data/lib/rgeo/geographic/simple_mercator_projector.rb +0 -2
- data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
- data/lib/rgeo/geographic/spherical_feature_methods.rb +79 -2
- data/lib/rgeo/geos/capi_factory.rb +21 -38
- data/lib/rgeo/geos/capi_feature_classes.rb +54 -11
- data/lib/rgeo/geos/ffi_factory.rb +6 -35
- data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
- data/lib/rgeo/geos/ffi_feature_methods.rb +39 -5
- data/lib/rgeo/geos/interface.rb +0 -24
- data/lib/rgeo/geos/zm_factory.rb +0 -19
- data/lib/rgeo/geos/zm_feature_methods.rb +16 -0
- data/lib/rgeo/geos.rb +6 -3
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +4 -4
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -1
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +15 -19
- data/lib/rgeo/impl_helper/basic_point_methods.rb +1 -1
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +1 -1
- data/lib/rgeo/impl_helper/valid_op.rb +354 -0
- data/lib/rgeo/impl_helper/validity_check.rb +139 -0
- data/lib/rgeo/impl_helper.rb +1 -0
- data/lib/rgeo/version.rb +1 -1
- metadata +45 -9
- data/lib/rgeo/coord_sys/srs_database/entry.rb +0 -107
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +0 -64
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +0 -65
@@ -26,7 +26,6 @@ module RGeo
|
|
26
26
|
|
27
27
|
# Get flags to pass to the C extension
|
28
28
|
flags = 0
|
29
|
-
flags |= 1 if opts_[:uses_lenient_assertions] || opts_[:lenient_multi_polygon_assertions] || opts_[:uses_lenient_multi_polygon_assertions]
|
30
29
|
flags |= 2 if opts_[:has_z_coordinate]
|
31
30
|
flags |= 4 if opts_[:has_m_coordinate]
|
32
31
|
if flags & 6 == 6
|
@@ -72,13 +71,6 @@ module RGeo
|
|
72
71
|
if coord_sys_.is_a?(String)
|
73
72
|
coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_)
|
74
73
|
end
|
75
|
-
if (!proj4_ || !coord_sys_) && srid_ && (db_ = opts_[:srs_database])
|
76
|
-
entry_ = db_.get(srid_.to_i)
|
77
|
-
if entry_
|
78
|
-
proj4_ ||= entry_.proj4
|
79
|
-
coord_sys_ ||= entry_.coord_sys
|
80
|
-
end
|
81
|
-
end
|
82
74
|
srid_ ||= coord_sys_.authority_code if coord_sys_
|
83
75
|
|
84
76
|
# Create the factory and set instance variables
|
@@ -137,16 +129,15 @@ module RGeo
|
|
137
129
|
|
138
130
|
def marshal_dump # :nodoc:
|
139
131
|
hash_ = {
|
140
|
-
"hasz" =>
|
141
|
-
"hasm" =>
|
132
|
+
"hasz" => supports_z?,
|
133
|
+
"hasm" => supports_m?,
|
142
134
|
"srid" => _srid,
|
143
135
|
"bufr" => _buffer_resolution,
|
144
136
|
"wktg" => _wkt_generator ? _wkt_generator.properties : {},
|
145
137
|
"wkbg" => _wkb_generator ? _wkb_generator.properties : {},
|
146
138
|
"wktp" => _wkt_parser ? _wkt_parser.properties : {},
|
147
139
|
"wkbp" => _wkb_parser ? _wkb_parser.properties : {},
|
148
|
-
"
|
149
|
-
"apre" => ((_flags & 0x8) >> 3)
|
140
|
+
"apre" => auto_prepare
|
150
141
|
}
|
151
142
|
if (proj4_ = _proj4)
|
152
143
|
hash_["proj4"] = proj4_.marshal_dump
|
@@ -179,8 +170,7 @@ module RGeo
|
|
179
170
|
wkb_generator: symbolize_hash(data_["wkbg"]),
|
180
171
|
wkt_parser: symbolize_hash(data_["wktp"]),
|
181
172
|
wkb_parser: symbolize_hash(data_["wkbp"]),
|
182
|
-
|
183
|
-
auto_prepare: (data_["apre"] == 0 ? :disabled : :simple),
|
173
|
+
auto_prepare: data_["apre"],
|
184
174
|
proj4: proj4_,
|
185
175
|
coord_sys: coord_sys_
|
186
176
|
)
|
@@ -190,16 +180,15 @@ module RGeo
|
|
190
180
|
# Psych support
|
191
181
|
|
192
182
|
def encode_with(coder_) # :nodoc:
|
193
|
-
coder_["has_z_coordinate"] =
|
194
|
-
coder_["has_m_coordinate"] =
|
183
|
+
coder_["has_z_coordinate"] = supports_z?
|
184
|
+
coder_["has_m_coordinate"] = supports_m?
|
195
185
|
coder_["srid"] = _srid
|
196
186
|
coder_["buffer_resolution"] = _buffer_resolution
|
197
|
-
coder_["lenient_multi_polygon_assertions"] = (_flags & 0x1 != 0)
|
198
187
|
coder_["wkt_generator"] = _wkt_generator ? _wkt_generator.properties : {}
|
199
188
|
coder_["wkb_generator"] = _wkb_generator ? _wkb_generator.properties : {}
|
200
189
|
coder_["wkt_parser"] = _wkt_parser ? _wkt_parser.properties : {}
|
201
190
|
coder_["wkb_parser"] = _wkb_parser ? _wkb_parser.properties : {}
|
202
|
-
coder_["auto_prepare"] =
|
191
|
+
coder_["auto_prepare"] = auto_prepare
|
203
192
|
if (proj4_ = _proj4)
|
204
193
|
str_ = proj4_.original_str || proj4_.canonical_str
|
205
194
|
coder_["proj4"] = proj4_.radians? ? { "proj4" => str_, "radians" => true } : str_
|
@@ -236,7 +225,6 @@ module RGeo
|
|
236
225
|
wkt_parser: symbolize_hash(coder_["wkt_parser"]),
|
237
226
|
wkb_parser: symbolize_hash(coder_["wkb_parser"]),
|
238
227
|
auto_prepare: coder_["auto_prepare"] == "disabled" ? :disabled : :simple,
|
239
|
-
uses_lenient_multi_polygon_assertions: coder_["lenient_multi_polygon_assertions"],
|
240
228
|
proj4: proj4_,
|
241
229
|
coord_sys: coord_sys_
|
242
230
|
)
|
@@ -256,28 +244,19 @@ module RGeo
|
|
256
244
|
_buffer_resolution
|
257
245
|
end
|
258
246
|
|
259
|
-
# Returns true if this factory is lenient with MultiPolygon assertions
|
260
|
-
|
261
|
-
def lenient_multi_polygon_assertions?
|
262
|
-
_flags & 0x1 != 0
|
263
|
-
end
|
264
|
-
|
265
247
|
# See RGeo::Feature::Factory#property
|
266
|
-
|
267
248
|
def property(name_)
|
268
249
|
case name_
|
269
250
|
when :has_z_coordinate
|
270
|
-
|
251
|
+
supports_z?
|
271
252
|
when :has_m_coordinate
|
272
|
-
|
253
|
+
supports_m?
|
273
254
|
when :is_cartesian
|
274
255
|
true
|
275
|
-
when :uses_lenient_multi_polygon_assertions
|
276
|
-
_flags & 0x1 != 0
|
277
256
|
when :buffer_resolution
|
278
257
|
_buffer_resolution
|
279
258
|
when :auto_prepare
|
280
|
-
|
259
|
+
prepare_heuristic? ? :simple : :disabled
|
281
260
|
end
|
282
261
|
end
|
283
262
|
|
@@ -307,11 +286,11 @@ module RGeo
|
|
307
286
|
|
308
287
|
# See RGeo::Feature::Factory#point
|
309
288
|
|
310
|
-
def point(
|
311
|
-
if
|
289
|
+
def point(x, y, *extra)
|
290
|
+
if extra.length > (supports_z_or_m? ? 1 : 0)
|
312
291
|
raise(RGeo::Error::InvalidGeometry, "Parse error")
|
313
292
|
else
|
314
|
-
CAPIPointImpl.create(self,
|
293
|
+
CAPIPointImpl.create(self, x, y, extra[0].to_f)
|
315
294
|
end
|
316
295
|
end
|
317
296
|
|
@@ -398,7 +377,7 @@ module RGeo
|
|
398
377
|
# Optimization if we're just changing factories, but the
|
399
378
|
# factories are zm-compatible and proj4-compatible.
|
400
379
|
if original.factory != self && ntype == type &&
|
401
|
-
original.factory._flags &
|
380
|
+
original.factory._flags & FLAG_SUPPORTS_Z_OR_M == _flags & FLAG_SUPPORTS_Z_OR_M &&
|
402
381
|
(!project || original.factory.proj4 == _proj4)
|
403
382
|
result = original.dup
|
404
383
|
result.factory = self
|
@@ -406,7 +385,7 @@ module RGeo
|
|
406
385
|
end
|
407
386
|
# LineString conversion optimization.
|
408
387
|
if (original.factory != self || ntype != type) &&
|
409
|
-
original.factory._flags &
|
388
|
+
original.factory._flags & FLAG_SUPPORTS_Z_OR_M == _flags & FLAG_SUPPORTS_Z_OR_M &&
|
410
389
|
(!project || original.factory.proj4 == _proj4) &&
|
411
390
|
type.subtype_of?(Feature::LineString) && ntype.subtype_of?(Feature::LineString)
|
412
391
|
return IMPL_CLASSES[ntype]._copy_from(self, original)
|
@@ -414,15 +393,19 @@ module RGeo
|
|
414
393
|
when ZMGeometryMethods
|
415
394
|
# Optimization for just removing a coordinate from an otherwise
|
416
395
|
# compatible factory
|
417
|
-
if
|
396
|
+
if supports_z? && !supports_m? && self == original.factory.z_factory
|
418
397
|
return Feature.cast(original.z_geometry, ntype, flags)
|
419
|
-
elsif
|
398
|
+
elsif supports_m? && !supports_z? && self == original.factory.m_factory
|
420
399
|
return Feature.cast(original.m_geometry, ntype, flags)
|
421
400
|
end
|
422
401
|
end
|
423
402
|
false
|
424
403
|
end
|
425
404
|
|
405
|
+
def auto_prepare # :nodoc:
|
406
|
+
prepare_heuristic? ? :simple : :disabled
|
407
|
+
end
|
408
|
+
|
426
409
|
# :stopdoc:
|
427
410
|
|
428
411
|
IMPL_CLASSES = {
|
@@ -6,11 +6,24 @@
|
|
6
6
|
#
|
7
7
|
# -----------------------------------------------------------------------------
|
8
8
|
|
9
|
+
require_relative "../impl_helper/validity_check"
|
10
|
+
|
9
11
|
module RGeo
|
10
12
|
module Geos
|
11
|
-
module CAPIGeometryMethods
|
13
|
+
module CAPIGeometryMethods
|
12
14
|
include Feature::Instance
|
13
15
|
|
16
|
+
def coordinate_dimension
|
17
|
+
dim = 2
|
18
|
+
dim += 1 if factory.supports_z?
|
19
|
+
dim += 1 if factory.supports_m?
|
20
|
+
dim
|
21
|
+
end
|
22
|
+
|
23
|
+
def spatial_dimension
|
24
|
+
factory.supports_z? ? 3 : 2
|
25
|
+
end
|
26
|
+
|
14
27
|
def is_empty? # rubocop:disable Naming/PredicateName
|
15
28
|
warn "The is_empty? method is deprecated, please use the empty? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
16
29
|
empty?
|
@@ -21,6 +34,14 @@ module RGeo
|
|
21
34
|
simple?
|
22
35
|
end
|
23
36
|
|
37
|
+
def is_3d?
|
38
|
+
factory.supports_z?
|
39
|
+
end
|
40
|
+
|
41
|
+
def measured?
|
42
|
+
factory.supports_m?
|
43
|
+
end
|
44
|
+
|
24
45
|
def inspect
|
25
46
|
"#<#{self.class}:0x#{object_id.to_s(16)} #{as_text.inspect}>"
|
26
47
|
end
|
@@ -83,21 +104,29 @@ module RGeo
|
|
83
104
|
include Enumerable
|
84
105
|
end
|
85
106
|
|
86
|
-
class CAPIGeometryImpl
|
107
|
+
class CAPIGeometryImpl
|
108
|
+
include Feature::Geometry
|
109
|
+
include ImplHelper::ValidityCheck
|
87
110
|
include CAPIGeometryMethods
|
88
111
|
end
|
89
112
|
|
90
|
-
class CAPIPointImpl
|
113
|
+
class CAPIPointImpl
|
114
|
+
include Feature::Point
|
115
|
+
include ImplHelper::ValidityCheck
|
91
116
|
include CAPIGeometryMethods
|
92
117
|
include CAPIPointMethods
|
93
118
|
end
|
94
119
|
|
95
|
-
class CAPILineStringImpl
|
120
|
+
class CAPILineStringImpl
|
121
|
+
include Feature::LineString
|
122
|
+
include ImplHelper::ValidityCheck
|
96
123
|
include CAPIGeometryMethods
|
97
124
|
include CAPILineStringMethods
|
98
125
|
end
|
99
126
|
|
100
|
-
class CAPILinearRingImpl
|
127
|
+
class CAPILinearRingImpl
|
128
|
+
include Feature::LinearRing
|
129
|
+
include ImplHelper::ValidityCheck
|
101
130
|
include CAPIGeometryMethods
|
102
131
|
include CAPILineStringMethods
|
103
132
|
include CAPILinearRingMethods
|
@@ -107,38 +136,52 @@ module RGeo
|
|
107
136
|
end
|
108
137
|
end
|
109
138
|
|
110
|
-
class CAPILineImpl
|
139
|
+
class CAPILineImpl
|
140
|
+
include Feature::Line
|
141
|
+
include ImplHelper::ValidityCheck
|
111
142
|
include CAPIGeometryMethods
|
112
143
|
include CAPILineStringMethods
|
113
144
|
include CAPILineMethods
|
114
145
|
end
|
115
146
|
|
116
|
-
class CAPIPolygonImpl
|
147
|
+
class CAPIPolygonImpl
|
148
|
+
include Feature::Polygon
|
149
|
+
include ImplHelper::ValidityCheck
|
117
150
|
include CAPIGeometryMethods
|
118
151
|
include CAPIPolygonMethods
|
119
152
|
end
|
120
153
|
|
121
|
-
class CAPIGeometryCollectionImpl
|
154
|
+
class CAPIGeometryCollectionImpl
|
155
|
+
include Feature::GeometryCollection
|
156
|
+
include ImplHelper::ValidityCheck
|
122
157
|
include CAPIGeometryMethods
|
123
158
|
include CAPIGeometryCollectionMethods
|
124
159
|
end
|
125
160
|
|
126
|
-
class CAPIMultiPointImpl
|
161
|
+
class CAPIMultiPointImpl
|
162
|
+
include Feature::MultiPoint
|
163
|
+
include ImplHelper::ValidityCheck
|
127
164
|
include CAPIGeometryMethods
|
128
165
|
include CAPIGeometryCollectionMethods
|
129
166
|
include CAPIMultiPointMethods
|
130
167
|
end
|
131
168
|
|
132
|
-
class CAPIMultiLineStringImpl
|
169
|
+
class CAPIMultiLineStringImpl
|
170
|
+
include Feature::MultiLineString
|
171
|
+
include ImplHelper::ValidityCheck
|
133
172
|
include CAPIGeometryMethods
|
134
173
|
include CAPIGeometryCollectionMethods
|
135
174
|
include CAPIMultiLineStringMethods
|
136
175
|
end
|
137
176
|
|
138
|
-
class CAPIMultiPolygonImpl
|
177
|
+
class CAPIMultiPolygonImpl
|
178
|
+
include Feature::MultiPolygon
|
179
|
+
include ImplHelper::ValidityCheck
|
139
180
|
include CAPIGeometryMethods
|
140
181
|
include CAPIGeometryCollectionMethods
|
141
182
|
include CAPIMultiPolygonMethods
|
142
183
|
end
|
184
|
+
|
185
|
+
ImplHelper::ValidityCheck.override_classes
|
143
186
|
end
|
144
187
|
end
|
@@ -20,14 +20,16 @@ module RGeo
|
|
20
20
|
# See RGeo::Geos.factory for a list of supported options.
|
21
21
|
|
22
22
|
def initialize(opts = {})
|
23
|
-
# Main flags
|
24
|
-
@uses_lenient_multi_polygon_assertions = opts[:uses_lenient_assertions] ||
|
25
|
-
opts[:lenient_multi_polygon_assertions] || opts[:uses_lenient_multi_polygon_assertions]
|
26
23
|
@has_z = opts[:has_z_coordinate] ? true : false
|
27
24
|
@has_m = opts[:has_m_coordinate] ? true : false
|
28
25
|
if @has_z && @has_m
|
29
26
|
raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
|
30
27
|
end
|
28
|
+
@coordinate_dimension = 2
|
29
|
+
@coordinate_dimension += 1 if @has_z
|
30
|
+
@coordinate_dimension += 1 if @has_m
|
31
|
+
@spatial_dimension = @has_z ? 3 : 2
|
32
|
+
|
31
33
|
@_has_3d = @has_z || @has_m
|
32
34
|
@buffer_resolution = opts[:buffer_resolution].to_i
|
33
35
|
@buffer_resolution = 1 if @buffer_resolution < 1
|
@@ -73,13 +75,6 @@ module RGeo
|
|
73
75
|
if @coord_sys.is_a?(String)
|
74
76
|
@coord_sys = CoordSys::CS.create_from_wkt(@coord_sys)
|
75
77
|
end
|
76
|
-
if (!@proj4 || !@coord_sys) && @srid && (db = opts[:srs_database])
|
77
|
-
entry = db.get(@srid.to_i)
|
78
|
-
if entry
|
79
|
-
@proj4 ||= entry.proj4
|
80
|
-
@coord_sys ||= entry.coord_sys
|
81
|
-
end
|
82
|
-
end
|
83
78
|
@srid ||= @coord_sys.authority_code if @coord_sys
|
84
79
|
@srid = @srid.to_i
|
85
80
|
|
@@ -109,6 +104,7 @@ module RGeo
|
|
109
104
|
@wkb_reader = nil
|
110
105
|
end
|
111
106
|
end
|
107
|
+
attr_reader :coordinate_dimension, :spatial_dimension
|
112
108
|
|
113
109
|
# Standard object inspection output
|
114
110
|
|
@@ -145,7 +141,6 @@ module RGeo
|
|
145
141
|
"wkbg" => @wkb_generator.properties,
|
146
142
|
"wktp" => @wkt_parser.properties,
|
147
143
|
"wkbp" => @wkb_parser.properties,
|
148
|
-
"lmpa" => @uses_lenient_multi_polygon_assertions,
|
149
144
|
"apre" => @_auto_prepare
|
150
145
|
}
|
151
146
|
hash["proj4"] = @proj4.marshal_dump if @proj4
|
@@ -174,7 +169,6 @@ module RGeo
|
|
174
169
|
wkb_generator: symbolize_hash(data["wkbg"]),
|
175
170
|
wkt_parser: symbolize_hash(data["wktp"]),
|
176
171
|
wkb_parser: symbolize_hash(data["wkbp"]),
|
177
|
-
uses_lenient_multi_polygon_assertions: data["lmpa"],
|
178
172
|
auto_prepare: (data["apre"] ? :simple : :disabled),
|
179
173
|
proj4: proj4,
|
180
174
|
coord_sys: coord_sys
|
@@ -188,7 +182,6 @@ module RGeo
|
|
188
182
|
coder["has_m_coordinate"] = @has_m
|
189
183
|
coder["srid"] = @srid
|
190
184
|
coder["buffer_resolution"] = @buffer_resolution
|
191
|
-
coder["lenient_multi_polygon_assertions"] = @uses_lenient_multi_polygon_assertions
|
192
185
|
coder["wkt_generator"] = @wkt_generator.properties
|
193
186
|
coder["wkb_generator"] = @wkb_generator.properties
|
194
187
|
coder["wkt_parser"] = @wkt_parser.properties
|
@@ -227,7 +220,6 @@ module RGeo
|
|
227
220
|
wkt_parser: symbolize_hash(coder["wkt_parser"]),
|
228
221
|
wkb_parser: symbolize_hash(coder["wkb_parser"]),
|
229
222
|
auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
|
230
|
-
uses_lenient_multi_polygon_assertions: coder["lenient_multi_polygon_assertions"],
|
231
223
|
proj4: proj4,
|
232
224
|
coord_sys: coord_sys
|
233
225
|
)
|
@@ -242,14 +234,7 @@ module RGeo
|
|
242
234
|
|
243
235
|
attr_reader :buffer_resolution
|
244
236
|
|
245
|
-
# Returns true if this factory is lenient with MultiPolygon assertions
|
246
|
-
|
247
|
-
def lenient_multi_polygon_assertions?
|
248
|
-
@uses_lenient_multi_polygon_assertions
|
249
|
-
end
|
250
|
-
|
251
237
|
# See RGeo::Feature::Factory#property
|
252
|
-
|
253
238
|
def property(name_)
|
254
239
|
case name_
|
255
240
|
when :has_z_coordinate
|
@@ -260,15 +245,12 @@ module RGeo
|
|
260
245
|
true
|
261
246
|
when :buffer_resolution
|
262
247
|
@buffer_resolution
|
263
|
-
when :uses_lenient_multi_polygon_assertions
|
264
|
-
@uses_lenient_multi_polygon_assertions
|
265
248
|
when :auto_prepare
|
266
249
|
@_auto_prepare ? :simple : :disabled
|
267
250
|
end
|
268
251
|
end
|
269
252
|
|
270
253
|
# See RGeo::Feature::Factory#parse_wkt
|
271
|
-
|
272
254
|
def parse_wkt(str)
|
273
255
|
if @wkt_reader
|
274
256
|
wrap_fg_geom(@wkt_reader.read(str), nil)
|
@@ -417,17 +399,6 @@ module RGeo
|
|
417
399
|
raise(RGeo::Error::InvalidGeometry, "Could not cast to polygon: #{elem}") unless elem
|
418
400
|
elem.detach_fg_geom
|
419
401
|
end
|
420
|
-
unless @uses_lenient_multi_polygon_assertions
|
421
|
-
(1...elems.size).each do |i|
|
422
|
-
(0...i).each do |j|
|
423
|
-
igeom = elems[i]
|
424
|
-
jgeom = elems[j]
|
425
|
-
if igeom.relate_pattern(jgeom, "2********") || igeom.relate_pattern(jgeom, "****1****")
|
426
|
-
raise(RGeo::Error::InvalidGeometry, "Invalid relate pattern: #{jgeom}")
|
427
|
-
end
|
428
|
-
end
|
429
|
-
end
|
430
|
-
end
|
431
402
|
klasses = Array.new(elems.size, FFIPolygonImpl)
|
432
403
|
fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_MULTIPOLYGON, elems)
|
433
404
|
FFIMultiPolygonImpl.new(self, fg_geom, klasses)
|
@@ -6,60 +6,84 @@
|
|
6
6
|
#
|
7
7
|
# -----------------------------------------------------------------------------
|
8
8
|
|
9
|
+
require_relative "../impl_helper/validity_check"
|
10
|
+
|
9
11
|
module RGeo
|
10
12
|
module Geos
|
11
|
-
class FFIGeometryImpl
|
13
|
+
class FFIGeometryImpl
|
14
|
+
include Feature::Geometry
|
15
|
+
include ImplHelper::ValidityCheck
|
12
16
|
include FFIGeometryMethods
|
13
17
|
end
|
14
18
|
|
15
|
-
class FFIPointImpl
|
19
|
+
class FFIPointImpl
|
20
|
+
include Feature::Point
|
21
|
+
include ImplHelper::ValidityCheck
|
16
22
|
include FFIGeometryMethods
|
17
23
|
include FFIPointMethods
|
18
24
|
end
|
19
25
|
|
20
|
-
class FFILineStringImpl
|
26
|
+
class FFILineStringImpl
|
27
|
+
include Feature::LineString
|
28
|
+
include ImplHelper::ValidityCheck
|
21
29
|
include FFIGeometryMethods
|
22
30
|
include FFILineStringMethods
|
23
31
|
end
|
24
32
|
|
25
|
-
class FFILinearRingImpl
|
33
|
+
class FFILinearRingImpl
|
34
|
+
include Feature::LinearRing
|
35
|
+
include ImplHelper::ValidityCheck
|
26
36
|
include FFIGeometryMethods
|
27
37
|
include FFILineStringMethods
|
28
38
|
include FFILinearRingMethods
|
29
39
|
end
|
30
40
|
|
31
|
-
class FFILineImpl
|
41
|
+
class FFILineImpl
|
42
|
+
include Feature::Line
|
43
|
+
include ImplHelper::ValidityCheck
|
32
44
|
include FFIGeometryMethods
|
33
45
|
include FFILineStringMethods
|
34
46
|
include FFILineMethods
|
35
47
|
end
|
36
48
|
|
37
|
-
class FFIPolygonImpl
|
49
|
+
class FFIPolygonImpl
|
50
|
+
include Feature::Polygon
|
51
|
+
include ImplHelper::ValidityCheck
|
38
52
|
include FFIGeometryMethods
|
39
53
|
include FFIPolygonMethods
|
40
54
|
end
|
41
55
|
|
42
|
-
class FFIGeometryCollectionImpl
|
56
|
+
class FFIGeometryCollectionImpl
|
57
|
+
include Feature::GeometryCollection
|
58
|
+
include ImplHelper::ValidityCheck
|
43
59
|
include FFIGeometryMethods
|
44
60
|
include FFIGeometryCollectionMethods
|
45
61
|
end
|
46
62
|
|
47
|
-
class FFIMultiPointImpl
|
63
|
+
class FFIMultiPointImpl
|
64
|
+
include Feature::MultiPoint
|
65
|
+
include ImplHelper::ValidityCheck
|
48
66
|
include FFIGeometryMethods
|
49
67
|
include FFIGeometryCollectionMethods
|
50
68
|
include FFIMultiPointMethods
|
51
69
|
end
|
52
70
|
|
53
|
-
class FFIMultiLineStringImpl
|
71
|
+
class FFIMultiLineStringImpl
|
72
|
+
include Feature::MultiLineString
|
73
|
+
include ImplHelper::ValidityCheck
|
54
74
|
include FFIGeometryMethods
|
55
75
|
include FFIGeometryCollectionMethods
|
56
76
|
include FFIMultiLineStringMethods
|
57
77
|
end
|
58
78
|
|
59
|
-
class FFIMultiPolygonImpl
|
79
|
+
class FFIMultiPolygonImpl
|
80
|
+
include Feature::MultiPolygon
|
81
|
+
include ImplHelper::ValidityCheck
|
60
82
|
include FFIGeometryMethods
|
61
83
|
include FFIGeometryCollectionMethods
|
62
84
|
include FFIMultiPolygonMethods
|
63
85
|
end
|
86
|
+
|
87
|
+
ImplHelper::ValidityCheck.override_classes
|
64
88
|
end
|
65
89
|
end
|
@@ -6,6 +6,8 @@
|
|
6
6
|
#
|
7
7
|
# -----------------------------------------------------------------------------
|
8
8
|
|
9
|
+
require "ffi-geos"
|
10
|
+
|
9
11
|
module RGeo
|
10
12
|
module Geos
|
11
13
|
module FFIGeometryMethods # :nodoc:
|
@@ -75,6 +77,14 @@ module RGeo
|
|
75
77
|
Utils.ffi_compute_dimension(@fg_geom)
|
76
78
|
end
|
77
79
|
|
80
|
+
def coordinate_dimension
|
81
|
+
factory.coordinate_dimension
|
82
|
+
end
|
83
|
+
|
84
|
+
def spatial_dimension
|
85
|
+
factory.spatial_dimension
|
86
|
+
end
|
87
|
+
|
78
88
|
def geometry_type
|
79
89
|
Feature::Geometry
|
80
90
|
end
|
@@ -95,11 +105,9 @@ module RGeo
|
|
95
105
|
end
|
96
106
|
|
97
107
|
def boundary
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
@factory.wrap_fg_geom(@fg_geom.boundary, nil)
|
102
|
-
end
|
108
|
+
@factory.wrap_fg_geom(@fg_geom.boundary, nil)
|
109
|
+
rescue ::Geos::GEOSException
|
110
|
+
raise Error::InvalidGeometry, "Operation not supported by GeometryCollection"
|
103
111
|
end
|
104
112
|
|
105
113
|
def as_text
|
@@ -131,6 +139,32 @@ module RGeo
|
|
131
139
|
simple?
|
132
140
|
end
|
133
141
|
|
142
|
+
def is_3d?
|
143
|
+
factory.property(:has_z_coordinate)
|
144
|
+
end
|
145
|
+
|
146
|
+
def measured?
|
147
|
+
factory.property(:has_m_coordinate)
|
148
|
+
end
|
149
|
+
|
150
|
+
def valid?
|
151
|
+
@fg_geom.valid?
|
152
|
+
end
|
153
|
+
|
154
|
+
def invalid_reason
|
155
|
+
# valid_detail gives solely the reason, or nil if valid, which is
|
156
|
+
# what we want.
|
157
|
+
fg_geom.valid_detail&.dig(:detail)&.force_encoding(Encoding::UTF_8)
|
158
|
+
end
|
159
|
+
|
160
|
+
# (see RGeo::ImplHelper::ValidityCheck#make_valid)
|
161
|
+
# Only available since GEOS 3.8+
|
162
|
+
def make_valid
|
163
|
+
@factory.wrap_fg_geom(@fg_geom.make_valid, nil)
|
164
|
+
rescue ::Geos::GEOSException
|
165
|
+
raise Error::UnsupportedOperation
|
166
|
+
end if ::Geos::FFIGeos.respond_to?(:GEOSMakeValid_r)
|
167
|
+
|
134
168
|
def equals?(rhs)
|
135
169
|
return false unless rhs.is_a?(RGeo::Feature::Instance)
|
136
170
|
fg = factory.convert_to_fg_geometry(rhs)
|
data/lib/rgeo/geos/interface.rb
CHANGED
@@ -116,13 +116,6 @@ module RGeo
|
|
116
116
|
# Specifies which native interface to use. Possible values are
|
117
117
|
# <tt>:capi</tt> and <tt>:ffi</tt>. The default is the value
|
118
118
|
# of the preferred_native_interface.
|
119
|
-
# [<tt>:uses_lenient_multi_polygon_assertions</tt>]
|
120
|
-
# If set to true, assertion checking on MultiPolygon is disabled.
|
121
|
-
# This may speed up creation of MultiPolygon objects, at the
|
122
|
-
# expense of not doing the proper checking for OGC MultiPolygon
|
123
|
-
# compliance. See RGeo::Feature::MultiPolygon for details on
|
124
|
-
# the MultiPolygon assertions. Default is false. Also called
|
125
|
-
# <tt>:lenient_multi_polygon_assertions</tt>.
|
126
119
|
# [<tt>:buffer_resolution</tt>]
|
127
120
|
# The resolution of buffers around geometries created by this
|
128
121
|
# factory. This controls the number of line segments used to
|
@@ -142,11 +135,6 @@ module RGeo
|
|
142
135
|
# The coordinate system in OGC form, either as a subclass of
|
143
136
|
# CoordSys::CS::CoordinateSystem, or as a string in WKT format.
|
144
137
|
# Optional.
|
145
|
-
# [<tt>:srs_database</tt>]
|
146
|
-
# Optional. If provided, the object should respond to #get and
|
147
|
-
# #clear_cache. If both this and an SRID are
|
148
|
-
# provided, they are used to look up the proj4 and coord_sys
|
149
|
-
# objects from a spatial reference system database.
|
150
138
|
# [<tt>:has_z_coordinate</tt>]
|
151
139
|
# Support <tt>z_coordinate</tt>. Default is false.
|
152
140
|
# [<tt>:has_m_coordinate</tt>]
|
@@ -201,18 +189,6 @@ module RGeo
|
|
201
189
|
end
|
202
190
|
end
|
203
191
|
end
|
204
|
-
|
205
|
-
# Returns a Feature::FactoryGenerator that creates Geos-backed
|
206
|
-
# factories. The given options are used as the default options.
|
207
|
-
#
|
208
|
-
# A common case for this is to provide the <tt>:srs_database</tt>
|
209
|
-
# as a default. Then, the factory generator need only be passed
|
210
|
-
# an SRID and it will automatically fetch the appropriate Proj4
|
211
|
-
# and CoordSys objects.
|
212
|
-
|
213
|
-
def factory_generator(defaults = {})
|
214
|
-
proc { |c| factory(defaults.merge(c)) }
|
215
|
-
end
|
216
192
|
end
|
217
193
|
end
|
218
194
|
end
|
data/lib/rgeo/geos/zm_factory.rb
CHANGED
@@ -44,17 +44,8 @@ module RGeo
|
|
44
44
|
proj4 = opts[:proj4]
|
45
45
|
coord_sys = opts[:coord_sys]
|
46
46
|
srid = opts[:srid]
|
47
|
-
if (!proj4 || !coord_sys) && srid && (db = opts[:srs_database])
|
48
|
-
entry = db.get(srid.to_i)
|
49
|
-
if entry
|
50
|
-
proj4 ||= entry.proj4
|
51
|
-
coord_sys ||= entry.coord_sys
|
52
|
-
end
|
53
|
-
end
|
54
47
|
srid ||= coord_sys.authority_code if coord_sys
|
55
48
|
config = {
|
56
|
-
uses_lenient_multi_polygon_assertions: opts[:lenient_multi_polygon_assertions] ||
|
57
|
-
opts[:uses_lenient_multi_polygon_assertions],
|
58
49
|
buffer_resolution: opts[:buffer_resolution], auto_prepare: opts[:auto_prepare],
|
59
50
|
wkt_generator: opts[:wkt_generator], wkt_parser: opts[:wkt_parser],
|
60
51
|
wkb_generator: opts[:wkb_generator], wkb_parser: opts[:wkb_parser],
|
@@ -109,7 +100,6 @@ module RGeo
|
|
109
100
|
"wkbg" => @wkb_generator.properties,
|
110
101
|
"wktp" => @wkt_parser.properties,
|
111
102
|
"wkbp" => @wkb_parser.properties,
|
112
|
-
"lmpa" => @zfactory.lenient_multi_polygon_assertions?,
|
113
103
|
"apre" => @zfactory.property(:auto_prepare) == :simple,
|
114
104
|
"nffi" => @zfactory.is_a?(FFIFactory)
|
115
105
|
}
|
@@ -142,7 +132,6 @@ module RGeo
|
|
142
132
|
wkb_generator: symbolize_hash(data["wkbg"]),
|
143
133
|
wkt_parser: symbolize_hash(data["wktp"]),
|
144
134
|
wkb_parser: symbolize_hash(data["wkbp"]),
|
145
|
-
uses_lenient_multi_polygon_assertions: data["lmpa"],
|
146
135
|
auto_prepare: (data["apre"] ? :simple : :disabled),
|
147
136
|
proj4: proj4,
|
148
137
|
coord_sys: coord_sys
|
@@ -154,7 +143,6 @@ module RGeo
|
|
154
143
|
def encode_with(coder) # :nodoc:
|
155
144
|
coder["srid"] = @zfactory.srid
|
156
145
|
coder["buffer_resolution"] = @zfactory.buffer_resolution
|
157
|
-
coder["lenient_multi_polygon_assertions"] = @zfactory.lenient_multi_polygon_assertions?
|
158
146
|
coder["wkt_generator"] = @wkt_generator.properties
|
159
147
|
coder["wkb_generator"] = @wkb_generator.properties
|
160
148
|
coder["wkt_parser"] = @wkt_parser.properties
|
@@ -197,7 +185,6 @@ module RGeo
|
|
197
185
|
wkt_parser: symbolize_hash(coder["wkt_parser"]),
|
198
186
|
wkb_parser: symbolize_hash(coder["wkb_parser"]),
|
199
187
|
auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
|
200
|
-
uses_lenient_multi_polygon_assertions: coder["lenient_multi_polygon_assertions"],
|
201
188
|
proj4: proj4,
|
202
189
|
coord_sys: coord_sys
|
203
190
|
)
|
@@ -216,12 +203,6 @@ module RGeo
|
|
216
203
|
@zfactory.buffer_resolution
|
217
204
|
end
|
218
205
|
|
219
|
-
# Returns true if this factory is lenient with MultiPolygon assertions
|
220
|
-
|
221
|
-
def lenient_multi_polygon_assertions?
|
222
|
-
@zfactory.lenient_multi_polygon_assertions?
|
223
|
-
end
|
224
|
-
|
225
206
|
# Returns the z-only factory corresponding to this factory.
|
226
207
|
|
227
208
|
def z_factory
|