proj4r 1.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 +7 -0
- data/API.md +111 -0
- data/README.md +23 -0
- data/extconf.rb +12 -0
- data/lib/proj4r.rb +184 -0
- data/proj4r.gemspec +22 -0
- data/rb_geod.c +392 -0
- data/rb_proj.c +357 -0
- data/rb_proj4r.c +232 -0
- data/rb_proj4r.h +46 -0
- data/test/TEST.txt +5 -0
- data/test/attributes.rb +13 -0
- data/test/tenkizu.rb +29 -0
- data/test/test.rb +25 -0
- data/test/test_ca.rb +17 -0
- data/test/test_geod_ca.rb +25 -0
- data/test/test_proj.rb +14 -0
- data/test/test_proj_ca.rb +15 -0
- metadata +60 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 20be86854d023b958dc46d3858b78656bfd5e0b0e81a094ca6bc452511190b30
|
4
|
+
data.tar.gz: 0bcf9158aca9445914c84bbf16c0b93b08def84d5151306126e7437dac3b6a7b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc451a9dbcebdcb5febb9e32c79736eabd0ff6b7d452d48fceaf4f18ed1d56e393256c8ae67a9f800e7fdcee91f9e5d9a0352c295c8d191f2e12e21a6cee48b8
|
7
|
+
data.tar.gz: 2682e765ea2b320234cbc39a67518df6c0dd93470064eca109d08b86e177b7d3e58c2f6d1fca5a807601557c62d119f764529ec8052792a32cf0988d05a9f4a6
|
data/API.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
PROJ4R
|
2
|
+
=======
|
3
|
+
|
4
|
+
Notes for forward or inverse transformation
|
5
|
+
|
6
|
+
Proj
|
7
|
+
forward : (lon, lat) -> (x, y)
|
8
|
+
inverse : (x, y) -> (lon, lat)
|
9
|
+
|
10
|
+
Proj.transform
|
11
|
+
forward : (src, dst, x, y, z) -> (x', y', z')
|
12
|
+
inverse : (dst, src, x, y, z) -> (x', y', z')
|
13
|
+
|
14
|
+
If src = latlong, dst = projection, they work like Proj#forward, Proj#inverse.
|
15
|
+
In the cases, use lon as x, lat as y.
|
16
|
+
|
17
|
+
Geod
|
18
|
+
forward : (lat1, lon1, az12, dist) -> (lat2, lon2, az21)
|
19
|
+
inverse : (lat1, lon1, lat2, lon2) -> (dist, az12, az21)
|
20
|
+
|
21
|
+
Notes for (lon,lat) or (lat,lon)
|
22
|
+
|
23
|
+
PROJ4::Proj -> (lon, lat)
|
24
|
+
PROJ4.transform -> (lon, lat)
|
25
|
+
PROJ4::Geod -> (lat, lon)
|
26
|
+
|
27
|
+
These differences originate from Proj.4 C API.
|
28
|
+
|
29
|
+
Proj
|
30
|
+
----
|
31
|
+
|
32
|
+
### Constructor
|
33
|
+
|
34
|
+
pj = PROJ4::Proj.new("+proj=latlon +ellps=WGS84 units=km")
|
35
|
+
|
36
|
+
### Attributes
|
37
|
+
|
38
|
+
pj.definition
|
39
|
+
pj.latlong?
|
40
|
+
pj.geocent?
|
41
|
+
|
42
|
+
### Replication
|
43
|
+
|
44
|
+
pj.to_latlong
|
45
|
+
|
46
|
+
### forward
|
47
|
+
|
48
|
+
x, y = pj.forward(lon, lat)
|
49
|
+
|
50
|
+
### inverse
|
51
|
+
|
52
|
+
lon, lat = *pj.inverse(x, y)
|
53
|
+
|
54
|
+
p pj.to_latlong.definition
|
55
|
+
|
56
|
+
Transformation
|
57
|
+
--------------
|
58
|
+
|
59
|
+
|
60
|
+
Geod
|
61
|
+
----
|
62
|
+
|
63
|
+
### Constructor
|
64
|
+
|
65
|
+
geod = PROJ4::Geod.new() ### [+ellps=WGS84, units=m]
|
66
|
+
geod = PROJ4::Geod.new(6378137.0, 1/298.257223563) ### [+ellps=WGS84, units=m]
|
67
|
+
geod = PROJ4::Geod.new("+ellps=WGS84 units=m")
|
68
|
+
|
69
|
+
### forward
|
70
|
+
|
71
|
+
lat2, lon2, az21 = *geod.forward(lat1, lon1, az12, dist)
|
72
|
+
|
73
|
+
input:
|
74
|
+
lat1: latitude of original point in degree
|
75
|
+
lon1: longitudde of original point in degree
|
76
|
+
az12: azimuth point to target point at origninal point in degree
|
77
|
+
dist: distance from original point to target point in units defined in constructor
|
78
|
+
|
79
|
+
output:
|
80
|
+
lat2: latitude of target point in degree
|
81
|
+
lon1: longitude of target point in degree
|
82
|
+
az21: azimuth point to original point at target point in degree
|
83
|
+
|
84
|
+
### inverse
|
85
|
+
|
86
|
+
dist, az12, az21 = *geod.inverse(lat1, lon1, lat2, lon2)
|
87
|
+
|
88
|
+
input:
|
89
|
+
lat1: latitude of original point in degree
|
90
|
+
lon1: longitude of original point in degree
|
91
|
+
lat2: latitude of target point in degree
|
92
|
+
lon2: longitude of target point in degree
|
93
|
+
|
94
|
+
output:
|
95
|
+
dist: distance between original and target points in units defined in constructor
|
96
|
+
az12: azimuth point to target point at origninal point in degree
|
97
|
+
az21: azimuth point to original point at target point in degree
|
98
|
+
|
99
|
+
### distance
|
100
|
+
|
101
|
+
dist = *geod.distance(lat1, lon1, lat2, lon2)
|
102
|
+
|
103
|
+
input:
|
104
|
+
lat1: latitude of original point in degree
|
105
|
+
lon1: longitude of original point in degree
|
106
|
+
lat2: latitude of target point in degree
|
107
|
+
lon2: longitude of target point in degree
|
108
|
+
|
109
|
+
output:
|
110
|
+
dist: distance between original and target points in units defined in constructor
|
111
|
+
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
proj4r
|
2
|
+
======
|
3
|
+
|
4
|
+
module PROJ4
|
5
|
+
RAD_TO_DEG
|
6
|
+
DEG_TO_RAD
|
7
|
+
def self.dmstor
|
8
|
+
def self.rtodms
|
9
|
+
def self.dmstod
|
10
|
+
def self.dtodms
|
11
|
+
def self.transform
|
12
|
+
def self.transform_ca
|
13
|
+
class Proj
|
14
|
+
def inverse
|
15
|
+
def forward
|
16
|
+
end
|
17
|
+
class Geod
|
18
|
+
def inverse
|
19
|
+
def forward
|
20
|
+
def distance
|
21
|
+
def geodline
|
22
|
+
end
|
23
|
+
end
|
data/extconf.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
require 'carray/mkmf'
|
3
|
+
|
4
|
+
dir_config("proj", possible_includes, possible_libs)
|
5
|
+
dir_config("geod", possible_includes, possible_libs)
|
6
|
+
|
7
|
+
if have_header("proj_api.h") and have_library("proj")
|
8
|
+
have_carray()
|
9
|
+
create_makefile("proj4r")
|
10
|
+
end
|
11
|
+
|
12
|
+
|
data/lib/proj4r.rb
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'carray'
|
2
|
+
require 'proj4r.so'
|
3
|
+
|
4
|
+
module PROJ4
|
5
|
+
|
6
|
+
def self.transform (src, dst, x, y, z = nil)
|
7
|
+
if x.is_a?(CArray) and y.is_a?(CArray)
|
8
|
+
if z.is_a?(CArray)
|
9
|
+
x2 = x.to_ca
|
10
|
+
y2 = y.to_ca
|
11
|
+
z2 = z.to_ca
|
12
|
+
_transform_ca(src, dst, x2, y2, z2)
|
13
|
+
return [x2, y2, z2]
|
14
|
+
elsif z.nil?
|
15
|
+
x2 = x.to_ca
|
16
|
+
y2 = y.to_ca
|
17
|
+
z2 = x.template { 0 }
|
18
|
+
_transform_ca(src, dst, x2, y2, z2)
|
19
|
+
return [x2, y2]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
return _transform(src, dst, x, y, z)
|
23
|
+
end
|
24
|
+
|
25
|
+
class Proj
|
26
|
+
|
27
|
+
def forward (*argv)
|
28
|
+
if argv.size == 2
|
29
|
+
lon1, lat1 = *argv
|
30
|
+
if lon1.is_a?(CArray) and lat1.is_a?(CArray)
|
31
|
+
x2 = lon1.template
|
32
|
+
y2 = lat1.template
|
33
|
+
_forward_ca(lon1, lat1, x2, y2)
|
34
|
+
return [x2, y2]
|
35
|
+
else
|
36
|
+
return _forward(lon1, lat1)
|
37
|
+
end
|
38
|
+
else
|
39
|
+
return _forward_ca(*argv)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def inverse (*argv)
|
44
|
+
if argv.size == 2
|
45
|
+
x1, y1 = *argv
|
46
|
+
if x1.is_a?(CArray) and y1.is_a?(CArray)
|
47
|
+
lon2 = x1.template
|
48
|
+
lat2 = y1.template
|
49
|
+
_inverse_ca(x1, y1, lon2, lat2)
|
50
|
+
return [lon2, lat2]
|
51
|
+
else
|
52
|
+
return _inverse(x1, y1)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
return _inverse_ca(*argv)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
class Geod
|
62
|
+
|
63
|
+
def initialize (*argv)
|
64
|
+
if argv.size == 1 and (arg = argv.first).is_a?(String)
|
65
|
+
pj = Proj.new("+proj=latlon " + arg)
|
66
|
+
a = pj.a
|
67
|
+
f = pj.f
|
68
|
+
@fr_meter = pj.fr_meter
|
69
|
+
@to_meter = 1.0/@fr_meter
|
70
|
+
_initialize(a,f)
|
71
|
+
else
|
72
|
+
@fr_meter = 1.0
|
73
|
+
@to_meter = 1.0
|
74
|
+
_initialize(*argv)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def forward (*argv)
|
79
|
+
case argv.size
|
80
|
+
when 4
|
81
|
+
lat1, lon1, az12, dist = *argv
|
82
|
+
if lat1.is_a?(CArray) and lon1.is_a?(CArray) and
|
83
|
+
az12.is_a?(CArray) and dist.is_a?(CArray)
|
84
|
+
lon2 = lon1.template
|
85
|
+
lat2 = lat1.template
|
86
|
+
az21 = az12.template
|
87
|
+
_forward_ca(lat1, lon1, az12, dist*@to_meter, lat2, lon2, az21)
|
88
|
+
return [lon2, lat2, az21]
|
89
|
+
else
|
90
|
+
return _forward(lat1, lon1, az12, dist*@to_meter)
|
91
|
+
end
|
92
|
+
when 7
|
93
|
+
argv[2] *= @to_meter
|
94
|
+
return _forward_ca(*argv)
|
95
|
+
else
|
96
|
+
raise "invalid # of argument 4 or 7 required"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def inverse (*argv)
|
101
|
+
case argv.size
|
102
|
+
when 4
|
103
|
+
lat1, lon1, lat2, lon2 = *argv
|
104
|
+
if lat1.is_a?(CArray) and lon1.is_a?(CArray) and
|
105
|
+
lat2.is_a?(CArray) and lon2.is_a?(CArray)
|
106
|
+
dist = lat1.template
|
107
|
+
az12 = lat1.template
|
108
|
+
az21 = lat1.template
|
109
|
+
_inverse_ca(lat1, lon1, lat2, lon2, dist, az12, az21)
|
110
|
+
az21 += 180
|
111
|
+
az21[:gt,180] -= 360
|
112
|
+
return dist*@fr_meter, az12, az21
|
113
|
+
else
|
114
|
+
dist, az12, az21 = *_inverse(lat1, lon1, lat2, lon2)
|
115
|
+
az21 += 180
|
116
|
+
if az21 > 180
|
117
|
+
az21 -= 360
|
118
|
+
end
|
119
|
+
return dist*@fr_meter, az12, az21
|
120
|
+
end
|
121
|
+
when 7
|
122
|
+
_inverse_ca(*argv)
|
123
|
+
argv[4] *= @fr_meter
|
124
|
+
argv[6] += 180
|
125
|
+
argv[6][:gt,180] -= 360
|
126
|
+
return self
|
127
|
+
else
|
128
|
+
raise "invalid # of argument 4 or 7 required"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def distance (*argv)
|
133
|
+
case argv.size
|
134
|
+
when 4
|
135
|
+
lat1, lon1, lat2, lon2 = *argv
|
136
|
+
if lat1.is_a?(CArray) and lon1.is_a?(CArray) and
|
137
|
+
lat2.is_a?(CArray) and lon2.is_a?(CArray)
|
138
|
+
dist = lon1.template
|
139
|
+
_distance_ca(lat1, lon1, lat2, lon2, dist)
|
140
|
+
return dist*@fr_meter
|
141
|
+
else
|
142
|
+
return _distance(lat1, lon1, lat2, lon2)*@fr_meter
|
143
|
+
end
|
144
|
+
when 5
|
145
|
+
_distance_ca(*argv)
|
146
|
+
argv[4] *= @fr_meter
|
147
|
+
return self
|
148
|
+
else
|
149
|
+
raise "invalid # of argument 4 or 5 required"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def geodline (lat0, lon0, lat1, lon1, count: nil, interval: nil)
|
154
|
+
|
155
|
+
total_geod_S, az12, az21 = self.inverse(lat0, lon0, lat1, lon1)
|
156
|
+
total_geod_S *= @fr_meter
|
157
|
+
|
158
|
+
if not count.nil? and interval.nil?
|
159
|
+
del_S = total_geod_S / ( count - 1 )
|
160
|
+
elsif count.nil? and not interval.nil?
|
161
|
+
del_S = interval
|
162
|
+
else
|
163
|
+
del_S = total_geod_S / ( 100 - 1 )
|
164
|
+
end
|
165
|
+
|
166
|
+
list = []
|
167
|
+
list.push [lon0, lat0, 0]
|
168
|
+
|
169
|
+
geod_S = del_S
|
170
|
+
loop do
|
171
|
+
lat, lon, az21 = self.forward(lat0, lon0, az12, geod_S*@to_meter)
|
172
|
+
list.push [lat, lon, geod_S]
|
173
|
+
geod_S += del_S
|
174
|
+
if geod_S >= total_geod_S
|
175
|
+
break
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
list.push [lat1, lon1, total_geod_S]
|
180
|
+
|
181
|
+
return list
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
data/proj4r.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
Gem::Specification::new do |s|
|
3
|
+
version = "1.0.0"
|
4
|
+
|
5
|
+
files = Dir.glob("**/*") - [
|
6
|
+
Dir.glob("proj4r*.gem"),
|
7
|
+
].flatten
|
8
|
+
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.name = "proj4r"
|
11
|
+
s.summary = "Extension library for PROJ.4"
|
12
|
+
s.description = <<-HERE
|
13
|
+
Extension library for PROJ.4
|
14
|
+
HERE
|
15
|
+
s.version = version
|
16
|
+
s.author = "Hiroki Motoyoshi"
|
17
|
+
s.email = ""
|
18
|
+
s.homepage = 'https://github.com/himotoyoshi/proj4r'
|
19
|
+
s.files = files
|
20
|
+
s.extensions = [ "extconf.rb" ]
|
21
|
+
s.required_ruby_version = ">= 1.8.1"
|
22
|
+
end
|