proj4r 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|