proj4rb 3.0.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +26 -15
- data/README.rdoc +82 -44
- data/Rakefile +27 -27
- data/lib/api/api.rb +96 -118
- data/lib/api/api_5_0.rb +331 -300
- data/lib/api/api_5_1.rb +6 -6
- data/lib/api/api_5_2.rb +4 -4
- data/lib/api/api_6_0.rb +116 -14
- data/lib/api/api_6_1.rb +4 -4
- data/lib/api/api_6_2.rb +9 -6
- data/lib/api/api_6_3.rb +6 -0
- data/lib/api/api_7_0.rb +68 -0
- data/lib/api/api_7_1.rb +73 -0
- data/lib/api/api_7_2.rb +14 -0
- data/lib/api/api_8_0.rb +6 -0
- data/lib/api/api_8_1.rb +24 -0
- data/lib/api/api_8_2.rb +6 -0
- data/lib/api/api_9_1.rb +7 -0
- data/lib/api/api_9_2.rb +9 -0
- data/lib/api/api_experimental.rb +196 -0
- data/lib/proj/area.rb +73 -32
- data/lib/proj/axis_info.rb +44 -0
- data/lib/proj/bounds.rb +13 -0
- data/lib/proj/context.rb +174 -28
- data/lib/proj/conversion.rb +92 -0
- data/lib/proj/coordinate.rb +281 -197
- data/lib/proj/coordinate_operation_mixin.rb +381 -0
- data/lib/proj/coordinate_system.rb +137 -0
- data/lib/proj/crs.rb +672 -204
- data/lib/proj/crs_info.rb +47 -0
- data/lib/proj/database.rb +305 -0
- data/lib/proj/datum.rb +32 -0
- data/lib/proj/datum_ensemble.rb +34 -0
- data/lib/proj/ellipsoid.rb +77 -41
- data/lib/proj/error.rb +62 -9
- data/lib/proj/file_api.rb +166 -0
- data/lib/proj/grid.rb +121 -0
- data/lib/proj/grid_cache.rb +64 -0
- data/lib/proj/grid_info.rb +19 -0
- data/lib/proj/network_api.rb +92 -0
- data/lib/proj/operation.rb +42 -42
- data/lib/proj/operation_factory_context.rb +136 -0
- data/lib/proj/parameter.rb +38 -0
- data/lib/proj/parameters.rb +106 -0
- data/lib/proj/pj_object.rb +670 -80
- data/lib/proj/pj_objects.rb +44 -0
- data/lib/proj/prime_meridian.rb +65 -39
- data/lib/proj/projection.rb +698 -207
- data/lib/proj/session.rb +46 -0
- data/lib/proj/strings.rb +32 -0
- data/lib/proj/transformation.rb +101 -60
- data/lib/proj/unit.rb +108 -53
- data/lib/proj.rb +110 -9
- data/proj4rb.gemspec +5 -5
- data/test/abstract_test.rb +23 -1
- data/test/context_test.rb +172 -82
- data/test/conversion_test.rb +368 -0
- data/test/coordinate_system_test.rb +144 -0
- data/test/crs_test.rb +770 -71
- data/test/database_test.rb +360 -0
- data/test/datum_ensemble_test.rb +65 -0
- data/test/datum_test.rb +55 -0
- data/test/ellipsoid_test.rb +64 -18
- data/test/file_api_test.rb +66 -0
- data/test/grid_cache_test.rb +72 -0
- data/test/grid_test.rb +141 -0
- data/test/network_api_test.rb +45 -0
- data/test/operation_factory_context_test.rb +201 -0
- data/test/parameters_test.rb +40 -0
- data/test/pj_object_test.rb +179 -0
- data/test/prime_meridian_test.rb +76 -0
- data/test/proj_test.rb +46 -4
- data/test/projection_test.rb +646 -222
- data/test/session_test.rb +78 -0
- data/test/transformation_test.rb +149 -7
- data/test/unit_test.rb +57 -28
- metadata +51 -13
- data/lib/api/api_4_9.rb +0 -31
- data/lib/proj/config.rb +0 -70
- data/lib/proj/point.rb +0 -72
- data/test/prime_meridians_test.rb +0 -33
data/lib/proj/crs.rb
CHANGED
@@ -1,204 +1,672 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
module Proj
|
5
|
-
# Represents a coordinate reference system.
|
6
|
-
class Crs < PjObject
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# @
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
#
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
#
|
89
|
-
#
|
90
|
-
# @
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
#
|
130
|
-
#
|
131
|
-
# @
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
#
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Proj
|
5
|
+
# Represents a coordinate reference system.
|
6
|
+
class Crs < PjObject
|
7
|
+
# Create a ProjectedCRS.
|
8
|
+
#
|
9
|
+
# @param ctx [Context] Context
|
10
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
11
|
+
# @param geodetic_crs [CRS] Base GeodeticCRS
|
12
|
+
# @param conversion [Conversion] Conversion
|
13
|
+
# @param coordinate_system [CoordinateSystem] Cartesian coordinate system
|
14
|
+
#
|
15
|
+
# @return [CRS]
|
16
|
+
def self.create_projected(context, name: nil, geodetic_crs:, conversion:, coordinate_system:)
|
17
|
+
pointer = Api.proj_create_projected_crs(context, name, geodetic_crs, conversion, coordinate_system)
|
18
|
+
|
19
|
+
if pointer.null?
|
20
|
+
Error.check_context(context)
|
21
|
+
end
|
22
|
+
|
23
|
+
self.create_object(pointer, context)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a BoundCRS
|
27
|
+
#
|
28
|
+
# @param ctx [Context] Context
|
29
|
+
# @param base_crs [CRS] Base CRS
|
30
|
+
# @param hub_crs [CRS] HUB CRS
|
31
|
+
# @param transformation [Transformation]
|
32
|
+
#
|
33
|
+
# @return [CRS]
|
34
|
+
def self.create_bound(context, base_crs:, hub_crs:, transformation:)
|
35
|
+
pointer = Api.proj_crs_create_bound_crs(context, base_crs, hub_crs, transformation)
|
36
|
+
|
37
|
+
if pointer.null?
|
38
|
+
Error.check_context(context)
|
39
|
+
end
|
40
|
+
|
41
|
+
self.create_object(pointer, context)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns a BoundCRS with a transformation to EPSG:4326 wrapping it
|
45
|
+
#
|
46
|
+
# @param ctx [Context] Context
|
47
|
+
# @param crs [CRS] CRS to wrap
|
48
|
+
# @param allow_intermediate_crs [String] Specifies if an intermediate CRS may be considered when
|
49
|
+
# computing the possible transformations. Allowed values are:
|
50
|
+
# * ALWAYS
|
51
|
+
# * IF_NO_DIRECT_TRANSFORMATION
|
52
|
+
# * NEVER
|
53
|
+
#
|
54
|
+
# Default is NEVER
|
55
|
+
#
|
56
|
+
# @return [CRS]
|
57
|
+
def self.create_bound_to_wgs84(context, crs:, allow_intermediate_crs: "NEVER")
|
58
|
+
options = {"ALLOW_INTERMEDIATE_CRS": allow_intermediate_crs}
|
59
|
+
options_ptr = create_options_pointer(options)
|
60
|
+
|
61
|
+
pointer = Api.proj_crs_create_bound_crs_to_WGS84(context, crs, options_ptr)
|
62
|
+
|
63
|
+
if pointer.null?
|
64
|
+
Error.check_context(context)
|
65
|
+
end
|
66
|
+
|
67
|
+
self.create_object(pointer, context)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create a a EngineeringCRS
|
71
|
+
#
|
72
|
+
# @param ctx [Context] Context
|
73
|
+
# @param name [String] Name of the CRS. Default is nil.
|
74
|
+
#
|
75
|
+
# @return [CRS]
|
76
|
+
def self.create_engineering(context, name:)
|
77
|
+
pointer = Api.proj_create_engineering_crs(context, name)
|
78
|
+
|
79
|
+
if pointer.null?
|
80
|
+
Error.check_context(context)
|
81
|
+
end
|
82
|
+
|
83
|
+
self.create_object(pointer, context)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Create a VerticalCRS. For additional functionality see Crs#create_vertical_ex
|
87
|
+
#
|
88
|
+
# @param ctx [Context] Context
|
89
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
90
|
+
# @param datum_name [String] Name of the GeodeticReferenceFrame. Default is nil.
|
91
|
+
# @param linear_units [String] Name of the angular units. Or nil for meters.
|
92
|
+
# @param linear_units_conv [Double] Conversion factor from linear units to meters. Default is 0 if linear_units is nil
|
93
|
+
#
|
94
|
+
# @return [CRS]
|
95
|
+
def self.create_vertical(context, name:, datum_name:, linear_units:, linear_units_conv:)
|
96
|
+
pointer = Api.proj_create_vertical_crs(context, name, datum_name, linear_units, linear_units_conv)
|
97
|
+
|
98
|
+
if pointer.null?
|
99
|
+
Error.check_context(context)
|
100
|
+
end
|
101
|
+
|
102
|
+
self.create_object(pointer, context)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Create a Bound Vertical CRS, with a transformation to a hub geographic 3D crs, such as
|
106
|
+
# EPSG:4979 or WGS84, using a grid
|
107
|
+
#
|
108
|
+
# @param ctx [Context] Context
|
109
|
+
# @param vertical_crs [CRS] A VerticalCRS
|
110
|
+
# @param hub_geographic_3d_crs [CRS] A Geographic 3D CRS
|
111
|
+
# @param grid_name [String] Grid name (typically a .gtx file)
|
112
|
+
#
|
113
|
+
# @return [CRS]
|
114
|
+
def self.create_bound_vertical(context, vertical_crs:, hub_crs:, grid_name:)
|
115
|
+
pointer = Api.proj_crs_create_bound_vertical_crs(context, vertical_crs, hub_crs, grid_name)
|
116
|
+
|
117
|
+
if pointer.null?
|
118
|
+
Error.check_context(context)
|
119
|
+
end
|
120
|
+
|
121
|
+
self.create_object(pointer, context)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Create a VerticalCRS. This is an extended version of Crs#create_vertical that adds
|
125
|
+
# the capability of defining a geoid model.
|
126
|
+
#
|
127
|
+
# @param ctx [Context] Context
|
128
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
129
|
+
# @param datum_name [String] Name of the GeodeticReferenceFrame. Default is nil.
|
130
|
+
# @param datum_auth_name [String] Authority name of the VerticalReferenceFrame. Default is nil.
|
131
|
+
# @param datum_code [String] Code of the VerticalReferenceFrame. Default is nil.
|
132
|
+
# @param linear_units [String] Name of the angular units. Or nil for meters.
|
133
|
+
# @param linear_units_conv [Double] Conversion factor from linear units to meters. Default is 0 if linear_units is nil
|
134
|
+
# @param geoid_model_name [String] Geoid model name. Can be a name from the geoid_model name or a string "PROJ foo.gtx". Default is nil.
|
135
|
+
# @param geoid_model_auth_name [String] Authority name of the transformation for the geoid model. Default is nil.
|
136
|
+
# @param geoid_model_code [String] Code of the transformation for the geoid model. Default is nil.
|
137
|
+
# @param geoid_geog_crs [Crs] Geographic CRS for the geoid transformation. Default is nil.
|
138
|
+
# @param accuracy [Double] Accuracy in meters. Default is nil
|
139
|
+
#
|
140
|
+
# @return [CRS]
|
141
|
+
def self.create_vertical_ex(context, name: nil, datum_name: nil, datum_auth_name: nil, datum_code: nil,
|
142
|
+
linear_units: nil, linear_units_conv: 0,
|
143
|
+
geoid_model_name: nil, geoid_model_auth_name: nil, geoid_model_code: nil,
|
144
|
+
geoid_geog_crs: nil, accuracy: nil)
|
145
|
+
|
146
|
+
options = {"ACCURACY": accuracy.nil? ? nil : accuracy.to_s}
|
147
|
+
options_ptr = create_options_pointer(options)
|
148
|
+
|
149
|
+
pointer = Api.proj_create_vertical_crs_ex(context, name, datum_name, datum_auth_name, datum_code, linear_units, linear_units_conv, geoid_model_name, geoid_model_auth_name, geoid_model_code, geoid_geog_crs, options_ptr)
|
150
|
+
|
151
|
+
if pointer.null?
|
152
|
+
Error.check_context(context)
|
153
|
+
end
|
154
|
+
|
155
|
+
self.create_object(pointer, context)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Create a CompoundCRS.
|
159
|
+
#
|
160
|
+
# @param ctx [Context] Context
|
161
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
162
|
+
# @param horizontal_crs [CRS] A horizontal CRS
|
163
|
+
# @param vertical_crs [CRS] A vertical CRS
|
164
|
+
#
|
165
|
+
# @return [CRS]
|
166
|
+
def self.create_compound(context, name:, horizontal_crs:, vertical_crs:)
|
167
|
+
pointer = Api.proj_create_compound_crs(context, name, horizontal_crs, vertical_crs)
|
168
|
+
|
169
|
+
if pointer.null?
|
170
|
+
Error.check_context(context)
|
171
|
+
end
|
172
|
+
|
173
|
+
self.create_object(pointer, context)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Create a GeographicCRS.
|
177
|
+
#
|
178
|
+
# @param ctx [Context] Context
|
179
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
180
|
+
# @param datum_name [String] Name of the GeodeticReferenceFrame. Default is nil.
|
181
|
+
# @param ellipsoid_name [String] Name of the Ellipsoid. Default is nil.
|
182
|
+
# @param semi_major_meter [Double] Ellipsoid semi-major axis, in meters.
|
183
|
+
# @param inv_flattening [Double] Ellipsoid inverse flattening. Or 0 for a sphere.
|
184
|
+
# @param prime_meridian_name [String] Name of the PrimeMeridian. Default is nil.
|
185
|
+
# @param prime_meridian_offset [Double] Offset of the prime meridian, expressed in the specified angular units.
|
186
|
+
# @param pm_angular_units [String] Name of the angular units. Or nil for degrees.
|
187
|
+
# @param pm_angular_units_conv [Double] Conversion factor from the angular unit to radians. Default is 0 if pm_angular_units is nil
|
188
|
+
# @param coordinate_system [CoordinateSystem] Ellipsoidal coordinate system
|
189
|
+
#
|
190
|
+
# @return [CRS]
|
191
|
+
def self.create_geographic(context, name:, datum_name:, ellps_name:, semi_major_meter:, inv_flattening:, prime_meridian_name:, prime_meridian_offset:, pm_angular_units:, pm_units_conv:, coordinate_system:)
|
192
|
+
pointer = Api.proj_create_geographic_crs(context, name, datum_name, ellps_name, semi_major_meter, inv_flattening, prime_meridian_name, prime_meridian_offset, pm_angular_units, pm_units_conv, coordinate_system)
|
193
|
+
|
194
|
+
if pointer.null?
|
195
|
+
Error.check_context(context)
|
196
|
+
end
|
197
|
+
|
198
|
+
self.create_object(pointer, context)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Create a GeographicCRS from a datum
|
202
|
+
#
|
203
|
+
# @param ctx [Context] Context
|
204
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
205
|
+
# @param datum [Datum | DatumEnsemble] Datum or DatumEnsemble
|
206
|
+
# @param coordinate_system [CoordinateSystem] Ellipsoidal coordinate system
|
207
|
+
#
|
208
|
+
# @return [CRS]
|
209
|
+
def self.create_geographic_from_datum(context, name:, datum:, coordinate_system:)
|
210
|
+
pointer = Api.proj_create_geographic_crs_from_datum(context, name, datum, coordinate_system)
|
211
|
+
|
212
|
+
if pointer.null?
|
213
|
+
Error.check_context(context)
|
214
|
+
end
|
215
|
+
|
216
|
+
self.create_object(pointer, context)
|
217
|
+
end
|
218
|
+
|
219
|
+
# Create a GeographicCRS.
|
220
|
+
#
|
221
|
+
# @param ctx [Context] Context
|
222
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
223
|
+
# @param datum_name [String] Name of the GeodeticReferenceFrame. Default is nil.
|
224
|
+
# @param ellipsoid_name [String] Name of the Ellipsoid. Default is nil.
|
225
|
+
# @param semi_major_meter [Double] Ellipsoid semi-major axis, in meters.
|
226
|
+
# @param inv_flattening [Double] Ellipsoid inverse flattening. Or 0 for a sphere.
|
227
|
+
# @param prime_meridian_name [String] Name of the PrimeMeridian. Default is nil.
|
228
|
+
# @param prime_meridian_offset [Double] Offset of the prime meridian, expressed in the specified angular units.
|
229
|
+
# @param angular_units [String] Name of the angular units. Or nil for degrees.
|
230
|
+
# @param angular_units_conv [Double] Conversion factor from the angular unit to radians. Default is 0 if angular_units is nil
|
231
|
+
# @param linear_units [String] Name of the angular units. Or nil for meters.
|
232
|
+
# @param linear_units_conv [Double] Conversion factor from linear units to meters. Default is 0 if linear_units is nil
|
233
|
+
#
|
234
|
+
# @return [CRS]
|
235
|
+
def self.create_geocentric(context, name:, datum_name:, ellps_name:, semi_major_meter:, inv_flattening:, prime_meridian_name:, prime_meridian_offset:, angular_units:, angular_units_conv:, linear_units:, linear_units_conv:)
|
236
|
+
pointer = Api.proj_create_geocentric_crs(context, name, datum_name, ellps_name, semi_major_meter, inv_flattening, prime_meridian_name, prime_meridian_offset, angular_units, angular_units_conv, linear_units, linear_units_conv)
|
237
|
+
|
238
|
+
if pointer.null?
|
239
|
+
Error.check_context(context)
|
240
|
+
end
|
241
|
+
|
242
|
+
self.create_object(pointer, context)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Create a GeodeticCRS of geocentric type
|
246
|
+
#
|
247
|
+
# @param ctx [Context] Context
|
248
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
249
|
+
# @param datum [Datum | DatumEnsemble] Datum or DatumEnsemble
|
250
|
+
# @param linear_units [String] Name of the angular units. Or nil for meters.
|
251
|
+
# @param linear_units_conv [Double] Conversion factor from linear units to meters. Default is 0 if linear_units is nil
|
252
|
+
#
|
253
|
+
# @return [CRS]
|
254
|
+
def self.create_geocentric_from_datum(context, name:, datum:, linear_units:, linear_units_conv:)
|
255
|
+
pointer = Api.proj_create_geocentric_crs_from_datum(context, name, datum, linear_units, linear_units_conv)
|
256
|
+
|
257
|
+
if pointer.null?
|
258
|
+
Error.check_context(context)
|
259
|
+
end
|
260
|
+
|
261
|
+
self.create_object(pointer, context)
|
262
|
+
end
|
263
|
+
|
264
|
+
# Create a DerivedGeograhicCRS
|
265
|
+
#
|
266
|
+
# @param ctx [Context] Context
|
267
|
+
# @param name [String] Name of the GeographicCRS. Default is nil.
|
268
|
+
# @param base_geographic_crs [CRS] Base Geographic CRS
|
269
|
+
# @param conversion [Conversion] Conversion from the base Geographic to the DerivedGeograhicCRS
|
270
|
+
# @param coordinate_system [CoordinateSystem] Ellipsoidal coordinate system
|
271
|
+
#
|
272
|
+
# @return [CRS]
|
273
|
+
def self.create_derived_geographic(context, name: nil, base_geographic_crs:, conversion:, coordinate_system:)
|
274
|
+
pointer = Api.proj_create_derived_geographic_crs(context, name, base_geographic_crs, conversion, coordinate_system)
|
275
|
+
|
276
|
+
if pointer.null?
|
277
|
+
Error.check_context(context)
|
278
|
+
end
|
279
|
+
|
280
|
+
self.create_object(pointer, context)
|
281
|
+
end
|
282
|
+
|
283
|
+
# Find GeodeticCRSes that use the specified datum
|
284
|
+
#
|
285
|
+
# @param ctx [Context] Context
|
286
|
+
# @param auth_name [string] - Authority name. Default is nil.
|
287
|
+
# @param datum_auth_name [String] Datum authority name
|
288
|
+
# @param datum_code [String] Datum code
|
289
|
+
# @param crs_type [String] The CRS type. Default is nil. Allowed values are:
|
290
|
+
# * geographic 2D
|
291
|
+
# * geographic 3D
|
292
|
+
# * geocentric
|
293
|
+
#
|
294
|
+
# @return [PjObjects] - A list of CRSes
|
295
|
+
def self.query_geodetic_from_datum(context, auth_name: nil, datum_auth_name:, datum_code:, crs_type: nil)
|
296
|
+
pointer = Api.proj_query_geodetic_crs_from_datum(context, auth_name, datum_auth_name, datum_code, crs_type)
|
297
|
+
|
298
|
+
if pointer.null?
|
299
|
+
Error.check_context(context)
|
300
|
+
end
|
301
|
+
|
302
|
+
PjObjects.new(pointer, context)
|
303
|
+
end
|
304
|
+
|
305
|
+
# To create a coordinate system, you can use CRS codes, well-known text (WKT) strings
|
306
|
+
# or old-style Proj4 strings (which are deprecated).
|
307
|
+
#
|
308
|
+
# @example
|
309
|
+
# crs1 = Proj::Crs.new('EPSG:4326')
|
310
|
+
# crs2 = Proj::Crs.new('urn:ogc:def:crs:EPSG::4326')
|
311
|
+
# crs3 = Proj::Crs.new('+proj=longlat +datum=WGS84 +no_defs +type=crs')
|
312
|
+
# crs4 = Proj::Crs.new(<<~EOS)
|
313
|
+
# GEOGCRS["WGS 84",
|
314
|
+
# DATUM["World Geodetic System 1984",
|
315
|
+
# ELLIPSOID["WGS 84",6378137,298.257223563,
|
316
|
+
# LENGTHUNIT["meter",1]]],
|
317
|
+
# PRIMEM["Greenwich",0,
|
318
|
+
# ANGLEUNIT["degree",0.0174532925199433]],
|
319
|
+
# CS[ellipsoidal,2],
|
320
|
+
# AXIS["geodetic latitude (Lat)",north,
|
321
|
+
# ORDER[1],
|
322
|
+
# ANGLEUNIT["degree",0.0174532925199433]],
|
323
|
+
# AXIS["geodetic longitude (Lon)",east,
|
324
|
+
# ORDER[2],
|
325
|
+
# ANGLEUNIT["degree",0.0174532925199433]],
|
326
|
+
# USAGE[
|
327
|
+
# SCOPE["unknown"],
|
328
|
+
# AREA["World"],
|
329
|
+
# BBOX[-90,-180,90,180]],
|
330
|
+
# ID["EPSG",4326]]
|
331
|
+
# EOS
|
332
|
+
#
|
333
|
+
# Notice when using the old-style Proj4 string, the addition of the "+type=crs" value.
|
334
|
+
#
|
335
|
+
# @param value [String]. See above
|
336
|
+
# @param context [Context]. An optional Context that the Crs will use for calculations.
|
337
|
+
def initialize(value, context=nil)
|
338
|
+
ptr = Api.proj_create(context || Context.current, value)
|
339
|
+
|
340
|
+
if ptr.null?
|
341
|
+
Error.check_object(self)
|
342
|
+
end
|
343
|
+
|
344
|
+
super(ptr, context)
|
345
|
+
|
346
|
+
if Api.method_defined?(:proj_is_crs) && !Api.proj_is_crs(ptr)
|
347
|
+
raise(Error, "Invalid crs definition. Proj created an instance of: #{self.proj_type}.")
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
# Get the geodeticCRS / geographicCRS from a CRS.
|
352
|
+
#
|
353
|
+
# @example
|
354
|
+
# crs = Proj::Crs.new('EPSG:4326')
|
355
|
+
# geodetic = crs.geodetic_crs
|
356
|
+
# assert_equal(:PJ_TYPE_GEOGRAPHIC_2D_CRS, geodetic.proj_type)
|
357
|
+
# assert_equal('+proj=longlat +datum=WGS84 +no_defs +type=crs', geodetic.to_proj_string)
|
358
|
+
#
|
359
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_crs_get_geodetic_crs
|
360
|
+
#
|
361
|
+
# @return [CRS]
|
362
|
+
def geodetic_crs
|
363
|
+
pointer = Api.proj_crs_get_geodetic_crs(self.context, self)
|
364
|
+
self.class.create_object(pointer, self.context)
|
365
|
+
end
|
366
|
+
|
367
|
+
# Get a CRS component from a CompoundCRS.
|
368
|
+
#
|
369
|
+
# @see {https://proj.org/development/reference/functions.html#c.proj_crs_get_sub_crs} proj_crs_get_sub_crs
|
370
|
+
#
|
371
|
+
# @param index [Integer] Index of the CRS component (typically 0 = horizontal, 1 = vertical)
|
372
|
+
#
|
373
|
+
# @return [CRS]
|
374
|
+
def sub_crs(index)
|
375
|
+
pointer = Api.proj_crs_get_sub_crs(self.context, self, index)
|
376
|
+
self.class.create_object(pointer, self.context)
|
377
|
+
end
|
378
|
+
|
379
|
+
# Returns the datum of a SingleCRS.
|
380
|
+
#
|
381
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_crs_get_datum
|
382
|
+
#
|
383
|
+
# @return [Datum]
|
384
|
+
def datum
|
385
|
+
ptr = Api.proj_crs_get_datum(self.context, self)
|
386
|
+
|
387
|
+
if ptr.null?
|
388
|
+
Error.check_object(self)
|
389
|
+
end
|
390
|
+
|
391
|
+
self.class.create_object(ptr, self.context)
|
392
|
+
end
|
393
|
+
|
394
|
+
# Returns a datum for a SingleCRS. If the SingleCRS has a datum, then this datum is returned.
|
395
|
+
# Otherwise, the SingleCRS has a datum ensemble, and this datum ensemble is returned as
|
396
|
+
# a regular datum instead of a datum ensemble.
|
397
|
+
#
|
398
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_crs_get_datum_forced
|
399
|
+
#
|
400
|
+
# @return [Datum]
|
401
|
+
def datum_forced
|
402
|
+
pointer = Api.proj_crs_get_datum_forced(self.context, self)
|
403
|
+
self.class.create_object(pointer, self.context)
|
404
|
+
end
|
405
|
+
|
406
|
+
# Get the horizontal datum from a CRS.
|
407
|
+
#
|
408
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_crs_get_horizontal_datum
|
409
|
+
#
|
410
|
+
# @return [CRS]
|
411
|
+
def horizontal_datum
|
412
|
+
pointer = Api.proj_crs_get_horizontal_datum(self.context, self)
|
413
|
+
self.class.create_object(pointer, self.context)
|
414
|
+
end
|
415
|
+
|
416
|
+
# Returns the {DatumEnsemble datum ensemble} of a SingleCRS.
|
417
|
+
#
|
418
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_crs_get_datum_ensemble
|
419
|
+
#
|
420
|
+
# @return [DatumEnsemble]
|
421
|
+
def datum_ensemble
|
422
|
+
pointer = Api.proj_crs_get_datum_ensemble(self.context, self)
|
423
|
+
self.class.create_object(pointer, self.context)
|
424
|
+
end
|
425
|
+
|
426
|
+
# Returns the coordinate system of a SingleCRS.
|
427
|
+
#
|
428
|
+
# @return [CoordinateSystem]
|
429
|
+
def coordinate_system
|
430
|
+
pointer = Api.proj_crs_get_coordinate_system(self.context, self)
|
431
|
+
CoordinateSystem.new(pointer, self.context)
|
432
|
+
end
|
433
|
+
|
434
|
+
# Returns the ellipsoid
|
435
|
+
#
|
436
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_get_ellipsoid
|
437
|
+
#
|
438
|
+
# @return [PjObject]
|
439
|
+
def ellipsoid
|
440
|
+
pointer = Api.proj_get_ellipsoid(self.context, self)
|
441
|
+
self.class.create_object(pointer, self.context)
|
442
|
+
end
|
443
|
+
|
444
|
+
# Returns whether a CRS is a derived CRS.
|
445
|
+
#
|
446
|
+
# @return [Boolean]
|
447
|
+
def derived?
|
448
|
+
result = Api.proj_crs_is_derived(self.context, self)
|
449
|
+
result == 1 ? true : false
|
450
|
+
end
|
451
|
+
|
452
|
+
# Return the Conversion of a DerivedCRS (such as a ProjectedCRS), or the Transformation from
|
453
|
+
# the baseCRS to the hubCRS of a BoundCRS.
|
454
|
+
#
|
455
|
+
# @return [PjObject]
|
456
|
+
def coordinate_operation
|
457
|
+
ptr = Api.proj_crs_get_coordoperation(self.context, self)
|
458
|
+
if ptr.null?
|
459
|
+
Error.check_object(self)
|
460
|
+
end
|
461
|
+
self.class.create_object(ptr, self.context)
|
462
|
+
end
|
463
|
+
|
464
|
+
# Returns the prime meridian
|
465
|
+
#
|
466
|
+
# @see https://proj.org/development/reference/functions.html#c.proj_get_prime_meridian
|
467
|
+
#
|
468
|
+
# @return [PjObject]
|
469
|
+
def prime_meridian
|
470
|
+
pointer = Api.proj_get_prime_meridian(self.context, self)
|
471
|
+
self.class.create_object(pointer, self.context)
|
472
|
+
end
|
473
|
+
|
474
|
+
# Returns a list of matching reference CRS, and the percentage (0-100) of confidence in the match.
|
475
|
+
#
|
476
|
+
# @param auth_name [string] - Authority name, or nil for all authorities
|
477
|
+
#
|
478
|
+
# @return [Array] - Array of CRS objects sorted by decreasing confidence.
|
479
|
+
def identify(auth_name)
|
480
|
+
confidences_out_ptr = FFI::MemoryPointer.new(:pointer)
|
481
|
+
pointer = Api.proj_identify(self.context, self, auth_name, nil, confidences_out_ptr)
|
482
|
+
objects = PjObjects.new(pointer, self.context)
|
483
|
+
|
484
|
+
# Get confidences and free the list
|
485
|
+
confidences_ptr = confidences_out_ptr.read_pointer
|
486
|
+
confidences = confidences_ptr.read_array_of_type(:int, :read_int, objects.count)
|
487
|
+
Api.proj_int_list_destroy(confidences_ptr)
|
488
|
+
|
489
|
+
return objects, confidences
|
490
|
+
end
|
491
|
+
|
492
|
+
# Returns whether a CRS is a Derived CRS
|
493
|
+
#
|
494
|
+
# @return [Boolean] - True if the CRS is derived
|
495
|
+
def derived?
|
496
|
+
result = Api.proj_is_derived_crs(self.context, self)
|
497
|
+
result == 1 ? true : false
|
498
|
+
end
|
499
|
+
|
500
|
+
# Return a copy of the CRS with its name changed
|
501
|
+
#
|
502
|
+
# @param name [String] The new name of the CRS
|
503
|
+
#
|
504
|
+
# @return [CRS]
|
505
|
+
def alter_name(name)
|
506
|
+
ptr = Api.proj_alter_name(self.context, self, name)
|
507
|
+
|
508
|
+
if ptr.null?
|
509
|
+
Error.check_object(self)
|
510
|
+
end
|
511
|
+
|
512
|
+
self.class.create_object(ptr, context)
|
513
|
+
end
|
514
|
+
|
515
|
+
# Return a copy of the CRS with its identifier changed
|
516
|
+
#
|
517
|
+
# @param name [String] The new authority name of the CRS
|
518
|
+
# @param code [String] The new code of the CRS
|
519
|
+
#
|
520
|
+
# @return [CRS]
|
521
|
+
def alter_id(auth_name, code)
|
522
|
+
ptr = Api.proj_alter_id(self.context, self, auth_name, code)
|
523
|
+
|
524
|
+
if ptr.null?
|
525
|
+
Error.check_object(self)
|
526
|
+
end
|
527
|
+
|
528
|
+
self.class.create_object(ptr, context)
|
529
|
+
end
|
530
|
+
|
531
|
+
# Return a copy of the CRS with its geodetic CRS changed.
|
532
|
+
# * If the CRS is a GeodeticCRS then a clone of new_geod_crs is returned.
|
533
|
+
# * If the CRS is a ProjectedCRS, then it replaces the base CRS with new_geod_crs.
|
534
|
+
# * If the CRS is a CompoundCRS, then it replaces the GeodeticCRS part of the horizontal
|
535
|
+
# CRS with new_geod_crs.
|
536
|
+
# * In other cases, it returns a clone of obj.
|
537
|
+
#
|
538
|
+
# @param new_geod_crs [CRS] A GeodeticCRS
|
539
|
+
#
|
540
|
+
# @return [CRS]
|
541
|
+
def alter_geodetic_crs(new_geod_crs)
|
542
|
+
ptr = Api.proj_crs_alter_geodetic_crs(self.context, self, new_geod_crs)
|
543
|
+
|
544
|
+
if ptr.null?
|
545
|
+
Error.check_object(self)
|
546
|
+
end
|
547
|
+
|
548
|
+
self.class.create_object(ptr, context)
|
549
|
+
end
|
550
|
+
|
551
|
+
# Return a copy of the CRS with its angular units changed
|
552
|
+
#
|
553
|
+
# @param angular_units [String] Name of the angular units. Or nil for degrees.
|
554
|
+
# @param angular_units_conv [Double] Conversion factor from the angular unit to radians. Default is 0 if angular_units is nil
|
555
|
+
# @param unit_auth_name [String] Unit authority name. Defaults to nil.
|
556
|
+
# @param unit_code [String] Unit code. Defaults to nil.
|
557
|
+
#
|
558
|
+
# @return [CRS]
|
559
|
+
def alter_cs_angular_unit(angular_units: nil, angular_units_conv: 0, unit_auth_name: nil, unit_code: nil)
|
560
|
+
ptr = Api.proj_crs_alter_cs_angular_unit(self.context, self, angular_units, angular_units_conv, unit_auth_name, unit_code)
|
561
|
+
|
562
|
+
if ptr.null?
|
563
|
+
Error.check_object(self)
|
564
|
+
end
|
565
|
+
|
566
|
+
self.class.create_object(ptr, context)
|
567
|
+
end
|
568
|
+
|
569
|
+
# Return a copy of the CRS with its linear units changed. The CRS
|
570
|
+
# must be or contain a ProjectedCRS, VerticalCRS or a GeocentricCRS.
|
571
|
+
#
|
572
|
+
# @param linear_units [String] Name of the linear units. Or nil for meters.
|
573
|
+
# @param linear_units_conv [Double] Conversion factor from the linear unit to meters. Default is 0 if linear_units is nil
|
574
|
+
# @param unit_auth_name [String] Unit authority name. Defaults to nil.
|
575
|
+
# @param unit_code [String] Unit code. Defaults to nil.
|
576
|
+
#
|
577
|
+
# @return [CRS]
|
578
|
+
def alter_cs_linear_unit(linear_units: nil, linear_units_conv: 0, unit_auth_name: nil, unit_code: nil)
|
579
|
+
ptr = Api.proj_crs_alter_cs_linear_unit(self.context, self, linear_units, linear_units_conv, unit_auth_name, unit_code)
|
580
|
+
|
581
|
+
if ptr.null?
|
582
|
+
Error.check_object(self)
|
583
|
+
end
|
584
|
+
|
585
|
+
self.class.create_object(ptr, context)
|
586
|
+
end
|
587
|
+
|
588
|
+
# Return a copy of the CRS with its linear units changed. The CRS
|
589
|
+
# must be or contain a ProjectedCRS, VerticalCRS or a GeocentricCRS.
|
590
|
+
#
|
591
|
+
# @param linear_units [String] Name of the linear units. Or nil for meters.
|
592
|
+
# @param linear_units_conv [Double] Conversion factor from the linear unit to meters. Default is 0 if linear_units is nil
|
593
|
+
# @param unit_auth_name [String] Unit authority name. Defaults to nil.
|
594
|
+
# @param unit_code [String] Unit code. Defaults to nil.
|
595
|
+
# @param convert_to_new_unit [Boolean] If true then existing values will be converted from
|
596
|
+
# their current unit to the new unit. If false then their values will be left unchanged
|
597
|
+
# and the unit overridden (so the resulting CRS will not be equivalent to the
|
598
|
+
# original one for reprojection purposes).
|
599
|
+
#
|
600
|
+
# @return [CRS]
|
601
|
+
def alter_parameters_linear_unit(linear_units: nil, linear_units_conv: 0, unit_auth_name: nil, unit_code: nil, convert_to_new_unit:)
|
602
|
+
ptr = Api.proj_crs_alter_parameters_linear_unit(self.context, self, linear_units, linear_units_conv,
|
603
|
+
unit_auth_name, unit_code,
|
604
|
+
convert_to_new_unit ? 1 : 0)
|
605
|
+
|
606
|
+
if ptr.null?
|
607
|
+
Error.check_object(self)
|
608
|
+
end
|
609
|
+
|
610
|
+
self.class.create_object(ptr, context)
|
611
|
+
end
|
612
|
+
|
613
|
+
# Create a 3D CRS from this 2D CRS. The new axis will be ellipsoidal height,
|
614
|
+
# oriented upwards, and with metre units.
|
615
|
+
#
|
616
|
+
# @param name [String] CRS name. If nil then the name of this CRS will be used.
|
617
|
+
#
|
618
|
+
# @return [CRS]
|
619
|
+
def promote_to_3d(name: nil)
|
620
|
+
ptr = Api.proj_crs_promote_to_3D(self.context, name, self)
|
621
|
+
|
622
|
+
if ptr.null?
|
623
|
+
Error.check_object(self)
|
624
|
+
end
|
625
|
+
|
626
|
+
self.class.create_object(ptr, context)
|
627
|
+
end
|
628
|
+
|
629
|
+
# Create a 2D CRS from an this 3D CRS.
|
630
|
+
#
|
631
|
+
# @param name [String] CRS name. If nil then the name of this CRS will be used.
|
632
|
+
#
|
633
|
+
# @return [CRS]
|
634
|
+
def demote_to_2d(name: nil)
|
635
|
+
ptr = Api.proj_crs_demote_to_2D(self.context, name, self)
|
636
|
+
|
637
|
+
if ptr.null?
|
638
|
+
Error.check_object(self)
|
639
|
+
end
|
640
|
+
|
641
|
+
self.class.create_object(ptr, context)
|
642
|
+
end
|
643
|
+
|
644
|
+
# Create a projected 3D CRS from this projected 2D CRS.
|
645
|
+
#
|
646
|
+
# This CRS's name is replaced by the name parameter and its base geographic CRS
|
647
|
+
# is replaced by geog_3D_crs. The vertical axis of geog_3D_crs (ellipsoidal height)
|
648
|
+
# will be added as the 3rd axis of the resulting projected 3D CRS.
|
649
|
+
#
|
650
|
+
# Normally, the passed geog_3D_crs should be the 3D counterpart of the original
|
651
|
+
# 2D base geographic CRS of projected_2D_crs, but such no check is done.
|
652
|
+
#
|
653
|
+
# It is also possible to invoke this function with a nil geog_3D_crs. In this case
|
654
|
+
# the existing base geographic of this CRS will be automatically promoted to 3D by
|
655
|
+
# assuming a 3rd axis being an ellipsoidal height, oriented upwards, and with metre units.
|
656
|
+
# This is equivalent to using Crs#promote_to_3d
|
657
|
+
#
|
658
|
+
# @param name [String] CRS name. If nil then the name of this CRS will be used.
|
659
|
+
# @param geog_3D_crs [CRS] Base geographic 3D CRS for the new CRS. Defaults to nil.
|
660
|
+
#
|
661
|
+
# @return [CRS]
|
662
|
+
def projected_3d(name: nil, geog_3d_crs: nil)
|
663
|
+
ptr = Api.proj_crs_create_projected_3D_crs_from_2D(self.context, name, self, geog_3d_crs)
|
664
|
+
|
665
|
+
if ptr.null?
|
666
|
+
Error.check_object(self)
|
667
|
+
end
|
668
|
+
|
669
|
+
self.class.create_object(ptr, context)
|
670
|
+
end
|
671
|
+
end
|
672
|
+
end
|