rgeo 2.3.1 → 3.0.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 +23 -14
- data/ext/geos_c_impl/analysis.c +30 -25
- data/ext/geos_c_impl/analysis.h +8 -7
- data/ext/geos_c_impl/coordinates.c +27 -21
- data/ext/geos_c_impl/coordinates.h +5 -2
- data/ext/geos_c_impl/errors.c +19 -10
- data/ext/geos_c_impl/errors.h +11 -4
- data/ext/geos_c_impl/extconf.rb +42 -28
- data/ext/geos_c_impl/factory.c +540 -451
- data/ext/geos_c_impl/factory.h +105 -95
- data/ext/geos_c_impl/geometry.c +593 -387
- data/ext/geos_c_impl/geometry.h +10 -5
- data/ext/geos_c_impl/geometry_collection.c +306 -339
- data/ext/geos_c_impl/geometry_collection.h +6 -20
- data/ext/geos_c_impl/globals.c +169 -0
- data/ext/geos_c_impl/globals.h +46 -0
- data/ext/geos_c_impl/line_string.c +271 -231
- data/ext/geos_c_impl/line_string.h +5 -8
- data/ext/geos_c_impl/main.c +16 -16
- data/ext/geos_c_impl/point.c +65 -67
- data/ext/geos_c_impl/point.h +4 -7
- data/ext/geos_c_impl/polygon.c +137 -135
- data/ext/geos_c_impl/polygon.h +11 -11
- data/ext/geos_c_impl/preface.h +16 -10
- data/ext/geos_c_impl/ruby_more.c +67 -0
- data/ext/geos_c_impl/ruby_more.h +25 -0
- data/lib/rgeo/cartesian/analysis.rb +5 -3
- data/lib/rgeo/cartesian/bounding_box.rb +74 -79
- data/lib/rgeo/cartesian/calculations.rb +64 -33
- data/lib/rgeo/cartesian/factory.rb +57 -102
- data/lib/rgeo/cartesian/feature_classes.rb +68 -46
- data/lib/rgeo/cartesian/feature_methods.rb +67 -25
- data/lib/rgeo/cartesian/interface.rb +6 -41
- data/lib/rgeo/cartesian/planar_graph.rb +373 -0
- data/lib/rgeo/cartesian/sweepline_intersector.rb +147 -0
- data/lib/rgeo/cartesian/valid_op.rb +69 -0
- data/lib/rgeo/cartesian.rb +3 -0
- data/lib/rgeo/coord_sys/cs/entities.rb +303 -99
- data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +90 -42
- data/lib/rgeo/coord_sys.rb +1 -20
- data/lib/rgeo/error.rb +15 -0
- data/lib/rgeo/feature/curve.rb +0 -11
- data/lib/rgeo/feature/factory.rb +26 -36
- data/lib/rgeo/feature/factory_generator.rb +6 -14
- data/lib/rgeo/feature/geometry.rb +146 -66
- data/lib/rgeo/feature/geometry_collection.rb +16 -9
- data/lib/rgeo/feature/line_string.rb +4 -5
- data/lib/rgeo/feature/linear_ring.rb +0 -1
- data/lib/rgeo/feature/multi_curve.rb +0 -6
- data/lib/rgeo/feature/multi_surface.rb +3 -4
- data/lib/rgeo/feature/point.rb +4 -5
- data/lib/rgeo/feature/polygon.rb +1 -2
- data/lib/rgeo/feature/surface.rb +3 -4
- data/lib/rgeo/feature/types.rb +69 -85
- data/lib/rgeo/geographic/factory.rb +98 -125
- data/lib/rgeo/geographic/interface.rb +69 -166
- data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
- data/lib/rgeo/geographic/projected_feature_methods.rb +67 -42
- data/lib/rgeo/geographic/projected_window.rb +36 -22
- data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -5
- data/lib/rgeo/geographic/simple_mercator_projector.rb +26 -25
- data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
- data/lib/rgeo/geographic/spherical_feature_methods.rb +86 -9
- data/lib/rgeo/geographic/spherical_math.rb +17 -20
- data/lib/rgeo/geographic.rb +1 -1
- data/lib/rgeo/geos/capi_factory.rb +87 -158
- data/lib/rgeo/geos/capi_feature_classes.rb +50 -36
- data/lib/rgeo/geos/ffi_factory.rb +105 -173
- data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
- data/lib/rgeo/geos/ffi_feature_methods.rb +105 -127
- data/lib/rgeo/geos/interface.rb +20 -59
- data/lib/rgeo/geos/utils.rb +5 -5
- data/lib/rgeo/geos/zm_factory.rb +53 -95
- data/lib/rgeo/geos/zm_feature_methods.rb +30 -33
- data/lib/rgeo/geos.rb +8 -8
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +9 -22
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +28 -56
- data/lib/rgeo/impl_helper/basic_point_methods.rb +2 -14
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +17 -26
- data/lib/rgeo/impl_helper/utils.rb +21 -0
- data/lib/rgeo/impl_helper/valid_op.rb +350 -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
- data/lib/rgeo/wkrep/wkb_generator.rb +73 -63
- data/lib/rgeo/wkrep/wkb_parser.rb +33 -31
- data/lib/rgeo/wkrep/wkt_generator.rb +52 -45
- data/lib/rgeo/wkrep/wkt_parser.rb +48 -35
- data/lib/rgeo.rb +1 -3
- metadata +50 -13
- 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
@@ -134,12 +134,19 @@ module RGeo
|
|
134
134
|
# Highest possible value for local datum types.
|
135
135
|
LD_MAX = 32_767
|
136
136
|
|
137
|
+
# Flags indicating parts of domain covered by a convex hull. These flags can be combined. For
|
138
|
+
# example, the value 3 corresponds to a combination of CT_DF_Inside and MF_DF_Outside, which
|
139
|
+
# means that some parts of the convex hull are inside the domain, and some parts of the convex
|
140
|
+
# hull are outside the domain
|
141
|
+
CT_DF_INSIDE = 1
|
142
|
+
CT_DF_OUTSIDE = 2
|
143
|
+
CT_DF_DISCONTINUOUS = 4
|
144
|
+
|
137
145
|
# This is a base class for all OGC coordinate system objects.
|
138
146
|
# This includes both interfaces and data types from the OGC
|
139
147
|
# Coordinate Transformation spec.
|
140
148
|
#
|
141
149
|
# This is a non-instantiable abstract class.
|
142
|
-
|
143
150
|
class Base
|
144
151
|
# Standard object inspection output
|
145
152
|
|
@@ -150,8 +157,8 @@ module RGeo
|
|
150
157
|
# Tests for equality. Two objects are defined as equal if they
|
151
158
|
# have the same type (class) and the same WKT representation.
|
152
159
|
|
153
|
-
def eql?(
|
154
|
-
|
160
|
+
def eql?(other)
|
161
|
+
other.class == self.class && other.to_wkt == to_wkt
|
155
162
|
end
|
156
163
|
alias == eql?
|
157
164
|
|
@@ -172,19 +179,21 @@ module RGeo
|
|
172
179
|
# <tt>:standard_brackets</tt>
|
173
180
|
# If true, outputs parentheses rather than square
|
174
181
|
# brackets. Default is false.
|
175
|
-
def to_wkt(standard_brackets
|
182
|
+
def to_wkt(standard_brackets: false)
|
176
183
|
open, close = brackets(standard_brackets)
|
177
184
|
content = wkt_content(standard_brackets).map { |obj| ",#{obj}" }.join
|
178
|
-
|
179
|
-
authority
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
185
|
+
authority =
|
186
|
+
if defined?(@authority) && @authority
|
187
|
+
",AUTHORITY#{open}#{@authority.inspect},#{@authority_code.inspect}#{close}"
|
188
|
+
else
|
189
|
+
""
|
190
|
+
end
|
191
|
+
extensions =
|
192
|
+
if defined?(@extensions) && @extensions
|
193
|
+
@extensions.map { |k, v| ",EXTENSION#{open}#{k.inspect},#{v.inspect}#{close}" }.join
|
194
|
+
else
|
195
|
+
""
|
196
|
+
end
|
188
197
|
"#{wkt_typename}#{open}#{@name.inspect}#{content}#{extensions}#{authority}#{close}"
|
189
198
|
end
|
190
199
|
|
@@ -197,12 +206,11 @@ module RGeo
|
|
197
206
|
def marshal_load(data) # :nodoc:
|
198
207
|
data = data["wkt"] if data.is_a?(Hash)
|
199
208
|
temp = CS.create_from_wkt(data)
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
raise TypeError, "Bad Marshal data"
|
209
|
+
|
210
|
+
raise TypeError, "Bad Marshal data" unless temp.instance_of?(self.class)
|
211
|
+
|
212
|
+
temp.instance_variables.each do |iv|
|
213
|
+
instance_variable_set(iv, temp.instance_variable_get(iv))
|
206
214
|
end
|
207
215
|
end
|
208
216
|
|
@@ -214,12 +222,11 @@ module RGeo
|
|
214
222
|
|
215
223
|
def init_with(coder) # :nodoc:
|
216
224
|
temp = CS.create_from_wkt(coder.type == :scalar ? coder.scalar : coder["wkt"])
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
raise TypeError, "Bad YAML data"
|
225
|
+
|
226
|
+
raise TypeError, "Bad YAML data" unless temp.instance_of?(self.class)
|
227
|
+
|
228
|
+
temp.instance_variables.each do |iv|
|
229
|
+
instance_variable_set(iv, temp.instance_variable_get(iv))
|
223
230
|
end
|
224
231
|
end
|
225
232
|
|
@@ -238,20 +245,21 @@ module RGeo
|
|
238
245
|
#
|
239
246
|
# Details of axis. This is used to label axes, and indicate the
|
240
247
|
# orientation.
|
241
|
-
|
242
248
|
class AxisInfo < Base
|
243
249
|
# :stopdoc:
|
244
250
|
NAMES_BY_VALUE = %w[OTHER NORTH SOUTH EAST WEST UP DOWN].freeze
|
245
251
|
# :startdoc:
|
246
252
|
|
247
253
|
def initialize(name, orientation) # :nodoc:
|
254
|
+
super()
|
248
255
|
@name = name
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
256
|
+
@orientation =
|
257
|
+
case orientation
|
258
|
+
when String, Symbol
|
259
|
+
NAMES_BY_VALUE.index(orientation.to_s.upcase).to_i
|
260
|
+
else
|
261
|
+
orientation.to_i
|
262
|
+
end
|
255
263
|
end
|
256
264
|
|
257
265
|
# Human readable name for axis. Possible values are "X", "Y",
|
@@ -293,9 +301,9 @@ module RGeo
|
|
293
301
|
# projected coordinate system. The angular units of parameter
|
294
302
|
# values match the angular units of the geographic coordinate
|
295
303
|
# system that the projected coordinate system is based on.
|
296
|
-
|
297
304
|
class ProjectionParameter < Base
|
298
305
|
def initialize(name, value) # :nodoc:
|
306
|
+
super()
|
299
307
|
@name = name
|
300
308
|
@value = value.to_f
|
301
309
|
end
|
@@ -331,15 +339,15 @@ module RGeo
|
|
331
339
|
# Wolf parameters should be applied to geocentric coordinates, where
|
332
340
|
# the X axis points towards the Greenwich Prime Meridian, the Y axis
|
333
341
|
# points East, and the Z axis points North.
|
334
|
-
|
335
342
|
class WGS84ConversionInfo < Base
|
336
|
-
def initialize(
|
337
|
-
|
338
|
-
@
|
339
|
-
@
|
340
|
-
@
|
341
|
-
@
|
342
|
-
@
|
343
|
+
def initialize(dx_meters, dy_meters, dz_meters, ex_arc_seconds, ey_arc_seconds, ez_arc_seconds, ppm) # :nodoc:
|
344
|
+
super()
|
345
|
+
@dx = dx_meters.to_f
|
346
|
+
@dy = dy_meters.to_f
|
347
|
+
@dz = dz_meters.to_f
|
348
|
+
@ex = ex_arc_seconds.to_f
|
349
|
+
@ey = ey_arc_seconds.to_f
|
350
|
+
@ez = ez_arc_seconds.to_f
|
343
351
|
@ppm = ppm.to_f
|
344
352
|
end
|
345
353
|
|
@@ -364,7 +372,7 @@ module RGeo
|
|
364
372
|
# Bursa Wolf scaling in in parts per million.
|
365
373
|
attr_reader :ppm
|
366
374
|
|
367
|
-
def to_wkt(standard_brackets
|
375
|
+
def to_wkt(standard_brackets: false)
|
368
376
|
open, close = brackets(standard_brackets)
|
369
377
|
"TOWGS84#{open}#{@dx},#{@dy},#{@dz},#{@ex},#{@ey},#{@ez},#{@ppm}#{close}"
|
370
378
|
end
|
@@ -375,8 +383,8 @@ module RGeo
|
|
375
383
|
# The Bursa Wolf shift should be in meters, the rotation in arc
|
376
384
|
# seconds, and the scaling in parts per million.
|
377
385
|
|
378
|
-
def create(
|
379
|
-
new(
|
386
|
+
def create(dx_meters, dy_meters, dz_meters, ex_arc_seconds, ey_arc_seconds, ez_arc_seconds, ppm)
|
387
|
+
new(dx_meters, dy_meters, dz_meters, ex_arc_seconds, ey_arc_seconds, ez_arc_seconds, ppm)
|
380
388
|
end
|
381
389
|
end
|
382
390
|
end
|
@@ -419,9 +427,10 @@ module RGeo
|
|
419
427
|
# * <b>alias</b>: an alias
|
420
428
|
# * <b>remarks</b>: provider-supplied remarks.
|
421
429
|
# * <b>extensions</b>: a hash of extension keys and values
|
422
|
-
|
423
430
|
class Info < Base
|
424
|
-
def initialize(name, authority = nil, authority_code = nil, abbreviation = nil, init_alias = nil,
|
431
|
+
def initialize(name, authority = nil, authority_code = nil, abbreviation = nil, init_alias = nil,
|
432
|
+
remarks = nil, extensions = nil) # :nodoc:
|
433
|
+
super()
|
425
434
|
@name = name
|
426
435
|
@authority = authority ? authority.to_s : nil
|
427
436
|
@authority_code = authority_code ? authority_code.to_s : nil
|
@@ -480,7 +489,6 @@ module RGeo
|
|
480
489
|
# Normally, you will instantiate one of the subclasses LinearUnit or
|
481
490
|
# AngularUnit. However, it is possible to instantiate Unit if it is
|
482
491
|
# not clear whether the data refers to a LinearUnit or AngularUnit.
|
483
|
-
|
484
492
|
class Unit < Info
|
485
493
|
def initialize(name, conversion_factor, *optional) # :nodoc:
|
486
494
|
super(name, *optional)
|
@@ -517,7 +525,6 @@ module RGeo
|
|
517
525
|
# == OGC spec description
|
518
526
|
#
|
519
527
|
# Definition of linear units.
|
520
|
-
|
521
528
|
class LinearUnit < Unit
|
522
529
|
# Returns the number of meters per LinearUnit.
|
523
530
|
# Also available as Unit#conversion_factor.
|
@@ -540,7 +547,6 @@ module RGeo
|
|
540
547
|
# == OGC spec description
|
541
548
|
#
|
542
549
|
# Definition of angular units.
|
543
|
-
|
544
550
|
class AngularUnit < Unit
|
545
551
|
# Returns the number of radians per AngularUnit.
|
546
552
|
# Also available as Unit#conversion_factor.
|
@@ -563,7 +569,6 @@ module RGeo
|
|
563
569
|
# == OGC spec description
|
564
570
|
#
|
565
571
|
# A meridian used to take longitude measurements from.
|
566
|
-
|
567
572
|
class PrimeMeridian < Info
|
568
573
|
def initialize(name, angular_unit, longitude, *optional) # :nodoc:
|
569
574
|
super(name, *optional)
|
@@ -603,9 +608,9 @@ module RGeo
|
|
603
608
|
# == OGC spec description
|
604
609
|
#
|
605
610
|
# An approximation of the Earth's surface as a squashed sphere.
|
606
|
-
|
607
611
|
class Ellipsoid < Info
|
608
|
-
def initialize(name, semi_major_axis, semi_minor_axis, inverse_flattening, ivf_definitive,
|
612
|
+
def initialize(name, semi_major_axis, semi_minor_axis, inverse_flattening, ivf_definitive,
|
613
|
+
linear_unit, *optional) # :nodoc:
|
609
614
|
super(name, *optional)
|
610
615
|
@semi_major_axis = semi_major_axis.to_f
|
611
616
|
@semi_minor_axis = semi_minor_axis.to_f
|
@@ -710,7 +715,6 @@ module RGeo
|
|
710
715
|
# This is a non-instantiable abstract class. You must instantiate
|
711
716
|
# one of the subclasses HorizontalDatum, VerticalDatum, or
|
712
717
|
# LocalDatum.
|
713
|
-
|
714
718
|
class Datum < Info
|
715
719
|
def initialize(name, datum_type, *optional) # :nodoc:
|
716
720
|
super(name, *optional)
|
@@ -730,7 +734,6 @@ module RGeo
|
|
730
734
|
# == OGC spec description
|
731
735
|
#
|
732
736
|
# Procedure used to measure vertical distances.
|
733
|
-
|
734
737
|
class VerticalDatum < Datum
|
735
738
|
def wkt_typename
|
736
739
|
"VERT_DATUM"
|
@@ -760,7 +763,6 @@ module RGeo
|
|
760
763
|
# coordinates can be transformed between two different local
|
761
764
|
# coordinate systems, as long as they are based on the same local
|
762
765
|
# datum.
|
763
|
-
|
764
766
|
class LocalDatum < Datum
|
765
767
|
def wkt_typename
|
766
768
|
"LOCAL_DATUM"
|
@@ -786,7 +788,6 @@ module RGeo
|
|
786
788
|
# == OGC spec description
|
787
789
|
#
|
788
790
|
# Procedure used to measure positions on the surface of the Earth.
|
789
|
-
|
790
791
|
class HorizontalDatum < Datum
|
791
792
|
def initialize(name, datum_type, ellipsoid, wgs84_parameters, *optional) # :nodoc:
|
792
793
|
super(name, datum_type, *optional)
|
@@ -820,8 +821,8 @@ module RGeo
|
|
820
821
|
private
|
821
822
|
|
822
823
|
def wkt_content(standard_brackets)
|
823
|
-
array = [@ellipsoid.to_wkt(standard_brackets)]
|
824
|
-
array << @wgs84_parameters.to_wkt(standard_brackets) if @wgs84_parameters
|
824
|
+
array = [@ellipsoid.to_wkt(standard_brackets: standard_brackets)]
|
825
|
+
array << @wgs84_parameters.to_wkt(standard_brackets: standard_brackets) if @wgs84_parameters
|
825
826
|
array
|
826
827
|
end
|
827
828
|
end
|
@@ -829,7 +830,6 @@ module RGeo
|
|
829
830
|
# == OGC spec description
|
830
831
|
#
|
831
832
|
# A projection from geographic coordinates to projected coordinates.
|
832
|
-
|
833
833
|
class Projection < Info
|
834
834
|
def initialize(name, class_name, parameters, *optional) # :nodoc:
|
835
835
|
super(name, *optional)
|
@@ -908,7 +908,6 @@ module RGeo
|
|
908
908
|
# GeographicCoordinateSystem, ProjectedCoordinateSystem,
|
909
909
|
# VerticalCoordinateSystem, LocalCoordinateSystem, or
|
910
910
|
# CompoundCoordinateSystem.
|
911
|
-
|
912
911
|
class CoordinateSystem < Info
|
913
912
|
def initialize(name, dimension, *optional) # :nodoc:
|
914
913
|
super(name, *optional)
|
@@ -921,16 +920,61 @@ module RGeo
|
|
921
920
|
# Gets axis details for dimension within coordinate system. Each
|
922
921
|
# dimension in the coordinate system has a corresponding axis.
|
923
922
|
|
924
|
-
def get_axis(
|
923
|
+
def get_axis(_dimension)
|
925
924
|
nil
|
926
925
|
end
|
927
926
|
|
928
927
|
# Gets units for dimension within coordinate system. Each
|
929
928
|
# dimension in the coordinate system has corresponding units.
|
930
929
|
|
931
|
-
def get_units(
|
930
|
+
def get_units(_dimension)
|
932
931
|
nil
|
933
932
|
end
|
933
|
+
|
934
|
+
def geographic?
|
935
|
+
false
|
936
|
+
end
|
937
|
+
|
938
|
+
def projected?
|
939
|
+
false
|
940
|
+
end
|
941
|
+
|
942
|
+
def wkt_typename
|
943
|
+
"CS"
|
944
|
+
end
|
945
|
+
|
946
|
+
# Not an OGC method, but useful for being able to
|
947
|
+
# transform directly from a CoordinateSystem object.
|
948
|
+
def transform_coords(target_cs, x, y, z = nil)
|
949
|
+
ct = CoordinateTransform.create(self, target_cs)
|
950
|
+
ct.transform_coords(x, y, z)
|
951
|
+
end
|
952
|
+
|
953
|
+
class << self
|
954
|
+
def create(defn, dimension = 2, *optional)
|
955
|
+
# Need this so we can maintain consistency with actual
|
956
|
+
# CoordinateSystem implementations
|
957
|
+
|
958
|
+
if defn.is_a?(Integer)
|
959
|
+
# not technically correct but we can use cartesian as a placeholder
|
960
|
+
# to form valid wkt
|
961
|
+
defn_string = "Cartesian"
|
962
|
+
new(defn_string, dimension, "EPSG", defn, *optional)
|
963
|
+
else
|
964
|
+
new(defn, dimension, *optional)
|
965
|
+
end
|
966
|
+
end
|
967
|
+
|
968
|
+
def create_from_wkt(str)
|
969
|
+
CS.create_from_wkt(str)
|
970
|
+
end
|
971
|
+
end
|
972
|
+
|
973
|
+
private
|
974
|
+
|
975
|
+
def wkt_content(_)
|
976
|
+
[@dimension]
|
977
|
+
end
|
934
978
|
end
|
935
979
|
|
936
980
|
# == OGC spec description
|
@@ -940,7 +984,6 @@ module RGeo
|
|
940
984
|
# as a geographic or a projected coordinate system with a horizontal
|
941
985
|
# datum. The other is a vertical CRS which is a one-dimensional
|
942
986
|
# coordinate system with a vertical datum.
|
943
|
-
|
944
987
|
class CompoundCoordinateSystem < CoordinateSystem
|
945
988
|
def initialize(name, head, tail, *optional) # :nodoc:
|
946
989
|
super(name, head.dimension + tail.dimension, *optional)
|
@@ -985,7 +1028,7 @@ module RGeo
|
|
985
1028
|
private
|
986
1029
|
|
987
1030
|
def wkt_content(standard_brackets)
|
988
|
-
[@head.to_wkt(standard_brackets), @tail.to_wkt(standard_brackets)]
|
1031
|
+
[@head.to_wkt(standard_brackets: standard_brackets), @tail.to_wkt(standard_brackets: standard_brackets)]
|
989
1032
|
end
|
990
1033
|
end
|
991
1034
|
|
@@ -1007,7 +1050,6 @@ module RGeo
|
|
1007
1050
|
#
|
1008
1051
|
# RGeo's implementation does not provide the Coordinate
|
1009
1052
|
# Transformation (CT) package.
|
1010
|
-
|
1011
1053
|
class LocalCoordinateSystem < CoordinateSystem
|
1012
1054
|
def initialize(name, local_datum, unit, axes, *optional) # :nodoc:
|
1013
1055
|
super(name, axes.size, *optional)
|
@@ -1027,7 +1069,7 @@ module RGeo
|
|
1027
1069
|
|
1028
1070
|
# Implements CoordinateSystem#get_units
|
1029
1071
|
|
1030
|
-
def get_units(
|
1072
|
+
def get_units(_index)
|
1031
1073
|
@unit
|
1032
1074
|
end
|
1033
1075
|
|
@@ -1050,9 +1092,9 @@ module RGeo
|
|
1050
1092
|
|
1051
1093
|
def wkt_content(standard_brackets)
|
1052
1094
|
[
|
1053
|
-
@local_datum.to_wkt(standard_brackets),
|
1054
|
-
@unit.to_wkt(standard_brackets)
|
1055
|
-
] + @axes.map { |ax| ax.to_wkt(standard_brackets) }
|
1095
|
+
@local_datum.to_wkt(standard_brackets: standard_brackets),
|
1096
|
+
@unit.to_wkt(standard_brackets: standard_brackets)
|
1097
|
+
] + @axes.map { |ax| ax.to_wkt(standard_brackets: standard_brackets) }
|
1056
1098
|
end
|
1057
1099
|
end
|
1058
1100
|
|
@@ -1064,7 +1106,6 @@ module RGeo
|
|
1064
1106
|
# the Z axis will point North, and the Y axis will point East (e.g.
|
1065
1107
|
# a right handed system), but you should check the axes for
|
1066
1108
|
# non-default values.
|
1067
|
-
|
1068
1109
|
class GeocentricCoordinateSystem < CoordinateSystem
|
1069
1110
|
def initialize(name, horizontal_datum, prime_meridian, linear_unit, axis0, axis1, axis2, *optional) # :nodoc:
|
1070
1111
|
super(name, 3, *optional)
|
@@ -1090,7 +1131,7 @@ module RGeo
|
|
1090
1131
|
|
1091
1132
|
# Implements CoordinateSystem#get_units
|
1092
1133
|
|
1093
|
-
def get_units(
|
1134
|
+
def get_units(_index)
|
1094
1135
|
@linear_unit
|
1095
1136
|
end
|
1096
1137
|
|
@@ -1100,6 +1141,10 @@ module RGeo
|
|
1100
1141
|
[@axis0, @axis1, @axis2][index]
|
1101
1142
|
end
|
1102
1143
|
|
1144
|
+
def geographic?
|
1145
|
+
true
|
1146
|
+
end
|
1147
|
+
|
1103
1148
|
def wkt_typename
|
1104
1149
|
"GEOCCS"
|
1105
1150
|
end
|
@@ -1120,13 +1165,13 @@ module RGeo
|
|
1120
1165
|
|
1121
1166
|
def wkt_content(standard_brackets)
|
1122
1167
|
arr = [
|
1123
|
-
@horizontal_datum.to_wkt(standard_brackets),
|
1124
|
-
@prime_meridian.to_wkt(standard_brackets),
|
1125
|
-
@linear_unit.to_wkt(standard_brackets)
|
1168
|
+
@horizontal_datum.to_wkt(standard_brackets: standard_brackets),
|
1169
|
+
@prime_meridian.to_wkt(standard_brackets: standard_brackets),
|
1170
|
+
@linear_unit.to_wkt(standard_brackets: standard_brackets)
|
1126
1171
|
]
|
1127
|
-
arr << @axis0.to_wkt(standard_brackets) if @axis0
|
1128
|
-
arr << @axis1.to_wkt(standard_brackets) if @axis1
|
1129
|
-
arr << @axis2.to_wkt(standard_brackets) if @axis2
|
1172
|
+
arr << @axis0.to_wkt(standard_brackets: standard_brackets) if @axis0
|
1173
|
+
arr << @axis1.to_wkt(standard_brackets: standard_brackets) if @axis1
|
1174
|
+
arr << @axis2.to_wkt(standard_brackets: standard_brackets) if @axis2
|
1130
1175
|
arr
|
1131
1176
|
end
|
1132
1177
|
end
|
@@ -1135,7 +1180,6 @@ module RGeo
|
|
1135
1180
|
#
|
1136
1181
|
# A one-dimensional coordinate system suitable for vertical
|
1137
1182
|
# measurements.
|
1138
|
-
|
1139
1183
|
class VerticalCoordinateSystem < CoordinateSystem
|
1140
1184
|
def initialize(name, vertical_datum, vertical_unit, axis, *optional) # :nodoc:
|
1141
1185
|
super(name, 1, *optional)
|
@@ -1153,13 +1197,13 @@ module RGeo
|
|
1153
1197
|
|
1154
1198
|
# Implements CoordinateSystem#get_units
|
1155
1199
|
|
1156
|
-
def get_units(
|
1200
|
+
def get_units(_index)
|
1157
1201
|
@vertical_unit
|
1158
1202
|
end
|
1159
1203
|
|
1160
1204
|
# Implements CoordinateSystem#get_axis
|
1161
1205
|
|
1162
|
-
def get_axis(
|
1206
|
+
def get_axis(_index)
|
1163
1207
|
@axis
|
1164
1208
|
end
|
1165
1209
|
|
@@ -1181,8 +1225,11 @@ module RGeo
|
|
1181
1225
|
private
|
1182
1226
|
|
1183
1227
|
def wkt_content(standard_brackets)
|
1184
|
-
arr = [
|
1185
|
-
|
1228
|
+
arr = [
|
1229
|
+
@vertical_datum.to_wkt(standard_brackets: standard_brackets),
|
1230
|
+
@vertical_unit.to_wkt(standard_brackets: standard_brackets)
|
1231
|
+
]
|
1232
|
+
arr << @axis.to_wkt(standard_brackets: standard_brackets) if @axis
|
1186
1233
|
arr
|
1187
1234
|
end
|
1188
1235
|
end
|
@@ -1196,7 +1243,6 @@ module RGeo
|
|
1196
1243
|
# This is a non-instantiable abstract class. You must instantiate
|
1197
1244
|
# one of the subclasses GeographicCoordinateSystem or
|
1198
1245
|
# ProjectedCoordinateSystem.
|
1199
|
-
|
1200
1246
|
class HorizontalCoordinateSystem < CoordinateSystem
|
1201
1247
|
def initialize(name, horizontal_datum, *optional) # :nodoc:
|
1202
1248
|
super(name, 2, *optional)
|
@@ -1214,7 +1260,6 @@ module RGeo
|
|
1214
1260
|
# You can find out which this is by examining the axes. You should
|
1215
1261
|
# also check the angular units, since not all geographic coordinate
|
1216
1262
|
# systems use degrees.
|
1217
|
-
|
1218
1263
|
class GeographicCoordinateSystem < HorizontalCoordinateSystem
|
1219
1264
|
def initialize(name, angular_unit, horizontal_datum, prime_meridian, axis0, axis1, *optional) # :nodoc:
|
1220
1265
|
super(name, horizontal_datum, *optional)
|
@@ -1233,7 +1278,7 @@ module RGeo
|
|
1233
1278
|
|
1234
1279
|
# Implements CoordinateSystem#get_units
|
1235
1280
|
|
1236
|
-
def get_units(
|
1281
|
+
def get_units(_index)
|
1237
1282
|
@angular_unit
|
1238
1283
|
end
|
1239
1284
|
|
@@ -1255,10 +1300,14 @@ module RGeo
|
|
1255
1300
|
# of interest. The first conversion (with index=0) should provide
|
1256
1301
|
# acceptable accuracy over the largest possible area of interest.
|
1257
1302
|
|
1258
|
-
def get_wgs84_conversion_info(
|
1303
|
+
def get_wgs84_conversion_info(_index)
|
1259
1304
|
@horizontal_datum.wgs84_parameters
|
1260
1305
|
end
|
1261
1306
|
|
1307
|
+
def geographic?
|
1308
|
+
true
|
1309
|
+
end
|
1310
|
+
|
1262
1311
|
def wkt_typename
|
1263
1312
|
"GEOGCS"
|
1264
1313
|
end
|
@@ -1279,12 +1328,12 @@ module RGeo
|
|
1279
1328
|
|
1280
1329
|
def wkt_content(standard_brackets)
|
1281
1330
|
arr = [
|
1282
|
-
@horizontal_datum.to_wkt(standard_brackets),
|
1283
|
-
@prime_meridian.to_wkt(standard_brackets),
|
1284
|
-
@angular_unit.to_wkt(standard_brackets)
|
1331
|
+
@horizontal_datum.to_wkt(standard_brackets: standard_brackets),
|
1332
|
+
@prime_meridian.to_wkt(standard_brackets: standard_brackets),
|
1333
|
+
@angular_unit.to_wkt(standard_brackets: standard_brackets)
|
1285
1334
|
]
|
1286
|
-
arr << @axis0.to_wkt(standard_brackets) if @axis0
|
1287
|
-
arr << @axis1.to_wkt(standard_brackets) if @axis1
|
1335
|
+
arr << @axis0.to_wkt(standard_brackets: standard_brackets) if @axis0
|
1336
|
+
arr << @axis1.to_wkt(standard_brackets: standard_brackets) if @axis1
|
1288
1337
|
arr
|
1289
1338
|
end
|
1290
1339
|
end
|
@@ -1292,7 +1341,6 @@ module RGeo
|
|
1292
1341
|
# == OGC spec description
|
1293
1342
|
#
|
1294
1343
|
# A 2D cartographic coordinate system.
|
1295
|
-
|
1296
1344
|
class ProjectedCoordinateSystem < HorizontalCoordinateSystem
|
1297
1345
|
def initialize(name, geographic_coordinate_system, projection, linear_unit, axis0, axis1, *optional) # :nodoc:
|
1298
1346
|
super(name, geographic_coordinate_system.horizontal_datum, *optional)
|
@@ -1315,7 +1363,7 @@ module RGeo
|
|
1315
1363
|
|
1316
1364
|
# Implements CoordinateSystem#get_units
|
1317
1365
|
|
1318
|
-
def get_units(
|
1366
|
+
def get_units(_index)
|
1319
1367
|
@linear_unit
|
1320
1368
|
end
|
1321
1369
|
|
@@ -1325,6 +1373,10 @@ module RGeo
|
|
1325
1373
|
index == 1 ? @axis1 : @axis0
|
1326
1374
|
end
|
1327
1375
|
|
1376
|
+
def projected?
|
1377
|
+
true
|
1378
|
+
end
|
1379
|
+
|
1328
1380
|
def wkt_typename
|
1329
1381
|
"PROJCS"
|
1330
1382
|
end
|
@@ -1344,14 +1396,166 @@ module RGeo
|
|
1344
1396
|
private
|
1345
1397
|
|
1346
1398
|
def wkt_content(standard_brackets)
|
1347
|
-
arr = [
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
arr <<
|
1399
|
+
arr = [
|
1400
|
+
@geographic_coordinate_system.to_wkt(standard_brackets: standard_brackets),
|
1401
|
+
@projection.to_wkt(standard_brackets: standard_brackets)
|
1402
|
+
]
|
1403
|
+
@projection.each_parameter { |param| arr << param.to_wkt(standard_brackets: standard_brackets) }
|
1404
|
+
arr << @linear_unit.to_wkt(standard_brackets: standard_brackets)
|
1405
|
+
arr << @axis0.to_wkt(standard_brackets: standard_brackets) if @axis0
|
1406
|
+
arr << @axis1.to_wkt(standard_brackets: standard_brackets) if @axis1
|
1352
1407
|
arr
|
1353
1408
|
end
|
1354
1409
|
end
|
1410
|
+
|
1411
|
+
# CoordinateTransform object. Note it is a combo of
|
1412
|
+
# CoordinateTransform and MathTransform as specified in
|
1413
|
+
# the OGC standard. This is just to simplify the model
|
1414
|
+
# and keep all functionality in this class.
|
1415
|
+
#
|
1416
|
+
# @see https://portal.ogc.org/files/?artifact_id=999 page 79
|
1417
|
+
class CoordinateTransform < Info
|
1418
|
+
# Initialize a new CoordinateTransform
|
1419
|
+
#
|
1420
|
+
# Note this class should not be used directly since it does not
|
1421
|
+
# implement any transformation logic. It merely defines
|
1422
|
+
# what methods actual implementations must use.
|
1423
|
+
#
|
1424
|
+
# @param [CoordinateSystem] source_cs
|
1425
|
+
# @param [CoordinateSystem] target_cs
|
1426
|
+
# @param [Array] optional any params for Info or Base
|
1427
|
+
# @return [CoordinateTransform]
|
1428
|
+
def initialize(source_cs, target_cs, *optional)
|
1429
|
+
super(optional)
|
1430
|
+
@source_cs = source_cs
|
1431
|
+
@target_cs = target_cs
|
1432
|
+
end
|
1433
|
+
attr_accessor :source_cs, :target_cs
|
1434
|
+
|
1435
|
+
# TODO: This changes depending on what type of conversion is done
|
1436
|
+
# and we can't know unless we implement the conversion ourselves.
|
1437
|
+
# We should delegate all of the wkt generation to the library
|
1438
|
+
# if possible.
|
1439
|
+
def wkt_typename
|
1440
|
+
"CONVERSION"
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
def inspect
|
1444
|
+
"#<#{self.class}:0x#{object_id.to_s(16)} @source_cs=#{source_cs.to_wkt} @target_cs=#{target_cs.to_wkt}>"
|
1445
|
+
end
|
1446
|
+
|
1447
|
+
# Human readable description of domain in source coordinate system.
|
1448
|
+
#
|
1449
|
+
# @return [String]
|
1450
|
+
def area_of_use
|
1451
|
+
raise NotImplementedError, "#{__method__} is not implemented in the abstract CoordinateTransform class."
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
# Semantic type of transform. For example, a datum transformation or a coordinate conversion.
|
1455
|
+
#
|
1456
|
+
# @return [String]
|
1457
|
+
def transform_type
|
1458
|
+
raise NotImplementedError, "#{__method__} is not implemented in the abstract CoordinateTransform class."
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
# Dimension of the source_cs
|
1462
|
+
#
|
1463
|
+
# @return [Integer]
|
1464
|
+
def dim_source
|
1465
|
+
source_cs.dimension
|
1466
|
+
end
|
1467
|
+
|
1468
|
+
# Dimension of the target_cs
|
1469
|
+
#
|
1470
|
+
# @return [Integer]
|
1471
|
+
def dim_target
|
1472
|
+
target_cs.dimension
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
# Tests whether this transform does not move any points
|
1476
|
+
#
|
1477
|
+
# @return [Boolean]
|
1478
|
+
def identity?
|
1479
|
+
raise NotImplementedError, "#{__method__} is not implemented in the abstract CoordinateTransform class."
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
# Gets flags classifying domain points within a convex hull. The supplied ordinates are interpreted
|
1483
|
+
# as a sequence of points, which generates a convex hull in the source space. Conceptually, each
|
1484
|
+
# of the (usually infinite) points inside the convex hull is then tested against the source domain.
|
1485
|
+
# The flags of all these tests are then combined. In practice, implementations of different
|
1486
|
+
# transforms will use different short-cuts to avoid doing an infinite number of tests.
|
1487
|
+
#
|
1488
|
+
# @param [Array<<Array<Integer>>] points in tuples of (x,y,z) with z being optional
|
1489
|
+
# @return [Array<Integer>] the domain_flags of the input points
|
1490
|
+
def domain_flags(points)
|
1491
|
+
raise NotImplementedError, "#{__method__} is not implemented in the abstract CoordinateTransform class."
|
1492
|
+
end
|
1493
|
+
|
1494
|
+
# Gets transformed convex hull. The supplied ordinates are interpreted as a sequence of points,
|
1495
|
+
# which generates a convex hull in the source space. The returned sequence of ordinates
|
1496
|
+
# represents a convex hull in the output space. The number of output points will often be different
|
1497
|
+
# from the number of input points. Each of the input points should be inside the valid domain (this
|
1498
|
+
# can be checked by testing the points' domain flags individually). However, the convex hull of the
|
1499
|
+
# input points may go outside the valid domain. The returned convex hull should contain the
|
1500
|
+
# transformed image of the intersection of the source convex hull and the source domain.
|
1501
|
+
#
|
1502
|
+
# @param [Array<<Array<Integer>>] points in tuples of (x,y,z) with z being optional
|
1503
|
+
# @return [Array<<Array<Integer>>]
|
1504
|
+
def codomain_convex_hull(points)
|
1505
|
+
raise NotImplementedError, "#{__method__} is not implemented in the abstract CoordinateTransform class."
|
1506
|
+
end
|
1507
|
+
|
1508
|
+
# Transforms a coordinate point. The passed parameter point should not be modified.
|
1509
|
+
#
|
1510
|
+
# @param [Integer] x
|
1511
|
+
# @param [Integer] y
|
1512
|
+
# @param [Integer] z optional
|
1513
|
+
# @return [Array<Integer>] transformed point coordinates in (x,y,z) order
|
1514
|
+
def transform_coords(x, y, z = nil)
|
1515
|
+
raise NotImplementedError, "#{__method__} is not implemented in the abstract CoordinateTransform class."
|
1516
|
+
end
|
1517
|
+
|
1518
|
+
# Transforms a coordinate point. The passed parameter point should not be modified.
|
1519
|
+
#
|
1520
|
+
# @param [Array<Array<Integer>>] points in (x,y,z) tuples where z is optional
|
1521
|
+
# @return [Array<Array<Integer>>] list of transformed point coordinates in (x,y,z) order
|
1522
|
+
def transform_list(points)
|
1523
|
+
points.map { |x, y, z| transform_coords(x, y, z) }
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
# Creates the inverse transform of this object. This method may fail if the transform is not one to
|
1527
|
+
# one. However, all cartographic projections should succeed.
|
1528
|
+
#
|
1529
|
+
# @return [CoordinateTransform]
|
1530
|
+
def inverse
|
1531
|
+
self.class.create(target_cs, source_cs)
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
class << self
|
1535
|
+
# Initialize a new CoordinateTransform
|
1536
|
+
#
|
1537
|
+
# Note this class should not be used directly since it does not
|
1538
|
+
# implement any transformation logic. It merely defines
|
1539
|
+
# what methods actual implementations must use.
|
1540
|
+
#
|
1541
|
+
# @param [CoordinateSystem] source_cs
|
1542
|
+
# @param [CoordinateSystem] target_cs
|
1543
|
+
# @param [Array] optional any params for Info or Base
|
1544
|
+
# @return [CoordinateTransform]
|
1545
|
+
def create(source_cs, target_cs, *optional)
|
1546
|
+
new(source_cs, target_cs, optional)
|
1547
|
+
end
|
1548
|
+
end
|
1549
|
+
|
1550
|
+
private
|
1551
|
+
|
1552
|
+
def wkt_content(standard_brackets)
|
1553
|
+
source_cs_wkt = "SOURCECS[#{source_cs.to_wkt(standard_brackets: standard_brackets)}]"
|
1554
|
+
target_cs_wkt = "TARGETCS[#{target_cs.to_wkt(standard_brackets: standard_brackets)}]"
|
1555
|
+
|
1556
|
+
[source_cs_wkt, target_cs_wkt]
|
1557
|
+
end
|
1558
|
+
end
|
1355
1559
|
end
|
1356
1560
|
end
|
1357
1561
|
end
|