rgeo-proj4 1.0.0.rc1 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/proj4_c_impl/extconf.rb +7 -2
- data/ext/proj4_c_impl/main.c +204 -87
- data/lib/rgeo/coord_sys/proj4.rb +59 -43
- data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +18 -15
- data/lib/rgeo/proj4.rb +2 -0
- data/lib/rgeo/proj4/version.rb +3 -1
- metadata +30 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e899f9ec9d4cb7036400cb716e4d414c87adf5b1b20fbcf081666d869af48ad
|
4
|
+
data.tar.gz: 423a52b4b72050a519b8df4c63f01058b608c9345cb0abc5e1bf2a33729c381b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59fda580463933b22228f0748d7ddbb38deefe04c2b01ea2979d1a2f15a2d565bfad6b3056f0f4ab9a27fa147df69e8eae9dec8dd1cd075c48c108bcce96858b
|
7
|
+
data.tar.gz: 1cd3d716d7c9ba6c832d3703abb2c6ddefa87985e75034ed38458bd447f6afd32e02a72547ff2014db52db0bd0d3c3709c776e97698dc0e0a792eb33168b0314
|
data/ext/proj4_c_impl/extconf.rb
CHANGED
@@ -45,14 +45,19 @@ else
|
|
45
45
|
|
46
46
|
found_proj_ = false
|
47
47
|
header_dirs_, lib_dirs_ = dir_config("proj", header_dirs_, lib_dirs_)
|
48
|
-
if have_header("
|
48
|
+
if have_header("proj.h")
|
49
49
|
$libs << " -lproj"
|
50
|
-
|
50
|
+
|
51
|
+
if have_func("proj_create", "proj.h")
|
51
52
|
found_proj_ = true
|
53
|
+
have_func("proj_create_crs_to_crs_from_pj", "proj.h")
|
54
|
+
have_func("proj_normalize_for_visualization", "proj.h")
|
52
55
|
else
|
53
56
|
$libs.gsub!(" -lproj", "")
|
54
57
|
end
|
55
58
|
end
|
59
|
+
have_func("rb_gc_mark_movable")
|
60
|
+
|
56
61
|
unless found_proj_
|
57
62
|
puts "**** WARNING: Unable to find Proj headers or Proj version is too old."
|
58
63
|
puts "**** Compiling without Proj support."
|
data/ext/proj4_c_impl/main.c
CHANGED
@@ -1,12 +1,21 @@
|
|
1
1
|
/*
|
2
2
|
Main initializer for Proj4 wrapper
|
3
3
|
*/
|
4
|
-
|
5
|
-
#ifdef
|
6
|
-
#ifdef
|
4
|
+
#ifdef HAVE_PROJ_H
|
5
|
+
#ifdef HAVE_PROJ_CREATE
|
6
|
+
#ifdef HAVE_PROJ_CREATE_CRS_TO_CRS_FROM_PJ
|
7
|
+
#ifdef HAVE_PROJ_NORMALIZE_FOR_VISUALIZATION
|
7
8
|
#define RGEO_PROJ4_SUPPORTED
|
8
9
|
#endif
|
9
10
|
#endif
|
11
|
+
#endif
|
12
|
+
#endif
|
13
|
+
|
14
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
15
|
+
#define mark rb_gc_mark_movable
|
16
|
+
#else
|
17
|
+
#define mark rb_gc_mark
|
18
|
+
#endif
|
10
19
|
|
11
20
|
#ifdef __cplusplus
|
12
21
|
#define RGEO_BEGIN_C extern "C" {
|
@@ -20,7 +29,7 @@
|
|
20
29
|
#ifdef RGEO_PROJ4_SUPPORTED
|
21
30
|
|
22
31
|
#include <ruby.h>
|
23
|
-
#include <
|
32
|
+
#include <proj.h>
|
24
33
|
|
25
34
|
#endif
|
26
35
|
|
@@ -30,78 +39,112 @@ RGEO_BEGIN_C
|
|
30
39
|
|
31
40
|
#ifdef RGEO_PROJ4_SUPPORTED
|
32
41
|
|
42
|
+
#if PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR < 3
|
43
|
+
#define WKT_TYPE PJ_WKT2_2018
|
44
|
+
#else
|
45
|
+
#define WKT_TYPE PJ_WKT2_2019
|
46
|
+
#endif
|
33
47
|
|
34
48
|
typedef struct {
|
35
|
-
|
49
|
+
PJ *pj;
|
36
50
|
VALUE original_str;
|
37
51
|
char uses_radians;
|
38
52
|
} RGeo_Proj4Data;
|
39
53
|
|
40
54
|
|
41
|
-
|
55
|
+
// Destroy function for proj data.
|
56
|
+
static void rgeo_proj4_free(void *ptr)
|
57
|
+
{
|
58
|
+
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
59
|
+
if(data->pj){
|
60
|
+
proj_destroy(data->pj);
|
61
|
+
}
|
62
|
+
free(data);
|
63
|
+
}
|
42
64
|
|
65
|
+
static size_t rgeo_proj4_memsize(const void *ptr)
|
66
|
+
{
|
67
|
+
size_t size = 0;
|
68
|
+
const RGeo_Proj4Data *data = (const RGeo_Proj4Data *)ptr;
|
43
69
|
|
44
|
-
|
70
|
+
size += sizeof(*data);
|
71
|
+
if(data->pj){
|
72
|
+
size += sizeof(data->pj);
|
73
|
+
}
|
74
|
+
return size;
|
75
|
+
}
|
45
76
|
|
46
|
-
static void
|
77
|
+
static void rgeo_proj4_mark(void *ptr)
|
47
78
|
{
|
48
|
-
|
49
|
-
|
79
|
+
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
80
|
+
if(!NIL_P(data->original_str)){
|
81
|
+
mark(data->original_str);
|
50
82
|
}
|
51
|
-
free(data);
|
52
83
|
}
|
53
84
|
|
85
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
86
|
+
static void rgeo_proj4_compact(void *ptr)
|
87
|
+
{
|
88
|
+
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
89
|
+
if(data && !NIL_P(data->original_str)){
|
90
|
+
data->original_str = rb_gc_location(data->original_str);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
#endif
|
54
94
|
|
55
|
-
static void
|
95
|
+
static void rgeo_proj4_clear_struct(RGeo_Proj4Data *data)
|
56
96
|
{
|
57
|
-
if
|
58
|
-
|
97
|
+
if(data->pj){
|
98
|
+
proj_destroy(data->pj);
|
99
|
+
data->pj = NULL;
|
100
|
+
data->original_str = Qnil;
|
59
101
|
}
|
60
102
|
}
|
61
103
|
|
104
|
+
static const rb_data_type_t rgeo_proj4_data_type = {
|
105
|
+
"RGeo::CoordSys::Proj4",
|
106
|
+
{rgeo_proj4_mark, rgeo_proj4_free, rgeo_proj4_memsize,
|
107
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
108
|
+
rgeo_proj4_compact
|
109
|
+
#endif
|
110
|
+
},
|
111
|
+
0, 0,
|
112
|
+
RUBY_TYPED_FREE_IMMEDIATELY};
|
62
113
|
|
63
|
-
static VALUE
|
114
|
+
static VALUE rgeo_proj4_data_alloc(VALUE self)
|
64
115
|
{
|
65
116
|
VALUE result;
|
66
|
-
RGeo_Proj4Data*
|
117
|
+
RGeo_Proj4Data *data = ALLOC(RGeo_Proj4Data);
|
67
118
|
|
68
119
|
result = Qnil;
|
69
|
-
|
70
|
-
if
|
120
|
+
|
121
|
+
if(data){
|
71
122
|
data->pj = NULL;
|
72
123
|
data->original_str = Qnil;
|
73
124
|
data->uses_radians = 0;
|
74
|
-
result =
|
125
|
+
result = TypedData_Wrap_Struct(self, &rgeo_proj4_data_type, data);
|
75
126
|
}
|
76
127
|
return result;
|
77
128
|
}
|
78
129
|
|
79
|
-
|
80
130
|
static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig)
|
81
131
|
{
|
82
|
-
RGeo_Proj4Data*
|
83
|
-
|
84
|
-
|
85
|
-
char* str;
|
132
|
+
RGeo_Proj4Data *self_data;
|
133
|
+
RGeo_Proj4Data *orig_data;
|
134
|
+
const char* str;
|
86
135
|
|
87
136
|
// Clear out any existing value
|
88
|
-
|
89
|
-
|
90
|
-
if (pj) {
|
91
|
-
pj_free(pj);
|
92
|
-
self_data->pj = NULL;
|
93
|
-
self_data->original_str = Qnil;
|
94
|
-
}
|
137
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, self_data);
|
138
|
+
rgeo_proj4_clear_struct(self_data);
|
95
139
|
|
96
140
|
// Copy value from orig
|
97
|
-
|
141
|
+
TypedData_Get_Struct(orig, RGeo_Proj4Data, &rgeo_proj4_data_type, orig_data);
|
98
142
|
if (!NIL_P(orig_data->original_str)) {
|
99
|
-
self_data->pj =
|
143
|
+
self_data->pj = proj_create(PJ_DEFAULT_CTX, StringValuePtr(orig_data->original_str));
|
100
144
|
}
|
101
145
|
else {
|
102
|
-
str =
|
103
|
-
self_data->pj =
|
104
|
-
pj_dalloc(str);
|
146
|
+
str = proj_as_proj_string(PJ_DEFAULT_CTX, orig_data->pj, PJ_PROJ_4, NULL);
|
147
|
+
self_data->pj = proj_create(PJ_DEFAULT_CTX, str);
|
105
148
|
}
|
106
149
|
self_data->original_str = orig_data->original_str;
|
107
150
|
self_data->uses_radians = orig_data->uses_radians;
|
@@ -112,22 +155,16 @@ static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig)
|
|
112
155
|
|
113
156
|
static VALUE method_proj4_set_value(VALUE self, VALUE str, VALUE uses_radians)
|
114
157
|
{
|
115
|
-
RGeo_Proj4Data*
|
116
|
-
projPJ pj;
|
158
|
+
RGeo_Proj4Data *self_data;
|
117
159
|
|
118
160
|
Check_Type(str, T_STRING);
|
119
161
|
|
120
162
|
// Clear out any existing value
|
121
|
-
|
122
|
-
|
123
|
-
if (pj) {
|
124
|
-
pj_free(pj);
|
125
|
-
self_data->pj = NULL;
|
126
|
-
self_data->original_str = Qnil;
|
127
|
-
}
|
163
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, self_data);
|
164
|
+
rgeo_proj4_clear_struct(self_data);
|
128
165
|
|
129
166
|
// Set new data
|
130
|
-
self_data->pj =
|
167
|
+
self_data->pj = proj_create(PJ_DEFAULT_CTX, StringValuePtr(str));
|
131
168
|
self_data->original_str = str;
|
132
169
|
self_data->uses_radians = RTEST(uses_radians) ? 1 : 0;
|
133
170
|
|
@@ -138,17 +175,18 @@ static VALUE method_proj4_set_value(VALUE self, VALUE str, VALUE uses_radians)
|
|
138
175
|
static VALUE method_proj4_get_geographic(VALUE self)
|
139
176
|
{
|
140
177
|
VALUE result;
|
141
|
-
RGeo_Proj4Data*
|
142
|
-
RGeo_Proj4Data*
|
178
|
+
RGeo_Proj4Data *new_data;
|
179
|
+
RGeo_Proj4Data *self_data;
|
143
180
|
|
144
181
|
result = Qnil;
|
145
182
|
new_data = ALLOC(RGeo_Proj4Data);
|
146
183
|
if (new_data) {
|
147
|
-
|
148
|
-
|
184
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, self_data);
|
185
|
+
|
186
|
+
new_data->pj = proj_crs_get_geodetic_crs(PJ_DEFAULT_CTX, self_data->pj);
|
149
187
|
new_data->original_str = Qnil;
|
150
188
|
new_data->uses_radians = self_data->uses_radians;
|
151
|
-
result =
|
189
|
+
result = TypedData_Wrap_Struct(CLASS_OF(self), &rgeo_proj4_data_type, new_data);
|
152
190
|
}
|
153
191
|
return result;
|
154
192
|
}
|
@@ -156,44 +194,97 @@ static VALUE method_proj4_get_geographic(VALUE self)
|
|
156
194
|
|
157
195
|
static VALUE method_proj4_original_str(VALUE self)
|
158
196
|
{
|
159
|
-
|
197
|
+
RGeo_Proj4Data *data;
|
198
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
199
|
+
return data->original_str;
|
160
200
|
}
|
161
201
|
|
162
202
|
|
163
203
|
static VALUE method_proj4_uses_radians(VALUE self)
|
164
204
|
{
|
165
|
-
|
205
|
+
RGeo_Proj4Data *data;
|
206
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
207
|
+
return data->uses_radians ? Qtrue : Qfalse;
|
166
208
|
}
|
167
209
|
|
168
210
|
|
169
211
|
static VALUE method_proj4_canonical_str(VALUE self)
|
170
212
|
{
|
171
213
|
VALUE result;
|
172
|
-
|
173
|
-
char*
|
214
|
+
PJ *pj;
|
215
|
+
const char *str;
|
216
|
+
RGeo_Proj4Data *data;
|
174
217
|
|
175
218
|
result = Qnil;
|
176
|
-
|
219
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
220
|
+
pj = data->pj;
|
177
221
|
if (pj) {
|
178
|
-
str =
|
222
|
+
str = proj_as_proj_string(PJ_DEFAULT_CTX, pj, PJ_PROJ_4, NULL);
|
179
223
|
if (str) {
|
180
224
|
result = rb_str_new2(str);
|
181
|
-
pj_dalloc(str);
|
182
225
|
}
|
183
226
|
}
|
184
227
|
return result;
|
185
228
|
}
|
186
229
|
|
230
|
+
static VALUE method_proj4_wkt_str(VALUE self)
|
231
|
+
{
|
232
|
+
VALUE result;
|
233
|
+
PJ *pj;
|
234
|
+
const char *str;
|
235
|
+
RGeo_Proj4Data *data;
|
236
|
+
|
237
|
+
result = Qnil;
|
238
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
239
|
+
pj = data->pj;
|
240
|
+
if (pj) {
|
241
|
+
const char *const options[] = {"MULTILINE=NO", NULL};
|
242
|
+
str = proj_as_wkt(PJ_DEFAULT_CTX, pj, WKT_TYPE, options);
|
243
|
+
if(str){
|
244
|
+
result = rb_str_new2(str);
|
245
|
+
}
|
246
|
+
}
|
247
|
+
return result;
|
248
|
+
}
|
249
|
+
|
250
|
+
static VALUE method_proj4_auth_name_str(VALUE self)
|
251
|
+
{
|
252
|
+
VALUE result;
|
253
|
+
PJ *pj;
|
254
|
+
const char *id;
|
255
|
+
const char *auth;
|
256
|
+
RGeo_Proj4Data *data;
|
257
|
+
|
258
|
+
result = Qnil;
|
259
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
260
|
+
pj = data->pj;
|
261
|
+
if (pj) {
|
262
|
+
auth = proj_get_id_auth_name(pj, 0);
|
263
|
+
id = proj_get_id_code(pj, 0);
|
264
|
+
if(id && auth){
|
265
|
+
result = rb_sprintf("%s:%s", auth, id);
|
266
|
+
}
|
267
|
+
}
|
268
|
+
return result;
|
269
|
+
}
|
187
270
|
|
188
271
|
static VALUE method_proj4_is_geographic(VALUE self)
|
189
272
|
{
|
190
273
|
VALUE result;
|
191
|
-
|
274
|
+
PJ *pj;
|
275
|
+
PJ_TYPE proj_type;
|
276
|
+
RGeo_Proj4Data *data;
|
192
277
|
|
193
278
|
result = Qnil;
|
194
|
-
|
279
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
280
|
+
pj = data->pj;
|
195
281
|
if (pj) {
|
196
|
-
|
282
|
+
proj_type = proj_get_type(pj);
|
283
|
+
if(proj_type == PJ_TYPE_GEOGRAPHIC_2D_CRS || proj_type == PJ_TYPE_GEOGRAPHIC_3D_CRS){
|
284
|
+
result = Qtrue;
|
285
|
+
} else {
|
286
|
+
result = Qfalse;
|
287
|
+
}
|
197
288
|
}
|
198
289
|
return result;
|
199
290
|
}
|
@@ -202,12 +293,16 @@ static VALUE method_proj4_is_geographic(VALUE self)
|
|
202
293
|
static VALUE method_proj4_is_geocentric(VALUE self)
|
203
294
|
{
|
204
295
|
VALUE result;
|
205
|
-
|
296
|
+
PJ *pj;
|
297
|
+
PJ_TYPE proj_type;
|
298
|
+
RGeo_Proj4Data *data;
|
206
299
|
|
207
300
|
result = Qnil;
|
208
|
-
|
301
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
302
|
+
pj = data->pj;
|
209
303
|
if (pj) {
|
210
|
-
|
304
|
+
proj_type = proj_get_type(pj);
|
305
|
+
result = proj_type == PJ_TYPE_GEOCENTRIC_CRS ? Qtrue : Qfalse;
|
211
306
|
}
|
212
307
|
return result;
|
213
308
|
}
|
@@ -215,42 +310,62 @@ static VALUE method_proj4_is_geocentric(VALUE self)
|
|
215
310
|
|
216
311
|
static VALUE method_proj4_is_valid(VALUE self)
|
217
312
|
{
|
218
|
-
|
313
|
+
RGeo_Proj4Data *data;
|
314
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
315
|
+
return data->pj ? Qtrue : Qfalse;
|
219
316
|
}
|
220
317
|
|
221
318
|
|
222
319
|
static VALUE cmethod_proj4_version(VALUE module)
|
223
320
|
{
|
224
|
-
return
|
321
|
+
return rb_sprintf("%d.%d.%d", PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR, PROJ_VERSION_PATCH);
|
225
322
|
}
|
226
323
|
|
227
324
|
|
228
325
|
static VALUE cmethod_proj4_transform(VALUE module, VALUE from, VALUE to, VALUE x, VALUE y, VALUE z)
|
229
326
|
{
|
230
327
|
VALUE result;
|
231
|
-
|
232
|
-
|
328
|
+
RGeo_Proj4Data *from_data;
|
329
|
+
RGeo_Proj4Data *to_data;
|
330
|
+
PJ *from_pj;
|
331
|
+
PJ *to_pj;
|
332
|
+
PJ *crs_to_crs;
|
333
|
+
PJ *gis_pj;
|
233
334
|
double xval, yval, zval;
|
234
|
-
|
335
|
+
PJ_COORD input;
|
336
|
+
PJ_COORD output;
|
235
337
|
|
236
338
|
result = Qnil;
|
237
|
-
|
238
|
-
|
339
|
+
TypedData_Get_Struct(from, RGeo_Proj4Data, &rgeo_proj4_data_type, from_data);
|
340
|
+
TypedData_Get_Struct(to, RGeo_Proj4Data, &rgeo_proj4_data_type, to_data);
|
341
|
+
from_pj = from_data->pj;
|
342
|
+
to_pj = to_data->pj;
|
239
343
|
if (from_pj && to_pj) {
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
344
|
+
crs_to_crs = proj_create_crs_to_crs_from_pj(PJ_DEFAULT_CTX, from_pj, to_pj, 0, NULL);
|
345
|
+
if(crs_to_crs){
|
346
|
+
// necessary to use proj_normalize_for_visualization so that we
|
347
|
+
// do not have to worry about the order of coordinates in every
|
348
|
+
// coord system.
|
349
|
+
gis_pj = proj_normalize_for_visualization(PJ_DEFAULT_CTX, crs_to_crs);
|
350
|
+
if(gis_pj){
|
351
|
+
proj_destroy(crs_to_crs);
|
352
|
+
crs_to_crs = gis_pj;
|
353
|
+
|
354
|
+
xval = rb_num2dbl(x);
|
355
|
+
yval = rb_num2dbl(y);
|
356
|
+
zval = NIL_P(z) ? 0.0 : rb_num2dbl(z);
|
357
|
+
|
358
|
+
input = proj_coord(xval, yval, zval, HUGE_VAL);
|
359
|
+
output = proj_trans(crs_to_crs, PJ_FWD, input);
|
360
|
+
|
361
|
+
result = rb_ary_new2(NIL_P(z) ? 2 : 3);
|
362
|
+
rb_ary_push(result, DBL2NUM(output.xyz.x));
|
363
|
+
rb_ary_push(result, DBL2NUM(output.xyz.y));
|
364
|
+
if(!NIL_P(z)){
|
365
|
+
rb_ary_push(result, DBL2NUM(output.xyz.z));
|
366
|
+
}
|
253
367
|
}
|
368
|
+
proj_destroy(crs_to_crs);
|
254
369
|
}
|
255
370
|
}
|
256
371
|
return result;
|
@@ -266,10 +381,10 @@ static VALUE cmethod_proj4_create(VALUE klass, VALUE str, VALUE uses_radians)
|
|
266
381
|
Check_Type(str, T_STRING);
|
267
382
|
data = ALLOC(RGeo_Proj4Data);
|
268
383
|
if (data) {
|
269
|
-
data->pj =
|
384
|
+
data->pj = proj_create(PJ_DEFAULT_CTX, StringValuePtr(str));
|
270
385
|
data->original_str = str;
|
271
386
|
data->uses_radians = RTEST(uses_radians) ? 1 : 0;
|
272
|
-
result =
|
387
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_proj4_data_type, data);
|
273
388
|
}
|
274
389
|
return result;
|
275
390
|
}
|
@@ -285,12 +400,14 @@ static void rgeo_init_proj4()
|
|
285
400
|
coordsys_module = rb_define_module_under(rgeo_module, "CoordSys");
|
286
401
|
proj4_class = rb_define_class_under(coordsys_module, "Proj4", rb_cObject);
|
287
402
|
|
288
|
-
rb_define_alloc_func(proj4_class,
|
403
|
+
rb_define_alloc_func(proj4_class, rgeo_proj4_data_alloc);
|
289
404
|
rb_define_module_function(proj4_class, "_create", cmethod_proj4_create, 2);
|
290
405
|
rb_define_method(proj4_class, "initialize_copy", method_proj4_initialize_copy, 1);
|
291
406
|
rb_define_method(proj4_class, "_set_value", method_proj4_set_value, 2);
|
292
407
|
rb_define_method(proj4_class, "_original_str", method_proj4_original_str, 0);
|
293
408
|
rb_define_method(proj4_class, "_canonical_str", method_proj4_canonical_str, 0);
|
409
|
+
rb_define_method(proj4_class, "_as_text", method_proj4_wkt_str, 0);
|
410
|
+
rb_define_method(proj4_class, "_auth_name", method_proj4_auth_name_str, 0);
|
294
411
|
rb_define_method(proj4_class, "_valid?", method_proj4_is_valid, 0);
|
295
412
|
rb_define_method(proj4_class, "_geographic?", method_proj4_is_geographic, 0);
|
296
413
|
rb_define_method(proj4_class, "_geocentric?", method_proj4_is_geocentric, 0);
|
data/lib/rgeo/coord_sys/proj4.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# Proj4 wrapper for RGeo
|
@@ -39,10 +41,10 @@ module RGeo
|
|
39
41
|
# there are sometimes multiple ways to express a given coordinate
|
40
42
|
# system.
|
41
43
|
|
42
|
-
def eql?(
|
43
|
-
|
44
|
+
def eql?(other)
|
45
|
+
other.class == self.class && other.canonical_hash == canonical_hash && other._radians? == _radians?
|
44
46
|
end
|
45
|
-
|
47
|
+
alias == eql?
|
46
48
|
|
47
49
|
# Marshal support
|
48
50
|
|
@@ -76,9 +78,7 @@ module RGeo
|
|
76
78
|
def canonical_str
|
77
79
|
unless defined?(@canonical_str)
|
78
80
|
@canonical_str = _canonical_str
|
79
|
-
if @canonical_str.respond_to?(:force_encoding)
|
80
|
-
@canonical_str.force_encoding("US-ASCII")
|
81
|
-
end
|
81
|
+
@canonical_str.force_encoding("US-ASCII") if @canonical_str.respond_to?(:force_encoding)
|
82
82
|
end
|
83
83
|
@canonical_str
|
84
84
|
end
|
@@ -105,6 +105,21 @@ module RGeo
|
|
105
105
|
_original_str
|
106
106
|
end
|
107
107
|
|
108
|
+
# Returns the WKT representation of the CRS.
|
109
|
+
|
110
|
+
def as_text
|
111
|
+
_as_text
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns the string representing the authority and code of the
|
115
|
+
# CRS if it exists, nil otherwise.
|
116
|
+
#
|
117
|
+
# Ex. EPSG:4326
|
118
|
+
|
119
|
+
def auth_name
|
120
|
+
_auth_name
|
121
|
+
end
|
122
|
+
|
108
123
|
# Returns true if this Proj4 object is a geographic (lat-long)
|
109
124
|
# coordinate system.
|
110
125
|
|
@@ -172,9 +187,7 @@ module RGeo
|
|
172
187
|
if defn_.is_a?(::Hash)
|
173
188
|
defn_ = defn_.map { |k_, v_| v_ ? "+#{k_}=#{v_}" : "+#{k_}" }.join(" ")
|
174
189
|
end
|
175
|
-
|
176
|
-
defn_ = defn_.sub(/^(\s*)/, '\1+').gsub(/(\s+)([^+\s])/, '\1+\2')
|
177
|
-
end
|
190
|
+
|
178
191
|
result_ = _create(defn_, opts_[:radians])
|
179
192
|
result_ = nil unless result_._valid?
|
180
193
|
end
|
@@ -200,9 +213,7 @@ module RGeo
|
|
200
213
|
|
201
214
|
def new(defn_, opts_ = {})
|
202
215
|
result_ = create(defn_, opts_)
|
203
|
-
unless result_
|
204
|
-
raise Error::UnsupportedOperation, "Proj4 not supported in this installation"
|
205
|
-
end
|
216
|
+
raise Error::UnsupportedOperation, "Proj4 not supported in this installation" unless result_
|
206
217
|
result_
|
207
218
|
end
|
208
219
|
|
@@ -212,14 +223,15 @@ module RGeo
|
|
212
223
|
# or three elements.
|
213
224
|
|
214
225
|
def transform_coords(from_proj_, to_proj_, x_, y_, z_ = nil)
|
215
|
-
if
|
216
|
-
x_ *= ImplHelper::Math::
|
217
|
-
y_ *= ImplHelper::Math::
|
226
|
+
if from_proj_._radians? && from_proj_._geographic?
|
227
|
+
x_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
228
|
+
y_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
218
229
|
end
|
230
|
+
|
219
231
|
result_ = _transform_coords(from_proj_, to_proj_, x_, y_, z_)
|
220
|
-
if result_ &&
|
221
|
-
result_[0] *= ImplHelper::Math::
|
222
|
-
result_[1] *= ImplHelper::Math::
|
232
|
+
if result_ && to_proj_._radians? && to_proj_._geographic?
|
233
|
+
result_[0] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
234
|
+
result_[1] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
223
235
|
end
|
224
236
|
result_
|
225
237
|
end
|
@@ -233,27 +245,29 @@ module RGeo
|
|
233
245
|
def transform(from_proj_, from_geometry_, to_proj_, to_factory_)
|
234
246
|
case from_geometry_
|
235
247
|
when Feature::Point
|
236
|
-
|
248
|
+
transform_point(from_proj_, from_geometry_, to_proj_, to_factory_)
|
237
249
|
when Feature::Line
|
238
|
-
to_factory_.line(from_geometry_.points.map { |p_|
|
250
|
+
to_factory_.line(from_geometry_.points.map { |p_| transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
239
251
|
when Feature::LinearRing
|
240
|
-
|
252
|
+
transform_linear_ring(from_proj_, from_geometry_, to_proj_, to_factory_)
|
241
253
|
when Feature::LineString
|
242
|
-
to_factory_.line_string(from_geometry_.points.map { |p_|
|
254
|
+
to_factory_.line_string(from_geometry_.points.map { |p_| transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
243
255
|
when Feature::Polygon
|
244
|
-
|
256
|
+
transform_polygon(from_proj_, from_geometry_, to_proj_, to_factory_)
|
245
257
|
when Feature::MultiPoint
|
246
|
-
to_factory_.multi_point(from_geometry_.map { |p_|
|
258
|
+
to_factory_.multi_point(from_geometry_.map { |p_| transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
247
259
|
when Feature::MultiLineString
|
248
260
|
to_factory_.multi_line_string(from_geometry_.map { |g_| transform(from_proj_, g_, to_proj_, to_factory_) })
|
249
261
|
when Feature::MultiPolygon
|
250
|
-
to_factory_.multi_polygon(from_geometry_.map { |p_|
|
262
|
+
to_factory_.multi_polygon(from_geometry_.map { |p_| transform_polygon(from_proj_, p_, to_proj_, to_factory_) })
|
251
263
|
when Feature::GeometryCollection
|
252
264
|
to_factory_.collection(from_geometry_.map { |g_| transform(from_proj_, g_, to_proj_, to_factory_) })
|
253
265
|
end
|
254
266
|
end
|
255
267
|
|
256
|
-
|
268
|
+
private
|
269
|
+
|
270
|
+
def transform_point(from_proj_, from_point_, to_proj_, to_factory_)
|
257
271
|
from_factory_ = from_point_.factory
|
258
272
|
from_has_z_ = from_factory_.property(:has_z_coordinate)
|
259
273
|
from_has_m_ = from_factory_.property(:has_m_coordinate)
|
@@ -261,30 +275,32 @@ module RGeo
|
|
261
275
|
to_has_m_ = to_factory_.property(:has_m_coordinate)
|
262
276
|
x_ = from_point_.x
|
263
277
|
y_ = from_point_.y
|
264
|
-
if
|
265
|
-
x_ *= ImplHelper::Math::
|
266
|
-
y_ *= ImplHelper::Math::
|
278
|
+
if from_proj_._radians? && from_proj_._geographic?
|
279
|
+
x_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
280
|
+
y_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
267
281
|
end
|
268
282
|
coords_ = _transform_coords(from_proj_, to_proj_, x_, y_, from_has_z_ ? from_point_.z : nil)
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
283
|
+
return unless coords_
|
284
|
+
|
285
|
+
if to_proj_._radians? && to_proj_._geographic?
|
286
|
+
coords_[0] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
287
|
+
coords_[1] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
288
|
+
end
|
289
|
+
extras_ = []
|
290
|
+
extras_ << coords_[2].to_f if to_has_z_
|
291
|
+
if to_has_m_
|
292
|
+
extras_ << from_has_m_ ? from_point_.m : 0.0
|
278
293
|
end
|
294
|
+
to_factory_.point(coords_[0], coords_[1], *extras_)
|
279
295
|
end
|
280
296
|
|
281
|
-
def
|
282
|
-
to_factory_.linear_ring(from_ring_.points[0..-2].map { |p_|
|
297
|
+
def transform_linear_ring(from_proj_, from_ring_, to_proj_, to_factory_)
|
298
|
+
to_factory_.linear_ring(from_ring_.points[0..-2].map { |p_| transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
283
299
|
end
|
284
300
|
|
285
|
-
def
|
286
|
-
ext_ =
|
287
|
-
int_ = from_polygon_.interior_rings.map { |r_|
|
301
|
+
def transform_polygon(from_proj_, from_polygon_, to_proj_, to_factory_)
|
302
|
+
ext_ = transform_linear_ring(from_proj_, from_polygon_.exterior_ring, to_proj_, to_factory_)
|
303
|
+
int_ = from_polygon_.interior_rings.map { |r_| transform_linear_ring(from_proj_, r_, to_proj_, to_factory_) }
|
288
304
|
to_factory_.polygon(ext_, int_)
|
289
305
|
end
|
290
306
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# SRS database interface
|
@@ -62,7 +64,7 @@ module RGeo
|
|
62
64
|
when :read_all
|
63
65
|
@populate_state = 1
|
64
66
|
when :preload
|
65
|
-
|
67
|
+
search_file(nil)
|
66
68
|
@populate_state = 2
|
67
69
|
else
|
68
70
|
@populate_state = 0
|
@@ -77,14 +79,15 @@ module RGeo
|
|
77
79
|
|
78
80
|
def get(ident_)
|
79
81
|
ident_ = ident_.to_s
|
80
|
-
return @cache[ident_] if @cache
|
82
|
+
return @cache[ident_] if @cache&.include?(ident_)
|
81
83
|
result_ = nil
|
82
|
-
|
83
|
-
|
84
|
+
case @populate_state
|
85
|
+
when 0
|
86
|
+
data_ = search_file(ident_)
|
84
87
|
result_ = Entry.new(ident_, authority: @authority, authority_code: @authority ? ident_ : nil, name: data_[1], proj4: data_[2]) if data_
|
85
88
|
@cache[ident_] = result_ if @cache
|
86
|
-
|
87
|
-
|
89
|
+
when 1
|
90
|
+
search_file(nil)
|
88
91
|
result_ = @cache[ident_]
|
89
92
|
@populate_state = 2
|
90
93
|
end
|
@@ -94,27 +97,27 @@ module RGeo
|
|
94
97
|
# Clear the cache if one exists.
|
95
98
|
|
96
99
|
def clear_cache
|
97
|
-
@cache
|
100
|
+
@cache&.clear
|
98
101
|
@populate_state = 1 if @populate_state == 2
|
99
102
|
end
|
100
103
|
|
101
|
-
|
104
|
+
private
|
105
|
+
|
106
|
+
def search_file(ident_)
|
102
107
|
::File.open(@path) do |file_|
|
103
108
|
cur_name_ = nil
|
104
109
|
cur_ident_ = nil
|
105
110
|
cur_text_ = nil
|
106
111
|
file_.each do |line_|
|
107
112
|
line_.strip!
|
108
|
-
if (comment_delim_ = line_.index(
|
113
|
+
if (comment_delim_ = line_.index("#"))
|
109
114
|
cur_name_ = line_[comment_delim_ + 1..-1].strip
|
110
115
|
line_ = line_[0..comment_delim_ - 1].strip
|
111
116
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
line_ = Regexp.last_match(2).strip
|
117
|
-
end
|
117
|
+
if !cur_ident_ && (line_ =~ /^<(\w+)>(.*)/)
|
118
|
+
cur_ident_ = Regexp.last_match(1)
|
119
|
+
cur_text_ = []
|
120
|
+
line_ = Regexp.last_match(2).strip
|
118
121
|
end
|
119
122
|
next unless cur_ident_
|
120
123
|
if line_[-2..-1] == "<>"
|
data/lib/rgeo/proj4.rb
CHANGED
data/lib/rgeo/proj4/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgeo-proj4
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tee Parham, Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rgeo
|
@@ -16,42 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '2.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5.14'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '5.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.9.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.9.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '13.0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '13.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake-compiler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,19 +81,19 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '1.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: rubocop
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
89
|
+
version: 1.8.1
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
96
|
+
version: 1.8.1
|
83
97
|
description: Proj4 extension for rgeo.
|
84
98
|
email:
|
85
99
|
- parhameter@gmail.com, dazuma@gmail.com
|
@@ -107,15 +121,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
121
|
requirements:
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: 2.
|
124
|
+
version: 2.5.0
|
111
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
126
|
requirements:
|
113
|
-
- - "
|
127
|
+
- - ">="
|
114
128
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
129
|
+
version: '0'
|
116
130
|
requirements: []
|
117
|
-
|
118
|
-
rubygems_version: 2.7.0
|
131
|
+
rubygems_version: 3.1.4
|
119
132
|
signing_key:
|
120
133
|
specification_version: 4
|
121
134
|
summary: Proj4 extension for rgeo.
|