rgeo-proj4 3.0.1 → 3.1.0
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 +2 -0
- data/ext/proj4_c_impl/main.c +111 -45
- data/lib/rgeo/coord_sys/crs_to_crs.rb +45 -0
- data/lib/rgeo/coord_sys/proj4.rb +3 -14
- data/lib/rgeo/proj4/version.rb +1 -1
- data/lib/rgeo/proj4.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9135e04b9e8911c2ce6c1c0f39be9edbe80d8adcbfa661dc57116320c616ff2d
|
4
|
+
data.tar.gz: da0f069d9d7314c35a396fa0a2d2797944cc830a8f408b5ebdf577bba8c6a7c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9e9d80f1df22a9fb3f1564ed622f008a53cacad669af211766c6b43e1654e7b589bce9b95ba0c2018e501b2625a43208f2195b47dda472e7daee45faa21bd5c
|
7
|
+
data.tar.gz: d26e2e71aa7fab5737a70463f5a4689507707a9910eb874ae44e74df90899d4b3c52b88bef81b5d66298c28e0a22f6602c45fbcfa6c02633074e0351ee4e68e5
|
data/ext/proj4_c_impl/extconf.rb
CHANGED
@@ -22,6 +22,7 @@ else
|
|
22
22
|
"/opt/proj/include",
|
23
23
|
"/opt/proj4/include",
|
24
24
|
"/opt/include",
|
25
|
+
"/opt/homebrew/include",
|
25
26
|
"/Library/Frameworks/PROJ.framework/unix/include",
|
26
27
|
"/usr/include"
|
27
28
|
]
|
@@ -36,6 +37,7 @@ else
|
|
36
37
|
"/opt/proj/lib",
|
37
38
|
"/opt/proj4/lib",
|
38
39
|
"/opt/lib",
|
40
|
+
"/opt/homebrew/lib",
|
39
41
|
"/Library/Frameworks/PROJ.framework/unix/lib",
|
40
42
|
"/usr/lib",
|
41
43
|
"/usr/lib64"
|
data/ext/proj4_c_impl/main.c
CHANGED
@@ -51,6 +51,10 @@ typedef struct {
|
|
51
51
|
char uses_radians;
|
52
52
|
} RGeo_Proj4Data;
|
53
53
|
|
54
|
+
typedef struct {
|
55
|
+
PJ *crs_to_crs;
|
56
|
+
} RGeo_CRSToCRSData;
|
57
|
+
|
54
58
|
|
55
59
|
// Destroy function for proj data.
|
56
60
|
static void rgeo_proj4_free(void *ptr)
|
@@ -62,6 +66,17 @@ static void rgeo_proj4_free(void *ptr)
|
|
62
66
|
free(data);
|
63
67
|
}
|
64
68
|
|
69
|
+
// Destroy function for crs_to_crs data.
|
70
|
+
static void rgeo_crs_to_crs_free(void *ptr)
|
71
|
+
{
|
72
|
+
RGeo_CRSToCRSData *data = (RGeo_CRSToCRSData *)ptr;
|
73
|
+
if(data->crs_to_crs){
|
74
|
+
proj_destroy(data->crs_to_crs);
|
75
|
+
}
|
76
|
+
free(data);
|
77
|
+
}
|
78
|
+
|
79
|
+
|
65
80
|
static size_t rgeo_proj4_memsize(const void *ptr)
|
66
81
|
{
|
67
82
|
size_t size = 0;
|
@@ -74,6 +89,17 @@ static size_t rgeo_proj4_memsize(const void *ptr)
|
|
74
89
|
return size;
|
75
90
|
}
|
76
91
|
|
92
|
+
static size_t rgeo_crs_to_crs_memsize(const void *ptr)
|
93
|
+
{
|
94
|
+
size_t size = 0;
|
95
|
+
const RGeo_CRSToCRSData *data = (const RGeo_CRSToCRSData *)ptr;
|
96
|
+
size += sizeof(*data);
|
97
|
+
if(data->crs_to_crs){
|
98
|
+
size += sizeof(data->crs_to_crs);
|
99
|
+
}
|
100
|
+
return size;
|
101
|
+
}
|
102
|
+
|
77
103
|
static void rgeo_proj4_mark(void *ptr)
|
78
104
|
{
|
79
105
|
RGeo_Proj4Data *data = (RGeo_Proj4Data *)ptr;
|
@@ -111,6 +137,12 @@ static const rb_data_type_t rgeo_proj4_data_type = {
|
|
111
137
|
0, 0,
|
112
138
|
RUBY_TYPED_FREE_IMMEDIATELY};
|
113
139
|
|
140
|
+
static const rb_data_type_t rgeo_crs_to_crs_data_type = {
|
141
|
+
"RGeo::CoordSys::CRSToCRS",
|
142
|
+
{0, rgeo_crs_to_crs_free, rgeo_crs_to_crs_memsize},
|
143
|
+
0, 0,
|
144
|
+
RUBY_TYPED_FREE_IMMEDIATELY};
|
145
|
+
|
114
146
|
static VALUE rgeo_proj4_data_alloc(VALUE self)
|
115
147
|
{
|
116
148
|
VALUE result;
|
@@ -127,6 +159,21 @@ static VALUE rgeo_proj4_data_alloc(VALUE self)
|
|
127
159
|
return result;
|
128
160
|
}
|
129
161
|
|
162
|
+
|
163
|
+
static VALUE rgeo_crs_to_crs_data_alloc(VALUE self)
|
164
|
+
{
|
165
|
+
VALUE result;
|
166
|
+
RGeo_CRSToCRSData *data = ALLOC(RGeo_CRSToCRSData);
|
167
|
+
|
168
|
+
result = Qnil;
|
169
|
+
|
170
|
+
if(data){
|
171
|
+
data->crs_to_crs = NULL;
|
172
|
+
result = TypedData_Wrap_Struct(self, &rgeo_crs_to_crs_data_type, data);
|
173
|
+
}
|
174
|
+
return result;
|
175
|
+
}
|
176
|
+
|
130
177
|
static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig)
|
131
178
|
{
|
132
179
|
RGeo_Proj4Data *self_data;
|
@@ -321,85 +368,99 @@ static VALUE cmethod_proj4_version(VALUE module)
|
|
321
368
|
return rb_sprintf("%d.%d.%d", PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR, PROJ_VERSION_PATCH);
|
322
369
|
}
|
323
370
|
|
371
|
+
static VALUE cmethod_proj4_create(VALUE klass, VALUE str, VALUE uses_radians)
|
372
|
+
{
|
373
|
+
VALUE result;
|
374
|
+
RGeo_Proj4Data* data;
|
324
375
|
|
325
|
-
|
376
|
+
result = Qnil;
|
377
|
+
Check_Type(str, T_STRING);
|
378
|
+
data = ALLOC(RGeo_Proj4Data);
|
379
|
+
if (data) {
|
380
|
+
data->pj = proj_create(PJ_DEFAULT_CTX, StringValuePtr(str));
|
381
|
+
data->original_str = str;
|
382
|
+
data->uses_radians = RTEST(uses_radians) ? 1 : 0;
|
383
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_proj4_data_type, data);
|
384
|
+
}
|
385
|
+
return result;
|
386
|
+
}
|
387
|
+
|
388
|
+
static VALUE cmethod_crs_to_crs_create(VALUE klass, VALUE from, VALUE to)
|
326
389
|
{
|
327
390
|
VALUE result;
|
328
391
|
RGeo_Proj4Data *from_data;
|
329
392
|
RGeo_Proj4Data *to_data;
|
393
|
+
result = Qnil;
|
330
394
|
PJ *from_pj;
|
331
395
|
PJ *to_pj;
|
332
|
-
PJ *crs_to_crs;
|
333
396
|
PJ *gis_pj;
|
334
|
-
|
335
|
-
|
336
|
-
PJ_COORD output;
|
397
|
+
PJ *crs_to_crs;
|
398
|
+
RGeo_CRSToCRSData* data;
|
337
399
|
|
338
|
-
result = Qnil;
|
339
400
|
TypedData_Get_Struct(from, RGeo_Proj4Data, &rgeo_proj4_data_type, from_data);
|
340
401
|
TypedData_Get_Struct(to, RGeo_Proj4Data, &rgeo_proj4_data_type, to_data);
|
341
402
|
from_pj = from_data->pj;
|
342
403
|
to_pj = to_data->pj;
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
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
|
-
}
|
367
|
-
}
|
368
|
-
proj_destroy(crs_to_crs);
|
369
|
-
}
|
404
|
+
crs_to_crs = proj_create_crs_to_crs_from_pj(PJ_DEFAULT_CTX, from_pj, to_pj, 0, NULL);
|
405
|
+
|
406
|
+
// necessary to use proj_normalize_for_visualization so that we
|
407
|
+
// do not have to worry about the order of coordinates in every
|
408
|
+
// coord system
|
409
|
+
gis_pj = proj_normalize_for_visualization(PJ_DEFAULT_CTX, crs_to_crs);
|
410
|
+
if(gis_pj){
|
411
|
+
proj_destroy(crs_to_crs);
|
412
|
+
crs_to_crs = gis_pj;
|
413
|
+
}
|
414
|
+
data = ALLOC(RGeo_CRSToCRSData);
|
415
|
+
if (data){
|
416
|
+
data->crs_to_crs = crs_to_crs;
|
417
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_crs_to_crs_data_type, data);
|
370
418
|
}
|
371
419
|
return result;
|
372
420
|
}
|
373
421
|
|
374
422
|
|
375
|
-
static VALUE
|
423
|
+
static VALUE method_crs_to_crs_transform(VALUE self, VALUE x, VALUE y, VALUE z)
|
376
424
|
{
|
377
425
|
VALUE result;
|
378
|
-
|
426
|
+
RGeo_CRSToCRSData *crs_to_crs_data;
|
427
|
+
PJ *crs_to_crs_pj;
|
428
|
+
double xval, yval, zval;
|
429
|
+
PJ_COORD input;
|
430
|
+
PJ_COORD output;
|
379
431
|
|
380
432
|
result = Qnil;
|
381
|
-
|
382
|
-
|
383
|
-
if
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
433
|
+
TypedData_Get_Struct(self, RGeo_CRSToCRSData, &rgeo_crs_to_crs_data_type, crs_to_crs_data);
|
434
|
+
crs_to_crs_pj = crs_to_crs_data->crs_to_crs;
|
435
|
+
if(crs_to_crs_pj){
|
436
|
+
xval = rb_num2dbl(x);
|
437
|
+
yval = rb_num2dbl(y);
|
438
|
+
zval = NIL_P(z) ? 0.0 : rb_num2dbl(z);
|
439
|
+
|
440
|
+
input = proj_coord(xval, yval, zval, HUGE_VAL);
|
441
|
+
output = proj_trans(crs_to_crs_pj, PJ_FWD, input);
|
442
|
+
|
443
|
+
result = rb_ary_new2(NIL_P(z) ? 2 : 3);
|
444
|
+
rb_ary_push(result, DBL2NUM(output.xyz.x));
|
445
|
+
rb_ary_push(result, DBL2NUM(output.xyz.y));
|
446
|
+
if(!NIL_P(z)){
|
447
|
+
rb_ary_push(result, DBL2NUM(output.xyz.z));
|
448
|
+
}
|
388
449
|
}
|
389
450
|
return result;
|
390
451
|
}
|
391
452
|
|
392
|
-
|
393
453
|
static void rgeo_init_proj4()
|
394
454
|
{
|
395
455
|
VALUE rgeo_module;
|
396
456
|
VALUE coordsys_module;
|
397
457
|
VALUE proj4_class;
|
458
|
+
VALUE crs_to_crs_class;
|
398
459
|
|
399
460
|
rgeo_module = rb_define_module("RGeo");
|
400
461
|
coordsys_module = rb_define_module_under(rgeo_module, "CoordSys");
|
401
|
-
proj4_class = rb_define_class_under(coordsys_module, "Proj4", rb_cObject);
|
402
462
|
|
463
|
+
proj4_class = rb_define_class_under(coordsys_module, "Proj4", rb_cObject);
|
403
464
|
rb_define_alloc_func(proj4_class, rgeo_proj4_data_alloc);
|
404
465
|
rb_define_module_function(proj4_class, "_create", cmethod_proj4_create, 2);
|
405
466
|
rb_define_method(proj4_class, "initialize_copy", method_proj4_initialize_copy, 1);
|
@@ -413,8 +474,13 @@ static void rgeo_init_proj4()
|
|
413
474
|
rb_define_method(proj4_class, "_geocentric?", method_proj4_is_geocentric, 0);
|
414
475
|
rb_define_method(proj4_class, "_radians?", method_proj4_uses_radians, 0);
|
415
476
|
rb_define_method(proj4_class, "_get_geographic", method_proj4_get_geographic, 0);
|
416
|
-
rb_define_module_function(proj4_class, "_transform_coords", cmethod_proj4_transform, 5);
|
417
477
|
rb_define_module_function(proj4_class, "_proj_version", cmethod_proj4_version, 0);
|
478
|
+
|
479
|
+
|
480
|
+
crs_to_crs_class = rb_define_class_under(coordsys_module, "CRSToCRS", rb_cObject);
|
481
|
+
rb_define_alloc_func(crs_to_crs_class, rgeo_crs_to_crs_data_alloc);
|
482
|
+
rb_define_module_function(crs_to_crs_class, "_create", cmethod_crs_to_crs_create, 2);
|
483
|
+
rb_define_method(crs_to_crs_class, "_transform_coords", method_crs_to_crs_transform, 3);
|
418
484
|
}
|
419
485
|
|
420
486
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "singleton"
|
4
|
+
module RGeo
|
5
|
+
module CoordSys
|
6
|
+
# This is a Ruby wrapper around a proj crs_to_crs
|
7
|
+
# A crs_to_crs transformation object is a pipeline between two known coordinate reference systems.
|
8
|
+
# https://proj.org/development/reference/functions.html#c.proj_create_crs_to_crs
|
9
|
+
class CRSToCRS
|
10
|
+
# transform the coordinates from the initial CRS to the destination CRS
|
11
|
+
def transform_coords(x, y, z)
|
12
|
+
_transform_coords(x, y, z)
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def create(from, to)
|
17
|
+
_create(from, to)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Store of all the created CRSToCRS
|
23
|
+
class CRSStore
|
24
|
+
include Singleton
|
25
|
+
class << self
|
26
|
+
def get(from, to)
|
27
|
+
instance.get(from, to)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Key = Struct.new(:from, :to)
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@store = Hash.new { |h, k| h[k] = CRSToCRS.create(k.from, k.to) }
|
35
|
+
@semaphore = Mutex.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def get(from, to)
|
39
|
+
@semaphore.synchronize do
|
40
|
+
@store[Key.new(from, to)]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/rgeo/coord_sys/proj4.rb
CHANGED
@@ -221,14 +221,14 @@ module RGeo
|
|
221
221
|
# Transforms the given coordinate (x, y, [z]) from one proj4
|
222
222
|
# coordinate system to another. Returns an array with either two
|
223
223
|
# or three elements.
|
224
|
-
|
225
224
|
def transform_coords(from_proj_, to_proj_, x_, y_, z_ = nil)
|
226
225
|
if from_proj_._radians? && from_proj_._geographic?
|
227
226
|
x_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
228
227
|
y_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
229
228
|
end
|
230
229
|
|
231
|
-
|
230
|
+
crs_to_crs = CRSStore.get(from_proj_, to_proj_)
|
231
|
+
result_ = crs_to_crs.transform_coords(x_, y_, z_)
|
232
232
|
if result_ && to_proj_._radians? && to_proj_._geographic?
|
233
233
|
result_[0] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
234
234
|
result_[1] *= ImplHelper::Math::RADIANS_PER_DEGREE
|
@@ -273,19 +273,8 @@ module RGeo
|
|
273
273
|
from_has_m_ = from_factory_.property(:has_m_coordinate)
|
274
274
|
to_has_z_ = to_factory_.property(:has_z_coordinate)
|
275
275
|
to_has_m_ = to_factory_.property(:has_m_coordinate)
|
276
|
-
|
277
|
-
y_ = from_point_.y
|
278
|
-
if from_proj_._radians? && from_proj_._geographic?
|
279
|
-
x_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
280
|
-
y_ *= ImplHelper::Math::DEGREES_PER_RADIAN
|
281
|
-
end
|
282
|
-
coords_ = _transform_coords(from_proj_, to_proj_, x_, y_, from_has_z_ ? from_point_.z : nil)
|
276
|
+
coords_ = transform_coords(from_proj_, to_proj_, from_point_.x, from_point_.y, from_has_z_ ? from_point_.z : nil)
|
283
277
|
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
278
|
extras_ = []
|
290
279
|
extras_ << coords_[2].to_f if to_has_z_
|
291
280
|
if to_has_m_
|
data/lib/rgeo/proj4/version.rb
CHANGED
data/lib/rgeo/proj4.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: 3.0
|
4
|
+
version: 3.1.0
|
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: 2021-
|
11
|
+
date: 2021-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rgeo
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- LICENSE.txt
|
106
106
|
- ext/proj4_c_impl/extconf.rb
|
107
107
|
- ext/proj4_c_impl/main.c
|
108
|
+
- lib/rgeo/coord_sys/crs_to_crs.rb
|
108
109
|
- lib/rgeo/coord_sys/proj4.rb
|
109
110
|
- lib/rgeo/coord_sys/srs_database/proj4_data.rb
|
110
111
|
- lib/rgeo/proj4.rb
|