proj4rb 2.2.1 → 2.2.2
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/ChangeLog +66 -61
- data/Gemfile +4 -4
- data/Rakefile +27 -27
- data/lib/api/api.rb +110 -83
- data/lib/api/api_4_9.rb +30 -30
- data/lib/api/api_5_0.rb +300 -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 +41 -42
- data/lib/api/api_6_1.rb +4 -4
- data/lib/api/api_6_2.rb +6 -5
- data/lib/area.rb +32 -32
- data/lib/config.rb +69 -69
- data/lib/context.rb +102 -102
- data/lib/coordinate.rb +197 -197
- data/lib/crs.rb +204 -204
- data/lib/ellipsoid.rb +41 -41
- data/lib/error.rb +17 -17
- data/lib/operation.rb +42 -42
- data/lib/pj_object.rb +80 -80
- data/lib/point.rb +72 -72
- data/lib/prime_meridian.rb +39 -39
- data/lib/proj.rb +30 -30
- data/lib/projection.rb +206 -206
- data/lib/transformation.rb +60 -60
- data/lib/unit.rb +53 -53
- data/proj4rb.gemspec +32 -32
- data/test/abstract_test.rb +7 -7
- data/test/context_test.rb +81 -81
- data/test/coordinate_test.rb +34 -34
- data/test/crs_test.rb +372 -372
- data/test/ellipsoid_test.rb +34 -34
- data/test/operation_test.rb +29 -29
- data/test/prime_meridians_test.rb +33 -33
- data/test/proj_test.rb +16 -16
- data/test/projection_test.rb +223 -223
- data/test/transformation_test.rb +67 -67
- data/test/unit_test.rb +47 -47
- metadata +2 -2
data/lib/coordinate.rb
CHANGED
@@ -1,197 +1,197 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
module Proj
|
4
|
-
# A four dimensional coordinate of double values.
|
5
|
-
#
|
6
|
-
# For most geographic Crses, the units will be in degrees.
|
7
|
-
class Coordinate
|
8
|
-
def self.from_coord(pj_coord)
|
9
|
-
result = self.allocate
|
10
|
-
result.instance_variable_set(:@coord, pj_coord)
|
11
|
-
result
|
12
|
-
end
|
13
|
-
|
14
|
-
# Creates a new coordinate.
|
15
|
-
#
|
16
|
-
# @example
|
17
|
-
#
|
18
|
-
# coord = Proj::Coordinate.new(:x => 1, :y => 2, :z => 3, :t => 4)
|
19
|
-
# coord = Proj::Coordinate.new(:u => 5, :v => 6, :w => 7, :t => 8)
|
20
|
-
# coord = Proj::Coordinate.new(:lam => 9, :phi => 10, :z => 11, :t => 12)
|
21
|
-
# coord = Proj::Coordinate.new(:s => 13, :a1 => 14, :a2 => 15)
|
22
|
-
# coord = Proj::Coordinate.new(:o => 16, :p => 17, :k => 18)
|
23
|
-
# coord = Proj::Coordinate.new(:e => 19, :n => 20, :u => 21)
|
24
|
-
|
25
|
-
def initialize(x: nil, y: nil, z: nil, t: nil,
|
26
|
-
u: nil, v: nil, w: nil, # t: nil
|
27
|
-
lam: nil, phi: nil, # z: nil, t: nil,
|
28
|
-
s: nil, a1: nil, a2: nil,
|
29
|
-
o: nil, p: nil, k: nil,
|
30
|
-
e: nil, n: nil) #u: nil
|
31
|
-
|
32
|
-
@coord = Api::PJ_COORD.new
|
33
|
-
|
34
|
-
keys = if x && y && z && t
|
35
|
-
[:x, :y, :z, :t]
|
36
|
-
elsif x && y && z
|
37
|
-
[:x, :y, :z]
|
38
|
-
elsif x && y
|
39
|
-
[:x, :y]
|
40
|
-
elsif u && v && w && t
|
41
|
-
[:u, :v, :w, :t]
|
42
|
-
elsif u && v && w
|
43
|
-
[:u, :v, :w]
|
44
|
-
elsif u && v
|
45
|
-
[:u, :v]
|
46
|
-
elsif lam && phi && z && t
|
47
|
-
[:lam, :phi, :z, :t]
|
48
|
-
elsif lam && phi && z
|
49
|
-
[:lam, :phi, :z]
|
50
|
-
elsif lam && phi
|
51
|
-
[:lam, :phi]
|
52
|
-
elsif s && a1 && a2
|
53
|
-
[:s, :a1, :a2]
|
54
|
-
elsif e && n && u
|
55
|
-
[:e, :n, :u]
|
56
|
-
elsif o && p && k
|
57
|
-
[:o, :p, :k]
|
58
|
-
end
|
59
|
-
|
60
|
-
coord_struct = @coord[:v]
|
61
|
-
keys.each_with_index do |key, index|
|
62
|
-
coord_struct[index] = binding.local_variable_get(key)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def to_ptr
|
67
|
-
@coord.to_ptr
|
68
|
-
end
|
69
|
-
|
70
|
-
# Returns x coordinate
|
71
|
-
#
|
72
|
-
# @return [Float]
|
73
|
-
def x
|
74
|
-
@coord[:v][0]
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns y coordinate
|
78
|
-
#
|
79
|
-
# @return [Float]
|
80
|
-
def y
|
81
|
-
@coord[:v][1]
|
82
|
-
end
|
83
|
-
|
84
|
-
# Returns z coordinate
|
85
|
-
#
|
86
|
-
# @return [Float]
|
87
|
-
def z
|
88
|
-
@coord[:v][2]
|
89
|
-
end
|
90
|
-
|
91
|
-
# Returns t coordinate
|
92
|
-
#
|
93
|
-
# @return [Float]
|
94
|
-
def t
|
95
|
-
@coord[:v][3]
|
96
|
-
end
|
97
|
-
|
98
|
-
# Returns u coordinate
|
99
|
-
#
|
100
|
-
# @return [Float]
|
101
|
-
# TODO - This could be u in uvw or enu. Going to ignore that
|
102
|
-
def u
|
103
|
-
@coord[:v][0]
|
104
|
-
end
|
105
|
-
|
106
|
-
# Returns v coordinate
|
107
|
-
#
|
108
|
-
# @return [Float]
|
109
|
-
def v
|
110
|
-
@coord[:v][1]
|
111
|
-
end
|
112
|
-
|
113
|
-
# Returns w coordinate
|
114
|
-
#
|
115
|
-
# @return [Float]
|
116
|
-
def w
|
117
|
-
@coord[:v][2]
|
118
|
-
end
|
119
|
-
|
120
|
-
# Returns lam coordinate
|
121
|
-
#
|
122
|
-
# @return [Float]
|
123
|
-
def lam
|
124
|
-
@coord[:v][0]
|
125
|
-
end
|
126
|
-
|
127
|
-
# Returns phi coordinate
|
128
|
-
#
|
129
|
-
# @return [Float]
|
130
|
-
def phi
|
131
|
-
@coord[:v][1]
|
132
|
-
end
|
133
|
-
|
134
|
-
# Returns o coordinate
|
135
|
-
#
|
136
|
-
# @return [Float]
|
137
|
-
def o
|
138
|
-
@coord[:v][0]
|
139
|
-
end
|
140
|
-
|
141
|
-
# Returns p coordinate
|
142
|
-
#
|
143
|
-
# @return [Float]
|
144
|
-
def p
|
145
|
-
@coord[:v][1]
|
146
|
-
end
|
147
|
-
|
148
|
-
# Returns k coordinate
|
149
|
-
#
|
150
|
-
# @return [Float]
|
151
|
-
def k
|
152
|
-
@coord[:v][3]
|
153
|
-
end
|
154
|
-
|
155
|
-
# Returns e coordinate
|
156
|
-
#
|
157
|
-
# @return [Float]
|
158
|
-
def e
|
159
|
-
@coord[:v][0]
|
160
|
-
end
|
161
|
-
|
162
|
-
# Returns n coordinate
|
163
|
-
#
|
164
|
-
# @return [Float]
|
165
|
-
def n
|
166
|
-
@coord[:v][1]
|
167
|
-
end
|
168
|
-
|
169
|
-
# Returns s coordinate
|
170
|
-
#
|
171
|
-
# @return [Float]
|
172
|
-
def s
|
173
|
-
@coord[:v][0]
|
174
|
-
end
|
175
|
-
|
176
|
-
# Returns a1 coordinate
|
177
|
-
#
|
178
|
-
# @return [Float]
|
179
|
-
def a1
|
180
|
-
@coord[:v][1]
|
181
|
-
end
|
182
|
-
|
183
|
-
# Returns a2 coordinate
|
184
|
-
#
|
185
|
-
# @return [Float]
|
186
|
-
def a2
|
187
|
-
@coord[:v][2]
|
188
|
-
end
|
189
|
-
|
190
|
-
# Returns nice printout of coordinate contents
|
191
|
-
#
|
192
|
-
# @return [String]
|
193
|
-
def to_s
|
194
|
-
"v0: #{self.x}, v1: #{self.y}, v2: #{self.z}, v3: #{self.t}"
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Proj
|
4
|
+
# A four dimensional coordinate of double values.
|
5
|
+
#
|
6
|
+
# For most geographic Crses, the units will be in degrees.
|
7
|
+
class Coordinate
|
8
|
+
def self.from_coord(pj_coord)
|
9
|
+
result = self.allocate
|
10
|
+
result.instance_variable_set(:@coord, pj_coord)
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
# Creates a new coordinate.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
#
|
18
|
+
# coord = Proj::Coordinate.new(:x => 1, :y => 2, :z => 3, :t => 4)
|
19
|
+
# coord = Proj::Coordinate.new(:u => 5, :v => 6, :w => 7, :t => 8)
|
20
|
+
# coord = Proj::Coordinate.new(:lam => 9, :phi => 10, :z => 11, :t => 12)
|
21
|
+
# coord = Proj::Coordinate.new(:s => 13, :a1 => 14, :a2 => 15)
|
22
|
+
# coord = Proj::Coordinate.new(:o => 16, :p => 17, :k => 18)
|
23
|
+
# coord = Proj::Coordinate.new(:e => 19, :n => 20, :u => 21)
|
24
|
+
|
25
|
+
def initialize(x: nil, y: nil, z: nil, t: nil,
|
26
|
+
u: nil, v: nil, w: nil, # t: nil
|
27
|
+
lam: nil, phi: nil, # z: nil, t: nil,
|
28
|
+
s: nil, a1: nil, a2: nil,
|
29
|
+
o: nil, p: nil, k: nil,
|
30
|
+
e: nil, n: nil) #u: nil
|
31
|
+
|
32
|
+
@coord = Api::PJ_COORD.new
|
33
|
+
|
34
|
+
keys = if x && y && z && t
|
35
|
+
[:x, :y, :z, :t]
|
36
|
+
elsif x && y && z
|
37
|
+
[:x, :y, :z]
|
38
|
+
elsif x && y
|
39
|
+
[:x, :y]
|
40
|
+
elsif u && v && w && t
|
41
|
+
[:u, :v, :w, :t]
|
42
|
+
elsif u && v && w
|
43
|
+
[:u, :v, :w]
|
44
|
+
elsif u && v
|
45
|
+
[:u, :v]
|
46
|
+
elsif lam && phi && z && t
|
47
|
+
[:lam, :phi, :z, :t]
|
48
|
+
elsif lam && phi && z
|
49
|
+
[:lam, :phi, :z]
|
50
|
+
elsif lam && phi
|
51
|
+
[:lam, :phi]
|
52
|
+
elsif s && a1 && a2
|
53
|
+
[:s, :a1, :a2]
|
54
|
+
elsif e && n && u
|
55
|
+
[:e, :n, :u]
|
56
|
+
elsif o && p && k
|
57
|
+
[:o, :p, :k]
|
58
|
+
end
|
59
|
+
|
60
|
+
coord_struct = @coord[:v]
|
61
|
+
keys.each_with_index do |key, index|
|
62
|
+
coord_struct[index] = binding.local_variable_get(key)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_ptr
|
67
|
+
@coord.to_ptr
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns x coordinate
|
71
|
+
#
|
72
|
+
# @return [Float]
|
73
|
+
def x
|
74
|
+
@coord[:v][0]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns y coordinate
|
78
|
+
#
|
79
|
+
# @return [Float]
|
80
|
+
def y
|
81
|
+
@coord[:v][1]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns z coordinate
|
85
|
+
#
|
86
|
+
# @return [Float]
|
87
|
+
def z
|
88
|
+
@coord[:v][2]
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns t coordinate
|
92
|
+
#
|
93
|
+
# @return [Float]
|
94
|
+
def t
|
95
|
+
@coord[:v][3]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns u coordinate
|
99
|
+
#
|
100
|
+
# @return [Float]
|
101
|
+
# TODO - This could be u in uvw or enu. Going to ignore that
|
102
|
+
def u
|
103
|
+
@coord[:v][0]
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns v coordinate
|
107
|
+
#
|
108
|
+
# @return [Float]
|
109
|
+
def v
|
110
|
+
@coord[:v][1]
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns w coordinate
|
114
|
+
#
|
115
|
+
# @return [Float]
|
116
|
+
def w
|
117
|
+
@coord[:v][2]
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns lam coordinate
|
121
|
+
#
|
122
|
+
# @return [Float]
|
123
|
+
def lam
|
124
|
+
@coord[:v][0]
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns phi coordinate
|
128
|
+
#
|
129
|
+
# @return [Float]
|
130
|
+
def phi
|
131
|
+
@coord[:v][1]
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns o coordinate
|
135
|
+
#
|
136
|
+
# @return [Float]
|
137
|
+
def o
|
138
|
+
@coord[:v][0]
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns p coordinate
|
142
|
+
#
|
143
|
+
# @return [Float]
|
144
|
+
def p
|
145
|
+
@coord[:v][1]
|
146
|
+
end
|
147
|
+
|
148
|
+
# Returns k coordinate
|
149
|
+
#
|
150
|
+
# @return [Float]
|
151
|
+
def k
|
152
|
+
@coord[:v][3]
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns e coordinate
|
156
|
+
#
|
157
|
+
# @return [Float]
|
158
|
+
def e
|
159
|
+
@coord[:v][0]
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns n coordinate
|
163
|
+
#
|
164
|
+
# @return [Float]
|
165
|
+
def n
|
166
|
+
@coord[:v][1]
|
167
|
+
end
|
168
|
+
|
169
|
+
# Returns s coordinate
|
170
|
+
#
|
171
|
+
# @return [Float]
|
172
|
+
def s
|
173
|
+
@coord[:v][0]
|
174
|
+
end
|
175
|
+
|
176
|
+
# Returns a1 coordinate
|
177
|
+
#
|
178
|
+
# @return [Float]
|
179
|
+
def a1
|
180
|
+
@coord[:v][1]
|
181
|
+
end
|
182
|
+
|
183
|
+
# Returns a2 coordinate
|
184
|
+
#
|
185
|
+
# @return [Float]
|
186
|
+
def a2
|
187
|
+
@coord[:v][2]
|
188
|
+
end
|
189
|
+
|
190
|
+
# Returns nice printout of coordinate contents
|
191
|
+
#
|
192
|
+
# @return [String]
|
193
|
+
def to_s
|
194
|
+
"v0: #{self.x}, v1: #{self.y}, v2: #{self.z}, v3: #{self.t}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
data/lib/crs.rb
CHANGED
@@ -1,204 +1,204 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
module Proj
|
5
|
-
# Represents a coordinate reference system.
|
6
|
-
class Crs < PjObject
|
7
|
-
# To create a coordinate system, you can use CRS codes, well-known text (WKT) strings
|
8
|
-
# or old-style Proj4 strings (which are deprecated).
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# crs1 = Proj::Crs.new('EPSG:4326')
|
12
|
-
# crs2 = Proj::Crs.new('urn:ogc:def:crs:EPSG::4326')
|
13
|
-
# crs3 = Proj::Crs.new('+proj=longlat +datum=WGS84 +no_defs +type=crs')
|
14
|
-
# crs4 = Proj::Crs.new(<<~EOS)
|
15
|
-
# GEOGCRS["WGS 84",
|
16
|
-
# DATUM["World Geodetic System 1984",
|
17
|
-
# ELLIPSOID["WGS 84",6378137,298.257223563,
|
18
|
-
# LENGTHUNIT["metre",1]]],
|
19
|
-
# PRIMEM["Greenwich",0,
|
20
|
-
# ANGLEUNIT["degree",0.0174532925199433]],
|
21
|
-
# CS[ellipsoidal,2],
|
22
|
-
# AXIS["geodetic latitude (Lat)",north,
|
23
|
-
# ORDER[1],
|
24
|
-
# ANGLEUNIT["degree",0.0174532925199433]],
|
25
|
-
# AXIS["geodetic longitude (Lon)",east,
|
26
|
-
# ORDER[2],
|
27
|
-
# ANGLEUNIT["degree",0.0174532925199433]],
|
28
|
-
# USAGE[
|
29
|
-
# SCOPE["unknown"],
|
30
|
-
# AREA["World"],
|
31
|
-
# BBOX[-90,-180,90,180]],
|
32
|
-
# ID["EPSG",4326]]
|
33
|
-
# EOS
|
34
|
-
#
|
35
|
-
# Notice when using the old-style Proj4 string, the addition of the "+type=crs" value.
|
36
|
-
#
|
37
|
-
# @param value [String]. See above
|
38
|
-
# @param context [Context]. An optional Context that the Crs will use for calculations.
|
39
|
-
def initialize(value, context=nil)
|
40
|
-
pointer = Api.proj_create(context || Context.current, value)
|
41
|
-
|
42
|
-
if pointer.null?
|
43
|
-
Error.check
|
44
|
-
end
|
45
|
-
|
46
|
-
super(pointer, context)
|
47
|
-
|
48
|
-
if Api.method_defined?(:proj_is_crs) && !Api.proj_is_crs(pointer)
|
49
|
-
raise(Error, "Invalid crs definition. Proj created an instance of: #{self.proj_type}.")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Get the geodeticCRS / geographicCRS from a CRS.
|
54
|
-
#
|
55
|
-
# @return [Crs]
|
56
|
-
def geodetic_crs
|
57
|
-
PjObject.new(Api.proj_crs_get_geodetic_crs(self.context, self))
|
58
|
-
end
|
59
|
-
|
60
|
-
# Get a CRS component from a CompoundCRS.
|
61
|
-
#
|
62
|
-
# @return [Crs]
|
63
|
-
def sub_crs(index)
|
64
|
-
PjObject.new(Api.proj_crs_get_sub_crs(self.context, self, index))
|
65
|
-
end
|
66
|
-
|
67
|
-
# Returns the datum of a SingleCRS.
|
68
|
-
#
|
69
|
-
# @return [Crs]
|
70
|
-
def datum
|
71
|
-
PjObject.new(Api.proj_crs_get_datum(self.context, self))
|
72
|
-
end
|
73
|
-
|
74
|
-
# Get the horizontal datum from a CRS.
|
75
|
-
#
|
76
|
-
# @return [Crs]
|
77
|
-
def horizontal_datum
|
78
|
-
PjObject.new(Api.proj_crs_get_horizontal_datum(self.context, self))
|
79
|
-
end
|
80
|
-
|
81
|
-
# Returns the coordinate system of a SingleCRS.
|
82
|
-
#
|
83
|
-
# @return [Crs]
|
84
|
-
def coordinate_system
|
85
|
-
PjObject.new(Api.proj_crs_get_coordinate_system(self.context, self))
|
86
|
-
end
|
87
|
-
|
88
|
-
# Returns the number of axis of the coordinate system.
|
89
|
-
#
|
90
|
-
# @return [Integer]
|
91
|
-
def axis_count
|
92
|
-
result = Api.proj_cs_get_axis_count(self.context, self.coordinate_system)
|
93
|
-
if result == -1
|
94
|
-
Error.check
|
95
|
-
end
|
96
|
-
result
|
97
|
-
end
|
98
|
-
|
99
|
-
# Returns information on an axis.
|
100
|
-
#
|
101
|
-
# @return [Array<Hash>]
|
102
|
-
def axis_info
|
103
|
-
self.axis_count.times.map do |index|
|
104
|
-
p_name = FFI::MemoryPointer.new(:pointer)
|
105
|
-
p_abbreviation = FFI::MemoryPointer.new(:pointer)
|
106
|
-
p_direction = FFI::MemoryPointer.new(:pointer)
|
107
|
-
p_unit_conv_factor = FFI::MemoryPointer.new(:double)
|
108
|
-
p_unit_name = FFI::MemoryPointer.new(:pointer)
|
109
|
-
p_unit_auth_name = FFI::MemoryPointer.new(:pointer)
|
110
|
-
p_unit_code = FFI::MemoryPointer.new(:pointer)
|
111
|
-
|
112
|
-
result = Api.proj_cs_get_axis_info(self.context, self.coordinate_system, index,
|
113
|
-
p_name, p_abbreviation, p_direction, p_unit_conv_factor, p_unit_name, p_unit_auth_name, p_unit_code)
|
114
|
-
|
115
|
-
unless result
|
116
|
-
Error.check
|
117
|
-
end
|
118
|
-
|
119
|
-
{:name => p_name.read_pointer.read_string,
|
120
|
-
:abbreviation => p_abbreviation.read_pointer.read_string_to_null,
|
121
|
-
:direction => p_direction.read_pointer.read_string_to_null,
|
122
|
-
:unit_conv_factor => p_unit_conv_factor.read_double,
|
123
|
-
:unit_name => p_unit_name.read_pointer.read_string_to_null,
|
124
|
-
:unit_auth_name => p_unit_auth_name.read_pointer.read_string_to_null,
|
125
|
-
:unit_code => p_unit_code.read_pointer.read_string_to_null}
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
# Returns the type of the coordinate system.
|
130
|
-
#
|
131
|
-
# @return [:PJ_COORDINATE_SYSTEM_TYPE]
|
132
|
-
def crs_type
|
133
|
-
result = Api.proj_cs_get_type(self.context, self.coordinate_system)
|
134
|
-
if result == :PJ_CS_TYPE_UNKNOWN
|
135
|
-
Error.check
|
136
|
-
end
|
137
|
-
result
|
138
|
-
end
|
139
|
-
|
140
|
-
# Return the area of use of an object.
|
141
|
-
#
|
142
|
-
# @return [Area]
|
143
|
-
def area
|
144
|
-
@area ||= Area.for_object(self)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Get the ellipsoid from a CRS or a GeodeticReferenceFrame.
|
148
|
-
#
|
149
|
-
# @return [PjObject]
|
150
|
-
def ellipsoid
|
151
|
-
PjObject.new(Api.proj_get_ellipsoid(self.context, self))
|
152
|
-
end
|
153
|
-
|
154
|
-
# Return the Conversion of a DerivedCRS (such as a ProjectedCRS), or the Transformation from
|
155
|
-
# the baseCRS to the hubCRS of a BoundCRS.
|
156
|
-
#
|
157
|
-
# @return [PjObject]
|
158
|
-
def operation
|
159
|
-
pointer = Api.proj_crs_get_coordoperation(self.context, self)
|
160
|
-
if pointer.null?
|
161
|
-
Error.check
|
162
|
-
end
|
163
|
-
PjObject.new(pointer)
|
164
|
-
end
|
165
|
-
|
166
|
-
# Get the prime meridian of a CRS or a GeodeticReferenceFrame.
|
167
|
-
#
|
168
|
-
# @return [PjObject]
|
169
|
-
def prime_meridian
|
170
|
-
PjObject.new(Api.proj_get_prime_meridian(self.context, self))
|
171
|
-
end
|
172
|
-
|
173
|
-
# A nicely printed out description
|
174
|
-
#
|
175
|
-
# @return [String]
|
176
|
-
def inspect
|
177
|
-
result = StringIO.new
|
178
|
-
result.set_encoding('UTF-8')
|
179
|
-
result << <<~EOS
|
180
|
-
<#{self.class.name}>: #{self.auth(0)}
|
181
|
-
#{self.description}
|
182
|
-
Axis Info [#{self.crs_type}]:
|
183
|
-
EOS
|
184
|
-
|
185
|
-
self.axis_info.each do |axis_info|
|
186
|
-
result << "- #{axis_info[:abbreviation]}[#{axis_info[:direction]}]: #{axis_info[:name]} (#{axis_info[:unit_name]})" << "\n"
|
187
|
-
end
|
188
|
-
|
189
|
-
result << <<~EOS
|
190
|
-
Area of Use:
|
191
|
-
- name: #{self.area.name}
|
192
|
-
- bounds: (#{self.area.west_lon_degree}, #{self.area.south_lat_degree}, #{self.area.east_lon_degree}, #{self.area.north_lat_degree})
|
193
|
-
Coordinate operation:
|
194
|
-
- name: ?
|
195
|
-
- method: ?
|
196
|
-
Datum: #{self.datum.name}
|
197
|
-
- Ellipsoid: #{self.ellipsoid.name}
|
198
|
-
- Prime Meridian: #{self.prime_meridian.name}
|
199
|
-
EOS
|
200
|
-
|
201
|
-
result.string
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Proj
|
5
|
+
# Represents a coordinate reference system.
|
6
|
+
class Crs < PjObject
|
7
|
+
# To create a coordinate system, you can use CRS codes, well-known text (WKT) strings
|
8
|
+
# or old-style Proj4 strings (which are deprecated).
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# crs1 = Proj::Crs.new('EPSG:4326')
|
12
|
+
# crs2 = Proj::Crs.new('urn:ogc:def:crs:EPSG::4326')
|
13
|
+
# crs3 = Proj::Crs.new('+proj=longlat +datum=WGS84 +no_defs +type=crs')
|
14
|
+
# crs4 = Proj::Crs.new(<<~EOS)
|
15
|
+
# GEOGCRS["WGS 84",
|
16
|
+
# DATUM["World Geodetic System 1984",
|
17
|
+
# ELLIPSOID["WGS 84",6378137,298.257223563,
|
18
|
+
# LENGTHUNIT["metre",1]]],
|
19
|
+
# PRIMEM["Greenwich",0,
|
20
|
+
# ANGLEUNIT["degree",0.0174532925199433]],
|
21
|
+
# CS[ellipsoidal,2],
|
22
|
+
# AXIS["geodetic latitude (Lat)",north,
|
23
|
+
# ORDER[1],
|
24
|
+
# ANGLEUNIT["degree",0.0174532925199433]],
|
25
|
+
# AXIS["geodetic longitude (Lon)",east,
|
26
|
+
# ORDER[2],
|
27
|
+
# ANGLEUNIT["degree",0.0174532925199433]],
|
28
|
+
# USAGE[
|
29
|
+
# SCOPE["unknown"],
|
30
|
+
# AREA["World"],
|
31
|
+
# BBOX[-90,-180,90,180]],
|
32
|
+
# ID["EPSG",4326]]
|
33
|
+
# EOS
|
34
|
+
#
|
35
|
+
# Notice when using the old-style Proj4 string, the addition of the "+type=crs" value.
|
36
|
+
#
|
37
|
+
# @param value [String]. See above
|
38
|
+
# @param context [Context]. An optional Context that the Crs will use for calculations.
|
39
|
+
def initialize(value, context=nil)
|
40
|
+
pointer = Api.proj_create(context || Context.current, value)
|
41
|
+
|
42
|
+
if pointer.null?
|
43
|
+
Error.check
|
44
|
+
end
|
45
|
+
|
46
|
+
super(pointer, context)
|
47
|
+
|
48
|
+
if Api.method_defined?(:proj_is_crs) && !Api.proj_is_crs(pointer)
|
49
|
+
raise(Error, "Invalid crs definition. Proj created an instance of: #{self.proj_type}.")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the geodeticCRS / geographicCRS from a CRS.
|
54
|
+
#
|
55
|
+
# @return [Crs]
|
56
|
+
def geodetic_crs
|
57
|
+
PjObject.new(Api.proj_crs_get_geodetic_crs(self.context, self))
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get a CRS component from a CompoundCRS.
|
61
|
+
#
|
62
|
+
# @return [Crs]
|
63
|
+
def sub_crs(index)
|
64
|
+
PjObject.new(Api.proj_crs_get_sub_crs(self.context, self, index))
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the datum of a SingleCRS.
|
68
|
+
#
|
69
|
+
# @return [Crs]
|
70
|
+
def datum
|
71
|
+
PjObject.new(Api.proj_crs_get_datum(self.context, self))
|
72
|
+
end
|
73
|
+
|
74
|
+
# Get the horizontal datum from a CRS.
|
75
|
+
#
|
76
|
+
# @return [Crs]
|
77
|
+
def horizontal_datum
|
78
|
+
PjObject.new(Api.proj_crs_get_horizontal_datum(self.context, self))
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the coordinate system of a SingleCRS.
|
82
|
+
#
|
83
|
+
# @return [Crs]
|
84
|
+
def coordinate_system
|
85
|
+
PjObject.new(Api.proj_crs_get_coordinate_system(self.context, self))
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the number of axis of the coordinate system.
|
89
|
+
#
|
90
|
+
# @return [Integer]
|
91
|
+
def axis_count
|
92
|
+
result = Api.proj_cs_get_axis_count(self.context, self.coordinate_system)
|
93
|
+
if result == -1
|
94
|
+
Error.check
|
95
|
+
end
|
96
|
+
result
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns information on an axis.
|
100
|
+
#
|
101
|
+
# @return [Array<Hash>]
|
102
|
+
def axis_info
|
103
|
+
self.axis_count.times.map do |index|
|
104
|
+
p_name = FFI::MemoryPointer.new(:pointer)
|
105
|
+
p_abbreviation = FFI::MemoryPointer.new(:pointer)
|
106
|
+
p_direction = FFI::MemoryPointer.new(:pointer)
|
107
|
+
p_unit_conv_factor = FFI::MemoryPointer.new(:double)
|
108
|
+
p_unit_name = FFI::MemoryPointer.new(:pointer)
|
109
|
+
p_unit_auth_name = FFI::MemoryPointer.new(:pointer)
|
110
|
+
p_unit_code = FFI::MemoryPointer.new(:pointer)
|
111
|
+
|
112
|
+
result = Api.proj_cs_get_axis_info(self.context, self.coordinate_system, index,
|
113
|
+
p_name, p_abbreviation, p_direction, p_unit_conv_factor, p_unit_name, p_unit_auth_name, p_unit_code)
|
114
|
+
|
115
|
+
unless result
|
116
|
+
Error.check
|
117
|
+
end
|
118
|
+
|
119
|
+
{:name => p_name.read_pointer.read_string,
|
120
|
+
:abbreviation => p_abbreviation.read_pointer.read_string_to_null,
|
121
|
+
:direction => p_direction.read_pointer.read_string_to_null,
|
122
|
+
:unit_conv_factor => p_unit_conv_factor.read_double,
|
123
|
+
:unit_name => p_unit_name.read_pointer.read_string_to_null,
|
124
|
+
:unit_auth_name => p_unit_auth_name.read_pointer.read_string_to_null,
|
125
|
+
:unit_code => p_unit_code.read_pointer.read_string_to_null}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns the type of the coordinate system.
|
130
|
+
#
|
131
|
+
# @return [:PJ_COORDINATE_SYSTEM_TYPE]
|
132
|
+
def crs_type
|
133
|
+
result = Api.proj_cs_get_type(self.context, self.coordinate_system)
|
134
|
+
if result == :PJ_CS_TYPE_UNKNOWN
|
135
|
+
Error.check
|
136
|
+
end
|
137
|
+
result
|
138
|
+
end
|
139
|
+
|
140
|
+
# Return the area of use of an object.
|
141
|
+
#
|
142
|
+
# @return [Area]
|
143
|
+
def area
|
144
|
+
@area ||= Area.for_object(self)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Get the ellipsoid from a CRS or a GeodeticReferenceFrame.
|
148
|
+
#
|
149
|
+
# @return [PjObject]
|
150
|
+
def ellipsoid
|
151
|
+
PjObject.new(Api.proj_get_ellipsoid(self.context, self))
|
152
|
+
end
|
153
|
+
|
154
|
+
# Return the Conversion of a DerivedCRS (such as a ProjectedCRS), or the Transformation from
|
155
|
+
# the baseCRS to the hubCRS of a BoundCRS.
|
156
|
+
#
|
157
|
+
# @return [PjObject]
|
158
|
+
def operation
|
159
|
+
pointer = Api.proj_crs_get_coordoperation(self.context, self)
|
160
|
+
if pointer.null?
|
161
|
+
Error.check
|
162
|
+
end
|
163
|
+
PjObject.new(pointer)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Get the prime meridian of a CRS or a GeodeticReferenceFrame.
|
167
|
+
#
|
168
|
+
# @return [PjObject]
|
169
|
+
def prime_meridian
|
170
|
+
PjObject.new(Api.proj_get_prime_meridian(self.context, self))
|
171
|
+
end
|
172
|
+
|
173
|
+
# A nicely printed out description
|
174
|
+
#
|
175
|
+
# @return [String]
|
176
|
+
def inspect
|
177
|
+
result = StringIO.new
|
178
|
+
result.set_encoding('UTF-8')
|
179
|
+
result << <<~EOS
|
180
|
+
<#{self.class.name}>: #{self.auth(0)}
|
181
|
+
#{self.description}
|
182
|
+
Axis Info [#{self.crs_type}]:
|
183
|
+
EOS
|
184
|
+
|
185
|
+
self.axis_info.each do |axis_info|
|
186
|
+
result << "- #{axis_info[:abbreviation]}[#{axis_info[:direction]}]: #{axis_info[:name]} (#{axis_info[:unit_name]})" << "\n"
|
187
|
+
end
|
188
|
+
|
189
|
+
result << <<~EOS
|
190
|
+
Area of Use:
|
191
|
+
- name: #{self.area.name}
|
192
|
+
- bounds: (#{self.area.west_lon_degree}, #{self.area.south_lat_degree}, #{self.area.east_lon_degree}, #{self.area.north_lat_degree})
|
193
|
+
Coordinate operation:
|
194
|
+
- name: ?
|
195
|
+
- method: ?
|
196
|
+
Datum: #{self.datum.name}
|
197
|
+
- Ellipsoid: #{self.ellipsoid.name}
|
198
|
+
- Prime Meridian: #{self.prime_meridian.name}
|
199
|
+
EOS
|
200
|
+
|
201
|
+
result.string
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|