rgeo 3.0.0.pre.rc.3 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -0
- data/ext/geos_c_impl/factory.c +41 -5
- data/ext/geos_c_impl/factory.h +13 -2
- data/ext/geos_c_impl/geometry.c +151 -122
- data/ext/geos_c_impl/geometry_collection.c +17 -19
- data/ext/geos_c_impl/line_string.c +46 -36
- data/ext/geos_c_impl/point.c +0 -2
- data/ext/geos_c_impl/polygon.c +10 -11
- data/ext/geos_c_impl/polygon.h +1 -1
- data/ext/geos_c_impl/ruby_more.c +7 -0
- data/ext/geos_c_impl/ruby_more.h +8 -0
- data/lib/rgeo/cartesian/analysis.rb +5 -3
- data/lib/rgeo/cartesian/bounding_box.rb +74 -79
- data/lib/rgeo/cartesian/calculations.rb +20 -26
- data/lib/rgeo/cartesian/factory.rb +47 -49
- data/lib/rgeo/cartesian/planar_graph.rb +10 -16
- data/lib/rgeo/cartesian/sweepline_intersector.rb +1 -3
- data/lib/rgeo/cartesian/valid_op.rb +1 -3
- data/lib/rgeo/coord_sys/cs/entities.rb +87 -101
- data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +70 -29
- data/lib/rgeo/feature/curve.rb +0 -1
- data/lib/rgeo/feature/factory.rb +25 -27
- data/lib/rgeo/feature/factory_generator.rb +3 -4
- data/lib/rgeo/feature/geometry.rb +41 -30
- data/lib/rgeo/feature/geometry_collection.rb +3 -4
- data/lib/rgeo/feature/line_string.rb +1 -2
- data/lib/rgeo/feature/linear_ring.rb +0 -1
- data/lib/rgeo/feature/multi_curve.rb +0 -1
- data/lib/rgeo/feature/multi_surface.rb +0 -1
- data/lib/rgeo/feature/point.rb +0 -1
- data/lib/rgeo/feature/polygon.rb +1 -2
- data/lib/rgeo/feature/surface.rb +0 -1
- data/lib/rgeo/feature/types.rb +73 -83
- data/lib/rgeo/geographic/factory.rb +87 -80
- data/lib/rgeo/geographic/interface.rb +40 -23
- data/lib/rgeo/geographic/projected_feature_methods.rb +2 -6
- data/lib/rgeo/geographic/projected_window.rb +35 -21
- data/lib/rgeo/geographic/simple_mercator_projector.rb +25 -13
- data/lib/rgeo/geographic/spherical_feature_methods.rb +8 -3
- data/lib/rgeo/geographic/spherical_math.rb +17 -20
- data/lib/rgeo/geos/capi_factory.rb +50 -50
- data/lib/rgeo/geos/ffi_factory.rb +41 -42
- data/lib/rgeo/geos/ffi_feature_methods.rb +72 -97
- data/lib/rgeo/geos/interface.rb +16 -16
- data/lib/rgeo/geos/utils.rb +3 -3
- data/lib/rgeo/geos/zm_factory.rb +50 -42
- data/lib/rgeo/geos/zm_feature_methods.rb +15 -8
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +4 -4
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +18 -24
- data/lib/rgeo/impl_helper/basic_point_methods.rb +1 -3
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +15 -16
- data/lib/rgeo/impl_helper/utils.rb +3 -9
- data/lib/rgeo/impl_helper/valid_op.rb +12 -16
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +42 -47
- data/lib/rgeo/wkrep/wkb_parser.rb +17 -18
- data/lib/rgeo/wkrep/wkt_generator.rb +23 -16
- data/lib/rgeo/wkrep/wkt_parser.rb +23 -13
- metadata +5 -5
@@ -28,7 +28,6 @@ module RGeo
|
|
28
28
|
# include this module itself. Therefore, you should not depend on the
|
29
29
|
# kind_of? method to check type. Instead, use the provided check_type
|
30
30
|
# class method (or === operator) defined in the Type module.
|
31
|
-
|
32
31
|
module MultiSurface
|
33
32
|
include GeometryCollection
|
34
33
|
extend Type
|
data/lib/rgeo/feature/point.rb
CHANGED
data/lib/rgeo/feature/polygon.rb
CHANGED
@@ -45,7 +45,6 @@ module RGeo
|
|
45
45
|
# include this module itself. Therefore, you should not depend on the
|
46
46
|
# kind_of? method to check type. Instead, use the provided check_type
|
47
47
|
# class method (or === operator) defined in the Type module.
|
48
|
-
|
49
48
|
module Polygon
|
50
49
|
include Surface
|
51
50
|
extend Type
|
@@ -84,7 +83,7 @@ module RGeo
|
|
84
83
|
# if the given N is out of range. N is zero-based.
|
85
84
|
# Does not support negative indexes.
|
86
85
|
|
87
|
-
def interior_ring_n(
|
86
|
+
def interior_ring_n(_idx)
|
88
87
|
raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined."
|
89
88
|
end
|
90
89
|
|
data/lib/rgeo/feature/surface.rb
CHANGED
data/lib/rgeo/feature/types.rb
CHANGED
@@ -11,7 +11,6 @@ module RGeo
|
|
11
11
|
# All geometry implementations MUST include this submodule.
|
12
12
|
# This serves as a marker that may be used to test an object for
|
13
13
|
# feature-ness.
|
14
|
-
|
15
14
|
module Instance
|
16
15
|
end
|
17
16
|
|
@@ -49,7 +48,6 @@ module RGeo
|
|
49
48
|
# a particular object is a feature type:
|
50
49
|
#
|
51
50
|
# RGeo::Feature::Type === object.geometry_type # true
|
52
|
-
|
53
51
|
module Type
|
54
52
|
# Returns true if the given object is this type or a subtype
|
55
53
|
# thereof, or if it is a feature object whose geometry_type is
|
@@ -192,92 +190,84 @@ module RGeo
|
|
192
190
|
# Types are the same
|
193
191
|
if nfactory == factory
|
194
192
|
force_new ? obj.dup : obj
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
ncs = nfactory.coord_sys
|
201
|
-
end
|
202
|
-
hasz = factory.property(:has_z_coordinate)
|
203
|
-
nhasz = nfactory.property(:has_z_coordinate)
|
204
|
-
if cs && ncs
|
205
|
-
coords = cs.transform_coords(ncs, obj.x, obj.y, hasz ? obj.z : nil)
|
206
|
-
coords << (hasz ? obj.z : 0.0) if nhasz && coords.size < 3
|
207
|
-
else
|
208
|
-
coords = [obj.x, obj.y]
|
209
|
-
coords << (hasz ? obj.z : 0.0) if nhasz
|
210
|
-
end
|
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) })
|
230
|
-
end
|
231
|
-
end
|
232
|
-
else
|
233
|
-
# Types are different
|
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)
|
239
|
-
end
|
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))
|
245
|
-
end
|
246
|
-
elsif ntype == LinearRing
|
247
|
-
if type == LineString
|
248
|
-
nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) })
|
249
|
-
end
|
250
|
-
elsif ntype == LineString
|
251
|
-
if type == Line || type == LinearRing
|
252
|
-
nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) })
|
193
|
+
elsif type == Point
|
194
|
+
cs = ncs = nil
|
195
|
+
if project
|
196
|
+
cs = factory.coord_sys
|
197
|
+
ncs = nfactory.coord_sys
|
253
198
|
end
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
end
|
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) })
|
265
|
-
end
|
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) })
|
271
|
-
end
|
272
|
-
elsif ntype == GeometryCollection
|
273
|
-
if type == MultiPoint || type == MultiLineString || type == MultiPolygon
|
274
|
-
nfactory.collection(obj.map { |p| cast(p, nfactory, opts) })
|
199
|
+
hasz = factory.property(:has_z_coordinate)
|
200
|
+
nhasz = nfactory.property(:has_z_coordinate)
|
201
|
+
if cs && ncs
|
202
|
+
coords = cs.transform_coords(ncs, obj.x, obj.y, hasz ? obj.z : nil)
|
203
|
+
coords << (hasz ? obj.z : 0.0) if nhasz && coords.size < 3
|
275
204
|
else
|
276
|
-
|
205
|
+
coords = [obj.x, obj.y]
|
206
|
+
coords << (hasz ? obj.z : 0.0) if nhasz
|
277
207
|
end
|
208
|
+
coords << (factory.property(:has_m_coordinate) ? obj.m : 0.0) if nfactory.property(:has_m_coordinate)
|
209
|
+
nfactory.point(*coords)
|
210
|
+
elsif type == Line
|
211
|
+
nfactory.line(cast(obj.start_point, nfactory, opts), cast(obj.end_point, nfactory, opts))
|
212
|
+
elsif type == LinearRing
|
213
|
+
nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) })
|
214
|
+
elsif type == LineString
|
215
|
+
nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) })
|
216
|
+
elsif type == Polygon
|
217
|
+
nfactory.polygon(
|
218
|
+
cast(obj.exterior_ring, nfactory, opts),
|
219
|
+
obj.interior_rings.map { |r| cast(r, nfactory, opts) }
|
220
|
+
)
|
221
|
+
elsif type == MultiPoint
|
222
|
+
nfactory.multi_point(obj.map { |g| cast(g, nfactory, opts) })
|
223
|
+
elsif type == MultiLineString
|
224
|
+
nfactory.multi_line_string(obj.map { |g| cast(g, nfactory, opts) })
|
225
|
+
elsif type == MultiPolygon
|
226
|
+
nfactory.multi_polygon(obj.map { |g| cast(g, nfactory, opts) })
|
227
|
+
elsif type == GeometryCollection
|
228
|
+
nfactory.collection(obj.map { |g| cast(g, nfactory, opts) })
|
229
|
+
end
|
230
|
+
# Types are different
|
231
|
+
elsif ntype == Point && [MultiPoint, GeometryCollection].include?(type) ||
|
232
|
+
[Line, LineString, LinearRing].include?(ntype) && [MultiLineString, GeometryCollection].include?(type) ||
|
233
|
+
ntype == Polygon && [MultiPolygon, GeometryCollection].include?(type)
|
234
|
+
cast(obj.geometry_n(0), nfactory, ntype, opts) if obj.num_geometries == 1
|
235
|
+
elsif ntype == Point
|
236
|
+
raise(Error::InvalidGeometry, "Cannot cast to Point")
|
237
|
+
elsif ntype == Line
|
238
|
+
if type == LineString && obj.num_points == 2
|
239
|
+
nfactory.line(cast(obj.point_n(0), nfactory, opts), cast(obj.point_n(1), nfactory, opts))
|
240
|
+
end
|
241
|
+
elsif ntype == LinearRing
|
242
|
+
nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) if type == LineString
|
243
|
+
elsif ntype == LineString
|
244
|
+
nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) if [Line, LinearRing].include?(type)
|
245
|
+
elsif ntype == MultiPoint
|
246
|
+
if type == Point
|
247
|
+
nfactory.multi_point([cast(obj, nfactory, opts)])
|
248
|
+
elsif type == GeometryCollection
|
249
|
+
nfactory.multi_point(obj.map { |p| cast(p, nfactory, opts) })
|
250
|
+
end
|
251
|
+
elsif ntype == MultiLineString
|
252
|
+
if [Line, LinearRing, LineString].include?(type)
|
253
|
+
nfactory.multi_line_string([cast(obj, nfactory, opts)])
|
254
|
+
elsif type == GeometryCollection
|
255
|
+
nfactory.multi_line_string(obj.map { |p| cast(p, nfactory, opts) })
|
256
|
+
end
|
257
|
+
elsif ntype == MultiPolygon
|
258
|
+
if type == Polygon
|
259
|
+
nfactory.multi_polygon([cast(obj, nfactory, opts)])
|
260
|
+
elsif type == GeometryCollection
|
261
|
+
nfactory.multi_polygon(obj.map { |p| cast(p, nfactory, opts) })
|
262
|
+
end
|
263
|
+
elsif ntype == GeometryCollection
|
264
|
+
if [MultiPoint, MultiLineString, MultiPolygon].include?(type)
|
265
|
+
nfactory.collection(obj.map { |p| cast(p, nfactory, opts) })
|
278
266
|
else
|
279
|
-
|
267
|
+
nfactory.collection([cast(obj, nfactory, opts)])
|
280
268
|
end
|
269
|
+
else
|
270
|
+
raise(RGeo::Error::InvalidGeometry, "Undefined type cast from #{type.name} to #{ntype.name}")
|
281
271
|
end
|
282
272
|
end
|
283
273
|
end
|
@@ -11,13 +11,20 @@ module RGeo
|
|
11
11
|
# This class implements the various factories for geography features.
|
12
12
|
# See methods of the RGeo::Geographic module for the API for creating
|
13
13
|
# geography factories.
|
14
|
-
|
15
14
|
class Factory
|
16
15
|
include Feature::Factory::Instance
|
17
16
|
include ImplHelper::Utils
|
18
17
|
|
19
18
|
attr_writer :projector
|
20
19
|
|
20
|
+
attr_reader :coordinate_dimension, :spatial_dimension
|
21
|
+
|
22
|
+
# Returns the srid reported by this factory.
|
23
|
+
attr_reader :srid
|
24
|
+
|
25
|
+
# See RGeo::Feature::Factory#coord_sys
|
26
|
+
attr_reader :coord_sys
|
27
|
+
|
21
28
|
def initialize(impl_prefix, opts = {}) # :nodoc:
|
22
29
|
@impl_prefix = impl_prefix
|
23
30
|
@point_class = Geographic.const_get("#{impl_prefix}PointImpl")
|
@@ -45,45 +52,48 @@ module RGeo
|
|
45
52
|
@buffer_resolution = 1 if @buffer_resolution < 1
|
46
53
|
|
47
54
|
wkt_generator = opts[:wkt_generator]
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
55
|
+
@wkt_generator =
|
56
|
+
case wkt_generator
|
57
|
+
when Hash
|
58
|
+
WKRep::WKTGenerator.new(wkt_generator)
|
59
|
+
else
|
60
|
+
WKRep::WKTGenerator.new(convert_case: :upper)
|
61
|
+
end
|
54
62
|
wkb_generator = opts[:wkb_generator]
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
63
|
+
@wkb_generator =
|
64
|
+
case wkb_generator
|
65
|
+
when Hash
|
66
|
+
WKRep::WKBGenerator.new(wkb_generator)
|
67
|
+
else
|
68
|
+
WKRep::WKBGenerator.new
|
69
|
+
end
|
61
70
|
wkt_parser = opts[:wkt_parser]
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
71
|
+
@wkt_parser =
|
72
|
+
case wkt_parser
|
73
|
+
when Hash
|
74
|
+
WKRep::WKTParser.new(self, wkt_parser)
|
75
|
+
else
|
76
|
+
WKRep::WKTParser.new(self)
|
77
|
+
end
|
68
78
|
wkb_parser = opts[:wkb_parser]
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
79
|
+
@wkb_parser =
|
80
|
+
case wkb_parser
|
81
|
+
when Hash
|
82
|
+
WKRep::WKBParser.new(self, wkb_parser)
|
83
|
+
else
|
84
|
+
WKRep::WKBParser.new(self)
|
85
|
+
end
|
75
86
|
@projector = nil
|
76
87
|
end
|
77
|
-
attr_reader :coordinate_dimension, :spatial_dimension
|
78
88
|
|
79
89
|
# Equivalence test.
|
80
90
|
|
81
|
-
def eql?(
|
82
|
-
|
83
|
-
@impl_prefix ==
|
84
|
-
@support_z ==
|
85
|
-
@support_m ==
|
86
|
-
@coord_sys ==
|
91
|
+
def eql?(other)
|
92
|
+
other.is_a?(Geographic::Factory) &&
|
93
|
+
@impl_prefix == other.instance_variable_get(:@impl_prefix) &&
|
94
|
+
@support_z == other.instance_variable_get(:@support_z) &&
|
95
|
+
@support_m == other.instance_variable_get(:@support_m) &&
|
96
|
+
@coord_sys == other.instance_variable_get(:@coord_sys)
|
87
97
|
end
|
88
98
|
alias == eql?
|
89
99
|
|
@@ -116,12 +126,11 @@ module RGeo
|
|
116
126
|
end
|
117
127
|
|
118
128
|
def marshal_load(data_) # :nodoc:
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
initialize(data_["pref"],
|
129
|
+
cs_class = CoordSys::CONFIG.default_coord_sys_class
|
130
|
+
coord_sys = data_["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }
|
131
|
+
|
132
|
+
initialize(
|
133
|
+
data_["pref"],
|
125
134
|
has_z_coordinate: data_["hasz"],
|
126
135
|
has_m_coordinate: data_["hasm"],
|
127
136
|
srid: data_["srid"],
|
@@ -132,14 +141,18 @@ module RGeo
|
|
132
141
|
buffer_resolution: data_["bufr"],
|
133
142
|
coord_sys: coord_sys
|
134
143
|
)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
144
|
+
proj_klass = data_["prjc"]
|
145
|
+
proj_factory = data_["prjf"]
|
146
|
+
|
147
|
+
return unless proj_klass && proj_factory
|
148
|
+
|
149
|
+
klass_ = RGeo::Geographic.const_get(proj_klass)
|
150
|
+
|
151
|
+
return unless klass_
|
152
|
+
|
153
|
+
projector = klass_.allocate
|
154
|
+
projector.set_factories(self, proj_factory)
|
155
|
+
@projector = projector
|
143
156
|
end
|
144
157
|
|
145
158
|
# Psych support
|
@@ -155,19 +168,19 @@ module RGeo
|
|
155
168
|
coder["wkb_parser"] = @wkb_parser.properties
|
156
169
|
coder["buffer_resolution"] = @buffer_resolution
|
157
170
|
coder["coord_sys"] = @coord_sys.to_wkt if @coord_sys
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
171
|
+
|
172
|
+
return unless @projector
|
173
|
+
|
174
|
+
coder["projectorclass"] = @projector.class.name.sub(/.*::/, "")
|
175
|
+
coder["projection_factory"] = @projector.projection_factory
|
162
176
|
end
|
163
177
|
|
164
178
|
def init_with(coder) # :nodoc:
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
initialize(coder["impl_prefix"],
|
179
|
+
cs_class = CoordSys::CONFIG.default_coord_sys_class
|
180
|
+
coord_sys = coder["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }
|
181
|
+
|
182
|
+
initialize(
|
183
|
+
coder["impl_prefix"],
|
171
184
|
has_z_coordinate: coder["has_z_coordinate"],
|
172
185
|
has_m_coordinate: coder["has_m_coordinate"],
|
173
186
|
srid: coder["srid"],
|
@@ -178,19 +191,19 @@ module RGeo
|
|
178
191
|
buffer_resolution: coder["buffer_resolution"],
|
179
192
|
coord_sys: coord_sys
|
180
193
|
)
|
181
|
-
|
182
|
-
|
183
|
-
if klass_
|
184
|
-
projector = klass_.allocate
|
185
|
-
projector.set_factories(self, proj_factory)
|
186
|
-
@projector = projector
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
194
|
+
proj_klass = coder["projectorclass"]
|
195
|
+
proj_factory = coder["projection_factory"]
|
190
196
|
|
191
|
-
|
197
|
+
return unless proj_klass && proj_factory
|
192
198
|
|
193
|
-
|
199
|
+
klass_ = RGeo::Geographic.const_get(proj_klass)
|
200
|
+
|
201
|
+
return unless klass_
|
202
|
+
|
203
|
+
projector = klass_.allocate
|
204
|
+
projector.set_factories(self, proj_factory)
|
205
|
+
@projector = projector
|
206
|
+
end
|
194
207
|
|
195
208
|
# Returns true if this factory supports a projection.
|
196
209
|
|
@@ -213,9 +226,7 @@ module RGeo
|
|
213
226
|
|
214
227
|
def project(geometry)
|
215
228
|
return unless @projector && geometry
|
216
|
-
unless geometry.factory == self
|
217
|
-
raise Error::InvalidGeometry, "Wrong geometry type"
|
218
|
-
end
|
229
|
+
raise Error::InvalidGeometry, "Wrong geometry type" unless geometry.factory == self
|
219
230
|
@projector.project(geometry)
|
220
231
|
end
|
221
232
|
|
@@ -226,9 +237,11 @@ module RGeo
|
|
226
237
|
|
227
238
|
def unproject(geometry)
|
228
239
|
return unless geometry
|
240
|
+
|
229
241
|
unless @projector && @projector.projection_factory == geometry.factory
|
230
242
|
raise Error::InvalidGeometry, "You can unproject only features that are in the projected coordinate space."
|
231
243
|
end
|
244
|
+
|
232
245
|
@projector.unproject(geometry)
|
233
246
|
end
|
234
247
|
|
@@ -249,12 +262,10 @@ module RGeo
|
|
249
262
|
# projection limits are not known.
|
250
263
|
|
251
264
|
def projection_limits_window
|
252
|
-
if @
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
@projection_limits_window
|
257
|
-
end
|
265
|
+
return @projection_limits_window if defined?(@projection_limits_window)
|
266
|
+
return unless @projector
|
267
|
+
|
268
|
+
@projection_limits_window = @projector.limits_window
|
258
269
|
end
|
259
270
|
|
260
271
|
# See RGeo::Feature::Factory#property
|
@@ -338,10 +349,6 @@ module RGeo
|
|
338
349
|
@multi_polygon_class.new(self, elems)
|
339
350
|
end
|
340
351
|
|
341
|
-
# See RGeo::Feature::Factory#coord_sys
|
342
|
-
|
343
|
-
attr_reader :coord_sys
|
344
|
-
|
345
352
|
def generate_wkt(obj)
|
346
353
|
@wkt_generator.generate(obj)
|
347
354
|
end
|
@@ -102,7 +102,8 @@ module RGeo
|
|
102
102
|
coord_sys = opts[:coord_sys]
|
103
103
|
srid = opts[:srid]
|
104
104
|
srid ||= coord_sys.authority_code if coord_sys
|
105
|
-
Geographic::Factory.new(
|
105
|
+
Geographic::Factory.new(
|
106
|
+
"Spherical",
|
106
107
|
has_z_coordinate: opts[:has_z_coordinate],
|
107
108
|
has_m_coordinate: opts[:has_m_coordinate],
|
108
109
|
coord_sys: coord_sys || coord_sys_4055,
|
@@ -111,7 +112,8 @@ module RGeo
|
|
111
112
|
wkb_parser: opts[:wkb_parser],
|
112
113
|
wkt_generator: opts[:wkt_generator],
|
113
114
|
wkb_generator: opts[:wkb_generator],
|
114
|
-
srid: (srid || 4055).to_i
|
115
|
+
srid: (srid || 4055).to_i
|
116
|
+
)
|
115
117
|
end
|
116
118
|
|
117
119
|
# Creates and returns a geographic factory that is designed for
|
@@ -185,7 +187,8 @@ module RGeo
|
|
185
187
|
# options. See RGeo::Geos.factory for more details.
|
186
188
|
|
187
189
|
def simple_mercator_factory(opts = {})
|
188
|
-
factory = Geographic::Factory.new(
|
190
|
+
factory = Geographic::Factory.new(
|
191
|
+
"Projected",
|
189
192
|
coord_sys: coord_sys_4326,
|
190
193
|
srid: 4326,
|
191
194
|
wkt_parser: opts[:wkt_parser],
|
@@ -193,11 +196,14 @@ module RGeo
|
|
193
196
|
wkt_generator: opts[:wkt_generator],
|
194
197
|
wkb_generator: opts[:wkb_generator],
|
195
198
|
has_z_coordinate: opts[:has_z_coordinate],
|
196
|
-
has_m_coordinate: opts[:has_m_coordinate]
|
197
|
-
|
199
|
+
has_m_coordinate: opts[:has_m_coordinate]
|
200
|
+
)
|
201
|
+
projector = Geographic::SimpleMercatorProjector.new(
|
202
|
+
factory,
|
198
203
|
buffer_resolution: opts[:buffer_resolution],
|
199
204
|
has_z_coordinate: opts[:has_z_coordinate],
|
200
|
-
has_m_coordinate: opts[:has_m_coordinate]
|
205
|
+
has_m_coordinate: opts[:has_m_coordinate]
|
206
|
+
)
|
201
207
|
factory.projector = projector
|
202
208
|
factory
|
203
209
|
end
|
@@ -306,6 +312,7 @@ module RGeo
|
|
306
312
|
if projection_coord_sys && !projection_coord_sys.projected?
|
307
313
|
raise ArgumentError, "The :projection_factory's coord_sys is not a ProjectedCoordinateSystem."
|
308
314
|
end
|
315
|
+
|
309
316
|
# Determine geographic coordinate system. First check parameters.
|
310
317
|
coord_sys = opts[:coord_sys]
|
311
318
|
srid = opts[:srid]
|
@@ -314,18 +321,26 @@ module RGeo
|
|
314
321
|
srid ||= coord_sys.authority_code if coord_sys
|
315
322
|
srid ||= 4326
|
316
323
|
# Now we should have all the coordinate system info.
|
317
|
-
factory = Geographic::Factory.new(
|
324
|
+
factory = Geographic::Factory.new(
|
325
|
+
"Projected",
|
318
326
|
coord_sys: coord_sys,
|
319
327
|
srid: srid.to_i,
|
320
328
|
has_z_coordinate: projection_factory.property(:has_z_coordinate),
|
321
329
|
has_m_coordinate: projection_factory.property(:has_m_coordinate),
|
322
330
|
wkt_parser: opts[:wkt_parser], wkt_generator: opts[:wkt_generator],
|
323
|
-
wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]
|
324
|
-
|
325
|
-
|
331
|
+
wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]
|
332
|
+
)
|
333
|
+
projector = Geographic::Projector.create_from_existing_factory(
|
334
|
+
factory,
|
335
|
+
projection_factory
|
336
|
+
)
|
326
337
|
else
|
327
338
|
# Determine projection coordinate system. First check the parameters.
|
328
|
-
projection_coord_sys_info = ImplHelper::Utils.setup_coord_sys(
|
339
|
+
projection_coord_sys_info = ImplHelper::Utils.setup_coord_sys(
|
340
|
+
opts[:projection_srid],
|
341
|
+
opts[:projection_coord_sys],
|
342
|
+
opts[:projection_coord_sys_class]
|
343
|
+
)
|
329
344
|
projection_coord_sys = projection_coord_sys_info[:coord_sys]
|
330
345
|
projection_srid = projection_coord_sys_info[:srid]
|
331
346
|
|
@@ -338,21 +353,25 @@ module RGeo
|
|
338
353
|
srid ||= coord_sys.authority_code if coord_sys
|
339
354
|
srid ||= 4326
|
340
355
|
# Now we should have all the coordinate system info.
|
341
|
-
factory = Geographic::Factory.new(
|
356
|
+
factory = Geographic::Factory.new(
|
357
|
+
"Projected",
|
342
358
|
coord_sys: coord_sys,
|
343
359
|
srid: srid.to_i,
|
344
360
|
has_z_coordinate: opts[:has_z_coordinate],
|
345
361
|
has_m_coordinate: opts[:has_m_coordinate],
|
346
362
|
wkt_parser: opts[:wkt_parser], wkt_generator: opts[:wkt_generator],
|
347
|
-
wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]
|
348
|
-
|
363
|
+
wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]
|
364
|
+
)
|
365
|
+
projector = Geographic::Projector.create_from_opts(
|
366
|
+
factory,
|
349
367
|
srid: projection_srid,
|
350
368
|
coord_sys: projection_coord_sys,
|
351
369
|
buffer_resolution: opts[:buffer_resolution],
|
352
370
|
has_z_coordinate: opts[:has_z_coordinate],
|
353
371
|
has_m_coordinate: opts[:has_m_coordinate],
|
354
372
|
wkt_parser: opts[:wkt_parser], wkt_generator: opts[:wkt_generator],
|
355
|
-
wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]
|
373
|
+
wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]
|
374
|
+
)
|
356
375
|
end
|
357
376
|
factory.projector = projector
|
358
377
|
factory
|
@@ -361,17 +380,15 @@ module RGeo
|
|
361
380
|
private
|
362
381
|
|
363
382
|
def coord_sys_4055
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
@coord_sys_4055
|
383
|
+
return @coord_sys_4055 if defined?(@coord_sys_4055)
|
384
|
+
|
385
|
+
@coord_sys_4055 = CoordSys::CONFIG.default_coord_sys_class.create(4055)
|
368
386
|
end
|
369
387
|
|
370
388
|
def coord_sys_4326
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
@coord_sys_4326
|
389
|
+
return @coord_sys_4326 if defined?(@coord_sys_4326)
|
390
|
+
|
391
|
+
@coord_sys_4326 = CoordSys::CONFIG.default_coord_sys_class.create(4326)
|
375
392
|
end
|
376
393
|
end
|
377
394
|
end
|
@@ -219,9 +219,7 @@ module RGeo
|
|
219
219
|
# Ensure projection is available.
|
220
220
|
def init_geometry
|
221
221
|
super
|
222
|
-
unless projection
|
223
|
-
raise Error::InvalidGeometry, "Polygon failed assertions"
|
224
|
-
end
|
222
|
+
raise Error::InvalidGeometry, "Polygon failed assertions" unless projection
|
225
223
|
end
|
226
224
|
end
|
227
225
|
|
@@ -231,9 +229,7 @@ module RGeo
|
|
231
229
|
# Ensure projection is available.
|
232
230
|
def init_geometry
|
233
231
|
super
|
234
|
-
unless projection
|
235
|
-
raise Error::InvalidGeometry, "MultiPolygon failed assertions"
|
236
|
-
end
|
232
|
+
raise Error::InvalidGeometry, "MultiPolygon failed assertions" unless projection
|
237
233
|
end
|
238
234
|
end
|
239
235
|
end
|