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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e899f9ec9d4cb7036400cb716e4d414c87adf5b1b20fbcf081666d869af48ad
4
- data.tar.gz: 423a52b4b72050a519b8df4c63f01058b608c9345cb0abc5e1bf2a33729c381b
3
+ metadata.gz: 9135e04b9e8911c2ce6c1c0f39be9edbe80d8adcbfa661dc57116320c616ff2d
4
+ data.tar.gz: da0f069d9d7314c35a396fa0a2d2797944cc830a8f408b5ebdf577bba8c6a7c2
5
5
  SHA512:
6
- metadata.gz: 59fda580463933b22228f0748d7ddbb38deefe04c2b01ea2979d1a2f15a2d565bfad6b3056f0f4ab9a27fa147df69e8eae9dec8dd1cd075c48c108bcce96858b
7
- data.tar.gz: 1cd3d716d7c9ba6c832d3703abb2c6ddefa87985e75034ed38458bd447f6afd32e02a72547ff2014db52db0bd0d3c3709c776e97698dc0e0a792eb33168b0314
6
+ metadata.gz: a9e9d80f1df22a9fb3f1564ed622f008a53cacad669af211766c6b43e1654e7b589bce9b95ba0c2018e501b2625a43208f2195b47dda472e7daee45faa21bd5c
7
+ data.tar.gz: d26e2e71aa7fab5737a70463f5a4689507707a9910eb874ae44e74df90899d4b3c52b88bef81b5d66298c28e0a22f6602c45fbcfa6c02633074e0351ee4e68e5
@@ -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"
@@ -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
- static VALUE cmethod_proj4_transform(VALUE module, VALUE from, VALUE to, VALUE x, VALUE y, VALUE z)
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
- double xval, yval, zval;
335
- PJ_COORD input;
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
- if (from_pj && to_pj) {
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
- }
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 cmethod_proj4_create(VALUE klass, VALUE str, VALUE uses_radians)
423
+ static VALUE method_crs_to_crs_transform(VALUE self, VALUE x, VALUE y, VALUE z)
376
424
  {
377
425
  VALUE result;
378
- RGeo_Proj4Data* data;
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
- Check_Type(str, T_STRING);
382
- data = ALLOC(RGeo_Proj4Data);
383
- if (data) {
384
- data->pj = proj_create(PJ_DEFAULT_CTX, StringValuePtr(str));
385
- data->original_str = str;
386
- data->uses_radians = RTEST(uses_radians) ? 1 : 0;
387
- result = TypedData_Wrap_Struct(klass, &rgeo_proj4_data_type, data);
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
@@ -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
- result_ = _transform_coords(from_proj_, to_proj_, x_, y_, z_)
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
- x_ = from_point_.x
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_
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RGeo
4
4
  module Proj4
5
- VERSION = "3.0.1"
5
+ VERSION = "3.1.0"
6
6
  end
7
7
  end
data/lib/rgeo/proj4.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "rgeo"
4
4
  require "rgeo/proj4/version"
5
+ require "rgeo/coord_sys/crs_to_crs"
5
6
  require "rgeo/coord_sys/proj4"
6
7
  require "rgeo/coord_sys/srs_database/proj4_data"
7
8
  require "rgeo/coord_sys/proj4_c_impl"
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.1
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-05-07 00:00:00.000000000 Z
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