proj4rb 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/ChangeLog +46 -0
- data/Gemfile +4 -0
- data/README.rdoc +158 -148
- data/Rakefile +26 -41
- data/lib/area.rb +32 -0
- data/lib/config.rb +70 -0
- data/lib/context.rb +103 -0
- data/lib/coordinate.rb +197 -0
- data/lib/crs.rb +206 -0
- data/lib/ellipsoid.rb +42 -0
- data/lib/error.rb +18 -0
- data/lib/operation.rb +43 -0
- data/lib/pj_object.rb +82 -0
- data/lib/point.rb +72 -0
- data/lib/prime_meridian.rb +40 -0
- data/lib/proj.rb +31 -0
- data/lib/proj4.rb +3 -469
- data/lib/projection.rb +207 -0
- data/lib/transformation.rb +61 -0
- data/lib/unit.rb +54 -0
- data/proj4rb.gemspec +31 -0
- data/test/abstract_test.rb +7 -0
- data/test/context_test.rb +82 -0
- data/test/coordinate_test.rb +35 -0
- data/test/crs_test.rb +373 -0
- data/test/ellipsoid_test.rb +34 -0
- data/test/operation_test.rb +29 -0
- data/test/prime_meridians_test.rb +33 -0
- data/test/proj_test.rb +17 -0
- data/test/projection_test.rb +224 -0
- data/test/transformation_test.rb +68 -0
- data/test/unit_test.rb +47 -0
- metadata +82 -77
- data/data/GL27 +0 -22
- data/data/MD +0 -0
- data/data/TN +0 -0
- data/data/WI +0 -0
- data/data/WO +0 -0
- data/data/conus +0 -0
- data/data/epsg +0 -5443
- data/data/epsg-deprecated +0 -2
- data/data/esri +0 -5937
- data/data/esri.extra +0 -948
- data/data/hawaii +0 -0
- data/data/nad.lst +0 -142
- data/data/nad27 +0 -809
- data/data/nad83 +0 -744
- data/data/ntv1_can.dat +0 -0
- data/data/null +0 -0
- data/data/other.extra +0 -49
- data/data/proj_def.dat +0 -17
- data/data/prvi +0 -0
- data/data/stgeorge +0 -0
- data/data/stlrnc +0 -0
- data/data/stpaul +0 -0
- data/data/world +0 -212
- data/example/basic.rb +0 -18
- data/example/list-datums.rb +0 -17
- data/example/list-ellipsoids.rb +0 -17
- data/example/list-errors.rb +0 -11
- data/example/list-prime-meridians.rb +0 -17
- data/example/list-projection-types.rb +0 -17
- data/example/list-units.rb +0 -17
- data/example/version.rb +0 -8
- data/ext/Makefile +0 -238
- data/ext/extconf.rb +0 -16
- data/ext/mkmf.log +0 -103
- data/ext/out.log +0 -0
- data/ext/proj4_ruby-x64-mingw32.def +0 -2
- data/ext/proj4_ruby.so +0 -0
- data/ext/projrb.c +0 -566
- data/ext/projrb.o +0 -0
- data/ext/vc/proj4_ruby.sln +0 -19
- data/ext/vc/proj4_ruby.vcproj +0 -208
- data/test/test_constants.rb +0 -18
- data/test/test_create_projection.rb +0 -63
- data/test/test_datums.rb +0 -45
- data/test/test_ellipsoids.rb +0 -46
- data/test/test_errors.rb +0 -66
- data/test/test_init_projection.rb +0 -109
- data/test/test_prime_meridians.rb +0 -45
- data/test/test_projection_type.rb +0 -44
- data/test/test_simple_projection.rb +0 -58
- data/test/test_suite.rb +0 -14
- data/test/test_transform.rb +0 -115
- data/test/test_units.rb +0 -46
data/lib/area.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Proj
|
2
|
+
class Area
|
3
|
+
attr_reader :name, :west_lon_degree, :south_lat_degree, :east_lon_degree, :north_lat_degree
|
4
|
+
|
5
|
+
def self.for_object(pj_object)
|
6
|
+
p_name = FFI::MemoryPointer.new(:pointer)
|
7
|
+
p_west_lon_degree = FFI::MemoryPointer.new(:double)
|
8
|
+
p_south_lat_degree = FFI::MemoryPointer.new(:double)
|
9
|
+
p_east_lon_degree = FFI::MemoryPointer.new(:double)
|
10
|
+
p_north_lat_degree = FFI::MemoryPointer.new(:double)
|
11
|
+
|
12
|
+
result = Api.proj_get_area_of_use(Context.current, pj_object,
|
13
|
+
p_west_lon_degree, p_south_lat_degree, p_east_lon_degree, p_north_lat_degree,
|
14
|
+
p_name)
|
15
|
+
unless result
|
16
|
+
Error.check
|
17
|
+
end
|
18
|
+
|
19
|
+
name = p_name.read_pointer.read_string_to_null.force_encoding('utf-8')
|
20
|
+
self.new(name,
|
21
|
+
p_west_lon_degree.read_double, p_south_lat_degree.read_double, p_east_lon_degree.read_double, p_north_lat_degree.read_double)
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(name, west_lon_degree, south_lat_degree, east_lon_degree, north_lat_degree)
|
25
|
+
@name = name
|
26
|
+
@west_lon_degree = west_lon_degree
|
27
|
+
@south_lat_degree = south_lat_degree
|
28
|
+
@east_lon_degree = east_lon_degree
|
29
|
+
@north_lat_degree = north_lat_degree
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/config.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Proj
|
4
|
+
class Config
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
def set_search_paths
|
8
|
+
p_paths = self.search_paths_pointer
|
9
|
+
items = p_paths.type_size/p_paths.size
|
10
|
+
|
11
|
+
# Set search paths on default context - any new contexts will inherit from this
|
12
|
+
if Api.method_defined?(:proj_context_set_search_paths)
|
13
|
+
Api.proj_context_set_search_paths(nil, items, p_paths)
|
14
|
+
end
|
15
|
+
|
16
|
+
if Api.method_defined?(:pj_set_searchpath)
|
17
|
+
Api.pj_set_searchpath(items, p_paths)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def search_paths
|
22
|
+
['/usr/share/proj',
|
23
|
+
'/usr/local/share/proj',
|
24
|
+
'/opt/share/proj',
|
25
|
+
'/opt/local/share/proj',
|
26
|
+
'c:/msys64/mingw64/share/proj',
|
27
|
+
'c:/mingw64/share/proj',
|
28
|
+
'/opt/local/lib/proj6/share/proj',
|
29
|
+
'/opt/local/lib/proj5/share/proj',
|
30
|
+
'/opt/local/lib/proj49/share/proj']
|
31
|
+
end
|
32
|
+
|
33
|
+
def data_path
|
34
|
+
if ENV['PROJ_LIB'] && File.directory?(ENV['PROJ_LIB'])
|
35
|
+
ENV['PROJ_LIB']
|
36
|
+
else
|
37
|
+
result = self.search_paths.detect do |path|
|
38
|
+
File.directory?(path)
|
39
|
+
end
|
40
|
+
|
41
|
+
unless result
|
42
|
+
raise(Error, "Could not find Proj data directory. Please set the PROJ_LIB environmental variable to correct directory")
|
43
|
+
end
|
44
|
+
|
45
|
+
result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def search_paths_pointer
|
50
|
+
p_path = FFI::MemoryPointer.from_string(self.data_path)
|
51
|
+
p_paths = FFI::MemoryPointer.new(:pointer, 1)
|
52
|
+
p_paths[0].write_pointer(p_path)
|
53
|
+
p_paths
|
54
|
+
end
|
55
|
+
|
56
|
+
def db_path
|
57
|
+
result = self.search_paths.map do |path|
|
58
|
+
File.join(path, 'proj.db')
|
59
|
+
end.detect do |path|
|
60
|
+
File.exists?(path)
|
61
|
+
end
|
62
|
+
|
63
|
+
unless result
|
64
|
+
raise(Error, "Could not find Proj database (proj.db). Please set the PROJ_LIB environmental variable to directory that contains it")
|
65
|
+
end
|
66
|
+
|
67
|
+
result
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/context.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
module Proj
|
2
|
+
# Proj 4.8 introduced the concept of a thread context object to support multi-threaded programs. The bindings
|
3
|
+
# automatically create on context per thread (its stored in local thread storage).
|
4
|
+
class Context
|
5
|
+
# The context for the current thread
|
6
|
+
#
|
7
|
+
# @return [Context]
|
8
|
+
def self.current
|
9
|
+
Thread.current[:proj_context] ||= Context.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.finalize(pointer)
|
13
|
+
proc do
|
14
|
+
Api.proj_context_destroy(pointer)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@pointer = Api.proj_context_create
|
20
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(@pointer))
|
21
|
+
|
22
|
+
set_database_path
|
23
|
+
end
|
24
|
+
|
25
|
+
# Helper method that tries to locate the Proj coordinate database (proj.db)
|
26
|
+
def set_database_path
|
27
|
+
return unless Api.method_defined?(:proj_context_get_database_path)
|
28
|
+
return if database_path
|
29
|
+
|
30
|
+
self.database_path = Config.instance.db_path
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_ptr
|
34
|
+
@pointer
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get the last error number
|
38
|
+
#
|
39
|
+
# return [Integer]
|
40
|
+
def errno
|
41
|
+
Api.proj_context_errno(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Gets the path the Proj database
|
45
|
+
#
|
46
|
+
# return [String]
|
47
|
+
def database_path
|
48
|
+
Api.proj_context_get_database_path(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the path to the Proj database
|
52
|
+
def database_path=(value)
|
53
|
+
result = Api.proj_context_set_database_path(self, value, nil, nil)
|
54
|
+
unless result == 1
|
55
|
+
Error.check(self.errno)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sets a custom log function
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# context.set_log_function(data) do |pointer, int, message|
|
63
|
+
# ... do stuff...
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# @param pointer [FFI::MemoryPointer] Optional pointer to custom data
|
67
|
+
# @param proc [Proc] Custom logging procedure
|
68
|
+
# @return [nil]
|
69
|
+
def set_log_function(pointer = nil, &proc)
|
70
|
+
Api.proj_log_func(self, pointer, proc)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Gets the current log level
|
74
|
+
#
|
75
|
+
# @return [:PJ_LOG_LEVEL]
|
76
|
+
def log_level
|
77
|
+
Api.proj_log_level(self, :PJ_LOG_TELL)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Sets the current log level
|
81
|
+
#
|
82
|
+
# @param value [:PJ_LOG_LEVEL]
|
83
|
+
# @return [nil]
|
84
|
+
def log_level=(value)
|
85
|
+
Api.proj_log_level(self, value)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Gets if proj4 init rules are being used (i.e., support +init parameters)
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
def use_proj4_init_rules
|
92
|
+
Api.proj_context_get_use_proj4_init_rules(self, 0)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Sets if proj4 init rules should be used
|
96
|
+
#
|
97
|
+
# @param value [Boolean]
|
98
|
+
# @return [nil]
|
99
|
+
def use_proj4_init_rules=(value)
|
100
|
+
Api.proj_context_use_proj4_init_rules(self, value ? 1 : 0)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/coordinate.rb
ADDED
@@ -0,0 +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
|
data/lib/crs.rb
ADDED
@@ -0,0 +1,206 @@
|
|
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
|
+
foo = Api.proj_crs_get_coordinate_system(self.context, self)
|
93
|
+
result = Api.proj_cs_get_axis_count(self.context, self.coordinate_system)
|
94
|
+
if result == -1
|
95
|
+
Error.check
|
96
|
+
end
|
97
|
+
result
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns information on an axis.
|
101
|
+
#
|
102
|
+
# @return [Array<Hash>]
|
103
|
+
def axis_info
|
104
|
+
self.axis_count.times.map do |index|
|
105
|
+
p_name = FFI::MemoryPointer.new(:pointer)
|
106
|
+
p_abbreviation = FFI::MemoryPointer.new(:pointer)
|
107
|
+
p_direction = FFI::MemoryPointer.new(:pointer)
|
108
|
+
p_unit_conv_factor = FFI::MemoryPointer.new(:double)
|
109
|
+
p_unit_name = FFI::MemoryPointer.new(:pointer)
|
110
|
+
p_unit_auth_name = FFI::MemoryPointer.new(:pointer)
|
111
|
+
p_unit_code = FFI::MemoryPointer.new(:pointer)
|
112
|
+
|
113
|
+
result = Api.proj_cs_get_axis_info(self.context, self.coordinate_system, index,
|
114
|
+
p_name, p_abbreviation, p_direction, p_unit_conv_factor, p_unit_name, p_unit_auth_name, p_unit_code)
|
115
|
+
|
116
|
+
unless result
|
117
|
+
Error.check
|
118
|
+
end
|
119
|
+
|
120
|
+
{:name => p_name.read_pointer.read_string,
|
121
|
+
:abbreviation => p_abbreviation.read_pointer.read_string_to_null,
|
122
|
+
:direction => p_direction.read_pointer.read_string_to_null,
|
123
|
+
:unit_conv_factor => p_unit_conv_factor.read_double,
|
124
|
+
:unit_name => p_unit_name.read_pointer.read_string_to_null,
|
125
|
+
:unit_auth_name => p_unit_auth_name.read_pointer.read_string_to_null,
|
126
|
+
:unit_code => p_unit_code.read_pointer.read_string_to_null}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Returns the type of the coordinate system.
|
131
|
+
#
|
132
|
+
# @return [:PJ_COORDINATE_SYSTEM_TYPE]
|
133
|
+
def crs_type
|
134
|
+
foo = Api.proj_crs_get_coordinate_system(self.context, self)
|
135
|
+
result = Api.proj_cs_get_type(self.context, self.coordinate_system)
|
136
|
+
if result == :PJ_CS_TYPE_UNKNOWN
|
137
|
+
Error.check
|
138
|
+
end
|
139
|
+
result
|
140
|
+
end
|
141
|
+
|
142
|
+
# Return the area of use of an object.
|
143
|
+
#
|
144
|
+
# @return [Area]
|
145
|
+
def area
|
146
|
+
@area ||= Area.for_object(self)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Get the ellipsoid from a CRS or a GeodeticReferenceFrame.
|
150
|
+
#
|
151
|
+
# @return [PjObject]
|
152
|
+
def ellipsoid
|
153
|
+
PjObject.new(Api.proj_get_ellipsoid(self.context, self))
|
154
|
+
end
|
155
|
+
|
156
|
+
# Return the Conversion of a DerivedCRS (such as a ProjectedCRS), or the Transformation from
|
157
|
+
# the baseCRS to the hubCRS of a BoundCRS.
|
158
|
+
#
|
159
|
+
# @return [PjObject]
|
160
|
+
def operation
|
161
|
+
pointer = Api.proj_crs_get_coordoperation(self.context, self)
|
162
|
+
if pointer.null?
|
163
|
+
Error.check
|
164
|
+
end
|
165
|
+
PjObject.new(pointer)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Get the prime meridian of a CRS or a GeodeticReferenceFrame.
|
169
|
+
#
|
170
|
+
# @return [PjObject]
|
171
|
+
def prime_meridian
|
172
|
+
PjObject.new(Api.proj_get_prime_meridian(self.context, self))
|
173
|
+
end
|
174
|
+
|
175
|
+
# A nicely printed out description
|
176
|
+
#
|
177
|
+
# @return [String]
|
178
|
+
def inspect
|
179
|
+
result = StringIO.new
|
180
|
+
result.set_encoding('UTF-8')
|
181
|
+
result << <<~EOS
|
182
|
+
<#{self.class.name}>: #{self.auth(0)}
|
183
|
+
#{self.description}
|
184
|
+
Axis Info [#{self.crs_type}]:
|
185
|
+
EOS
|
186
|
+
|
187
|
+
self.axis_info.each do |axis_info|
|
188
|
+
result << "- #{axis_info[:abbreviation]}[#{axis_info[:direction]}]: #{axis_info[:name]} (#{axis_info[:unit_name]})" << "\n"
|
189
|
+
end
|
190
|
+
|
191
|
+
result << <<~EOS
|
192
|
+
Area of Use:
|
193
|
+
- name: #{self.area.name}
|
194
|
+
- bounds: (#{self.area.west_lon_degree}, #{self.area.south_lat_degree}, #{self.area.east_lon_degree}, #{self.area.north_lat_degree})
|
195
|
+
Coordinate operation:
|
196
|
+
- name: ?
|
197
|
+
- method: ?
|
198
|
+
Datum: #{self.datum.name}
|
199
|
+
- Ellipsoid: #{self.ellipsoid.name}
|
200
|
+
- Prime Meridian: #{self.prime_meridian.name}
|
201
|
+
EOS
|
202
|
+
|
203
|
+
result.string
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|