rgeo 0.2.9 → 0.3.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.
- data/History.rdoc +11 -0
- data/README.rdoc +3 -3
- data/Spatial_Programming_With_RGeo.rdoc +19 -8
- data/Version +1 -1
- data/ext/geos_c_impl/factory.c +1 -0
- data/ext/geos_c_impl/factory.h +1 -0
- data/ext/geos_c_impl/geometry.c +4 -5
- data/ext/geos_c_impl/geometry_collection.c +15 -0
- data/ext/geos_c_impl/line_string.c +10 -0
- data/ext/geos_c_impl/point.c +2 -0
- data/ext/geos_c_impl/polygon.c +4 -0
- data/lib/rgeo/cartesian/feature_classes.rb +23 -17
- data/lib/rgeo/cartesian/feature_methods.rb +20 -1
- data/lib/rgeo/feature.rb +1 -0
- data/lib/rgeo/feature/curve.rb +1 -2
- data/lib/rgeo/feature/geometry_collection.rb +1 -1
- data/lib/rgeo/feature/line.rb +1 -1
- data/lib/rgeo/feature/line_string.rb +1 -2
- data/lib/rgeo/feature/linear_ring.rb +1 -2
- data/lib/rgeo/feature/mixins.rb +198 -0
- data/lib/rgeo/feature/multi_curve.rb +1 -2
- data/lib/rgeo/feature/multi_line_string.rb +1 -2
- data/lib/rgeo/feature/multi_point.rb +1 -2
- data/lib/rgeo/feature/multi_polygon.rb +1 -2
- data/lib/rgeo/feature/multi_surface.rb +1 -2
- data/lib/rgeo/feature/point.rb +1 -2
- data/lib/rgeo/feature/polygon.rb +1 -3
- data/lib/rgeo/feature/surface.rb +1 -2
- data/lib/rgeo/feature/types.rb +27 -0
- data/lib/rgeo/geographic/projected_feature_classes.rb +31 -4
- data/lib/rgeo/geographic/projected_feature_methods.rb +2 -1
- data/lib/rgeo/geographic/spherical_feature_classes.rb +30 -3
- data/lib/rgeo/geos.rb +22 -0
- data/lib/rgeo/geos/factory.rb +11 -5
- data/lib/rgeo/geos/ffi_classes.rb +655 -0
- data/lib/rgeo/geos/ffi_factory.rb +503 -0
- data/lib/rgeo/geos/impl_additions.rb +1 -1
- data/lib/rgeo/geos/interface.rb +63 -8
- data/lib/rgeo/geos/zm_factory.rb +10 -4
- data/test/common/geometry_collection_tests.rb +1 -3
- data/test/coord_sys/tc_ogc_cs.rb +13 -2
- data/test/coord_sys/tc_proj4_srs_data.rb +1 -1
- data/test/{geos → geos_capi}/tc_factory.rb +2 -2
- data/test/{geos → geos_capi}/tc_geometry_collection.rb +2 -2
- data/test/{geos → geos_capi}/tc_line_string.rb +2 -2
- data/test/{geos → geos_capi}/tc_misc.rb +6 -2
- data/test/{geos → geos_capi}/tc_multi_line_string.rb +2 -2
- data/test/{geos → geos_capi}/tc_multi_point.rb +2 -2
- data/test/{geos → geos_capi}/tc_multi_polygon.rb +2 -2
- data/test/{geos → geos_capi}/tc_parsing_unparsing.rb +2 -2
- data/test/{geos → geos_capi}/tc_point.rb +2 -2
- data/test/{geos → geos_capi}/tc_polygon.rb +2 -2
- data/test/{geos → geos_capi}/tc_zmfactory.rb +2 -2
- data/test/geos_ffi/tc_factory.rb +91 -0
- data/test/geos_ffi/tc_geometry_collection.rb +62 -0
- data/test/geos_ffi/tc_line_string.rb +62 -0
- data/test/geos_ffi/tc_misc.rb +69 -0
- data/test/geos_ffi/tc_multi_line_string.rb +62 -0
- data/test/geos_ffi/tc_multi_point.rb +62 -0
- data/test/geos_ffi/tc_multi_polygon.rb +64 -0
- data/test/geos_ffi/tc_parsing_unparsing.rb +81 -0
- data/test/geos_ffi/tc_point.rb +87 -0
- data/test/geos_ffi/tc_polygon.rb +86 -0
- data/test/geos_ffi/tc_zmfactory.rb +86 -0
- data/test/tc_mixins.rb +188 -0
- data/test/tc_types.rb +77 -0
- metadata +54 -25
@@ -100,6 +100,9 @@ module RGeo
|
|
100
100
|
alias_method :lat, :y
|
101
101
|
|
102
102
|
|
103
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Point).include_in_class(self, true)
|
104
|
+
|
105
|
+
|
103
106
|
end
|
104
107
|
|
105
108
|
|
@@ -113,6 +116,9 @@ module RGeo
|
|
113
116
|
include SphericalLineStringMethods
|
114
117
|
|
115
118
|
|
119
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::LineString).include_in_class(self, true)
|
120
|
+
|
121
|
+
|
116
122
|
end
|
117
123
|
|
118
124
|
|
@@ -127,6 +133,9 @@ module RGeo
|
|
127
133
|
include SphericalLineStringMethods
|
128
134
|
|
129
135
|
|
136
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Line).include_in_class(self, true)
|
137
|
+
|
138
|
+
|
130
139
|
end
|
131
140
|
|
132
141
|
|
@@ -141,6 +150,9 @@ module RGeo
|
|
141
150
|
include SphericalLineStringMethods
|
142
151
|
|
143
152
|
|
153
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::LinearRing).include_in_class(self, true)
|
154
|
+
|
155
|
+
|
144
156
|
end
|
145
157
|
|
146
158
|
|
@@ -153,6 +165,9 @@ module RGeo
|
|
153
165
|
include SphericalGeometryMethods
|
154
166
|
|
155
167
|
|
168
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Polygon).include_in_class(self, true)
|
169
|
+
|
170
|
+
|
156
171
|
end
|
157
172
|
|
158
173
|
|
@@ -165,45 +180,57 @@ module RGeo
|
|
165
180
|
include SphericalGeometryMethods
|
166
181
|
|
167
182
|
|
183
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::GeometryCollection).include_in_class(self, true)
|
184
|
+
|
185
|
+
|
168
186
|
end
|
169
187
|
|
170
188
|
|
171
189
|
class SphericalMultiPointImpl # :nodoc:
|
172
190
|
|
173
191
|
|
174
|
-
include Feature::
|
192
|
+
include Feature::MultiPoint
|
175
193
|
include ImplHelper::BasicGeometryMethods
|
176
194
|
include ImplHelper::BasicGeometryCollectionMethods
|
177
195
|
include ImplHelper::BasicMultiPointMethods
|
178
196
|
include SphericalGeometryMethods
|
179
197
|
|
180
198
|
|
199
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPoint).include_in_class(self, true)
|
200
|
+
|
201
|
+
|
181
202
|
end
|
182
203
|
|
183
204
|
|
184
205
|
class SphericalMultiLineStringImpl # :nodoc:
|
185
206
|
|
186
207
|
|
187
|
-
include Feature::
|
208
|
+
include Feature::MultiLineString
|
188
209
|
include ImplHelper::BasicGeometryMethods
|
189
210
|
include ImplHelper::BasicGeometryCollectionMethods
|
190
211
|
include ImplHelper::BasicMultiLineStringMethods
|
191
212
|
include SphericalGeometryMethods
|
192
213
|
|
193
214
|
|
215
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self, true)
|
216
|
+
|
217
|
+
|
194
218
|
end
|
195
219
|
|
196
220
|
|
197
221
|
class SphericalMultiPolygonImpl # :nodoc:
|
198
222
|
|
199
223
|
|
200
|
-
include Feature::
|
224
|
+
include Feature::MultiPolygon
|
201
225
|
include ImplHelper::BasicGeometryMethods
|
202
226
|
include ImplHelper::BasicGeometryCollectionMethods
|
203
227
|
include ImplHelper::BasicMultiPolygonMethods
|
204
228
|
include SphericalGeometryMethods
|
205
229
|
|
206
230
|
|
231
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPolygon).include_in_class(self, true)
|
232
|
+
|
233
|
+
|
207
234
|
end
|
208
235
|
|
209
236
|
|
data/lib/rgeo/geos.rb
CHANGED
@@ -68,5 +68,27 @@ begin
|
|
68
68
|
require 'rgeo/geos/geos_c_impl'
|
69
69
|
rescue ::LoadError; end
|
70
70
|
require 'rgeo/geos/impl_additions'
|
71
|
+
require 'rgeo/geos/ffi_factory'
|
72
|
+
require 'rgeo/geos/ffi_classes'
|
71
73
|
require 'rgeo/geos/zm_factory'
|
72
74
|
require 'rgeo/geos/zm_impl'
|
75
|
+
|
76
|
+
# :stopdoc:
|
77
|
+
|
78
|
+
# Determine native interface support.
|
79
|
+
begin
|
80
|
+
require 'ffi-geos'
|
81
|
+
::RGeo::Geos::FFI_SUPPORTED = true
|
82
|
+
rescue ::LoadError
|
83
|
+
::RGeo::Geos::FFI_SUPPORTED = false
|
84
|
+
rescue
|
85
|
+
::RGeo::Geos::FFI_SUPPORTED = false
|
86
|
+
end
|
87
|
+
::RGeo::Geos::CAPI_SUPPORTED = ::RGeo::Geos::Factory.respond_to?(:_create) ? true : false
|
88
|
+
if ::RGeo::Geos::CAPI_SUPPORTED
|
89
|
+
::RGeo::Geos.preferred_native_interface = :capi
|
90
|
+
elsif ::RGeo::Geos::FFI_SUPPORTED
|
91
|
+
::RGeo::Geos.preferred_native_interface = :ffi
|
92
|
+
end
|
93
|
+
|
94
|
+
# :startdoc:
|
data/lib/rgeo/geos/factory.rb
CHANGED
@@ -39,7 +39,7 @@ module RGeo
|
|
39
39
|
module Geos
|
40
40
|
|
41
41
|
|
42
|
-
# This the GEOS implementation of ::RGeo::Feature::Factory.
|
42
|
+
# This the GEOS CAPI implementation of ::RGeo::Feature::Factory.
|
43
43
|
|
44
44
|
class Factory
|
45
45
|
|
@@ -50,8 +50,8 @@ module RGeo
|
|
50
50
|
class << self
|
51
51
|
|
52
52
|
|
53
|
-
# Create a new factory. Returns nil if the GEOS implementation
|
54
|
-
# not supported.
|
53
|
+
# Create a new factory. Returns nil if the GEOS CAPI implementation
|
54
|
+
# is not supported.
|
55
55
|
#
|
56
56
|
# See ::RGeo::Geos.factory for a list of supported options.
|
57
57
|
|
@@ -61,7 +61,7 @@ module RGeo
|
|
61
61
|
|
62
62
|
# Get flags to pass to the C extension
|
63
63
|
flags_ = 0
|
64
|
-
flags_ |= 1 if opts_[:lenient_multi_polygon_assertions]
|
64
|
+
flags_ |= 1 if opts_[:lenient_multi_polygon_assertions] || opts_[:uses_lenient_multi_polygon_assertions]
|
65
65
|
flags_ |= 2 if opts_[:has_z_coordinate]
|
66
66
|
flags_ |= 4 if opts_[:has_m_coordinate]
|
67
67
|
if flags_ & 6 == 6
|
@@ -163,7 +163,9 @@ module RGeo
|
|
163
163
|
# Factory equivalence test.
|
164
164
|
|
165
165
|
def eql?(rhs_)
|
166
|
-
rhs_.is_a?(Factory) && rhs_.srid == _srid &&
|
166
|
+
rhs_.is_a?(Factory) && rhs_.srid == _srid &&
|
167
|
+
rhs_._buffer_resolution == _buffer_resolution && rhs_._flags == _flags &&
|
168
|
+
rhs_.proj4 == @proj4
|
167
169
|
end
|
168
170
|
alias_method :==, :eql?
|
169
171
|
|
@@ -200,6 +202,10 @@ module RGeo
|
|
200
202
|
_flags & 0x4 != 0
|
201
203
|
when :is_cartesian
|
202
204
|
true
|
205
|
+
when :uses_lenient_multi_polygon_assertions
|
206
|
+
_flags & 0x1 != 0
|
207
|
+
when :buffer_resolution
|
208
|
+
_buffer_resolution
|
203
209
|
else
|
204
210
|
nil
|
205
211
|
end
|
@@ -0,0 +1,655 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# FFI-GEOS geometry implementation
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
module Geos
|
40
|
+
|
41
|
+
|
42
|
+
module FFIUtils # :nodoc:
|
43
|
+
|
44
|
+
class << self
|
45
|
+
|
46
|
+
|
47
|
+
def coord_seqs_equal?(cs1_, cs2_, check_z_)
|
48
|
+
len1_ = cs1_.length
|
49
|
+
len2_ = cs2_.length
|
50
|
+
if len1_ == len2_
|
51
|
+
(0...len1_).each do |i_|
|
52
|
+
return false unless cs1_.get_x(i_) == cs2_.get_x(i_) &&
|
53
|
+
cs1_.get_y(i_) == cs2_.get_y(i_) &&
|
54
|
+
(!check_z_ || cs1_.get_z(i_) == cs2_.get_z(i_))
|
55
|
+
end
|
56
|
+
true
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def compute_dimension(geom_)
|
64
|
+
result_ = -1
|
65
|
+
case geom_.type_id
|
66
|
+
when ::Geos::GeomTypes::GEOS_POINT
|
67
|
+
result_ = 0
|
68
|
+
when ::Geos::GeomTypes::GEOS_MULTIPOINT
|
69
|
+
result_ = 0 unless geom_.empty?
|
70
|
+
when ::Geos::GeomTypes::GEOS_LINESTRING, ::Geos::GeomTypes::GEOS_LINEARRING
|
71
|
+
result_ = 1
|
72
|
+
when ::Geos::GeomTypes::GEOS_MULTILINESTRING
|
73
|
+
result_ = 1 unless geom_.empty?
|
74
|
+
when ::Geos::GeomTypes::GEOS_POLYGON
|
75
|
+
result_ = 2
|
76
|
+
when ::Geos::GeomTypes::GEOS_MULTIPOLYGON
|
77
|
+
result_ = 2 unless geom_.empty?
|
78
|
+
when ::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION
|
79
|
+
geom_.each do |g_|
|
80
|
+
dim_ = compute_dimension(g_)
|
81
|
+
result_ = dim_ if result_ < dim_
|
82
|
+
end
|
83
|
+
end
|
84
|
+
result_
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
class FFIGeometryImpl # :nodoc:
|
94
|
+
|
95
|
+
include Feature::Instance
|
96
|
+
|
97
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Geometry).include_in_class(self)
|
98
|
+
|
99
|
+
|
100
|
+
def initialize(factory_, fg_geom_, klasses_)
|
101
|
+
@factory = factory_
|
102
|
+
@fg_geom = fg_geom_
|
103
|
+
@_klasses = klasses_
|
104
|
+
fg_geom_.srid = factory_.srid
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def inspect
|
109
|
+
"#<#{self.class}:0x#{object_id.to_s(16)} #{as_text.inspect}>"
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
attr_reader :factory
|
114
|
+
attr_reader :fg_geom
|
115
|
+
|
116
|
+
attr_reader :_klasses # :nodoc:
|
117
|
+
|
118
|
+
|
119
|
+
def initialize_copy(orig_)
|
120
|
+
@factory = orig_.factory
|
121
|
+
@fg_geom = orig_.fg_geom.clone
|
122
|
+
@fg_geom.srid = orig_.fg_geom.srid
|
123
|
+
@_klasses = orig_._klasses
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def srid
|
128
|
+
@fg_geom.srid
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
def dimension
|
133
|
+
FFIUtils.compute_dimension(@fg_geom)
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
def geometry_type
|
138
|
+
Feature::Geometry
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
def envelope
|
143
|
+
fg_geom_ = @fg_geom.envelope
|
144
|
+
# GEOS returns an "empty" point for an empty collection's envelope.
|
145
|
+
# We don't allow that type, so we replace it with an empty collection.
|
146
|
+
if fg_geom_.type_id == ::Geos::GeomTypes::GEOS_POINT && fg_geom_.empty?
|
147
|
+
fg_geom_ = ::Geos::Utils.create_geometry_collection
|
148
|
+
end
|
149
|
+
@factory.wrap_fg_geom(fg_geom_)
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
def boundary
|
154
|
+
if self.class == FFIGeometryCollectionImpl
|
155
|
+
nil
|
156
|
+
else
|
157
|
+
@factory.wrap_fg_geom(@fg_geom.boundary)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def as_text
|
163
|
+
@factory._generate_wkt(self)
|
164
|
+
end
|
165
|
+
alias_method :to_s, :as_text
|
166
|
+
|
167
|
+
|
168
|
+
def as_binary
|
169
|
+
@factory._generate_wkb(self)
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
def is_empty?
|
174
|
+
@fg_geom.empty?
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
def is_simple?
|
179
|
+
@fg_geom.simple?
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
def equals?(rhs_)
|
184
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
185
|
+
# GEOS has a bug where empty geometries are not spatially equal
|
186
|
+
# to each other. Work around this case first.
|
187
|
+
return true if fg_.empty? && @fg_geom.empty?
|
188
|
+
fg_ ? @fg_geom.eql?(fg_) : false
|
189
|
+
end
|
190
|
+
alias_method :==, :equals?
|
191
|
+
|
192
|
+
|
193
|
+
def disjoint?(rhs_)
|
194
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
195
|
+
fg_ ? @fg_geom.disjoint?(fg_) : false
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
def intersects?(rhs_)
|
200
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
201
|
+
fg_ ? @fg_geom.intersects?(fg_) : false
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
def touches?(rhs_)
|
206
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
207
|
+
fg_ ? @fg_geom.touches?(fg_) : false
|
208
|
+
end
|
209
|
+
|
210
|
+
|
211
|
+
def crosses?(rhs_)
|
212
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
213
|
+
fg_ ? @fg_geom.crosses?(fg_) : false
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
def within?(rhs_)
|
218
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
219
|
+
fg_ ? @fg_geom.within?(fg_) : false
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
def contains?(rhs_)
|
224
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
225
|
+
fg_ ? @fg_geom.contains?(fg_) : false
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
def overlaps?(rhs_)
|
230
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
231
|
+
fg_ ? @fg_geom.overlaps?(fg_) : false
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
def relate(rhs_, pattern_)
|
236
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
237
|
+
fg_ ? @fg_geom.relate_pattern(fg_, pattern_) : nil
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
def distance(rhs_)
|
242
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
243
|
+
fg_ ? @fg_geom.distance(fg_) : nil
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
def buffer(distance_)
|
248
|
+
@factory.wrap_fg_geom(@fg_geom.buffer(distance_, @factory.buffer_resolution))
|
249
|
+
end
|
250
|
+
|
251
|
+
|
252
|
+
def convex_hull
|
253
|
+
@factory.wrap_fg_geom(@fg_geom.convex_hull)
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
def intersection(rhs_)
|
258
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
259
|
+
fg_ ? @factory.wrap_fg_geom(@fg_geom.intersection(fg_)) : nil
|
260
|
+
end
|
261
|
+
|
262
|
+
|
263
|
+
def union(rhs_)
|
264
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
265
|
+
fg_ ? @factory.wrap_fg_geom(@fg_geom.union(fg_)) : nil
|
266
|
+
end
|
267
|
+
|
268
|
+
|
269
|
+
def difference(rhs_)
|
270
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
271
|
+
fg_ ? @factory.wrap_fg_geom(@fg_geom.difference(fg_)) : nil
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
def sym_difference(rhs_)
|
276
|
+
fg_ = factory._convert_to_fg_geometry(rhs_)
|
277
|
+
fg_ ? @factory.wrap_fg_geom(@fg_geom.sym_difference(fg_)) : nil
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
def _detach_fg_geom # :nodoc:
|
282
|
+
fg_ = @fg_geom
|
283
|
+
@fg_geom = nil
|
284
|
+
fg_
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
|
291
|
+
class FFIPointImpl < FFIGeometryImpl # :nodoc:
|
292
|
+
|
293
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Point).include_in_class(self)
|
294
|
+
|
295
|
+
|
296
|
+
def x
|
297
|
+
@fg_geom.coord_seq.get_x(0)
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
def y
|
302
|
+
@fg_geom.coord_seq.get_y(0)
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
def z
|
307
|
+
if @factory.property(:has_z_coordinate)
|
308
|
+
@fg_geom.coord_seq.get_z(0)
|
309
|
+
else
|
310
|
+
nil
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
|
315
|
+
def m
|
316
|
+
if @factory.property(:has_m_coordinate)
|
317
|
+
@fg_geom.coord_seq.get_z(0)
|
318
|
+
else
|
319
|
+
nil
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
|
324
|
+
def geometry_type
|
325
|
+
Feature::Point
|
326
|
+
end
|
327
|
+
|
328
|
+
|
329
|
+
def eql?(rhs_)
|
330
|
+
rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
|
331
|
+
FFIUtils.coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
|
338
|
+
class FFILineStringImpl < FFIGeometryImpl # :nodoc:
|
339
|
+
|
340
|
+
|
341
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Curve).include_in_class(self)
|
342
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::LineString).include_in_class(self)
|
343
|
+
|
344
|
+
|
345
|
+
def geometry_type
|
346
|
+
Feature::LineString
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
def length
|
351
|
+
@fg_geom.length
|
352
|
+
end
|
353
|
+
|
354
|
+
|
355
|
+
def num_points
|
356
|
+
@fg_geom.num_points
|
357
|
+
end
|
358
|
+
|
359
|
+
|
360
|
+
def point_n(n_)
|
361
|
+
if n_ >= 0 && n_ < @fg_geom.num_points
|
362
|
+
coord_seq_ = @fg_geom.coord_seq
|
363
|
+
x_ = coord_seq_.get_x(n_)
|
364
|
+
y_ = coord_seq_.get_y(n_)
|
365
|
+
extra_ = @factory._has_3d ? [coord_seq_.get_z(n_)] : []
|
366
|
+
@factory.point(x_, y_, *extra_)
|
367
|
+
else
|
368
|
+
nil
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
|
373
|
+
def start_point
|
374
|
+
point_n(0)
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
def end_point
|
379
|
+
point_n(@fg_geom.num_points - 1)
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
def points
|
384
|
+
coord_seq_ = @fg_geom.coord_seq
|
385
|
+
has_3d_ = @factory._has_3d
|
386
|
+
::Array.new(@fg_geom.num_points) do |n_|
|
387
|
+
x_ = coord_seq_.get_x(n_)
|
388
|
+
y_ = coord_seq_.get_y(n_)
|
389
|
+
extra_ = has_3d_ ? [coord_seq_.get_z(n_)] : []
|
390
|
+
@factory.point(x_, y_, *extra_)
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
|
395
|
+
def is_closed?
|
396
|
+
@fg_geom.closed?
|
397
|
+
end
|
398
|
+
|
399
|
+
|
400
|
+
def is_ring?
|
401
|
+
@fg_geom.ring?
|
402
|
+
end
|
403
|
+
|
404
|
+
|
405
|
+
def eql?(rhs_)
|
406
|
+
rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
|
407
|
+
FFIUtils.coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
|
408
|
+
end
|
409
|
+
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
|
414
|
+
class FFILinearRingImpl < FFILineStringImpl # :nodoc:
|
415
|
+
|
416
|
+
|
417
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::LinearRing).include_in_class(self)
|
418
|
+
|
419
|
+
|
420
|
+
def geometry_type
|
421
|
+
Feature::LinearRing
|
422
|
+
end
|
423
|
+
|
424
|
+
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
class FFILineImpl < FFILineStringImpl # :nodoc:
|
429
|
+
|
430
|
+
|
431
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Line).include_in_class(self)
|
432
|
+
|
433
|
+
|
434
|
+
def geometry_type
|
435
|
+
Feature::Line
|
436
|
+
end
|
437
|
+
|
438
|
+
|
439
|
+
end
|
440
|
+
|
441
|
+
|
442
|
+
class FFIPolygonImpl < FFIGeometryImpl # :nodoc:
|
443
|
+
|
444
|
+
|
445
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Surface).include_in_class(self)
|
446
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::Polygon).include_in_class(self)
|
447
|
+
|
448
|
+
|
449
|
+
def geometry_type
|
450
|
+
Feature::Polygon
|
451
|
+
end
|
452
|
+
|
453
|
+
|
454
|
+
def area
|
455
|
+
@fg_geom.area
|
456
|
+
end
|
457
|
+
|
458
|
+
|
459
|
+
def centroid
|
460
|
+
@factory.wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
|
461
|
+
end
|
462
|
+
|
463
|
+
|
464
|
+
def point_on_surface
|
465
|
+
@factory.wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
|
466
|
+
end
|
467
|
+
|
468
|
+
|
469
|
+
def exterior_ring
|
470
|
+
@factory.wrap_fg_geom(@fg_geom.exterior_ring, FFILinearRingImpl)
|
471
|
+
end
|
472
|
+
|
473
|
+
|
474
|
+
def num_interior_rings
|
475
|
+
@fg_geom.num_interior_rings
|
476
|
+
end
|
477
|
+
|
478
|
+
|
479
|
+
def interior_ring_n(n_)
|
480
|
+
if n_ >= 0 && n_ < @fg_geom.num_interior_rings
|
481
|
+
@factory.wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
|
482
|
+
else
|
483
|
+
nil
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
|
488
|
+
def interior_rings
|
489
|
+
::Array.new(@fg_geom.num_interior_rings) do |n_|
|
490
|
+
@factory.wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
|
495
|
+
def eql?(rhs_)
|
496
|
+
if rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
|
497
|
+
rhs_.exterior_ring.eql?(self.exterior_ring)
|
498
|
+
then
|
499
|
+
sn_ = @fg_geom.num_interior_rings
|
500
|
+
rn_ = rhs_.num_interior_rings
|
501
|
+
if sn_ == rn_
|
502
|
+
sn_.times do |i_|
|
503
|
+
return false unless interior_ring_n(i_).eql?(rhs_.interior_ring_n(i_))
|
504
|
+
end
|
505
|
+
return true
|
506
|
+
end
|
507
|
+
end
|
508
|
+
false
|
509
|
+
end
|
510
|
+
|
511
|
+
|
512
|
+
end
|
513
|
+
|
514
|
+
|
515
|
+
class FFIGeometryCollectionImpl < FFIGeometryImpl # :nodoc:
|
516
|
+
|
517
|
+
|
518
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::GeometryCollection).include_in_class(self)
|
519
|
+
|
520
|
+
|
521
|
+
def geometry_type
|
522
|
+
Feature::GeometryCollection
|
523
|
+
end
|
524
|
+
|
525
|
+
|
526
|
+
def eql?(rhs_)
|
527
|
+
if rhs_.class == self.class && rhs_.factory.eql?(@factory)
|
528
|
+
size_ = @fg_geom.num_geometries
|
529
|
+
if size_ == rhs_.num_geometries
|
530
|
+
size_.times do |n_|
|
531
|
+
return false unless geometry_n(n_).eql?(rhs_.geometry_n(n_))
|
532
|
+
end
|
533
|
+
return true
|
534
|
+
end
|
535
|
+
end
|
536
|
+
false
|
537
|
+
end
|
538
|
+
|
539
|
+
|
540
|
+
def num_geometries
|
541
|
+
@fg_geom.num_geometries
|
542
|
+
end
|
543
|
+
alias_method :size, :num_geometries
|
544
|
+
|
545
|
+
|
546
|
+
def geometry_n(n_)
|
547
|
+
if n_ >= 0 && n_ < @fg_geom.num_geometries
|
548
|
+
@factory.wrap_fg_geom(@fg_geom.get_geometry_n(n_),
|
549
|
+
@_klasses ? @_klasses[n_] : nil)
|
550
|
+
else
|
551
|
+
nil
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
|
556
|
+
def [](n_)
|
557
|
+
n_ += @fg_geom.num_geometries if n_ < 0
|
558
|
+
if n_ >= 0 && n_ < @fg_geom.num_geometries
|
559
|
+
@factory.wrap_fg_geom(@fg_geom.get_geometry_n(n_),
|
560
|
+
@_klasses ? @_klasses[n_] : nil)
|
561
|
+
else
|
562
|
+
nil
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
|
567
|
+
def each
|
568
|
+
@fg_geom.num_geometries.times do |n_|
|
569
|
+
yield @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n_),
|
570
|
+
@_klasses ? @_klasses[n_] : nil)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
include ::Enumerable
|
575
|
+
|
576
|
+
|
577
|
+
end
|
578
|
+
|
579
|
+
|
580
|
+
class FFIMultiPointImpl < FFIGeometryCollectionImpl # :nodoc:
|
581
|
+
|
582
|
+
|
583
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPoint).include_in_class(self)
|
584
|
+
|
585
|
+
|
586
|
+
def geometry_type
|
587
|
+
Feature::MultiPoint
|
588
|
+
end
|
589
|
+
|
590
|
+
|
591
|
+
end
|
592
|
+
|
593
|
+
|
594
|
+
class FFIMultiLineStringImpl < FFIGeometryCollectionImpl # :nodoc:
|
595
|
+
|
596
|
+
|
597
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiCurve).include_in_class(self)
|
598
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self)
|
599
|
+
|
600
|
+
|
601
|
+
def geometry_type
|
602
|
+
Feature::MultiLineString
|
603
|
+
end
|
604
|
+
|
605
|
+
|
606
|
+
def length
|
607
|
+
@fg_geom.length
|
608
|
+
end
|
609
|
+
|
610
|
+
|
611
|
+
def is_closed?
|
612
|
+
size_ = num_geometries
|
613
|
+
size_.times do |n_|
|
614
|
+
return false unless @fg_geom.get_geometry_n(n_).closed?
|
615
|
+
end
|
616
|
+
true
|
617
|
+
end
|
618
|
+
|
619
|
+
|
620
|
+
end
|
621
|
+
|
622
|
+
|
623
|
+
class FFIMultiPolygonImpl < FFIGeometryCollectionImpl # :nodoc:
|
624
|
+
|
625
|
+
|
626
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiSurface).include_in_class(self)
|
627
|
+
Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPolygon).include_in_class(self)
|
628
|
+
|
629
|
+
|
630
|
+
def geometry_type
|
631
|
+
Feature::MultiPolygon
|
632
|
+
end
|
633
|
+
|
634
|
+
|
635
|
+
def area
|
636
|
+
@fg_geom.area
|
637
|
+
end
|
638
|
+
|
639
|
+
|
640
|
+
def centroid
|
641
|
+
@factory.wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
|
642
|
+
end
|
643
|
+
|
644
|
+
|
645
|
+
def point_on_surface
|
646
|
+
@factory.wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
|
647
|
+
end
|
648
|
+
|
649
|
+
|
650
|
+
end
|
651
|
+
|
652
|
+
|
653
|
+
end
|
654
|
+
|
655
|
+
end
|