rgeo-proj4 3.1.1 → 4.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 +4 -4
- data/ext/proj4_c_impl/errors.c +33 -0
- data/ext/proj4_c_impl/errors.h +22 -0
- data/ext/proj4_c_impl/extconf.rb +64 -16
- data/ext/proj4_c_impl/main.c +284 -135
- data/ext/proj4_c_impl/preface.h +27 -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 +31 -14
- data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +0 -143
data/ext/proj4_c_impl/main.c
CHANGED
@@ -1,42 +1,19 @@
|
|
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
|
-
#include
|
9
|
+
#include "errors.h"
|
32
10
|
#include <proj.h>
|
11
|
+
#include <ruby.h>
|
33
12
|
|
34
13
|
#endif
|
35
14
|
|
36
|
-
|
37
15
|
RGEO_BEGIN_C
|
38
16
|
|
39
|
-
|
40
17
|
#ifdef RGEO_PROJ4_SUPPORTED
|
41
18
|
|
42
19
|
#if PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR < 3
|
@@ -55,72 +32,63 @@ typedef struct {
|
|
55
32
|
PJ *crs_to_crs;
|
56
33
|
} RGeo_CRSToCRSData;
|
57
34
|
|
58
|
-
|
59
35
|
// Destroy function for proj data.
|
60
|
-
static void rgeo_proj4_free(void *ptr)
|
61
|
-
{
|
36
|
+
static void rgeo_proj4_free(void *ptr) {
|
62
37
|
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
63
|
-
if(data->pj){
|
38
|
+
if (data->pj) {
|
64
39
|
proj_destroy(data->pj);
|
65
40
|
}
|
66
|
-
|
41
|
+
FREE(data);
|
67
42
|
}
|
68
43
|
|
69
44
|
// Destroy function for crs_to_crs data.
|
70
|
-
static void rgeo_crs_to_crs_free(void *ptr)
|
71
|
-
{
|
45
|
+
static void rgeo_crs_to_crs_free(void *ptr) {
|
72
46
|
RGeo_CRSToCRSData *data = (RGeo_CRSToCRSData *)ptr;
|
73
|
-
if(data->crs_to_crs){
|
47
|
+
if (data->crs_to_crs) {
|
74
48
|
proj_destroy(data->crs_to_crs);
|
75
49
|
}
|
76
|
-
|
50
|
+
FREE(data);
|
77
51
|
}
|
78
52
|
|
79
|
-
|
80
|
-
static size_t rgeo_proj4_memsize(const void *ptr)
|
81
|
-
{
|
53
|
+
static size_t rgeo_proj4_memsize(const void *ptr) {
|
82
54
|
size_t size = 0;
|
83
55
|
const RGeo_Proj4Data *data = (const RGeo_Proj4Data *)ptr;
|
84
56
|
|
85
57
|
size += sizeof(*data);
|
86
|
-
if(data->pj){
|
58
|
+
if (data->pj) {
|
87
59
|
size += sizeof(data->pj);
|
88
60
|
}
|
89
61
|
return size;
|
90
62
|
}
|
91
63
|
|
92
|
-
static size_t rgeo_crs_to_crs_memsize(const void *ptr)
|
93
|
-
{
|
64
|
+
static size_t rgeo_crs_to_crs_memsize(const void *ptr) {
|
94
65
|
size_t size = 0;
|
95
66
|
const RGeo_CRSToCRSData *data = (const RGeo_CRSToCRSData *)ptr;
|
96
67
|
size += sizeof(*data);
|
97
|
-
if(data->crs_to_crs){
|
68
|
+
if (data->crs_to_crs) {
|
98
69
|
size += sizeof(data->crs_to_crs);
|
99
70
|
}
|
100
71
|
return size;
|
101
72
|
}
|
102
73
|
|
103
|
-
static void rgeo_proj4_mark(void *ptr)
|
104
|
-
{
|
74
|
+
static void rgeo_proj4_mark(void *ptr) {
|
105
75
|
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
106
|
-
if(!NIL_P(data->original_str)){
|
76
|
+
if (!NIL_P(data->original_str)) {
|
107
77
|
mark(data->original_str);
|
108
78
|
}
|
109
79
|
}
|
110
80
|
|
111
81
|
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
112
|
-
static void rgeo_proj4_compact(void *ptr)
|
113
|
-
{
|
82
|
+
static void rgeo_proj4_compact(void *ptr) {
|
114
83
|
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
115
|
-
if(data && !NIL_P(data->original_str)){
|
84
|
+
if (data && !NIL_P(data->original_str)) {
|
116
85
|
data->original_str = rb_gc_location(data->original_str);
|
117
86
|
}
|
118
87
|
}
|
119
88
|
#endif
|
120
89
|
|
121
|
-
static void rgeo_proj4_clear_struct(RGeo_Proj4Data *data)
|
122
|
-
{
|
123
|
-
if(data->pj){
|
90
|
+
static void rgeo_proj4_clear_struct(RGeo_Proj4Data *data) {
|
91
|
+
if (data->pj) {
|
124
92
|
proj_destroy(data->pj);
|
125
93
|
data->pj = NULL;
|
126
94
|
data->original_str = Qnil;
|
@@ -131,26 +99,27 @@ static const rb_data_type_t rgeo_proj4_data_type = {
|
|
131
99
|
"RGeo::CoordSys::Proj4",
|
132
100
|
{rgeo_proj4_mark, rgeo_proj4_free, rgeo_proj4_memsize,
|
133
101
|
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
134
|
-
|
102
|
+
rgeo_proj4_compact
|
135
103
|
#endif
|
136
104
|
},
|
137
|
-
0,
|
105
|
+
0,
|
106
|
+
0,
|
138
107
|
RUBY_TYPED_FREE_IMMEDIATELY};
|
139
108
|
|
140
109
|
static const rb_data_type_t rgeo_crs_to_crs_data_type = {
|
141
110
|
"RGeo::CoordSys::CRSToCRS",
|
142
111
|
{0, rgeo_crs_to_crs_free, rgeo_crs_to_crs_memsize},
|
143
|
-
0,
|
112
|
+
0,
|
113
|
+
0,
|
144
114
|
RUBY_TYPED_FREE_IMMEDIATELY};
|
145
115
|
|
146
|
-
static VALUE rgeo_proj4_data_alloc(VALUE self)
|
147
|
-
{
|
116
|
+
static VALUE rgeo_proj4_data_alloc(VALUE self) {
|
148
117
|
VALUE result;
|
149
118
|
RGeo_Proj4Data *data = ALLOC(RGeo_Proj4Data);
|
150
119
|
|
151
120
|
result = Qnil;
|
152
121
|
|
153
|
-
if(data){
|
122
|
+
if (data) {
|
154
123
|
data->pj = NULL;
|
155
124
|
data->original_str = Qnil;
|
156
125
|
data->uses_radians = 0;
|
@@ -159,26 +128,23 @@ static VALUE rgeo_proj4_data_alloc(VALUE self)
|
|
159
128
|
return result;
|
160
129
|
}
|
161
130
|
|
162
|
-
|
163
|
-
static VALUE rgeo_crs_to_crs_data_alloc(VALUE self)
|
164
|
-
{
|
131
|
+
static VALUE rgeo_crs_to_crs_data_alloc(VALUE self) {
|
165
132
|
VALUE result;
|
166
133
|
RGeo_CRSToCRSData *data = ALLOC(RGeo_CRSToCRSData);
|
167
134
|
|
168
135
|
result = Qnil;
|
169
136
|
|
170
|
-
if(data){
|
137
|
+
if (data) {
|
171
138
|
data->crs_to_crs = NULL;
|
172
139
|
result = TypedData_Wrap_Struct(self, &rgeo_crs_to_crs_data_type, data);
|
173
140
|
}
|
174
141
|
return result;
|
175
142
|
}
|
176
143
|
|
177
|
-
static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig)
|
178
|
-
{
|
144
|
+
static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig) {
|
179
145
|
RGeo_Proj4Data *self_data;
|
180
146
|
RGeo_Proj4Data *orig_data;
|
181
|
-
const char*
|
147
|
+
const char *str;
|
182
148
|
|
183
149
|
// Clear out any existing value
|
184
150
|
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, self_data);
|
@@ -187,9 +153,9 @@ static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig)
|
|
187
153
|
// Copy value from orig
|
188
154
|
TypedData_Get_Struct(orig, RGeo_Proj4Data, &rgeo_proj4_data_type, orig_data);
|
189
155
|
if (!NIL_P(orig_data->original_str)) {
|
190
|
-
self_data->pj =
|
191
|
-
|
192
|
-
else {
|
156
|
+
self_data->pj =
|
157
|
+
proj_create(PJ_DEFAULT_CTX, StringValuePtr(orig_data->original_str));
|
158
|
+
} else {
|
193
159
|
str = proj_as_proj_string(PJ_DEFAULT_CTX, orig_data->pj, PJ_PROJ_4, NULL);
|
194
160
|
self_data->pj = proj_create(PJ_DEFAULT_CTX, str);
|
195
161
|
}
|
@@ -199,9 +165,7 @@ static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig)
|
|
199
165
|
return self;
|
200
166
|
}
|
201
167
|
|
202
|
-
|
203
|
-
static VALUE method_proj4_set_value(VALUE self, VALUE str, VALUE uses_radians)
|
204
|
-
{
|
168
|
+
static VALUE method_proj4_set_value(VALUE self, VALUE str, VALUE uses_radians) {
|
205
169
|
RGeo_Proj4Data *self_data;
|
206
170
|
|
207
171
|
Check_Type(str, T_STRING);
|
@@ -218,45 +182,48 @@ static VALUE method_proj4_set_value(VALUE self, VALUE str, VALUE uses_radians)
|
|
218
182
|
return self;
|
219
183
|
}
|
220
184
|
|
221
|
-
|
222
|
-
static VALUE method_proj4_get_geographic(VALUE self)
|
223
|
-
{
|
185
|
+
static VALUE method_proj4_get_geographic(VALUE self) {
|
224
186
|
VALUE result;
|
225
187
|
RGeo_Proj4Data *new_data;
|
226
188
|
RGeo_Proj4Data *self_data;
|
189
|
+
PJ *geographic_proj;
|
227
190
|
|
228
191
|
result = Qnil;
|
229
192
|
new_data = ALLOC(RGeo_Proj4Data);
|
230
193
|
if (new_data) {
|
231
|
-
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type,
|
194
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type,
|
195
|
+
self_data);
|
196
|
+
|
197
|
+
geographic_proj = proj_crs_get_geodetic_crs(PJ_DEFAULT_CTX, self_data->pj);
|
198
|
+
if (geographic_proj == 0) {
|
199
|
+
FREE(new_data);
|
200
|
+
rb_raise(rb_eRGeoInvalidProjectionError,
|
201
|
+
"Geographic CRS could not be created because the source "
|
202
|
+
"projection is not a CRS");
|
203
|
+
}
|
232
204
|
|
233
|
-
new_data->pj =
|
205
|
+
new_data->pj = geographic_proj;
|
234
206
|
new_data->original_str = Qnil;
|
235
207
|
new_data->uses_radians = self_data->uses_radians;
|
236
|
-
result =
|
208
|
+
result =
|
209
|
+
TypedData_Wrap_Struct(CLASS_OF(self), &rgeo_proj4_data_type, new_data);
|
237
210
|
}
|
238
211
|
return result;
|
239
212
|
}
|
240
213
|
|
241
|
-
|
242
|
-
static VALUE method_proj4_original_str(VALUE self)
|
243
|
-
{
|
214
|
+
static VALUE method_proj4_original_str(VALUE self) {
|
244
215
|
RGeo_Proj4Data *data;
|
245
216
|
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
246
217
|
return data->original_str;
|
247
218
|
}
|
248
219
|
|
249
|
-
|
250
|
-
static VALUE method_proj4_uses_radians(VALUE self)
|
251
|
-
{
|
220
|
+
static VALUE method_proj4_uses_radians(VALUE self) {
|
252
221
|
RGeo_Proj4Data *data;
|
253
222
|
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
254
223
|
return data->uses_radians ? Qtrue : Qfalse;
|
255
224
|
}
|
256
225
|
|
257
|
-
|
258
|
-
static VALUE method_proj4_canonical_str(VALUE self)
|
259
|
-
{
|
226
|
+
static VALUE method_proj4_canonical_str(VALUE self) {
|
260
227
|
VALUE result;
|
261
228
|
PJ *pj;
|
262
229
|
const char *str;
|
@@ -274,8 +241,7 @@ static VALUE method_proj4_canonical_str(VALUE self)
|
|
274
241
|
return result;
|
275
242
|
}
|
276
243
|
|
277
|
-
static VALUE method_proj4_wkt_str(VALUE self)
|
278
|
-
{
|
244
|
+
static VALUE method_proj4_wkt_str(VALUE self) {
|
279
245
|
VALUE result;
|
280
246
|
PJ *pj;
|
281
247
|
const char *str;
|
@@ -287,15 +253,14 @@ static VALUE method_proj4_wkt_str(VALUE self)
|
|
287
253
|
if (pj) {
|
288
254
|
const char *const options[] = {"MULTILINE=NO", NULL};
|
289
255
|
str = proj_as_wkt(PJ_DEFAULT_CTX, pj, WKT_TYPE, options);
|
290
|
-
if(str){
|
256
|
+
if (str) {
|
291
257
|
result = rb_str_new2(str);
|
292
258
|
}
|
293
259
|
}
|
294
260
|
return result;
|
295
261
|
}
|
296
262
|
|
297
|
-
static VALUE method_proj4_auth_name_str(VALUE self)
|
298
|
-
{
|
263
|
+
static VALUE method_proj4_auth_name_str(VALUE self) {
|
299
264
|
VALUE result;
|
300
265
|
PJ *pj;
|
301
266
|
const char *id;
|
@@ -308,15 +273,67 @@ static VALUE method_proj4_auth_name_str(VALUE self)
|
|
308
273
|
if (pj) {
|
309
274
|
auth = proj_get_id_auth_name(pj, 0);
|
310
275
|
id = proj_get_id_code(pj, 0);
|
311
|
-
if(id && auth){
|
276
|
+
if (id && auth) {
|
312
277
|
result = rb_sprintf("%s:%s", auth, id);
|
313
278
|
}
|
314
279
|
}
|
315
280
|
return result;
|
316
281
|
}
|
317
282
|
|
318
|
-
static VALUE
|
319
|
-
|
283
|
+
static VALUE method_proj4_axis_and_unit_info_str(VALUE self, VALUE dimension) {
|
284
|
+
VALUE result;
|
285
|
+
int dimension_index;
|
286
|
+
PJ *pj;
|
287
|
+
PJ *pj_cs;
|
288
|
+
const char *axis_info;
|
289
|
+
const char *unit_name;
|
290
|
+
RGeo_Proj4Data *data;
|
291
|
+
|
292
|
+
Check_Type(dimension, T_FIXNUM);
|
293
|
+
|
294
|
+
dimension_index = FIX2INT(dimension);
|
295
|
+
result = Qnil;
|
296
|
+
|
297
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
298
|
+
pj = data->pj;
|
299
|
+
if (pj) {
|
300
|
+
pj_cs = proj_crs_get_coordinate_system(PJ_DEFAULT_CTX, pj);
|
301
|
+
if (pj_cs) {
|
302
|
+
if (proj_cs_get_axis_info(PJ_DEFAULT_CTX, pj_cs, dimension_index,
|
303
|
+
&axis_info, NULL, NULL, NULL, &unit_name, NULL,
|
304
|
+
NULL)) {
|
305
|
+
result = rb_sprintf("%s:%s", axis_info, unit_name);
|
306
|
+
}
|
307
|
+
|
308
|
+
proj_destroy(pj_cs);
|
309
|
+
}
|
310
|
+
}
|
311
|
+
return result;
|
312
|
+
}
|
313
|
+
|
314
|
+
static VALUE method_proj4_axis_count(VALUE self) {
|
315
|
+
VALUE result;
|
316
|
+
PJ *pj;
|
317
|
+
PJ *pj_cs;
|
318
|
+
int count;
|
319
|
+
RGeo_Proj4Data *data;
|
320
|
+
|
321
|
+
result = Qnil;
|
322
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
323
|
+
pj = data->pj;
|
324
|
+
if (pj) {
|
325
|
+
pj_cs = proj_crs_get_coordinate_system(PJ_DEFAULT_CTX, pj);
|
326
|
+
if (pj_cs) {
|
327
|
+
count = proj_cs_get_axis_count(PJ_DEFAULT_CTX, pj_cs);
|
328
|
+
result = INT2FIX(count);
|
329
|
+
|
330
|
+
proj_destroy(pj_cs);
|
331
|
+
}
|
332
|
+
}
|
333
|
+
return result;
|
334
|
+
}
|
335
|
+
|
336
|
+
static VALUE method_proj4_is_geographic(VALUE self) {
|
320
337
|
VALUE result;
|
321
338
|
PJ *pj;
|
322
339
|
PJ_TYPE proj_type;
|
@@ -327,7 +344,8 @@ static VALUE method_proj4_is_geographic(VALUE self)
|
|
327
344
|
pj = data->pj;
|
328
345
|
if (pj) {
|
329
346
|
proj_type = proj_get_type(pj);
|
330
|
-
if(proj_type == PJ_TYPE_GEOGRAPHIC_2D_CRS ||
|
347
|
+
if (proj_type == PJ_TYPE_GEOGRAPHIC_2D_CRS ||
|
348
|
+
proj_type == PJ_TYPE_GEOGRAPHIC_3D_CRS) {
|
331
349
|
result = Qtrue;
|
332
350
|
} else {
|
333
351
|
result = Qfalse;
|
@@ -336,9 +354,7 @@ static VALUE method_proj4_is_geographic(VALUE self)
|
|
336
354
|
return result;
|
337
355
|
}
|
338
356
|
|
339
|
-
|
340
|
-
static VALUE method_proj4_is_geocentric(VALUE self)
|
341
|
-
{
|
357
|
+
static VALUE method_proj4_is_geocentric(VALUE self) {
|
342
358
|
VALUE result;
|
343
359
|
PJ *pj;
|
344
360
|
PJ_TYPE proj_type;
|
@@ -354,24 +370,43 @@ static VALUE method_proj4_is_geocentric(VALUE self)
|
|
354
370
|
return result;
|
355
371
|
}
|
356
372
|
|
373
|
+
static VALUE method_proj4_is_projected(VALUE self) {
|
374
|
+
VALUE result;
|
375
|
+
PJ *pj;
|
376
|
+
PJ_TYPE proj_type;
|
377
|
+
RGeo_Proj4Data *data;
|
378
|
+
|
379
|
+
result = Qnil;
|
380
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
381
|
+
pj = data->pj;
|
382
|
+
if (pj) {
|
383
|
+
proj_type = proj_get_type(pj);
|
384
|
+
result = proj_type == PJ_TYPE_PROJECTED_CRS ? Qtrue : Qfalse;
|
385
|
+
}
|
386
|
+
return result;
|
387
|
+
}
|
357
388
|
|
358
|
-
static VALUE method_proj4_is_valid(VALUE self)
|
359
|
-
{
|
389
|
+
static VALUE method_proj4_is_valid(VALUE self) {
|
360
390
|
RGeo_Proj4Data *data;
|
361
391
|
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, data);
|
362
392
|
return data->pj ? Qtrue : Qfalse;
|
363
393
|
}
|
364
394
|
|
395
|
+
static VALUE method_proj4_is_crs(VALUE self) {
|
396
|
+
RGeo_Proj4Data *self_data;
|
365
397
|
|
366
|
-
|
367
|
-
|
368
|
-
|
398
|
+
TypedData_Get_Struct(self, RGeo_Proj4Data, &rgeo_proj4_data_type, self_data);
|
399
|
+
return proj_is_crs(self_data->pj) ? Qtrue : Qfalse;
|
400
|
+
}
|
401
|
+
|
402
|
+
static VALUE cmethod_proj4_version(VALUE module) {
|
403
|
+
return rb_sprintf("%d.%d.%d", PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR,
|
404
|
+
PROJ_VERSION_PATCH);
|
369
405
|
}
|
370
406
|
|
371
|
-
static VALUE cmethod_proj4_create(VALUE klass, VALUE str, VALUE uses_radians)
|
372
|
-
{
|
407
|
+
static VALUE cmethod_proj4_create(VALUE klass, VALUE str, VALUE uses_radians) {
|
373
408
|
VALUE result;
|
374
|
-
RGeo_Proj4Data*
|
409
|
+
RGeo_Proj4Data *data;
|
375
410
|
|
376
411
|
result = Qnil;
|
377
412
|
Check_Type(str, T_STRING);
|
@@ -385,8 +420,7 @@ static VALUE cmethod_proj4_create(VALUE klass, VALUE str, VALUE uses_radians)
|
|
385
420
|
return result;
|
386
421
|
}
|
387
422
|
|
388
|
-
static VALUE cmethod_crs_to_crs_create(VALUE klass, VALUE from, VALUE to)
|
389
|
-
{
|
423
|
+
static VALUE cmethod_crs_to_crs_create(VALUE klass, VALUE from, VALUE to) {
|
390
424
|
VALUE result;
|
391
425
|
RGeo_Proj4Data *from_data;
|
392
426
|
RGeo_Proj4Data *to_data;
|
@@ -395,33 +429,39 @@ static VALUE cmethod_crs_to_crs_create(VALUE klass, VALUE from, VALUE to)
|
|
395
429
|
PJ *to_pj;
|
396
430
|
PJ *gis_pj;
|
397
431
|
PJ *crs_to_crs;
|
398
|
-
RGeo_CRSToCRSData*
|
432
|
+
RGeo_CRSToCRSData *data;
|
399
433
|
|
400
434
|
TypedData_Get_Struct(from, RGeo_Proj4Data, &rgeo_proj4_data_type, from_data);
|
401
435
|
TypedData_Get_Struct(to, RGeo_Proj4Data, &rgeo_proj4_data_type, to_data);
|
402
436
|
from_pj = from_data->pj;
|
403
437
|
to_pj = to_data->pj;
|
404
|
-
crs_to_crs =
|
438
|
+
crs_to_crs =
|
439
|
+
proj_create_crs_to_crs_from_pj(PJ_DEFAULT_CTX, from_pj, to_pj, 0, NULL);
|
440
|
+
|
441
|
+
// check for invalid transformation
|
442
|
+
if (crs_to_crs == 0) {
|
443
|
+
rb_raise(rb_eRGeoInvalidProjectionError,
|
444
|
+
"CRSToCRS could not be created from input projections");
|
445
|
+
}
|
405
446
|
|
406
447
|
// necessary to use proj_normalize_for_visualization so that we
|
407
448
|
// do not have to worry about the order of coordinates in every
|
408
449
|
// coord system
|
409
450
|
gis_pj = proj_normalize_for_visualization(PJ_DEFAULT_CTX, crs_to_crs);
|
410
|
-
if(gis_pj){
|
451
|
+
if (gis_pj) {
|
411
452
|
proj_destroy(crs_to_crs);
|
412
453
|
crs_to_crs = gis_pj;
|
413
454
|
}
|
414
455
|
data = ALLOC(RGeo_CRSToCRSData);
|
415
|
-
if (data){
|
456
|
+
if (data) {
|
416
457
|
data->crs_to_crs = crs_to_crs;
|
417
458
|
result = TypedData_Wrap_Struct(klass, &rgeo_crs_to_crs_data_type, data);
|
418
459
|
}
|
419
460
|
return result;
|
420
461
|
}
|
421
462
|
|
422
|
-
|
423
|
-
|
424
|
-
{
|
463
|
+
static VALUE method_crs_to_crs_transform(VALUE self, VALUE x, VALUE y,
|
464
|
+
VALUE z) {
|
425
465
|
VALUE result;
|
426
466
|
RGeo_CRSToCRSData *crs_to_crs_data;
|
427
467
|
PJ *crs_to_crs_pj;
|
@@ -430,9 +470,10 @@ static VALUE method_crs_to_crs_transform(VALUE self, VALUE x, VALUE y, VALUE z)
|
|
430
470
|
PJ_COORD output;
|
431
471
|
|
432
472
|
result = Qnil;
|
433
|
-
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type,
|
473
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type,
|
474
|
+
crs_to_crs_data);
|
434
475
|
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
435
|
-
if(crs_to_crs_pj){
|
476
|
+
if (crs_to_crs_pj) {
|
436
477
|
xval = rb_num2dbl(x);
|
437
478
|
yval = rb_num2dbl(y);
|
438
479
|
zval = NIL_P(z) ? 0.0 : rb_num2dbl(z);
|
@@ -443,56 +484,164 @@ static VALUE method_crs_to_crs_transform(VALUE self, VALUE x, VALUE y, VALUE z)
|
|
443
484
|
result = rb_ary_new2(NIL_P(z) ? 2 : 3);
|
444
485
|
rb_ary_push(result, DBL2NUM(output.xyz.x));
|
445
486
|
rb_ary_push(result, DBL2NUM(output.xyz.y));
|
446
|
-
if(!NIL_P(z)){
|
487
|
+
if (!NIL_P(z)) {
|
447
488
|
rb_ary_push(result, DBL2NUM(output.xyz.z));
|
448
489
|
}
|
449
490
|
}
|
450
491
|
return result;
|
451
492
|
}
|
452
493
|
|
453
|
-
static
|
454
|
-
|
494
|
+
static VALUE method_crs_to_crs_wkt_str(VALUE self) {
|
495
|
+
VALUE result;
|
496
|
+
RGeo_CRSToCRSData *crs_to_crs_data;
|
497
|
+
PJ *crs_to_crs_pj;
|
498
|
+
const char *str;
|
499
|
+
|
500
|
+
result = Qnil;
|
501
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type,
|
502
|
+
crs_to_crs_data);
|
503
|
+
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
504
|
+
if (crs_to_crs_pj) {
|
505
|
+
const char *const options[] = {"MULTILINE=NO", NULL};
|
506
|
+
str = proj_as_wkt(PJ_DEFAULT_CTX, crs_to_crs_pj, WKT_TYPE, options);
|
507
|
+
if (str) {
|
508
|
+
result = rb_str_new2(str);
|
509
|
+
}
|
510
|
+
}
|
511
|
+
return result;
|
512
|
+
}
|
513
|
+
|
514
|
+
static VALUE method_crs_to_crs_area_of_use_str(VALUE self) {
|
515
|
+
VALUE result;
|
516
|
+
RGeo_CRSToCRSData *crs_to_crs_data;
|
517
|
+
PJ *crs_to_crs_pj;
|
518
|
+
const char *str;
|
519
|
+
|
520
|
+
result = Qnil;
|
521
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type,
|
522
|
+
crs_to_crs_data);
|
523
|
+
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
524
|
+
if (crs_to_crs_pj) {
|
525
|
+
if (proj_get_area_of_use(PJ_DEFAULT_CTX, crs_to_crs_pj, NULL, NULL, NULL,
|
526
|
+
NULL, &str)) {
|
527
|
+
result = rb_str_new2(str);
|
528
|
+
}
|
529
|
+
}
|
530
|
+
return result;
|
531
|
+
}
|
532
|
+
|
533
|
+
static VALUE method_crs_to_crs_proj_type(VALUE self) {
|
534
|
+
VALUE result;
|
535
|
+
RGeo_CRSToCRSData *crs_to_crs_data;
|
536
|
+
PJ *crs_to_crs_pj;
|
537
|
+
int proj_type;
|
538
|
+
|
539
|
+
result = Qnil;
|
540
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type,
|
541
|
+
crs_to_crs_data);
|
542
|
+
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
543
|
+
if (crs_to_crs_pj) {
|
544
|
+
proj_type = proj_get_type(crs_to_crs_pj);
|
545
|
+
result = INT2FIX(proj_type);
|
546
|
+
}
|
547
|
+
return result;
|
548
|
+
}
|
549
|
+
|
550
|
+
static VALUE method_crs_to_crs_identity(VALUE self, VALUE from, VALUE to) {
|
551
|
+
VALUE result;
|
552
|
+
RGeo_Proj4Data *from_data;
|
553
|
+
RGeo_Proj4Data *to_data;
|
554
|
+
result = Qnil;
|
555
|
+
PJ *from_pj;
|
556
|
+
PJ *to_pj;
|
557
|
+
|
558
|
+
result = Qfalse;
|
559
|
+
|
560
|
+
TypedData_Get_Struct(from, RGeo_Proj4Data, &rgeo_proj4_data_type, from_data);
|
561
|
+
TypedData_Get_Struct(to, RGeo_Proj4Data, &rgeo_proj4_data_type, to_data);
|
562
|
+
from_pj = from_data->pj;
|
563
|
+
to_pj = to_data->pj;
|
564
|
+
|
565
|
+
if (from_pj && to_pj) {
|
566
|
+
if (proj_is_equivalent_to(from_pj, to_pj, PJ_COMP_EQUIVALENT)) {
|
567
|
+
result = Qtrue;
|
568
|
+
}
|
569
|
+
}
|
570
|
+
|
571
|
+
return result;
|
572
|
+
}
|
573
|
+
|
574
|
+
static void rgeo_init_proj4() {
|
455
575
|
VALUE rgeo_module;
|
456
576
|
VALUE coordsys_module;
|
577
|
+
VALUE cs_module;
|
457
578
|
VALUE proj4_class;
|
458
579
|
VALUE crs_to_crs_class;
|
580
|
+
VALUE cs_base_class;
|
581
|
+
VALUE cs_info_class;
|
582
|
+
VALUE coordinate_system_class;
|
583
|
+
VALUE coordinate_transform_class;
|
459
584
|
|
460
585
|
rgeo_module = rb_define_module("RGeo");
|
461
586
|
coordsys_module = rb_define_module_under(rgeo_module, "CoordSys");
|
462
|
-
|
463
|
-
|
587
|
+
cs_module = rb_define_module_under(coordsys_module, "CS");
|
588
|
+
cs_base_class = rb_define_class_under(cs_module, "Base", rb_cObject);
|
589
|
+
cs_info_class = rb_define_class_under(cs_module, "Info", cs_base_class);
|
590
|
+
|
591
|
+
coordinate_system_class =
|
592
|
+
rb_define_class_under(cs_module, "CoordinateSystem", cs_info_class);
|
593
|
+
proj4_class =
|
594
|
+
rb_define_class_under(coordsys_module, "Proj4", coordinate_system_class);
|
464
595
|
rb_define_alloc_func(proj4_class, rgeo_proj4_data_alloc);
|
465
596
|
rb_define_module_function(proj4_class, "_create", cmethod_proj4_create, 2);
|
466
|
-
rb_define_method(proj4_class, "initialize_copy", method_proj4_initialize_copy,
|
597
|
+
rb_define_method(proj4_class, "initialize_copy", method_proj4_initialize_copy,
|
598
|
+
1);
|
467
599
|
rb_define_method(proj4_class, "_set_value", method_proj4_set_value, 2);
|
468
600
|
rb_define_method(proj4_class, "_original_str", method_proj4_original_str, 0);
|
469
|
-
rb_define_method(proj4_class, "_canonical_str", method_proj4_canonical_str,
|
601
|
+
rb_define_method(proj4_class, "_canonical_str", method_proj4_canonical_str,
|
602
|
+
0);
|
470
603
|
rb_define_method(proj4_class, "_as_text", method_proj4_wkt_str, 0);
|
471
604
|
rb_define_method(proj4_class, "_auth_name", method_proj4_auth_name_str, 0);
|
472
605
|
rb_define_method(proj4_class, "_valid?", method_proj4_is_valid, 0);
|
473
606
|
rb_define_method(proj4_class, "_geographic?", method_proj4_is_geographic, 0);
|
474
607
|
rb_define_method(proj4_class, "_geocentric?", method_proj4_is_geocentric, 0);
|
608
|
+
rb_define_method(proj4_class, "_projected?", method_proj4_is_projected, 0);
|
475
609
|
rb_define_method(proj4_class, "_radians?", method_proj4_uses_radians, 0);
|
476
|
-
rb_define_method(proj4_class, "_get_geographic", method_proj4_get_geographic,
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
610
|
+
rb_define_method(proj4_class, "_get_geographic", method_proj4_get_geographic,
|
611
|
+
0);
|
612
|
+
rb_define_method(proj4_class, "_crs?", method_proj4_is_crs, 0);
|
613
|
+
rb_define_method(proj4_class, "_axis_and_unit_info",
|
614
|
+
method_proj4_axis_and_unit_info_str, 1);
|
615
|
+
rb_define_method(proj4_class, "_axis_count", method_proj4_axis_count, 0);
|
616
|
+
rb_define_module_function(proj4_class, "_proj_version", cmethod_proj4_version,
|
617
|
+
0);
|
618
|
+
|
619
|
+
coordinate_transform_class =
|
620
|
+
rb_define_class_under(cs_module, "CoordinateTransform", cs_info_class);
|
621
|
+
|
622
|
+
crs_to_crs_class = rb_define_class_under(coordsys_module, "CRSToCRS",
|
623
|
+
coordinate_transform_class);
|
481
624
|
rb_define_alloc_func(crs_to_crs_class, rgeo_crs_to_crs_data_alloc);
|
482
|
-
rb_define_module_function(crs_to_crs_class, "_create",
|
483
|
-
|
625
|
+
rb_define_module_function(crs_to_crs_class, "_create",
|
626
|
+
cmethod_crs_to_crs_create, 2);
|
627
|
+
rb_define_method(crs_to_crs_class, "_transform_coords",
|
628
|
+
method_crs_to_crs_transform, 3);
|
629
|
+
rb_define_method(crs_to_crs_class, "_as_text", method_crs_to_crs_wkt_str, 0);
|
630
|
+
rb_define_method(crs_to_crs_class, "_proj_type", method_crs_to_crs_proj_type,
|
631
|
+
0);
|
632
|
+
rb_define_method(crs_to_crs_class, "_area_of_use",
|
633
|
+
method_crs_to_crs_area_of_use_str, 0);
|
634
|
+
rb_define_method(crs_to_crs_class, "_identity?", method_crs_to_crs_identity,
|
635
|
+
2);
|
484
636
|
}
|
485
637
|
|
486
|
-
|
487
638
|
#endif
|
488
639
|
|
489
|
-
|
490
|
-
void Init_proj4_c_impl()
|
491
|
-
{
|
640
|
+
void Init_proj4_c_impl() {
|
492
641
|
#ifdef RGEO_PROJ4_SUPPORTED
|
493
642
|
rgeo_init_proj4();
|
643
|
+
rgeo_init_proj_errors();
|
494
644
|
#endif
|
495
645
|
}
|
496
646
|
|
497
|
-
|
498
647
|
RGEO_END_C
|