rgeo 2.3.0 → 3.0.0.pre.rc.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/.yardopts +6 -0
- data/README.md +1 -0
- 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 +251 -182
- data/ext/geos_c_impl/factory.h +43 -62
- data/ext/geos_c_impl/geometry.c +56 -24
- data/ext/geos_c_impl/geometry.h +8 -3
- data/ext/geos_c_impl/geometry_collection.c +41 -148
- 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 +15 -51
- data/ext/geos_c_impl/polygon.h +1 -3
- data/ext/geos_c_impl/preface.h +8 -0
- data/lib/rgeo/cartesian/analysis.rb +2 -2
- data/lib/rgeo/cartesian/calculations.rb +54 -17
- data/lib/rgeo/cartesian/factory.rb +0 -7
- data/lib/rgeo/cartesian/feature_classes.rb +66 -46
- data/lib/rgeo/cartesian/feature_methods.rb +56 -20
- data/lib/rgeo/cartesian/interface.rb +0 -6
- 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/error.rb +15 -0
- data/lib/rgeo/feature/curve.rb +12 -2
- data/lib/rgeo/feature/geometry.rb +38 -28
- data/lib/rgeo/feature/geometry_collection.rb +13 -5
- data/lib/rgeo/feature/line_string.rb +3 -3
- data/lib/rgeo/feature/multi_curve.rb +6 -1
- 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 +0 -7
- data/lib/rgeo/geographic/interface.rb +4 -18
- 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 +63 -30
- 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 +68 -2
- data/lib/rgeo/geos/capi_factory.rb +21 -31
- data/lib/rgeo/geos/capi_feature_classes.rb +64 -11
- data/lib/rgeo/geos/ffi_factory.rb +0 -28
- data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
- data/lib/rgeo/geos/ffi_feature_methods.rb +53 -10
- data/lib/rgeo/geos/interface.rb +18 -10
- data/lib/rgeo/geos/zm_factory.rb +0 -12
- data/lib/rgeo/geos/zm_feature_methods.rb +30 -5
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +18 -8
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -1
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +37 -26
- data/lib/rgeo/impl_helper/basic_point_methods.rb +13 -3
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +8 -3
- data/lib/rgeo/impl_helper/valid_op.rb +354 -0
- data/lib/rgeo/impl_helper/validity_check.rb +138 -0
- data/lib/rgeo/impl_helper.rb +1 -0
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +1 -1
- data/lib/rgeo/wkrep/wkt_generator.rb +6 -6
- metadata +30 -7
@@ -79,7 +79,8 @@ module RGeo
|
|
79
79
|
|
80
80
|
private
|
81
81
|
|
82
|
-
|
82
|
+
# Ensure coordinates fall within a valid range.
|
83
|
+
def init_geometry
|
83
84
|
if @x < -180.0 || @x > 180.0
|
84
85
|
@x = @x % 360.0
|
85
86
|
@x -= 360.0 if @x > 180.0
|
@@ -97,7 +98,7 @@ module RGeo
|
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
100
|
-
def
|
101
|
+
def simple?
|
101
102
|
len = arcs.length
|
102
103
|
return false if arcs.any?(&:degenerate?)
|
103
104
|
return true if len == 1
|
@@ -120,9 +121,74 @@ module RGeo
|
|
120
121
|
true
|
121
122
|
end
|
122
123
|
|
124
|
+
def is_simple?
|
125
|
+
warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
126
|
+
simple?
|
127
|
+
end
|
128
|
+
|
123
129
|
def length
|
124
130
|
arcs.inject(0.0) { |sum, arc| sum + arc.length } * SphericalMath::RADIUS
|
125
131
|
end
|
132
|
+
|
133
|
+
def intersects?(rhs)
|
134
|
+
case rhs
|
135
|
+
when Feature::LineString
|
136
|
+
intersects_line_string?(rhs)
|
137
|
+
else
|
138
|
+
super
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def crosses?(rhs)
|
143
|
+
case rhs
|
144
|
+
when Feature::LineString
|
145
|
+
crosses_line_string?(rhs)
|
146
|
+
else
|
147
|
+
super
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
# TODO: replace with better algorithm (https://github.com/rgeo/rgeo/issues/274)
|
154
|
+
# Very simple algorithm to determine if 2 LineStrings intersect.
|
155
|
+
# Uses a nested for loop to look at each arc in the LineStrings and
|
156
|
+
# check if each arc intersects.
|
157
|
+
#
|
158
|
+
# @param [RGeo::Geographic::SphericalLineStringImpl] rhs
|
159
|
+
#
|
160
|
+
# @return [Boolean]
|
161
|
+
def intersects_line_string?(rhs)
|
162
|
+
arcs.each do |arc|
|
163
|
+
rhs.arcs.each do |rhs_arc|
|
164
|
+
return true if arc.intersects_arc?(rhs_arc)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
false
|
169
|
+
end
|
170
|
+
|
171
|
+
# TODO: replace with better algorithm (https://github.com/rgeo/rgeo/issues/274)
|
172
|
+
# Very simple algorithm to determine if 2 LineStrings cross.
|
173
|
+
# Uses a nested for loop to look at each arc in the LineStrings and
|
174
|
+
# check if each arc crosses.
|
175
|
+
#
|
176
|
+
# @param [RGeo::Geographic::SphericalLineStringImpl] rhs
|
177
|
+
#
|
178
|
+
# @return [Boolean]
|
179
|
+
def crosses_line_string?(rhs)
|
180
|
+
arcs.each do |arc|
|
181
|
+
rhs.arcs.each do |rhs_arc|
|
182
|
+
next unless arc.intersects_arc?(rhs_arc)
|
183
|
+
|
184
|
+
# check that endpoints aren't the intersection point
|
185
|
+
is_endpoint = arc.contains_point?(rhs_arc.s) || arc.contains_point?(rhs_arc.e) || rhs_arc.contains_point?(arc.s) || rhs_arc.contains_point?(arc.e)
|
186
|
+
return true unless is_endpoint
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
false
|
191
|
+
end
|
126
192
|
end
|
127
193
|
|
128
194
|
module SphericalMultiLineStringMethods # :nodoc:
|
@@ -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
|
@@ -137,16 +136,15 @@ module RGeo
|
|
137
136
|
|
138
137
|
def marshal_dump # :nodoc:
|
139
138
|
hash_ = {
|
140
|
-
"hasz" =>
|
141
|
-
"hasm" =>
|
139
|
+
"hasz" => supports_z?,
|
140
|
+
"hasm" => supports_m?,
|
142
141
|
"srid" => _srid,
|
143
142
|
"bufr" => _buffer_resolution,
|
144
143
|
"wktg" => _wkt_generator ? _wkt_generator.properties : {},
|
145
144
|
"wkbg" => _wkb_generator ? _wkb_generator.properties : {},
|
146
145
|
"wktp" => _wkt_parser ? _wkt_parser.properties : {},
|
147
146
|
"wkbp" => _wkb_parser ? _wkb_parser.properties : {},
|
148
|
-
"
|
149
|
-
"apre" => ((_flags & 0x8) >> 3)
|
147
|
+
"apre" => auto_prepare
|
150
148
|
}
|
151
149
|
if (proj4_ = _proj4)
|
152
150
|
hash_["proj4"] = proj4_.marshal_dump
|
@@ -179,8 +177,7 @@ module RGeo
|
|
179
177
|
wkb_generator: symbolize_hash(data_["wkbg"]),
|
180
178
|
wkt_parser: symbolize_hash(data_["wktp"]),
|
181
179
|
wkb_parser: symbolize_hash(data_["wkbp"]),
|
182
|
-
|
183
|
-
auto_prepare: (data_["apre"] == 0 ? :disabled : :simple),
|
180
|
+
auto_prepare: data_["apre"],
|
184
181
|
proj4: proj4_,
|
185
182
|
coord_sys: coord_sys_
|
186
183
|
)
|
@@ -190,16 +187,15 @@ module RGeo
|
|
190
187
|
# Psych support
|
191
188
|
|
192
189
|
def encode_with(coder_) # :nodoc:
|
193
|
-
coder_["has_z_coordinate"] =
|
194
|
-
coder_["has_m_coordinate"] =
|
190
|
+
coder_["has_z_coordinate"] = supports_z?
|
191
|
+
coder_["has_m_coordinate"] = supports_m?
|
195
192
|
coder_["srid"] = _srid
|
196
193
|
coder_["buffer_resolution"] = _buffer_resolution
|
197
|
-
coder_["lenient_multi_polygon_assertions"] = (_flags & 0x1 != 0)
|
198
194
|
coder_["wkt_generator"] = _wkt_generator ? _wkt_generator.properties : {}
|
199
195
|
coder_["wkb_generator"] = _wkb_generator ? _wkb_generator.properties : {}
|
200
196
|
coder_["wkt_parser"] = _wkt_parser ? _wkt_parser.properties : {}
|
201
197
|
coder_["wkb_parser"] = _wkb_parser ? _wkb_parser.properties : {}
|
202
|
-
coder_["auto_prepare"] =
|
198
|
+
coder_["auto_prepare"] = auto_prepare
|
203
199
|
if (proj4_ = _proj4)
|
204
200
|
str_ = proj4_.original_str || proj4_.canonical_str
|
205
201
|
coder_["proj4"] = proj4_.radians? ? { "proj4" => str_, "radians" => true } : str_
|
@@ -236,7 +232,6 @@ module RGeo
|
|
236
232
|
wkt_parser: symbolize_hash(coder_["wkt_parser"]),
|
237
233
|
wkb_parser: symbolize_hash(coder_["wkb_parser"]),
|
238
234
|
auto_prepare: coder_["auto_prepare"] == "disabled" ? :disabled : :simple,
|
239
|
-
uses_lenient_multi_polygon_assertions: coder_["lenient_multi_polygon_assertions"],
|
240
235
|
proj4: proj4_,
|
241
236
|
coord_sys: coord_sys_
|
242
237
|
)
|
@@ -256,28 +251,19 @@ module RGeo
|
|
256
251
|
_buffer_resolution
|
257
252
|
end
|
258
253
|
|
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
254
|
# See RGeo::Feature::Factory#property
|
266
|
-
|
267
255
|
def property(name_)
|
268
256
|
case name_
|
269
257
|
when :has_z_coordinate
|
270
|
-
|
258
|
+
supports_z?
|
271
259
|
when :has_m_coordinate
|
272
|
-
|
260
|
+
supports_m?
|
273
261
|
when :is_cartesian
|
274
262
|
true
|
275
|
-
when :uses_lenient_multi_polygon_assertions
|
276
|
-
_flags & 0x1 != 0
|
277
263
|
when :buffer_resolution
|
278
264
|
_buffer_resolution
|
279
265
|
when :auto_prepare
|
280
|
-
|
266
|
+
prepare_heuristic? ? :simple : :disabled
|
281
267
|
end
|
282
268
|
end
|
283
269
|
|
@@ -307,11 +293,11 @@ module RGeo
|
|
307
293
|
|
308
294
|
# See RGeo::Feature::Factory#point
|
309
295
|
|
310
|
-
def point(
|
311
|
-
if
|
296
|
+
def point(x, y, *extra)
|
297
|
+
if extra.length > (supports_z_or_m? ? 1 : 0)
|
312
298
|
raise(RGeo::Error::InvalidGeometry, "Parse error")
|
313
299
|
else
|
314
|
-
CAPIPointImpl.create(self,
|
300
|
+
CAPIPointImpl.create(self, x, y, extra[0].to_f)
|
315
301
|
end
|
316
302
|
end
|
317
303
|
|
@@ -398,7 +384,7 @@ module RGeo
|
|
398
384
|
# Optimization if we're just changing factories, but the
|
399
385
|
# factories are zm-compatible and proj4-compatible.
|
400
386
|
if original.factory != self && ntype == type &&
|
401
|
-
original.factory._flags &
|
387
|
+
original.factory._flags & FLAG_SUPPORTS_Z_OR_M == _flags & FLAG_SUPPORTS_Z_OR_M &&
|
402
388
|
(!project || original.factory.proj4 == _proj4)
|
403
389
|
result = original.dup
|
404
390
|
result.factory = self
|
@@ -406,7 +392,7 @@ module RGeo
|
|
406
392
|
end
|
407
393
|
# LineString conversion optimization.
|
408
394
|
if (original.factory != self || ntype != type) &&
|
409
|
-
original.factory._flags &
|
395
|
+
original.factory._flags & FLAG_SUPPORTS_Z_OR_M == _flags & FLAG_SUPPORTS_Z_OR_M &&
|
410
396
|
(!project || original.factory.proj4 == _proj4) &&
|
411
397
|
type.subtype_of?(Feature::LineString) && ntype.subtype_of?(Feature::LineString)
|
412
398
|
return IMPL_CLASSES[ntype]._copy_from(self, original)
|
@@ -414,15 +400,19 @@ module RGeo
|
|
414
400
|
when ZMGeometryMethods
|
415
401
|
# Optimization for just removing a coordinate from an otherwise
|
416
402
|
# compatible factory
|
417
|
-
if
|
403
|
+
if supports_z? && !supports_m? && self == original.factory.z_factory
|
418
404
|
return Feature.cast(original.z_geometry, ntype, flags)
|
419
|
-
elsif
|
405
|
+
elsif supports_m? && !supports_z? && self == original.factory.m_factory
|
420
406
|
return Feature.cast(original.m_geometry, ntype, flags)
|
421
407
|
end
|
422
408
|
end
|
423
409
|
false
|
424
410
|
end
|
425
411
|
|
412
|
+
def auto_prepare # :nodoc:
|
413
|
+
prepare_heuristic? ? :simple : :disabled
|
414
|
+
end
|
415
|
+
|
426
416
|
# :stopdoc:
|
427
417
|
|
428
418
|
IMPL_CLASSES = {
|
@@ -6,11 +6,23 @@
|
|
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 is_empty? # rubocop:disable Naming/PredicateName
|
17
|
+
warn "The is_empty? method is deprecated, please use the empty? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
18
|
+
empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_simple? # rubocop:disable Naming/PredicateName
|
22
|
+
warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
23
|
+
simple?
|
24
|
+
end
|
25
|
+
|
14
26
|
def inspect
|
15
27
|
"#<#{self.class}:0x#{object_id.to_s(16)} #{as_text.inspect}>"
|
16
28
|
end
|
@@ -50,25 +62,52 @@ module RGeo
|
|
50
62
|
alias to_s as_text
|
51
63
|
end
|
52
64
|
|
65
|
+
module CAPIMultiLineStringMethods # :nodoc:
|
66
|
+
def is_closed? # rubocop:disable Naming/PredicateName
|
67
|
+
warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
68
|
+
closed?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
module CAPILineStringMethods # :nodoc:
|
73
|
+
def is_closed? # rubocop:disable Naming/PredicateName
|
74
|
+
warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
75
|
+
closed?
|
76
|
+
end
|
77
|
+
|
78
|
+
def is_ring? # rubocop:disable Naming/PredicateName
|
79
|
+
warn "The is_ring? method is deprecated, please use the ring? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
80
|
+
ring?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
53
84
|
module CAPIGeometryCollectionMethods # :nodoc:
|
54
85
|
include Enumerable
|
55
86
|
end
|
56
87
|
|
57
|
-
class CAPIGeometryImpl
|
88
|
+
class CAPIGeometryImpl
|
89
|
+
include Feature::Geometry
|
90
|
+
include ImplHelper::ValidityCheck
|
58
91
|
include CAPIGeometryMethods
|
59
92
|
end
|
60
93
|
|
61
|
-
class CAPIPointImpl
|
94
|
+
class CAPIPointImpl
|
95
|
+
include Feature::Point
|
96
|
+
include ImplHelper::ValidityCheck
|
62
97
|
include CAPIGeometryMethods
|
63
98
|
include CAPIPointMethods
|
64
99
|
end
|
65
100
|
|
66
|
-
class CAPILineStringImpl
|
101
|
+
class CAPILineStringImpl
|
102
|
+
include Feature::LineString
|
103
|
+
include ImplHelper::ValidityCheck
|
67
104
|
include CAPIGeometryMethods
|
68
105
|
include CAPILineStringMethods
|
69
106
|
end
|
70
107
|
|
71
|
-
class CAPILinearRingImpl
|
108
|
+
class CAPILinearRingImpl
|
109
|
+
include Feature::LinearRing
|
110
|
+
include ImplHelper::ValidityCheck
|
72
111
|
include CAPIGeometryMethods
|
73
112
|
include CAPILineStringMethods
|
74
113
|
include CAPILinearRingMethods
|
@@ -78,38 +117,52 @@ module RGeo
|
|
78
117
|
end
|
79
118
|
end
|
80
119
|
|
81
|
-
class CAPILineImpl
|
120
|
+
class CAPILineImpl
|
121
|
+
include Feature::Line
|
122
|
+
include ImplHelper::ValidityCheck
|
82
123
|
include CAPIGeometryMethods
|
83
124
|
include CAPILineStringMethods
|
84
125
|
include CAPILineMethods
|
85
126
|
end
|
86
127
|
|
87
|
-
class CAPIPolygonImpl
|
128
|
+
class CAPIPolygonImpl
|
129
|
+
include Feature::Polygon
|
130
|
+
include ImplHelper::ValidityCheck
|
88
131
|
include CAPIGeometryMethods
|
89
132
|
include CAPIPolygonMethods
|
90
133
|
end
|
91
134
|
|
92
|
-
class CAPIGeometryCollectionImpl
|
135
|
+
class CAPIGeometryCollectionImpl
|
136
|
+
include Feature::GeometryCollection
|
137
|
+
include ImplHelper::ValidityCheck
|
93
138
|
include CAPIGeometryMethods
|
94
139
|
include CAPIGeometryCollectionMethods
|
95
140
|
end
|
96
141
|
|
97
|
-
class CAPIMultiPointImpl
|
142
|
+
class CAPIMultiPointImpl
|
143
|
+
include Feature::MultiPoint
|
144
|
+
include ImplHelper::ValidityCheck
|
98
145
|
include CAPIGeometryMethods
|
99
146
|
include CAPIGeometryCollectionMethods
|
100
147
|
include CAPIMultiPointMethods
|
101
148
|
end
|
102
149
|
|
103
|
-
class CAPIMultiLineStringImpl
|
150
|
+
class CAPIMultiLineStringImpl
|
151
|
+
include Feature::MultiLineString
|
152
|
+
include ImplHelper::ValidityCheck
|
104
153
|
include CAPIGeometryMethods
|
105
154
|
include CAPIGeometryCollectionMethods
|
106
155
|
include CAPIMultiLineStringMethods
|
107
156
|
end
|
108
157
|
|
109
|
-
class CAPIMultiPolygonImpl
|
158
|
+
class CAPIMultiPolygonImpl
|
159
|
+
include Feature::MultiPolygon
|
160
|
+
include ImplHelper::ValidityCheck
|
110
161
|
include CAPIGeometryMethods
|
111
162
|
include CAPIGeometryCollectionMethods
|
112
163
|
include CAPIMultiPolygonMethods
|
113
164
|
end
|
165
|
+
|
166
|
+
ImplHelper::ValidityCheck.override_classes
|
114
167
|
end
|
115
168
|
end
|
@@ -20,9 +20,6 @@ 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
|
@@ -145,7 +142,6 @@ module RGeo
|
|
145
142
|
"wkbg" => @wkb_generator.properties,
|
146
143
|
"wktp" => @wkt_parser.properties,
|
147
144
|
"wkbp" => @wkb_parser.properties,
|
148
|
-
"lmpa" => @uses_lenient_multi_polygon_assertions,
|
149
145
|
"apre" => @_auto_prepare
|
150
146
|
}
|
151
147
|
hash["proj4"] = @proj4.marshal_dump if @proj4
|
@@ -174,7 +170,6 @@ module RGeo
|
|
174
170
|
wkb_generator: symbolize_hash(data["wkbg"]),
|
175
171
|
wkt_parser: symbolize_hash(data["wktp"]),
|
176
172
|
wkb_parser: symbolize_hash(data["wkbp"]),
|
177
|
-
uses_lenient_multi_polygon_assertions: data["lmpa"],
|
178
173
|
auto_prepare: (data["apre"] ? :simple : :disabled),
|
179
174
|
proj4: proj4,
|
180
175
|
coord_sys: coord_sys
|
@@ -188,7 +183,6 @@ module RGeo
|
|
188
183
|
coder["has_m_coordinate"] = @has_m
|
189
184
|
coder["srid"] = @srid
|
190
185
|
coder["buffer_resolution"] = @buffer_resolution
|
191
|
-
coder["lenient_multi_polygon_assertions"] = @uses_lenient_multi_polygon_assertions
|
192
186
|
coder["wkt_generator"] = @wkt_generator.properties
|
193
187
|
coder["wkb_generator"] = @wkb_generator.properties
|
194
188
|
coder["wkt_parser"] = @wkt_parser.properties
|
@@ -227,7 +221,6 @@ module RGeo
|
|
227
221
|
wkt_parser: symbolize_hash(coder["wkt_parser"]),
|
228
222
|
wkb_parser: symbolize_hash(coder["wkb_parser"]),
|
229
223
|
auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
|
230
|
-
uses_lenient_multi_polygon_assertions: coder["lenient_multi_polygon_assertions"],
|
231
224
|
proj4: proj4,
|
232
225
|
coord_sys: coord_sys
|
233
226
|
)
|
@@ -242,14 +235,7 @@ module RGeo
|
|
242
235
|
|
243
236
|
attr_reader :buffer_resolution
|
244
237
|
|
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
238
|
# See RGeo::Feature::Factory#property
|
252
|
-
|
253
239
|
def property(name_)
|
254
240
|
case name_
|
255
241
|
when :has_z_coordinate
|
@@ -260,15 +246,12 @@ module RGeo
|
|
260
246
|
true
|
261
247
|
when :buffer_resolution
|
262
248
|
@buffer_resolution
|
263
|
-
when :uses_lenient_multi_polygon_assertions
|
264
|
-
@uses_lenient_multi_polygon_assertions
|
265
249
|
when :auto_prepare
|
266
250
|
@_auto_prepare ? :simple : :disabled
|
267
251
|
end
|
268
252
|
end
|
269
253
|
|
270
254
|
# See RGeo::Feature::Factory#parse_wkt
|
271
|
-
|
272
255
|
def parse_wkt(str)
|
273
256
|
if @wkt_reader
|
274
257
|
wrap_fg_geom(@wkt_reader.read(str), nil)
|
@@ -417,17 +400,6 @@ module RGeo
|
|
417
400
|
raise(RGeo::Error::InvalidGeometry, "Could not cast to polygon: #{elem}") unless elem
|
418
401
|
elem.detach_fg_geom
|
419
402
|
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
403
|
klasses = Array.new(elems.size, FFIPolygonImpl)
|
432
404
|
fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_MULTIPOLYGON, elems)
|
433
405
|
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:
|
@@ -95,11 +97,9 @@ module RGeo
|
|
95
97
|
end
|
96
98
|
|
97
99
|
def boundary
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
@factory.wrap_fg_geom(@fg_geom.boundary, nil)
|
102
|
-
end
|
100
|
+
@factory.wrap_fg_geom(@fg_geom.boundary, nil)
|
101
|
+
rescue ::Geos::GEOSException
|
102
|
+
raise Error::InvalidGeometry, "Operation not supported by GeometryCollection"
|
103
103
|
end
|
104
104
|
|
105
105
|
def as_text
|
@@ -113,14 +113,42 @@ module RGeo
|
|
113
113
|
@factory.generate_wkb(self)
|
114
114
|
end
|
115
115
|
|
116
|
-
def
|
116
|
+
def empty?
|
117
117
|
@fg_geom.empty?
|
118
118
|
end
|
119
119
|
|
120
|
-
def
|
120
|
+
def is_empty?
|
121
|
+
warn "The is_empty? method is deprecated, please use the empty? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
122
|
+
empty?
|
123
|
+
end
|
124
|
+
|
125
|
+
def simple?
|
121
126
|
@fg_geom.simple?
|
122
127
|
end
|
123
128
|
|
129
|
+
def is_simple?
|
130
|
+
warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
131
|
+
simple?
|
132
|
+
end
|
133
|
+
|
134
|
+
def valid?
|
135
|
+
@fg_geom.valid?
|
136
|
+
end
|
137
|
+
|
138
|
+
def invalid_reason
|
139
|
+
# valid_detail gives solely the reason, or nil if valid, which is
|
140
|
+
# what we want.
|
141
|
+
fg_geom.valid_detail&.dig(:detail)&.force_encoding(Encoding::UTF_8)
|
142
|
+
end
|
143
|
+
|
144
|
+
# (see RGeo::ImplHelper::ValidityCheck#make_valid)
|
145
|
+
# Only available since GEOS 3.8+
|
146
|
+
def make_valid
|
147
|
+
@factory.wrap_fg_geom(@fg_geom.make_valid, nil)
|
148
|
+
rescue ::Geos::GEOSException
|
149
|
+
raise Error::UnsupportedOperation
|
150
|
+
end if ::Geos::FFIGeos.respond_to?(:GEOSMakeValid_r)
|
151
|
+
|
124
152
|
def equals?(rhs)
|
125
153
|
return false unless rhs.is_a?(RGeo::Feature::Instance)
|
126
154
|
fg = factory.convert_to_fg_geometry(rhs)
|
@@ -367,14 +395,24 @@ module RGeo
|
|
367
395
|
end
|
368
396
|
end
|
369
397
|
|
370
|
-
def
|
398
|
+
def closed?
|
371
399
|
@fg_geom.closed?
|
372
400
|
end
|
373
401
|
|
374
|
-
def
|
402
|
+
def is_closed?
|
403
|
+
warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
404
|
+
closed?
|
405
|
+
end
|
406
|
+
|
407
|
+
def ring?
|
375
408
|
@fg_geom.ring?
|
376
409
|
end
|
377
410
|
|
411
|
+
def is_ring?
|
412
|
+
warn "The is_ring? method is deprecated, please use the ring? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
413
|
+
ring?
|
414
|
+
end
|
415
|
+
|
378
416
|
def rep_equals?(rhs)
|
379
417
|
rhs.class == self.class && rhs.factory.eql?(@factory) &&
|
380
418
|
Utils.ffi_coord_seqs_equal?(rhs.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
|
@@ -553,7 +591,7 @@ module RGeo
|
|
553
591
|
@fg_geom.length
|
554
592
|
end
|
555
593
|
|
556
|
-
def
|
594
|
+
def closed?
|
557
595
|
size = num_geometries
|
558
596
|
size.times do |n|
|
559
597
|
return false unless @fg_geom.get_geometry_n(n).closed?
|
@@ -561,6 +599,11 @@ module RGeo
|
|
561
599
|
true
|
562
600
|
end
|
563
601
|
|
602
|
+
def is_closed?
|
603
|
+
warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
604
|
+
closed?
|
605
|
+
end
|
606
|
+
|
564
607
|
def coordinates
|
565
608
|
each.map(&:coordinates)
|
566
609
|
end
|