rgeo-proj4 3.0.1 → 3.1.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 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