rgeo-proj4 3.1.1 → 4.0.0.pre.rc.1

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: b578b226ebc3b376a92f58cf080d34f237b5929751e6b856e493d9b6a6daa1ae
4
- data.tar.gz: 84f4953ac2aea3783e7a807542c7aaf102b265dc454a9de97c340d70f04685c1
3
+ metadata.gz: c0a179679b6f6471a9626bf6fbc08758a52b0d60f5ba81fa4ab5119456680470
4
+ data.tar.gz: 2a58dfbbf870d24ea9d4b2880444c1f331ba184dc38862af6b4347fb9cc96366
5
5
  SHA512:
6
- metadata.gz: bb2bddfdc101da5c0a4b2af5d5445ce7e57f8d49505b5bb2f53376e81b5ed392d4d2183c11e6cc1e0d86fc5b2fc83cc1afe1d6a3c72fcf8924d779fbd04fdffb
7
- data.tar.gz: 3f21328f3beff54191cf496f784a432185f9999d4b71ddeab91d772627f26bbc97deb1882cab9d9f997d16432993d2c742c3d2638005d2f372959428201f4e05
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
@@ -12,7 +12,7 @@ else
12
12
 
13
13
  require "mkmf"
14
14
 
15
- header_dirs_ =
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
- lib_dirs_ =
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
- header_dirs_.delete_if { |path_| !::File.directory?(path_) }
46
- lib_dirs_.delete_if { |path_| !::File.directory?(path_) }
45
+ header_dirs.delete_if { |path| !::File.directory?(path) }
46
+ lib_dirs.delete_if { |path| !::File.directory?(path) }
47
47
 
48
- found_proj_ = false
49
- header_dirs_, lib_dirs_ = dir_config("proj", header_dirs_, lib_dirs_)
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
- if have_func("proj_create", "proj.h")
54
- found_proj_ = true
55
- have_func("proj_create_crs_to_crs_from_pj", "proj.h")
56
- have_func("proj_normalize_for_visualization", "proj.h")
57
- else
58
- $libs.gsub!(" -lproj", "")
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 found_proj_
64
- puts "**** WARNING: Unable to find Proj headers or Proj version is too old."
65
- puts "**** Compiling without Proj support."
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
@@ -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
- new_data->pj = proj_crs_get_geodetic_crs(PJ_DEFAULT_CTX, self_data->pj);
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
- proj4_class = rb_define_class_under(coordsys_module, "Proj4", rb_cObject);
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", rb_cObject);
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
- class CRSToCRS
10
- attr_writer :from, :to
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.from = from
16
- crs_to_crs.to = to
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 @from._radians? && @from._geographic?
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 && @to._radians? && @to._geographic?
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
@@ -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 a hash. Returns nil if the given definition
169
- # is invalid or Proj4 is not supported.
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
- result_ = nil unless result_._valid?
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(from_proj_, to_proj_, x_, y_, z_ = nil)
225
- crs_to_crs = CRSStore.get(from_proj_, to_proj_)
226
- crs_to_crs.transform_coords(x_, y_, z_)
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(from_proj_, from_geometry_, to_proj_, to_factory_)
235
- crs_to_crs = CRSStore.get(from_proj_, to_proj_)
236
- crs_to_crs.transform(from_geometry_, to_factory_)
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
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RGeo
4
4
  module Proj4
5
- VERSION = "3.1.1"
5
+ VERSION = "4.0.0-rc.1"
6
6
  end
7
7
  end
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
- require "rgeo/coord_sys/srs_database/proj4_data"
8
- require "rgeo/coord_sys/proj4_c_impl"
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: 3.1.1
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: 2021-11-08 00:00:00.000000000 Z
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: '2.0'
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: '2.0'
26
+ version: 3.0.0.pre.rc.3
27
27
  - !ruby/object:Gem::Dependency
28
- name: minitest
28
+ name: ffi-geos
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.14'
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: '5.14'
40
+ version: '2.2'
41
41
  - !ruby/object:Gem::Dependency
42
- name: pry-byebug
42
+ name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 3.9.0
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: 3.9.0
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/coord_sys/srs_database/proj4_data.rb
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: '0'
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