rgeo-proj4 3.1.1 → 4.0.0.pre.rc.1
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/ext/proj4_c_impl/errors.c +31 -0
- data/ext/proj4_c_impl/errors.h +22 -0
- data/ext/proj4_c_impl/extconf.rb +53 -16
- data/ext/proj4_c_impl/main.c +210 -41
- data/ext/proj4_c_impl/preface.h +23 -0
- data/lib/rgeo/coord_sys/crs_to_crs.rb +34 -6
- data/lib/rgeo/coord_sys/proj4.rb +71 -10
- data/lib/rgeo/errors.rb +15 -0
- data/lib/rgeo/proj4/version.rb +1 -1
- data/lib/rgeo/proj4.rb +41 -2
- metadata +16 -13
- data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +0 -143
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0a179679b6f6471a9626bf6fbc08758a52b0d60f5ba81fa4ab5119456680470
|
4
|
+
data.tar.gz: 2a58dfbbf870d24ea9d4b2880444c1f331ba184dc38862af6b4347fb9cc96366
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3f86ad3fd2ef994a74ebf0df1f6f4d87446f7a28055417d551822ed88384893f74e20d6803200083f129fe152170ae3d887b50769a5861391b3c0447d83c7a5
|
7
|
+
data.tar.gz: b41045b6502bd6172632021e942da3214b9de534ffd1461bb4969813c3fbcd60a8c0c7f3074c692609380f1179a1c9b600b99bba9a0c3a3f620ad99a8226b618
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#ifndef RGEO_PROJ4_ERRORS_INCLUDED
|
2
|
+
#define RGEO_PROJ4_ERRORS_INCLUDED
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
|
6
|
+
#include "preface.h"
|
7
|
+
|
8
|
+
#ifdef RGEO_PROJ4_SUPPORTED
|
9
|
+
|
10
|
+
#include "errors.h"
|
11
|
+
|
12
|
+
RGEO_BEGIN_C
|
13
|
+
|
14
|
+
VALUE error_module;
|
15
|
+
VALUE rb_eRGeoError;
|
16
|
+
VALUE rb_eRGeoInvalidProjectionError;
|
17
|
+
|
18
|
+
void rgeo_init_proj_errors() {
|
19
|
+
VALUE rgeo_module;
|
20
|
+
|
21
|
+
rgeo_module = rb_define_module("RGeo");
|
22
|
+
error_module = rb_define_module_under(rgeo_module, "Error");
|
23
|
+
rb_eRGeoError = rb_define_class_under(error_module, "RGeoError", rb_eRuntimeError);
|
24
|
+
rb_eRGeoInvalidProjectionError = rb_define_class_under(error_module, "InvalidProjection", rb_eRGeoError);
|
25
|
+
}
|
26
|
+
|
27
|
+
RGEO_END_C
|
28
|
+
|
29
|
+
#endif // RGEO_PROJ4_SUPPORTED
|
30
|
+
|
31
|
+
#endif // RGEO_GEOS_ERROS_INCLUDED
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef RGEO_PROJ4_ERRORS_INCLUDED
|
2
|
+
#define RGEO_PROJ4_ERRORS_INCLUDED
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
|
6
|
+
#ifdef RGEO_PROJ4_SUPPORTED
|
7
|
+
|
8
|
+
RGEO_BEGIN_C
|
9
|
+
|
10
|
+
extern VALUE error_module;
|
11
|
+
// Main rgeo error type
|
12
|
+
extern VALUE rb_eRGeoError;
|
13
|
+
// RGeo::Error::InvalidProjection
|
14
|
+
extern VALUE rb_eRGeoInvalidProjectionError;
|
15
|
+
|
16
|
+
void rgeo_init_proj_errors();
|
17
|
+
|
18
|
+
RGEO_END_C
|
19
|
+
|
20
|
+
#endif // RGEO_PROJ4_SUPPORTED
|
21
|
+
|
22
|
+
#endif // RGEO_PROJ4_ERRORS_INCLUDED
|
data/ext/proj4_c_impl/extconf.rb
CHANGED
@@ -12,7 +12,7 @@ else
|
|
12
12
|
|
13
13
|
require "mkmf"
|
14
14
|
|
15
|
-
|
15
|
+
header_dirs =
|
16
16
|
[
|
17
17
|
::RbConfig::CONFIG["includedir"],
|
18
18
|
"/usr/local/include",
|
@@ -26,7 +26,7 @@ else
|
|
26
26
|
"/Library/Frameworks/PROJ.framework/unix/include",
|
27
27
|
"/usr/include"
|
28
28
|
]
|
29
|
-
|
29
|
+
lib_dirs =
|
30
30
|
[
|
31
31
|
::RbConfig::CONFIG["libdir"],
|
32
32
|
"/usr/local/lib",
|
@@ -42,28 +42,65 @@ else
|
|
42
42
|
"/usr/lib",
|
43
43
|
"/usr/lib64"
|
44
44
|
]
|
45
|
-
|
46
|
-
|
45
|
+
header_dirs.delete_if { |path| !::File.directory?(path) }
|
46
|
+
lib_dirs.delete_if { |path| !::File.directory?(path) }
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
found_proj = false
|
49
|
+
found_valid_proj_version = false
|
50
|
+
header_dirs, lib_dirs = dir_config("proj", header_dirs, lib_dirs)
|
50
51
|
if have_header("proj.h")
|
51
52
|
$libs << " -lproj"
|
53
|
+
found_proj = true
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
required_proj_funcs = %w[
|
56
|
+
proj_create
|
57
|
+
proj_create_crs_to_crs_from_pj
|
58
|
+
proj_normalize_for_visualization
|
59
|
+
]
|
60
|
+
found_valid_proj_version = required_proj_funcs.all? do |func|
|
61
|
+
have_func(func, "proj.h")
|
59
62
|
end
|
60
63
|
end
|
61
64
|
have_func("rb_gc_mark_movable")
|
62
65
|
|
63
|
-
unless
|
64
|
-
|
65
|
-
|
66
|
+
unless found_proj
|
67
|
+
|
68
|
+
install_text = case RUBY_PLATFORM
|
69
|
+
when /linux/
|
70
|
+
%(
|
71
|
+
Please install proj like so:
|
72
|
+
apt-get install libproj-dev proj-bin
|
73
|
+
)
|
74
|
+
when /darwin/
|
75
|
+
%(
|
76
|
+
Please install proj like so:
|
77
|
+
brew install proj
|
78
|
+
)
|
79
|
+
else
|
80
|
+
%(
|
81
|
+
Please install proj.
|
82
|
+
)
|
83
|
+
end
|
84
|
+
error_msg = %(
|
85
|
+
**** WARNING: Unable to find Proj headers. Ensure that Proj is properly installed.
|
86
|
+
|
87
|
+
#{install_text}
|
88
|
+
|
89
|
+
or set the path manually using:
|
90
|
+
--with-proj-dir or with the --with-proj-include and --with-proj-lib options
|
91
|
+
)
|
92
|
+
warn error_msg
|
93
|
+
raise
|
94
|
+
end
|
95
|
+
|
96
|
+
unless found_valid_proj_version
|
97
|
+
error_msg = %(
|
98
|
+
**** WARNING: The found Proj version is not new enough to be used for this version of rgeo-proj4.
|
99
|
+
**** Proj 6.2+ is required.
|
100
|
+
)
|
101
|
+
warn error_msg
|
102
|
+
raise
|
66
103
|
end
|
67
|
-
create_makefile("rgeo/coord_sys/proj4_c_impl")
|
68
104
|
|
105
|
+
create_makefile("rgeo/coord_sys/proj4_c_impl")
|
69
106
|
end
|
data/ext/proj4_c_impl/main.c
CHANGED
@@ -1,35 +1,14 @@
|
|
1
1
|
/*
|
2
2
|
Main initializer for Proj4 wrapper
|
3
3
|
*/
|
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
|
8
|
-
#define RGEO_PROJ4_SUPPORTED
|
9
|
-
#endif
|
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
|
19
|
-
|
20
|
-
#ifdef __cplusplus
|
21
|
-
#define RGEO_BEGIN_C extern "C" {
|
22
|
-
#define RGEO_END_C }
|
23
|
-
#else
|
24
|
-
#define RGEO_BEGIN_C
|
25
|
-
#define RGEO_END_C
|
26
|
-
#endif
|
27
4
|
|
5
|
+
#include "preface.h"
|
28
6
|
|
29
7
|
#ifdef RGEO_PROJ4_SUPPORTED
|
30
8
|
|
31
9
|
#include <ruby.h>
|
32
10
|
#include <proj.h>
|
11
|
+
#include "errors.h"
|
33
12
|
|
34
13
|
#endif
|
35
14
|
|
@@ -60,7 +39,7 @@ typedef struct {
|
|
60
39
|
static void rgeo_proj4_free(void *ptr)
|
61
40
|
{
|
62
41
|
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
63
|
-
if(data->pj){
|
42
|
+
if (data->pj){
|
64
43
|
proj_destroy(data->pj);
|
65
44
|
}
|
66
45
|
free(data);
|
@@ -70,7 +49,7 @@ static void rgeo_proj4_free(void *ptr)
|
|
70
49
|
static void rgeo_crs_to_crs_free(void *ptr)
|
71
50
|
{
|
72
51
|
RGeo_CRSToCRSData *data = (RGeo_CRSToCRSData *)ptr;
|
73
|
-
if(data->crs_to_crs){
|
52
|
+
if (data->crs_to_crs){
|
74
53
|
proj_destroy(data->crs_to_crs);
|
75
54
|
}
|
76
55
|
free(data);
|
@@ -83,7 +62,7 @@ static size_t rgeo_proj4_memsize(const void *ptr)
|
|
83
62
|
const RGeo_Proj4Data *data = (const RGeo_Proj4Data *)ptr;
|
84
63
|
|
85
64
|
size += sizeof(*data);
|
86
|
-
if(data->pj){
|
65
|
+
if (data->pj){
|
87
66
|
size += sizeof(data->pj);
|
88
67
|
}
|
89
68
|
return size;
|
@@ -94,7 +73,7 @@ static size_t rgeo_crs_to_crs_memsize(const void *ptr)
|
|
94
73
|
size_t size = 0;
|
95
74
|
const RGeo_CRSToCRSData *data = (const RGeo_CRSToCRSData *)ptr;
|
96
75
|
size += sizeof(*data);
|
97
|
-
if(data->crs_to_crs){
|
76
|
+
if (data->crs_to_crs){
|
98
77
|
size += sizeof(data->crs_to_crs);
|
99
78
|
}
|
100
79
|
return size;
|
@@ -103,7 +82,7 @@ static size_t rgeo_crs_to_crs_memsize(const void *ptr)
|
|
103
82
|
static void rgeo_proj4_mark(void *ptr)
|
104
83
|
{
|
105
84
|
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
106
|
-
if(!NIL_P(data->original_str)){
|
85
|
+
if (!NIL_P(data->original_str)){
|
107
86
|
mark(data->original_str);
|
108
87
|
}
|
109
88
|
}
|
@@ -112,7 +91,7 @@ static void rgeo_proj4_mark(void *ptr)
|
|
112
91
|
static void rgeo_proj4_compact(void *ptr)
|
113
92
|
{
|
114
93
|
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
115
|
-
if(data && !NIL_P(data->original_str)){
|
94
|
+
if (data && !NIL_P(data->original_str)){
|
116
95
|
data->original_str = rb_gc_location(data->original_str);
|
117
96
|
}
|
118
97
|
}
|
@@ -120,7 +99,7 @@ static void rgeo_proj4_compact(void *ptr)
|
|
120
99
|
|
121
100
|
static void rgeo_proj4_clear_struct(RGeo_Proj4Data *data)
|
122
101
|
{
|
123
|
-
if(data->pj){
|
102
|
+
if (data->pj){
|
124
103
|
proj_destroy(data->pj);
|
125
104
|
data->pj = NULL;
|
126
105
|
data->original_str = Qnil;
|
@@ -150,7 +129,7 @@ static VALUE rgeo_proj4_data_alloc(VALUE self)
|
|
150
129
|
|
151
130
|
result = Qnil;
|
152
131
|
|
153
|
-
if(data){
|
132
|
+
if (data){
|
154
133
|
data->pj = NULL;
|
155
134
|
data->original_str = Qnil;
|
156
135
|
data->uses_radians = 0;
|
@@ -167,7 +146,7 @@ static VALUE rgeo_crs_to_crs_data_alloc(VALUE self)
|
|
167
146
|
|
168
147
|
result = Qnil;
|
169
148
|
|
170
|
-
if(data){
|
149
|
+
if (data){
|
171
150
|
data->crs_to_crs = NULL;
|
172
151
|
result = TypedData_Wrap_Struct(self, &rgeo_crs_to_crs_data_type, data);
|
173
152
|
}
|
@@ -224,13 +203,20 @@ static VALUE method_proj4_get_geographic(VALUE self)
|
|
224
203
|
VALUE result;
|
225
204
|
RGeo_Proj4Data *new_data;
|
226
205
|
RGeo_Proj4Data *self_data;
|
206
|
+
PJ *geographic_proj;
|
227
207
|
|
228
208
|
result = Qnil;
|
229
209
|
new_data = ALLOC(RGeo_Proj4Data);
|
230
210
|
if (new_data) {
|
231
211
|
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, self_data);
|
232
212
|
|
233
|
-
|
213
|
+
geographic_proj = proj_crs_get_geodetic_crs(PJ_DEFAULT_CTX, self_data->pj);
|
214
|
+
if (geographic_proj == 0) {
|
215
|
+
xfree(new_data);
|
216
|
+
rb_raise(rb_eRGeoInvalidProjectionError, "Geographic CRS could not be created because the source projection is not a CRS");
|
217
|
+
}
|
218
|
+
|
219
|
+
new_data->pj = geographic_proj;
|
234
220
|
new_data->original_str = Qnil;
|
235
221
|
new_data->uses_radians = self_data->uses_radians;
|
236
222
|
result = TypedData_Wrap_Struct(CLASS_OF(self), &rgeo_proj4_data_type, new_data);
|
@@ -287,7 +273,7 @@ static VALUE method_proj4_wkt_str(VALUE self)
|
|
287
273
|
if (pj) {
|
288
274
|
const char *const options[] = {"MULTILINE=NO", NULL};
|
289
275
|
str = proj_as_wkt(PJ_DEFAULT_CTX, pj, WKT_TYPE, options);
|
290
|
-
if(str){
|
276
|
+
if (str){
|
291
277
|
result = rb_str_new2(str);
|
292
278
|
}
|
293
279
|
}
|
@@ -308,13 +294,67 @@ static VALUE method_proj4_auth_name_str(VALUE self)
|
|
308
294
|
if (pj) {
|
309
295
|
auth = proj_get_id_auth_name(pj, 0);
|
310
296
|
id = proj_get_id_code(pj, 0);
|
311
|
-
if(id && auth){
|
297
|
+
if (id && auth){
|
312
298
|
result = rb_sprintf("%s:%s", auth, id);
|
313
299
|
}
|
314
300
|
}
|
315
301
|
return result;
|
316
302
|
}
|
317
303
|
|
304
|
+
static VALUE method_proj4_axis_and_unit_info_str(VALUE self, VALUE dimension)
|
305
|
+
{
|
306
|
+
VALUE result;
|
307
|
+
int dimension_index;
|
308
|
+
PJ *pj;
|
309
|
+
PJ *pj_cs;
|
310
|
+
const char *axis_info;
|
311
|
+
const char *unit_name;
|
312
|
+
RGeo_Proj4Data *data;
|
313
|
+
|
314
|
+
Check_Type(dimension, T_FIXNUM);
|
315
|
+
|
316
|
+
dimension_index = FIX2INT(dimension);
|
317
|
+
result = Qnil;
|
318
|
+
|
319
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
320
|
+
pj = data->pj;
|
321
|
+
if (pj){
|
322
|
+
pj_cs = proj_crs_get_coordinate_system(PJ_DEFAULT_CTX, pj);
|
323
|
+
if (pj_cs) {
|
324
|
+
if (proj_cs_get_axis_info(PJ_DEFAULT_CTX, pj_cs, dimension_index, &axis_info, NULL, NULL, NULL, &unit_name, NULL, NULL)) {
|
325
|
+
result = rb_sprintf("%s:%s", axis_info, unit_name);
|
326
|
+
}
|
327
|
+
|
328
|
+
proj_destroy(pj_cs);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
return result;
|
332
|
+
}
|
333
|
+
|
334
|
+
static VALUE method_proj4_axis_count(VALUE self)
|
335
|
+
{
|
336
|
+
VALUE result;
|
337
|
+
PJ *pj;
|
338
|
+
PJ *pj_cs;
|
339
|
+
int count;
|
340
|
+
RGeo_Proj4Data *data;
|
341
|
+
|
342
|
+
result = Qnil;
|
343
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
344
|
+
pj = data->pj;
|
345
|
+
if (pj){
|
346
|
+
pj_cs = proj_crs_get_coordinate_system(PJ_DEFAULT_CTX, pj);
|
347
|
+
if (pj_cs) {
|
348
|
+
count = proj_cs_get_axis_count(PJ_DEFAULT_CTX, pj_cs);
|
349
|
+
result = INT2FIX(count);
|
350
|
+
|
351
|
+
proj_destroy(pj_cs);
|
352
|
+
}
|
353
|
+
}
|
354
|
+
return result;
|
355
|
+
}
|
356
|
+
|
357
|
+
|
318
358
|
static VALUE method_proj4_is_geographic(VALUE self)
|
319
359
|
{
|
320
360
|
VALUE result;
|
@@ -327,7 +367,7 @@ static VALUE method_proj4_is_geographic(VALUE self)
|
|
327
367
|
pj = data->pj;
|
328
368
|
if (pj) {
|
329
369
|
proj_type = proj_get_type(pj);
|
330
|
-
if(proj_type == PJ_TYPE_GEOGRAPHIC_2D_CRS || proj_type == PJ_TYPE_GEOGRAPHIC_3D_CRS){
|
370
|
+
if (proj_type == PJ_TYPE_GEOGRAPHIC_2D_CRS || proj_type == PJ_TYPE_GEOGRAPHIC_3D_CRS){
|
331
371
|
result = Qtrue;
|
332
372
|
} else {
|
333
373
|
result = Qfalse;
|
@@ -354,6 +394,23 @@ static VALUE method_proj4_is_geocentric(VALUE self)
|
|
354
394
|
return result;
|
355
395
|
}
|
356
396
|
|
397
|
+
static VALUE method_proj4_is_projected(VALUE self)
|
398
|
+
{
|
399
|
+
VALUE result;
|
400
|
+
PJ *pj;
|
401
|
+
PJ_TYPE proj_type;
|
402
|
+
RGeo_Proj4Data *data;
|
403
|
+
|
404
|
+
result = Qnil;
|
405
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
406
|
+
pj = data->pj;
|
407
|
+
if (pj) {
|
408
|
+
proj_type = proj_get_type(pj);
|
409
|
+
result = proj_type == PJ_TYPE_PROJECTED_CRS ? Qtrue : Qfalse;
|
410
|
+
}
|
411
|
+
return result;
|
412
|
+
}
|
413
|
+
|
357
414
|
|
358
415
|
static VALUE method_proj4_is_valid(VALUE self)
|
359
416
|
{
|
@@ -362,6 +419,14 @@ static VALUE method_proj4_is_valid(VALUE self)
|
|
362
419
|
return data->pj ? Qtrue : Qfalse;
|
363
420
|
}
|
364
421
|
|
422
|
+
static VALUE method_proj4_is_crs(VALUE self)
|
423
|
+
{
|
424
|
+
RGeo_Proj4Data *self_data;
|
425
|
+
|
426
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, self_data);
|
427
|
+
return proj_is_crs(self_data->pj) ? Qtrue : Qfalse;
|
428
|
+
}
|
429
|
+
|
365
430
|
|
366
431
|
static VALUE cmethod_proj4_version(VALUE module)
|
367
432
|
{
|
@@ -403,11 +468,16 @@ static VALUE cmethod_crs_to_crs_create(VALUE klass, VALUE from, VALUE to)
|
|
403
468
|
to_pj = to_data->pj;
|
404
469
|
crs_to_crs = proj_create_crs_to_crs_from_pj(PJ_DEFAULT_CTX, from_pj, to_pj, 0, NULL);
|
405
470
|
|
471
|
+
// check for invalid transformation
|
472
|
+
if (crs_to_crs == 0) {
|
473
|
+
rb_raise(rb_eRGeoInvalidProjectionError, "CRSToCRS could not be created from input projections");
|
474
|
+
}
|
475
|
+
|
406
476
|
// necessary to use proj_normalize_for_visualization so that we
|
407
477
|
// do not have to worry about the order of coordinates in every
|
408
478
|
// coord system
|
409
479
|
gis_pj = proj_normalize_for_visualization(PJ_DEFAULT_CTX, crs_to_crs);
|
410
|
-
if(gis_pj){
|
480
|
+
if (gis_pj){
|
411
481
|
proj_destroy(crs_to_crs);
|
412
482
|
crs_to_crs = gis_pj;
|
413
483
|
}
|
@@ -432,7 +502,7 @@ static VALUE method_crs_to_crs_transform(VALUE self, VALUE x, VALUE y, VALUE z)
|
|
432
502
|
result = Qnil;
|
433
503
|
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type, crs_to_crs_data);
|
434
504
|
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
435
|
-
if(crs_to_crs_pj){
|
505
|
+
if (crs_to_crs_pj){
|
436
506
|
xval = rb_num2dbl(x);
|
437
507
|
yval = rb_num2dbl(y);
|
438
508
|
zval = NIL_P(z) ? 0.0 : rb_num2dbl(z);
|
@@ -443,24 +513,113 @@ static VALUE method_crs_to_crs_transform(VALUE self, VALUE x, VALUE y, VALUE z)
|
|
443
513
|
result = rb_ary_new2(NIL_P(z) ? 2 : 3);
|
444
514
|
rb_ary_push(result, DBL2NUM(output.xyz.x));
|
445
515
|
rb_ary_push(result, DBL2NUM(output.xyz.y));
|
446
|
-
if(!NIL_P(z)){
|
516
|
+
if (!NIL_P(z)){
|
447
517
|
rb_ary_push(result, DBL2NUM(output.xyz.z));
|
448
518
|
}
|
449
519
|
}
|
450
520
|
return result;
|
451
521
|
}
|
452
522
|
|
523
|
+
static VALUE method_crs_to_crs_wkt_str(VALUE self)
|
524
|
+
{
|
525
|
+
VALUE result;
|
526
|
+
RGeo_CRSToCRSData *crs_to_crs_data;
|
527
|
+
PJ *crs_to_crs_pj;
|
528
|
+
const char *str;
|
529
|
+
|
530
|
+
result = Qnil;
|
531
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type, crs_to_crs_data);
|
532
|
+
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
533
|
+
if (crs_to_crs_pj) {
|
534
|
+
const char *const options[] = {"MULTILINE=NO", NULL};
|
535
|
+
str = proj_as_wkt(PJ_DEFAULT_CTX, crs_to_crs_pj, WKT_TYPE, options);
|
536
|
+
if (str){
|
537
|
+
result = rb_str_new2(str);
|
538
|
+
}
|
539
|
+
}
|
540
|
+
return result;
|
541
|
+
}
|
542
|
+
|
543
|
+
static VALUE method_crs_to_crs_area_of_use_str(VALUE self)
|
544
|
+
{
|
545
|
+
VALUE result;
|
546
|
+
RGeo_CRSToCRSData *crs_to_crs_data;
|
547
|
+
PJ *crs_to_crs_pj;
|
548
|
+
const char *str;
|
549
|
+
|
550
|
+
result = Qnil;
|
551
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type, crs_to_crs_data);
|
552
|
+
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
553
|
+
if (crs_to_crs_pj) {
|
554
|
+
if (proj_get_area_of_use(PJ_DEFAULT_CTX, crs_to_crs_pj, NULL, NULL, NULL, NULL, &str)){
|
555
|
+
result = rb_str_new2(str);
|
556
|
+
}
|
557
|
+
}
|
558
|
+
return result;
|
559
|
+
}
|
560
|
+
|
561
|
+
static VALUE method_crs_to_crs_proj_type(VALUE self)
|
562
|
+
{
|
563
|
+
VALUE result;
|
564
|
+
RGeo_CRSToCRSData *crs_to_crs_data;
|
565
|
+
PJ *crs_to_crs_pj;
|
566
|
+
int proj_type;
|
567
|
+
|
568
|
+
result = Qnil;
|
569
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type, crs_to_crs_data);
|
570
|
+
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
571
|
+
if (crs_to_crs_pj) {
|
572
|
+
proj_type = proj_get_type(crs_to_crs_pj);
|
573
|
+
result = INT2FIX(proj_type);
|
574
|
+
}
|
575
|
+
return result;
|
576
|
+
}
|
577
|
+
|
578
|
+
static VALUE method_crs_to_crs_identity(VALUE self, VALUE from, VALUE to)
|
579
|
+
{
|
580
|
+
VALUE result;
|
581
|
+
RGeo_Proj4Data *from_data;
|
582
|
+
RGeo_Proj4Data *to_data;
|
583
|
+
result = Qnil;
|
584
|
+
PJ *from_pj;
|
585
|
+
PJ *to_pj;
|
586
|
+
|
587
|
+
result = Qfalse;
|
588
|
+
|
589
|
+
TypedData_Get_Struct(from, RGeo_Proj4Data, &rgeo_proj4_data_type, from_data);
|
590
|
+
TypedData_Get_Struct(to, RGeo_Proj4Data, &rgeo_proj4_data_type, to_data);
|
591
|
+
from_pj = from_data->pj;
|
592
|
+
to_pj = to_data->pj;
|
593
|
+
|
594
|
+
if (from_pj && to_pj){
|
595
|
+
if (proj_is_equivalent_to(from_pj, to_pj, PJ_COMP_EQUIVALENT)){
|
596
|
+
result = Qtrue;
|
597
|
+
}
|
598
|
+
}
|
599
|
+
|
600
|
+
return result;
|
601
|
+
}
|
602
|
+
|
453
603
|
static void rgeo_init_proj4()
|
454
604
|
{
|
455
605
|
VALUE rgeo_module;
|
456
606
|
VALUE coordsys_module;
|
607
|
+
VALUE cs_module;
|
457
608
|
VALUE proj4_class;
|
458
609
|
VALUE crs_to_crs_class;
|
610
|
+
VALUE cs_base_class;
|
611
|
+
VALUE cs_info_class;
|
612
|
+
VALUE coordinate_system_class;
|
613
|
+
VALUE coordinate_transform_class;
|
459
614
|
|
460
615
|
rgeo_module = rb_define_module("RGeo");
|
461
616
|
coordsys_module = rb_define_module_under(rgeo_module, "CoordSys");
|
617
|
+
cs_module = rb_define_module_under(coordsys_module, "CS");
|
618
|
+
cs_base_class = rb_define_class_under(cs_module, "Base", rb_cObject);
|
619
|
+
cs_info_class = rb_define_class_under(cs_module, "Info", cs_base_class);
|
462
620
|
|
463
|
-
|
621
|
+
coordinate_system_class = rb_define_class_under(cs_module, "CoordinateSystem", cs_info_class);
|
622
|
+
proj4_class = rb_define_class_under(coordsys_module, "Proj4", coordinate_system_class);
|
464
623
|
rb_define_alloc_func(proj4_class, rgeo_proj4_data_alloc);
|
465
624
|
rb_define_module_function(proj4_class, "_create", cmethod_proj4_create, 2);
|
466
625
|
rb_define_method(proj4_class, "initialize_copy", method_proj4_initialize_copy, 1);
|
@@ -472,15 +631,24 @@ static void rgeo_init_proj4()
|
|
472
631
|
rb_define_method(proj4_class, "_valid?", method_proj4_is_valid, 0);
|
473
632
|
rb_define_method(proj4_class, "_geographic?", method_proj4_is_geographic, 0);
|
474
633
|
rb_define_method(proj4_class, "_geocentric?", method_proj4_is_geocentric, 0);
|
634
|
+
rb_define_method(proj4_class, "_projected?", method_proj4_is_projected, 0);
|
475
635
|
rb_define_method(proj4_class, "_radians?", method_proj4_uses_radians, 0);
|
476
636
|
rb_define_method(proj4_class, "_get_geographic", method_proj4_get_geographic, 0);
|
637
|
+
rb_define_method(proj4_class, "_crs?", method_proj4_is_crs, 0);
|
638
|
+
rb_define_method(proj4_class, "_axis_and_unit_info", method_proj4_axis_and_unit_info_str, 1);
|
639
|
+
rb_define_method(proj4_class, "_axis_count", method_proj4_axis_count, 0);
|
477
640
|
rb_define_module_function(proj4_class, "_proj_version", cmethod_proj4_version, 0);
|
478
641
|
|
642
|
+
coordinate_transform_class = rb_define_class_under(cs_module, "CoordinateTransform", cs_info_class);
|
479
643
|
|
480
|
-
crs_to_crs_class = rb_define_class_under(coordsys_module, "CRSToCRS",
|
644
|
+
crs_to_crs_class = rb_define_class_under(coordsys_module, "CRSToCRS", coordinate_transform_class);
|
481
645
|
rb_define_alloc_func(crs_to_crs_class, rgeo_crs_to_crs_data_alloc);
|
482
646
|
rb_define_module_function(crs_to_crs_class, "_create", cmethod_crs_to_crs_create, 2);
|
483
647
|
rb_define_method(crs_to_crs_class, "_transform_coords", method_crs_to_crs_transform, 3);
|
648
|
+
rb_define_method(crs_to_crs_class, "_as_text", method_crs_to_crs_wkt_str, 0);
|
649
|
+
rb_define_method(crs_to_crs_class, "_proj_type", method_crs_to_crs_proj_type, 0);
|
650
|
+
rb_define_method(crs_to_crs_class, "_area_of_use", method_crs_to_crs_area_of_use_str, 0);
|
651
|
+
rb_define_method(crs_to_crs_class, "_identity?", method_crs_to_crs_identity, 2);
|
484
652
|
}
|
485
653
|
|
486
654
|
|
@@ -491,6 +659,7 @@ void Init_proj4_c_impl()
|
|
491
659
|
{
|
492
660
|
#ifdef RGEO_PROJ4_SUPPORTED
|
493
661
|
rgeo_init_proj4();
|
662
|
+
rgeo_init_proj_errors();
|
494
663
|
#endif
|
495
664
|
}
|
496
665
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#ifdef HAVE_PROJ_H
|
2
|
+
#ifdef HAVE_PROJ_CREATE
|
3
|
+
#ifdef HAVE_PROJ_CREATE_CRS_TO_CRS_FROM_PJ
|
4
|
+
#ifdef HAVE_PROJ_NORMALIZE_FOR_VISUALIZATION
|
5
|
+
#define RGEO_PROJ4_SUPPORTED
|
6
|
+
#endif
|
7
|
+
#endif
|
8
|
+
#endif
|
9
|
+
#endif
|
10
|
+
|
11
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
12
|
+
#define mark rb_gc_mark_movable
|
13
|
+
#else
|
14
|
+
#define mark rb_gc_mark
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#ifdef __cplusplus
|
18
|
+
#define RGEO_BEGIN_C extern "C" {
|
19
|
+
#define RGEO_END_C }
|
20
|
+
#else
|
21
|
+
#define RGEO_BEGIN_C
|
22
|
+
#define RGEO_END_C
|
23
|
+
#endif
|
@@ -6,25 +6,49 @@ module RGeo
|
|
6
6
|
# This is a Ruby wrapper around a proj crs_to_crs
|
7
7
|
# A crs_to_crs transformation object is a pipeline between two known coordinate reference systems.
|
8
8
|
# https://proj.org/development/reference/functions.html#c.proj_create_crs_to_crs
|
9
|
-
|
10
|
-
|
9
|
+
#
|
10
|
+
# It also inherits from the RGeo::CoordSys::CoordinateTransform abstract class.
|
11
|
+
class CRSToCRS < CS::CoordinateTransform
|
12
|
+
attr_accessor :source_cs, :target_cs
|
11
13
|
|
12
14
|
class << self
|
13
15
|
def create(from, to)
|
14
16
|
crs_to_crs = _create(from, to)
|
15
|
-
crs_to_crs.
|
16
|
-
crs_to_crs.
|
17
|
+
crs_to_crs.source_cs = from
|
18
|
+
crs_to_crs.target_cs = to
|
17
19
|
crs_to_crs
|
18
20
|
end
|
19
21
|
end
|
22
|
+
|
23
|
+
alias from source_cs
|
24
|
+
alias to target_cs
|
25
|
+
alias to_wkt _as_text
|
26
|
+
|
27
|
+
def wkt_typename
|
28
|
+
wkt_str = to_wkt
|
29
|
+
wkt_str[0, wkt_str.index("[")]
|
30
|
+
end
|
31
|
+
|
32
|
+
def transform_type
|
33
|
+
PROJ_TYPES[_proj_type]
|
34
|
+
end
|
35
|
+
|
36
|
+
def area_of_use
|
37
|
+
_area_of_use
|
38
|
+
end
|
39
|
+
|
40
|
+
def identity?
|
41
|
+
_identity?(source_cs, target_cs)
|
42
|
+
end
|
43
|
+
|
20
44
|
# transform the coordinates from the initial CRS to the destination CRS
|
21
45
|
def transform_coords(x, y, z)
|
22
|
-
if
|
46
|
+
if from._radians? && from._geographic?
|
23
47
|
x *= ImplHelper::Math::DEGREES_PER_RADIAN
|
24
48
|
y *= ImplHelper::Math::DEGREES_PER_RADIAN
|
25
49
|
end
|
26
50
|
result = _transform_coords(x, y, z)
|
27
|
-
if result &&
|
51
|
+
if result && to._radians? && to._geographic?
|
28
52
|
result[0] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
29
53
|
result[1] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
30
54
|
end
|
@@ -79,6 +103,10 @@ module RGeo
|
|
79
103
|
int_ = from_polygon_.interior_rings.map { |r_| transform_linear_ring(r_, to_factory_) }
|
80
104
|
to_factory_.polygon(ext_, int_)
|
81
105
|
end
|
106
|
+
|
107
|
+
def inspect
|
108
|
+
"#<#{self.class}:0x#{object_id.to_s(16)} @source_cs=#{source_cs.original_str} @target_cs=#{target_cs.original_str}>"
|
109
|
+
end
|
82
110
|
end
|
83
111
|
|
84
112
|
# Store of all the created CRSToCRS
|
data/lib/rgeo/coord_sys/proj4.rb
CHANGED
@@ -19,7 +19,9 @@ module RGeo
|
|
19
19
|
# option. You may also use this object directly to perform low-level
|
20
20
|
# coordinate transformations.
|
21
21
|
|
22
|
-
class Proj4
|
22
|
+
class Proj4 < CS::CoordinateSystem
|
23
|
+
attr_accessor :dimension
|
24
|
+
|
23
25
|
def inspect # :nodoc:
|
24
26
|
"#<#{self.class}:0x#{object_id.to_s(16)} #{canonical_str.inspect}>"
|
25
27
|
end
|
@@ -110,6 +112,7 @@ module RGeo
|
|
110
112
|
def as_text
|
111
113
|
_as_text
|
112
114
|
end
|
115
|
+
alias to_wkt as_text
|
113
116
|
|
114
117
|
# Returns the string representing the authority and code of the
|
115
118
|
# CRS if it exists, nil otherwise.
|
@@ -120,6 +123,18 @@ module RGeo
|
|
120
123
|
_auth_name
|
121
124
|
end
|
122
125
|
|
126
|
+
# Gets axis details for dimension within coordinate system. Each
|
127
|
+
# dimension in the coordinate system has a corresponding axis.
|
128
|
+
def get_axis(dimension)
|
129
|
+
_axis_and_unit_info(dimension).split(":")[0]
|
130
|
+
end
|
131
|
+
|
132
|
+
# Gets units for dimension within coordinate system. Each
|
133
|
+
# dimension in the coordinate system has corresponding units.
|
134
|
+
def get_units(dimension)
|
135
|
+
_axis_and_unit_info(dimension).split(":")[1]
|
136
|
+
end
|
137
|
+
|
123
138
|
# Returns true if this Proj4 object is a geographic (lat-long)
|
124
139
|
# coordinate system.
|
125
140
|
|
@@ -134,6 +149,13 @@ module RGeo
|
|
134
149
|
_geocentric?
|
135
150
|
end
|
136
151
|
|
152
|
+
# Returns true if this Proj4 object is a projected
|
153
|
+
# coordinate system
|
154
|
+
|
155
|
+
def projected?
|
156
|
+
_projected?
|
157
|
+
end
|
158
|
+
|
137
159
|
# Returns true if this Proj4 object uses radians rather than degrees
|
138
160
|
# if it is a geographic coordinate system.
|
139
161
|
|
@@ -148,6 +170,39 @@ module RGeo
|
|
148
170
|
def get_geographic
|
149
171
|
_get_geographic
|
150
172
|
end
|
173
|
+
alias geographic_coordinate_system get_geographic
|
174
|
+
|
175
|
+
# Returns true if this Proj4 object represents a CRS.
|
176
|
+
|
177
|
+
def crs?
|
178
|
+
_crs?
|
179
|
+
end
|
180
|
+
|
181
|
+
# Sometimes used to assign SRIDs in factory creation
|
182
|
+
# Also in the base CS::Info class that CS::CoordinateSystem
|
183
|
+
# inherits from
|
184
|
+
#
|
185
|
+
# @return [Integer|NilClass] authority code if available
|
186
|
+
def authority_code
|
187
|
+
auth_name.split(":")[1].to_i if auth_name
|
188
|
+
end
|
189
|
+
|
190
|
+
# Low-level coordinate transform method.
|
191
|
+
# Transforms the given coordinate (x, y, [z]) from one proj4
|
192
|
+
# coordinate system to another. Returns an array with either two
|
193
|
+
# or three elements.
|
194
|
+
def transform_coords(to_proj, x, y, z = nil)
|
195
|
+
self.class.transform_coords(self, to_proj, x, y, z)
|
196
|
+
end
|
197
|
+
|
198
|
+
# Low-level geometry transform method.
|
199
|
+
# Transforms the given geometry between the given two projections.
|
200
|
+
# The resulting geometry is constructed using the to_factory.
|
201
|
+
# Any projections associated with the factories themselves are
|
202
|
+
# ignored.
|
203
|
+
def transform(from_geometry, to_proj, to_factory)
|
204
|
+
self.class.transform(self, from_geometry, to_proj, to_factory)
|
205
|
+
end
|
151
206
|
|
152
207
|
class << self
|
153
208
|
# Returns true if Proj4 is supported in this installation.
|
@@ -165,8 +220,9 @@ module RGeo
|
|
165
220
|
end
|
166
221
|
|
167
222
|
# Create a new Proj4 object, given a definition, which may be
|
168
|
-
# either a string or
|
169
|
-
#
|
223
|
+
# either a string, hash, or integer. If an integer is given, it
|
224
|
+
# assumes that you are using the EPSG SRID that matches that code.
|
225
|
+
# Returns nil if the given definition is invalid or Proj4 is not supported.
|
170
226
|
#
|
171
227
|
# Recognized options include:
|
172
228
|
#
|
@@ -188,11 +244,16 @@ module RGeo
|
|
188
244
|
defn_ = defn_.map { |k_, v_| v_ ? "+#{k_}=#{v_}" : "+#{k_}" }.join(" ")
|
189
245
|
end
|
190
246
|
|
247
|
+
defn_ = "EPSG:#{defn_}" if defn_.is_a?(Integer)
|
248
|
+
|
191
249
|
result_ = _create(defn_, opts_[:radians])
|
192
|
-
|
250
|
+
raise RGeo::Error::InvalidProjection unless result_._valid?
|
251
|
+
|
252
|
+
result_.dimension = result_._axis_count
|
193
253
|
end
|
194
254
|
result_
|
195
255
|
end
|
256
|
+
alias create_from_wkt create
|
196
257
|
|
197
258
|
# Create a new Proj4 object, given a definition, which may be
|
198
259
|
# either a string or a hash. Raises Error::UnsupportedOperation
|
@@ -221,9 +282,9 @@ module RGeo
|
|
221
282
|
# Transforms the given coordinate (x, y, [z]) from one proj4
|
222
283
|
# coordinate system to another. Returns an array with either two
|
223
284
|
# or three elements.
|
224
|
-
def transform_coords(
|
225
|
-
crs_to_crs = CRSStore.get(
|
226
|
-
crs_to_crs.transform_coords(
|
285
|
+
def transform_coords(from_proj, to_proj, x, y, z = nil)
|
286
|
+
crs_to_crs = CRSStore.get(from_proj, to_proj)
|
287
|
+
crs_to_crs.transform_coords(x, y, z)
|
227
288
|
end
|
228
289
|
|
229
290
|
# Low-level geometry transform method.
|
@@ -231,9 +292,9 @@ module RGeo
|
|
231
292
|
# The resulting geometry is constructed using the to_factory.
|
232
293
|
# Any projections associated with the factories themselves are
|
233
294
|
# ignored.
|
234
|
-
def transform(
|
235
|
-
crs_to_crs = CRSStore.get(
|
236
|
-
crs_to_crs.transform(
|
295
|
+
def transform(from_proj, from_geometry, to_proj, to_factory)
|
296
|
+
crs_to_crs = CRSStore.get(from_proj, to_proj)
|
297
|
+
crs_to_crs.transform(from_geometry, to_factory)
|
237
298
|
end
|
238
299
|
end
|
239
300
|
end
|
data/lib/rgeo/errors.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RGeo
|
4
|
+
# All RGeo errors are members of this namespace.
|
5
|
+
|
6
|
+
module Error
|
7
|
+
# Base class for all RGeo-related exceptions
|
8
|
+
class RGeoError < RuntimeError
|
9
|
+
end
|
10
|
+
|
11
|
+
# RGeo error specific to the PROJ library
|
12
|
+
class InvalidProjection < RGeoError
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rgeo/proj4/version.rb
CHANGED
data/lib/rgeo/proj4.rb
CHANGED
@@ -2,7 +2,46 @@
|
|
2
2
|
|
3
3
|
require "rgeo"
|
4
4
|
require "rgeo/proj4/version"
|
5
|
+
require "rgeo/coord_sys/proj4_c_impl"
|
5
6
|
require "rgeo/coord_sys/crs_to_crs"
|
6
7
|
require "rgeo/coord_sys/proj4"
|
7
|
-
|
8
|
-
|
8
|
+
require_relative "./errors"
|
9
|
+
|
10
|
+
module RGeo
|
11
|
+
module CoordSys
|
12
|
+
# PROJ uses enums for types, some methods require us to return
|
13
|
+
# the name of the type. We will use this as a lookup.
|
14
|
+
PROJ_TYPES = %w[
|
15
|
+
PJ_TYPE_UNKNOWN
|
16
|
+
PJ_TYPE_ELLIPSOID
|
17
|
+
PJ_TYPE_PRIME_MERIDIAN
|
18
|
+
PJ_TYPE_GEODETIC_REFERENCE_FRAME
|
19
|
+
PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME
|
20
|
+
PJ_TYPE_VERTICAL_REFERENCE_FRAME
|
21
|
+
PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME
|
22
|
+
PJ_TYPE_DATUM_ENSEMBLE
|
23
|
+
PJ_TYPE_CRS
|
24
|
+
PJ_TYPE_GEODETIC_CRS
|
25
|
+
PJ_TYPE_GEOCENTRIC_CRS
|
26
|
+
PJ_TYPE_GEOGRAPHIC_CRS
|
27
|
+
PJ_TYPE_GEOGRAPHIC_2D_CRS
|
28
|
+
PJ_TYPE_GEOGRAPHIC_3D_CRS
|
29
|
+
PJ_TYPE_VERTICAL_CRS
|
30
|
+
PJ_TYPE_PROJECTED_CRS
|
31
|
+
PJ_TYPE_COMPOUND_CRS
|
32
|
+
PJ_TYPE_TEMPORAL_CRS
|
33
|
+
PJ_TYPE_ENGINEERING_CRS
|
34
|
+
PJ_TYPE_BOUND_CRS
|
35
|
+
PJ_TYPE_OTHER_CRS
|
36
|
+
PJ_TYPE_CONVERSION
|
37
|
+
PJ_TYPE_TRANSFORMATION
|
38
|
+
PJ_TYPE_CONCATENATED_OPERATION
|
39
|
+
PJ_TYPE_OTHER_COORDINATE_OPERATION
|
40
|
+
PJ_TYPE_TEMPORAL_DATUM
|
41
|
+
PJ_TYPE_ENGINEERING_DATUM
|
42
|
+
PJ_TYPE_PARAMETRIC_DATUM
|
43
|
+
].freeze
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
RGeo::CoordSys::CONFIG.default_coord_sys_class = RGeo::CoordSys::Proj4 if RGeo::CoordSys::Proj4.supported?
|
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: 4.0.0.pre.rc.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: 2022-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rgeo
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 3.0.0.pre.rc.3
|
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: 3.0.0.pre.rc.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: ffi-geos
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '2.2'
|
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: '2.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '5.14'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '5.14'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,11 +103,14 @@ extensions:
|
|
103
103
|
extra_rdoc_files: []
|
104
104
|
files:
|
105
105
|
- LICENSE.txt
|
106
|
+
- ext/proj4_c_impl/errors.c
|
107
|
+
- ext/proj4_c_impl/errors.h
|
106
108
|
- ext/proj4_c_impl/extconf.rb
|
107
109
|
- ext/proj4_c_impl/main.c
|
110
|
+
- ext/proj4_c_impl/preface.h
|
108
111
|
- lib/rgeo/coord_sys/crs_to_crs.rb
|
109
112
|
- lib/rgeo/coord_sys/proj4.rb
|
110
|
-
- lib/rgeo/
|
113
|
+
- lib/rgeo/errors.rb
|
111
114
|
- lib/rgeo/proj4.rb
|
112
115
|
- lib/rgeo/proj4/version.rb
|
113
116
|
homepage: https://github.com/rgeo/rgeo-proj4
|
@@ -125,9 +128,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
128
|
version: 2.5.0
|
126
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
130
|
requirements:
|
128
|
-
- - "
|
131
|
+
- - ">"
|
129
132
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
133
|
+
version: 1.3.1
|
131
134
|
requirements: []
|
132
135
|
rubygems_version: 3.1.4
|
133
136
|
signing_key:
|
@@ -1,143 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# -----------------------------------------------------------------------------
|
4
|
-
#
|
5
|
-
# SRS database interface
|
6
|
-
#
|
7
|
-
# -----------------------------------------------------------------------------
|
8
|
-
|
9
|
-
module RGeo
|
10
|
-
module CoordSys
|
11
|
-
module SRSDatabase
|
12
|
-
# A spatial reference database implementation backed by coordinate
|
13
|
-
# system files installed as part of the proj4 library. For a given
|
14
|
-
# Proj4Data object, you specify a single file (e.g. the epsg data
|
15
|
-
# file), and you can retrieve records by ID number.
|
16
|
-
|
17
|
-
class Proj4Data
|
18
|
-
# Connect to one of the proj4 data files. You should provide the
|
19
|
-
# file name, optionally the installation directory if it is not
|
20
|
-
# in a typical location, and several additional options.
|
21
|
-
#
|
22
|
-
# These options are recognized:
|
23
|
-
#
|
24
|
-
# [<tt>:dir</tt>]
|
25
|
-
# The path for the share/proj directory that contains the
|
26
|
-
# requested data file. By default, the Proj4Data class will
|
27
|
-
# try a number of directories for you, including
|
28
|
-
# /usr/local/share/proj, /opt/local/share/proj, /usr/share/proj,
|
29
|
-
# and a few other variants. However, if you have proj4 installed
|
30
|
-
# elsewhere, you can provide an explicit directory using this
|
31
|
-
# option. You may also pass nil as the value, in which case all
|
32
|
-
# the normal lookup paths will be disabled, and you will have to
|
33
|
-
# provide the full path as the file name.
|
34
|
-
# [<tt>:cache</tt>]
|
35
|
-
# If set to true, this class caches previously looked up entries
|
36
|
-
# so subsequent lookups do not have to reread the file. If set
|
37
|
-
# to <tt>:read_all</tt>, then ALL values in the file are read in
|
38
|
-
# and cached the first time a lookup is done. If set to
|
39
|
-
# <tt>:preload</tt>, then ALL values in the file are read in
|
40
|
-
# immediately when the database is created. Default is false,
|
41
|
-
# indicating that the file will be reread on every lookup.
|
42
|
-
# [<tt>:authority</tt>]
|
43
|
-
# If set, its value is taken as the authority name for all
|
44
|
-
# entries. The authority code will be set to the identifier. If
|
45
|
-
# not set, then the authority fields of entries will be blank.
|
46
|
-
|
47
|
-
def initialize(filename_, opts_ = {})
|
48
|
-
dir_ = nil
|
49
|
-
if opts_.include?(:dir)
|
50
|
-
dir_ = opts_[:dir]
|
51
|
-
else
|
52
|
-
["/usr/local/share/proj", "/usr/local/proj/share/proj", "/usr/local/proj4/share/proj", "/opt/local/share/proj", "/opt/proj/share/proj", "/opt/proj4/share/proj", "/opt/share/proj", "/usr/share/proj"].each do |d_|
|
53
|
-
if ::File.directory?(d_) && ::File.readable?(d_)
|
54
|
-
dir_ = d_
|
55
|
-
break
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
@path = dir_ ? "#{dir_}/#{filename_}" : filename_
|
60
|
-
@authority = opts_[:authority]
|
61
|
-
if opts_[:cache]
|
62
|
-
@cache = {}
|
63
|
-
case opts_[:cache]
|
64
|
-
when :read_all
|
65
|
-
@populate_state = 1
|
66
|
-
when :preload
|
67
|
-
search_file(nil)
|
68
|
-
@populate_state = 2
|
69
|
-
else
|
70
|
-
@populate_state = 0
|
71
|
-
end
|
72
|
-
else
|
73
|
-
@cache = nil
|
74
|
-
@populate_state = 0
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Retrieve the Entry for the given ID number.
|
79
|
-
|
80
|
-
def get(ident_)
|
81
|
-
ident_ = ident_.to_s
|
82
|
-
return @cache[ident_] if @cache&.include?(ident_)
|
83
|
-
result_ = nil
|
84
|
-
case @populate_state
|
85
|
-
when 0
|
86
|
-
data_ = search_file(ident_)
|
87
|
-
result_ = Entry.new(ident_, authority: @authority, authority_code: @authority ? ident_ : nil, name: data_[1], proj4: data_[2]) if data_
|
88
|
-
@cache[ident_] = result_ if @cache
|
89
|
-
when 1
|
90
|
-
search_file(nil)
|
91
|
-
result_ = @cache[ident_]
|
92
|
-
@populate_state = 2
|
93
|
-
end
|
94
|
-
result_
|
95
|
-
end
|
96
|
-
|
97
|
-
# Clear the cache if one exists.
|
98
|
-
|
99
|
-
def clear_cache
|
100
|
-
@cache&.clear
|
101
|
-
@populate_state = 1 if @populate_state == 2
|
102
|
-
end
|
103
|
-
|
104
|
-
private
|
105
|
-
|
106
|
-
def search_file(ident_)
|
107
|
-
::File.open(@path) do |file_|
|
108
|
-
cur_name_ = nil
|
109
|
-
cur_ident_ = nil
|
110
|
-
cur_text_ = nil
|
111
|
-
file_.each do |line_|
|
112
|
-
line_.strip!
|
113
|
-
if (comment_delim_ = line_.index("#"))
|
114
|
-
cur_name_ = line_[comment_delim_ + 1..-1].strip
|
115
|
-
line_ = line_[0..comment_delim_ - 1].strip
|
116
|
-
end
|
117
|
-
if !cur_ident_ && (line_ =~ /^<(\w+)>(.*)/)
|
118
|
-
cur_ident_ = Regexp.last_match(1)
|
119
|
-
cur_text_ = []
|
120
|
-
line_ = Regexp.last_match(2).strip
|
121
|
-
end
|
122
|
-
next unless cur_ident_
|
123
|
-
if line_[-2..-1] == "<>"
|
124
|
-
cur_text_ << line_[0..-3].strip
|
125
|
-
cur_text_ = cur_text_.join(" ")
|
126
|
-
if ident_.nil?
|
127
|
-
@cache[ident_] = Entry.new(ident_, authority: @authority, authority_code: @authority ? id_ : nil, name: cur_name_, proj4: cur_text_)
|
128
|
-
end
|
129
|
-
return [ident_, cur_name_, cur_text_] if cur_ident_ == ident_
|
130
|
-
cur_ident_ = nil
|
131
|
-
cur_name_ = nil
|
132
|
-
cur_text_ = nil
|
133
|
-
else
|
134
|
-
cur_text_ << line_
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
nil
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|