rgeo 0.6.0 → 1.0.0.rc1

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
- SHA1:
3
- metadata.gz: 0b118363a5e851576b03d15095fc20d43e9e4c29
4
- data.tar.gz: 878518023c981c1b0c7200b81bc183120d93c2cd
2
+ SHA256:
3
+ metadata.gz: 1f829053838d792cf1148bc149d0bb29cca53437f1aa41bb10fa403c666c57b9
4
+ data.tar.gz: 01e39842598a32bf2deddde8b4d6430abd24f1fb6aaf92c954c18a5d9c316105
5
5
  SHA512:
6
- metadata.gz: b9731327e808aeafd48276409f2a7432536ba723c11dff9f5faf739b31d0731fb71b3c01f224c5663b55f1b088f564b7bd5004663238d7269adc77763a04c383
7
- data.tar.gz: 82dd3124fd0e669bfafd256abc7ff181f4e4c8f3381cbee492c7948adf244b28d0c664ba15413228cd34f67ac44e80b1105372253b7a8020bae0c4425f93f37c
6
+ metadata.gz: 8088804b587c0ae34d946f76d09360641d05ce5d608eebe3bc7a91ddf68e0082068bcd53ab1b2142b5ff7971ec488ea74140d8f1f39c06e551a2062f66de9884
7
+ data.tar.gz: 8a233f6ed24ec95d2eb72f5236af574cbdfbfa706a98cfecaa4f9f4bc27a4e341043cb523eacde2df25eb9a41284a8835e3cf98b27e443f160c3027a4133ad60
@@ -363,6 +363,23 @@ static VALUE method_multi_line_string_hash(VALUE self)
363
363
  return LONG2FIX(rb_hash_end(hash));
364
364
  }
365
365
 
366
+ static VALUE method_geometry_collection_node(VALUE self)
367
+ {
368
+ VALUE result = Qnil;
369
+ RGeo_GeometryData* self_data;
370
+ const GEOSGeometry* self_geom;
371
+ GEOSGeometry* noded;
372
+ GEOSContextHandle_t context;
373
+
374
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
375
+ self_geom = self_data->geom;
376
+ context = self_data->geos_context;
377
+
378
+ noded = GEOSNode_r(context, self_geom);
379
+ result = rgeo_wrap_geos_geometry(self_data->factory, noded, Qnil);
380
+
381
+ return result;
382
+ }
366
383
 
367
384
  static VALUE method_multi_line_string_coordinates(VALUE self)
368
385
  {
@@ -609,6 +626,7 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
609
626
  rb_define_method(geos_geometry_collection_methods, "geometry_n", method_geometry_collection_geometry_n, 1);
610
627
  rb_define_method(geos_geometry_collection_methods, "[]", method_geometry_collection_brackets, 1);
611
628
  rb_define_method(geos_geometry_collection_methods, "each", method_geometry_collection_each, 0);
629
+ rb_define_method(geos_geometry_collection_methods, "node", method_geometry_collection_node, 0);
612
630
 
613
631
 
614
632
  // Methods for MultiPointImpl
@@ -247,6 +247,54 @@ static VALUE method_line_string_end_point(VALUE self)
247
247
  return result;
248
248
  }
249
249
 
250
+ static VALUE method_line_string_project_point(VALUE self, VALUE point)
251
+ {
252
+ RGeo_FactoryData* factory_data;
253
+ VALUE result = Qnil;
254
+ VALUE factory;
255
+ RGeo_GeometryData* self_data;
256
+ const GEOSGeometry* self_geom;
257
+ const GEOSGeometry *geos_point;
258
+
259
+ double location;
260
+
261
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
262
+ factory = self_data->factory;
263
+ self_geom = self_data->geom;
264
+ factory_data = RGEO_FACTORY_DATA_PTR(factory);
265
+
266
+ if(self_geom && point) {
267
+ geos_point = rgeo_convert_to_geos_geometry(factory, point, factory_data->globals->geos_point);
268
+ location = GEOSProject_r(self_data->geos_context, self_geom, geos_point);
269
+ result = DBL2NUM(location);
270
+ }
271
+ return result;
272
+ }
273
+
274
+ static VALUE method_line_string_interpolate_point(VALUE self, VALUE loc_num)
275
+ {
276
+ RGeo_FactoryData* factory_data;
277
+ VALUE result = Qnil;
278
+ VALUE factory;
279
+ RGeo_GeometryData* self_data;
280
+ const GEOSGeometry* self_geom;
281
+ GEOSGeometry* geos_point;
282
+
283
+ double location;
284
+
285
+ location = NUM2DBL(loc_num);
286
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
287
+ factory = self_data->factory;
288
+ factory_data = RGEO_FACTORY_DATA_PTR(factory);
289
+ self_geom = self_data->geom;
290
+
291
+ if(self_geom) {
292
+ geos_point = GEOSInterpolate_r(self_data->geos_context, self_geom, location);
293
+ result = rgeo_wrap_geos_geometry(factory, geos_point, factory_data->globals->geos_point);
294
+ }
295
+
296
+ return result;
297
+ }
250
298
 
251
299
  static VALUE method_line_string_is_closed(VALUE self)
252
300
  {
@@ -613,6 +661,8 @@ void rgeo_init_geos_line_string(RGeo_Globals* globals)
613
661
  rb_define_method(geos_line_string_methods, "points", method_line_string_points, 0);
614
662
  rb_define_method(geos_line_string_methods, "start_point", method_line_string_start_point, 0);
615
663
  rb_define_method(geos_line_string_methods, "end_point", method_line_string_end_point, 0);
664
+ rb_define_method(geos_line_string_methods, "project_point", method_line_string_project_point, 1);
665
+ rb_define_method(geos_line_string_methods, "interpolate_point", method_line_string_interpolate_point, 1);
616
666
  rb_define_method(geos_line_string_methods, "is_closed?", method_line_string_is_closed, 0);
617
667
  rb_define_method(geos_line_string_methods, "is_ring?", method_line_string_is_ring, 0);
618
668
  rb_define_method(geos_line_string_methods, "coordinates", method_line_string_coordinates, 0);
@@ -20,12 +20,10 @@ module RGeo
20
20
  @has_z = opts_[:has_z_coordinate] ? true : false
21
21
  @has_m = opts_[:has_m_coordinate] ? true : false
22
22
  @proj4 = opts_[:proj4]
23
- if CoordSys::Proj4.supported?
23
+ if @proj4 && CoordSys.check!(:proj4)
24
24
  if @proj4.is_a?(::String) || @proj4.is_a?(::Hash)
25
25
  @proj4 = CoordSys::Proj4.create(@proj4)
26
26
  end
27
- else
28
- @proj4 = nil
29
27
  end
30
28
  srid_ = opts_[:srid]
31
29
  @coord_sys = opts_[:coord_sys]
@@ -115,7 +113,7 @@ module RGeo
115
113
  end
116
114
 
117
115
  def marshal_load(data_) # :nodoc:
118
- if CoordSys::Proj4.supported? && (proj4_data_ = data_["proj4"])
116
+ if (proj4_data_ = data_["proj4"]) && CoordSys.check!(:proj4)
119
117
  proj4_ = CoordSys::Proj4.allocate
120
118
  proj4_.marshal_load(proj4_data_)
121
119
  else
@@ -161,7 +159,7 @@ module RGeo
161
159
  end
162
160
 
163
161
  def init_with(coder_) # :nodoc:
164
- if (proj4_data_ = coder_["proj4"])
162
+ if (proj4_data_ = coder_["proj4"]) && CoordSys.check!(:proj4)
165
163
  if proj4_data_.is_a?(::Hash)
166
164
  proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
167
165
  else
@@ -26,18 +26,22 @@ module RGeo
26
26
  # such as those provided by spatialreference.org.
27
27
 
28
28
  module CoordSys
29
+ # The only valid key is :proj4
30
+ def self.supported?(key)
31
+ raise(Error::UnsupportedOperation, "Invalid key. The only valid key is :proj4.") unless key == :proj4
32
+ defined?(Proj4) && Proj4.supported?
33
+ end
34
+
35
+ def self.check!(key)
36
+ supported?(key) || raise(Error::UnsupportedOperation, "Coordinate system '#{key}' is not supported.")
37
+ end
29
38
  end
30
39
  end
31
40
 
32
41
  # Implementation files
33
- begin
34
- require "rgeo/coord_sys/proj4_c_impl"
35
- rescue ::LoadError; end
36
- require "rgeo/coord_sys/proj4"
37
42
  require "rgeo/coord_sys/cs/factories"
38
43
  require "rgeo/coord_sys/cs/entities"
39
44
  require "rgeo/coord_sys/cs/wkt_parser"
40
45
  require "rgeo/coord_sys/srs_database/interface.rb"
41
- require "rgeo/coord_sys/srs_database/proj4_data.rb"
42
46
  require "rgeo/coord_sys/srs_database/url_reader.rb"
43
47
  require "rgeo/coord_sys/srs_database/sr_org.rb"
@@ -75,12 +75,10 @@ module RGeo
75
75
  @coord_sys = CS.create_from_wkt(@coord_sys)
76
76
  end
77
77
  @proj4 = data_[:proj4]
78
- if Proj4.supported?
78
+ if @proj4 && CoordSys.check!(:proj4)
79
79
  if @proj4.is_a?(::String) || @proj4.is_a?(::Hash)
80
80
  @proj4 = Proj4.create(@proj4)
81
81
  end
82
- else
83
- @proj4 = nil
84
82
  end
85
83
  if @coord_sys
86
84
  @name = @coord_sys.name unless @name
@@ -403,12 +403,6 @@ module RGeo
403
403
  raise Error::UnsupportedOperation, "Method Geometry#relate not defined."
404
404
  end
405
405
 
406
- # Deprecated alias of Geometry#relate?
407
-
408
- def relate(another_geometry_, intersection_pattern_matrix_)
409
- relate?(another_geometry_, intersection_pattern_matrix_)
410
- end
411
-
412
406
  # === SFS 1.1 Description
413
407
  #
414
408
  # Returns the shortest distance between any two Points in the two
@@ -80,6 +80,12 @@ module RGeo
80
80
  raise Error::UnsupportedOperation, "Method GeometryCollection#[] not defined."
81
81
  end
82
82
 
83
+ # Nodes the linework in a list of Geometries
84
+ #
85
+ def node
86
+ raise Error::UnsupportedOperation, "Method GeometryCollection#node not defined."
87
+ end
88
+
83
89
  # Iterates over the geometries of this GeometryCollection.
84
90
  #
85
91
  # This is not a standard SFS method, but is provided so that a
@@ -49,9 +49,6 @@ module RGeo
49
49
  # ::RGeo::Feature::Type === object.geometry_type # true
50
50
 
51
51
  module Type
52
- # Deprecated alias for RGeo::Feature::Instance
53
- Instance = Feature::Instance
54
-
55
52
  # Returns true if the given object is this type or a subtype
56
53
  # thereof, or if it is a feature object whose geometry_type is
57
54
  # this type or a subtype thereof.
@@ -202,7 +199,7 @@ module RGeo
202
199
  end
203
200
  hasz_ = factory_.property(:has_z_coordinate)
204
201
  nhasz_ = nfactory_.property(:has_z_coordinate)
205
- if proj_ && nproj_
202
+ if proj_ && nproj_ && CoordSys.check!(:proj4)
206
203
  coords_ = CoordSys::Proj4.transform_coords(proj_, nproj_, obj_.x, obj_.y, hasz_ ? obj_.z : nil)
207
204
  coords_ << (hasz_ ? obj_.z : 0.0) if nhasz_ && coords_.size < 3
208
205
  else
@@ -28,12 +28,10 @@ module RGeo
28
28
  @support_m = opts_[:has_m_coordinate] ? true : false
29
29
  @srid = (opts_[:srid] || 4326).to_i
30
30
  @proj4 = opts_[:proj4]
31
- if CoordSys::Proj4.supported?
31
+ if @proj4 && CoordSys.check!(:proj4)
32
32
  if @proj4.is_a?(::String) || @proj4.is_a?(::Hash)
33
33
  @proj4 = CoordSys::Proj4.create(@proj4)
34
34
  end
35
- else
36
- @proj4 = nil
37
35
  end
38
36
  @coord_sys = opts_[:coord_sys]
39
37
  if @coord_sys.is_a?(::String)
@@ -124,7 +122,7 @@ module RGeo
124
122
  end
125
123
 
126
124
  def marshal_load(data_) # :nodoc:
127
- if CoordSys::Proj4.supported? && (proj4_data_ = data_["proj4"])
125
+ if (proj4_data_ = data_["proj4"]) && CoordSys.check!(:proj4)
128
126
  proj4_ = CoordSys::Proj4.allocate
129
127
  proj4_.marshal_load(proj4_data_)
130
128
  else
@@ -188,6 +186,7 @@ module RGeo
188
186
 
189
187
  def init_with(coder_) # :nodoc:
190
188
  if (proj4_data_ = coder_["proj4"])
189
+ CoordSys.check!(:proj4)
191
190
  if proj4_data_.is_a?(::Hash)
192
191
  proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
193
192
  else
@@ -344,9 +344,7 @@ module RGeo
344
344
  # more details.
345
345
 
346
346
  def projected_factory(opts_ = {})
347
- unless CoordSys::Proj4.supported?
348
- raise Error::UnsupportedOperation, "Proj4 is not supported because the proj4 library was not found at install time."
349
- end
347
+ CoordSys.check!(:proj4)
350
348
  db_ = opts_[:srs_database]
351
349
  if (projection_factory_ = opts_[:projection_factory])
352
350
  # Get the projection coordinate systems from the given factory
@@ -459,7 +457,7 @@ module RGeo
459
457
 
460
458
  def _proj4_4055 # :nodoc:
461
459
  unless defined?(@proj4_4055)
462
- @proj4_4055 = CoordSys::Proj4.create("+proj=longlat +a=6378137 +b=6378137 +towgs84=0,0,0,0,0,0,0 +no_defs")
460
+ @proj4_4055 = CoordSys.supported?(:proj4) && CoordSys::Proj4.create("+proj=longlat +a=6378137 +b=6378137 +towgs84=0,0,0,0,0,0,0 +no_defs")
463
461
  end
464
462
  @proj4_4055
465
463
  end
@@ -473,7 +471,7 @@ module RGeo
473
471
 
474
472
  def _proj4_4326 # :nodoc:
475
473
  unless defined?(@proj4_4326)
476
- @proj4_4326 = CoordSys::Proj4.create("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
474
+ @proj4_4326 = CoordSys.supported?(:proj4) && CoordSys::Proj4.create("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
477
475
  end
478
476
  @proj4_4326
479
477
  end
@@ -93,6 +93,7 @@ module RGeo
93
93
  end
94
94
 
95
95
  def self._proj4_3857 # :nodoc:
96
+ return unless CoordSys.supported?(:proj4)
96
97
  unless defined?(@proj4_3857)
97
98
  @proj4_3857 = CoordSys::Proj4.create("+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs")
98
99
  end
@@ -58,7 +58,7 @@ module RGeo
58
58
  # Coordinate system (srid, proj4, and coord_sys)
59
59
  srid_ = opts_[:srid]
60
60
  proj4_ = opts_[:proj4]
61
- if CoordSys::Proj4.supported?
61
+ if proj4_ && CoordSys.check!(:proj4)
62
62
  if proj4_.is_a?(::String) || proj4_.is_a?(::Hash)
63
63
  proj4_ = CoordSys::Proj4.create(proj4_)
64
64
  end
@@ -159,7 +159,7 @@ module RGeo
159
159
  end
160
160
 
161
161
  def marshal_load(data_) # :nodoc:
162
- if CoordSys::Proj4.supported? && (proj4_data_ = data_["proj4"])
162
+ if (proj4_data_ = data_["proj4"]) && CoordSys.check!(:proj4)
163
163
  proj4_ = CoordSys::Proj4.allocate
164
164
  proj4_.marshal_load(proj4_data_)
165
165
  else
@@ -210,6 +210,7 @@ module RGeo
210
210
 
211
211
  def init_with(coder_) # :nodoc:
212
212
  if (proj4_data_ = coder_["proj4"])
213
+ CoordSys.check!(:proj4)
213
214
  if proj4_data_.is_a?(::Hash)
214
215
  proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
215
216
  else
@@ -462,9 +463,5 @@ module RGeo
462
463
 
463
464
  # :startdoc:
464
465
  end
465
-
466
- # Deprecated alias of CAPIFactory.
467
- # Defined primarily to support old YAML serializations.
468
- Factory = CAPIFactory
469
466
  end
470
467
  end
@@ -59,7 +59,7 @@ module RGeo
59
59
  # Coordinate system (srid, proj4, and coord_sys)
60
60
  @srid = opts_[:srid]
61
61
  @proj4 = opts_[:proj4]
62
- if CoordSys::Proj4.supported?
62
+ if @proj4 && CoordSys.check!(:proj4)
63
63
  if @proj4.is_a?(::String) || @proj4.is_a?(::Hash)
64
64
  @proj4 = CoordSys::Proj4.create(@proj4)
65
65
  end
@@ -155,7 +155,7 @@ module RGeo
155
155
  end
156
156
 
157
157
  def marshal_load(data_) # :nodoc:
158
- if CoordSys::Proj4.supported? && (proj4_data_ = data_["proj4"])
158
+ if (proj4_data_ = data_["proj4"]) && CoordSys.check!(:proj4)
159
159
  proj4_ = CoordSys::Proj4.allocate
160
160
  proj4_.marshal_load(proj4_data_)
161
161
  else
@@ -204,6 +204,7 @@ module RGeo
204
204
 
205
205
  def init_with(coder_) # :nodoc:
206
206
  if (proj4_data_ = coder_["proj4"])
207
+ CoordSys.check!(:proj4)
207
208
  if proj4_data_.is_a?(::Hash)
208
209
  proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
209
210
  else
@@ -118,7 +118,7 @@ module RGeo
118
118
  end
119
119
 
120
120
  def marshal_load(data_) # :nodoc:
121
- if CoordSys::Proj4.supported? && (proj4_data_ = data_["proj4"])
121
+ if (proj4_data_ = data_["proj4"]) && CoordSys.check!(:proj4)
122
122
  proj4_ = CoordSys::Proj4.allocate
123
123
  proj4_.marshal_load(proj4_data_)
124
124
  else
@@ -169,6 +169,7 @@ module RGeo
169
169
 
170
170
  def init_with(coder_) # :nodoc:
171
171
  if (proj4_data_ = coder_["proj4"])
172
+ CoordSys.check!(:proj4)
172
173
  if proj4_data_.is_a?(::Hash)
173
174
  proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
174
175
  else
@@ -301,8 +301,13 @@ module RGeo
301
301
  alias_method :[], :geometry_n
302
302
 
303
303
  def each
304
- num_geometries.times do |i_|
305
- yield geometry_n(i_)
304
+ if block_given?
305
+ num_geometries.times do |i_|
306
+ yield geometry_n(i_)
307
+ end
308
+ self
309
+ else
310
+ enum_for
306
311
  end
307
312
  end
308
313
 
@@ -1,3 +1,3 @@
1
1
  module RGeo
2
- VERSION = "0.6.0".freeze
2
+ VERSION = "1.0.0.rc1".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgeo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma, Tee Parham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-01 00:00:00.000000000 Z
11
+ date: 2017-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -103,7 +103,6 @@ email: dazuma@gmail.com, parhameter@gmail.com
103
103
  executables: []
104
104
  extensions:
105
105
  - ext/geos_c_impl/extconf.rb
106
- - ext/proj4_c_impl/extconf.rb
107
106
  extra_rdoc_files: []
108
107
  files:
109
108
  - LICENSE.txt
@@ -124,8 +123,6 @@ files:
124
123
  - ext/geos_c_impl/polygon.c
125
124
  - ext/geos_c_impl/polygon.h
126
125
  - ext/geos_c_impl/preface.h
127
- - ext/proj4_c_impl/extconf.rb
128
- - ext/proj4_c_impl/main.c
129
126
  - lib/rgeo.rb
130
127
  - lib/rgeo/cartesian.rb
131
128
  - lib/rgeo/cartesian/analysis.rb
@@ -139,9 +136,7 @@ files:
139
136
  - lib/rgeo/coord_sys/cs/entities.rb
140
137
  - lib/rgeo/coord_sys/cs/factories.rb
141
138
  - lib/rgeo/coord_sys/cs/wkt_parser.rb
142
- - lib/rgeo/coord_sys/proj4.rb
143
139
  - lib/rgeo/coord_sys/srs_database/interface.rb
144
- - lib/rgeo/coord_sys/srs_database/proj4_data.rb
145
140
  - lib/rgeo/coord_sys/srs_database/sr_org.rb
146
141
  - lib/rgeo/coord_sys/srs_database/url_reader.rb
147
142
  - lib/rgeo/error.rb
@@ -214,12 +209,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
214
209
  version: 2.1.0
215
210
  required_rubygems_version: !ruby/object:Gem::Requirement
216
211
  requirements:
217
- - - ">="
212
+ - - ">"
218
213
  - !ruby/object:Gem::Version
219
- version: '0'
214
+ version: 1.3.1
220
215
  requirements: []
221
216
  rubyforge_project:
222
- rubygems_version: 2.6.10
217
+ rubygems_version: 2.7.0
223
218
  signing_key:
224
219
  specification_version: 4
225
220
  summary: RGeo is a geospatial data library for Ruby.
@@ -1,62 +0,0 @@
1
- # -----------------------------------------------------------------------------
2
- #
3
- # Makefile builder for Proj4 wrapper
4
- #
5
- # -----------------------------------------------------------------------------
6
-
7
- if ::RUBY_DESCRIPTION =~ /^jruby\s/
8
-
9
- ::File.open("Makefile", "w") { |f_| f_.write(".PHONY: install\ninstall:\n") }
10
-
11
- else
12
-
13
- require "mkmf"
14
-
15
- header_dirs_ =
16
- [
17
- ::RbConfig::CONFIG["includedir"],
18
- "/usr/local/include",
19
- "/usr/local/proj/include",
20
- "/usr/local/proj4/include",
21
- "/opt/local/include",
22
- "/opt/proj/include",
23
- "/opt/proj4/include",
24
- "/opt/include",
25
- "/Library/Frameworks/PROJ.framework/unix/include",
26
- "/usr/include"
27
- ]
28
- lib_dirs_ =
29
- [
30
- ::RbConfig::CONFIG["libdir"],
31
- "/usr/local/lib",
32
- "/usr/local/lib64",
33
- "/usr/local/proj/lib",
34
- "/usr/local/proj4/lib",
35
- "/opt/local/lib",
36
- "/opt/proj/lib",
37
- "/opt/proj4/lib",
38
- "/opt/lib",
39
- "/Library/Frameworks/PROJ.framework/unix/lib",
40
- "/usr/lib",
41
- "/usr/lib64"
42
- ]
43
- header_dirs_.delete_if { |path_| !::File.directory?(path_) }
44
- lib_dirs_.delete_if { |path_| !::File.directory?(path_) }
45
-
46
- found_proj_ = false
47
- header_dirs_, lib_dirs_ = dir_config("proj", header_dirs_, lib_dirs_)
48
- if have_header("proj_api.h")
49
- $libs << " -lproj"
50
- if have_func("pj_init_plus", "proj_api.h")
51
- found_proj_ = true
52
- else
53
- $libs.gsub!(" -lproj", "")
54
- end
55
- end
56
- unless found_proj_
57
- puts "**** WARNING: Unable to find Proj headers or Proj version is too old."
58
- puts "**** Compiling without Proj support."
59
- end
60
- create_makefile("rgeo/coord_sys/proj4_c_impl")
61
-
62
- end
@@ -1,315 +0,0 @@
1
- /*
2
- Main initializer for Proj4 wrapper
3
- */
4
-
5
- #ifdef HAVE_PROJ_API_H
6
- #ifdef HAVE_PJ_INIT_PLUS
7
- #define RGEO_PROJ4_SUPPORTED
8
- #endif
9
- #endif
10
-
11
- #ifdef __cplusplus
12
- #define RGEO_BEGIN_C extern "C" {
13
- #define RGEO_END_C }
14
- #else
15
- #define RGEO_BEGIN_C
16
- #define RGEO_END_C
17
- #endif
18
-
19
-
20
- #ifdef RGEO_PROJ4_SUPPORTED
21
-
22
- #include <ruby.h>
23
- #include <proj_api.h>
24
-
25
- #endif
26
-
27
-
28
- RGEO_BEGIN_C
29
-
30
-
31
- #ifdef RGEO_PROJ4_SUPPORTED
32
-
33
-
34
- typedef struct {
35
- projPJ pj;
36
- VALUE original_str;
37
- char uses_radians;
38
- } RGeo_Proj4Data;
39
-
40
-
41
- #define RGEO_PROJ4_DATA_PTR(obj) ((RGeo_Proj4Data*)DATA_PTR(obj))
42
-
43
-
44
- // Destroy function for proj data.
45
-
46
- static void destroy_proj4_func(RGeo_Proj4Data* data)
47
- {
48
- if (data->pj) {
49
- pj_free(data->pj);
50
- }
51
- free(data);
52
- }
53
-
54
-
55
- static void mark_proj4_func(RGeo_Proj4Data* data)
56
- {
57
- if (!NIL_P(data->original_str)) {
58
- rb_gc_mark(data->original_str);
59
- }
60
- }
61
-
62
-
63
- static VALUE alloc_proj4(VALUE klass)
64
- {
65
- VALUE result;
66
- RGeo_Proj4Data* data;
67
-
68
- result = Qnil;
69
- data = ALLOC(RGeo_Proj4Data);
70
- if (data) {
71
- data->pj = NULL;
72
- data->original_str = Qnil;
73
- data->uses_radians = 0;
74
- result = Data_Wrap_Struct(klass, mark_proj4_func, destroy_proj4_func, data);
75
- }
76
- return result;
77
- }
78
-
79
-
80
- static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig)
81
- {
82
- RGeo_Proj4Data* self_data;
83
- projPJ pj;
84
- RGeo_Proj4Data* orig_data;
85
- char* str;
86
-
87
- // Clear out any existing value
88
- self_data = RGEO_PROJ4_DATA_PTR(self);
89
- pj = self_data->pj;
90
- if (pj) {
91
- pj_free(pj);
92
- self_data->pj = NULL;
93
- self_data->original_str = Qnil;
94
- }
95
-
96
- // Copy value from orig
97
- orig_data = RGEO_PROJ4_DATA_PTR(orig);
98
- if (!NIL_P(orig_data->original_str)) {
99
- self_data->pj = pj_init_plus(RSTRING_PTR(orig_data->original_str));
100
- }
101
- else {
102
- str = pj_get_def(orig_data->pj, 0);
103
- self_data->pj = pj_init_plus(str);
104
- pj_dalloc(str);
105
- }
106
- self_data->original_str = orig_data->original_str;
107
- self_data->uses_radians = orig_data->uses_radians;
108
-
109
- return self;
110
- }
111
-
112
-
113
- static VALUE method_proj4_set_value(VALUE self, VALUE str, VALUE uses_radians)
114
- {
115
- RGeo_Proj4Data* self_data;
116
- projPJ pj;
117
-
118
- Check_Type(str, T_STRING);
119
-
120
- // Clear out any existing value
121
- self_data = RGEO_PROJ4_DATA_PTR(self);
122
- pj = self_data->pj;
123
- if (pj) {
124
- pj_free(pj);
125
- self_data->pj = NULL;
126
- self_data->original_str = Qnil;
127
- }
128
-
129
- // Set new data
130
- self_data->pj = pj_init_plus(RSTRING_PTR(str));
131
- self_data->original_str = str;
132
- self_data->uses_radians = RTEST(uses_radians) ? 1 : 0;
133
-
134
- return self;
135
- }
136
-
137
-
138
- static VALUE method_proj4_get_geographic(VALUE self)
139
- {
140
- VALUE result;
141
- RGeo_Proj4Data* new_data;
142
- RGeo_Proj4Data* self_data;
143
-
144
- result = Qnil;
145
- new_data = ALLOC(RGeo_Proj4Data);
146
- if (new_data) {
147
- self_data = RGEO_PROJ4_DATA_PTR(self);
148
- new_data->pj = pj_latlong_from_proj(self_data->pj);
149
- new_data->original_str = Qnil;
150
- new_data->uses_radians = self_data->uses_radians;
151
- result = Data_Wrap_Struct(CLASS_OF(self), mark_proj4_func, destroy_proj4_func, new_data);
152
- }
153
- return result;
154
- }
155
-
156
-
157
- static VALUE method_proj4_original_str(VALUE self)
158
- {
159
- return RGEO_PROJ4_DATA_PTR(self)->original_str;
160
- }
161
-
162
-
163
- static VALUE method_proj4_uses_radians(VALUE self)
164
- {
165
- return RGEO_PROJ4_DATA_PTR(self)->uses_radians ? Qtrue : Qfalse;
166
- }
167
-
168
-
169
- static VALUE method_proj4_canonical_str(VALUE self)
170
- {
171
- VALUE result;
172
- projPJ pj;
173
- char* str;
174
-
175
- result = Qnil;
176
- pj = RGEO_PROJ4_DATA_PTR(self)->pj;
177
- if (pj) {
178
- str = pj_get_def(pj, 0);
179
- if (str) {
180
- result = rb_str_new2(str);
181
- pj_dalloc(str);
182
- }
183
- }
184
- return result;
185
- }
186
-
187
-
188
- static VALUE method_proj4_is_geographic(VALUE self)
189
- {
190
- VALUE result;
191
- projPJ pj;
192
-
193
- result = Qnil;
194
- pj = RGEO_PROJ4_DATA_PTR(self)->pj;
195
- if (pj) {
196
- result = pj_is_latlong(pj) ? Qtrue : Qfalse;
197
- }
198
- return result;
199
- }
200
-
201
-
202
- static VALUE method_proj4_is_geocentric(VALUE self)
203
- {
204
- VALUE result;
205
- projPJ pj;
206
-
207
- result = Qnil;
208
- pj = RGEO_PROJ4_DATA_PTR(self)->pj;
209
- if (pj) {
210
- result = pj_is_geocent(pj) ? Qtrue : Qfalse;
211
- }
212
- return result;
213
- }
214
-
215
-
216
- static VALUE method_proj4_is_valid(VALUE self)
217
- {
218
- return RGEO_PROJ4_DATA_PTR(self)->pj ? Qtrue : Qfalse;
219
- }
220
-
221
-
222
- static VALUE cmethod_proj4_version(VALUE module)
223
- {
224
- return INT2NUM(PJ_VERSION);
225
- }
226
-
227
-
228
- static VALUE cmethod_proj4_transform(VALUE module, VALUE from, VALUE to, VALUE x, VALUE y, VALUE z)
229
- {
230
- VALUE result;
231
- projPJ from_pj;
232
- projPJ to_pj;
233
- double xval, yval, zval;
234
- int err;
235
-
236
- result = Qnil;
237
- from_pj = RGEO_PROJ4_DATA_PTR(from)->pj;
238
- to_pj = RGEO_PROJ4_DATA_PTR(to)->pj;
239
- if (from_pj && to_pj) {
240
- xval = rb_num2dbl(x);
241
- yval = rb_num2dbl(y);
242
- zval = 0.0;
243
- if (!NIL_P(z)) {
244
- zval = rb_num2dbl(z);
245
- }
246
- err = pj_transform(from_pj, to_pj, 1, 1, &xval, &yval, NIL_P(z) ? NULL : &zval);
247
- if (!err && xval != HUGE_VAL && yval != HUGE_VAL && (NIL_P(z) || zval != HUGE_VAL)) {
248
- result = rb_ary_new2(NIL_P(z) ? 2 : 3);
249
- rb_ary_push(result, rb_float_new(xval));
250
- rb_ary_push(result, rb_float_new(yval));
251
- if (!NIL_P(z)) {
252
- rb_ary_push(result, rb_float_new(zval));
253
- }
254
- }
255
- }
256
- return result;
257
- }
258
-
259
-
260
- static VALUE cmethod_proj4_create(VALUE klass, VALUE str, VALUE uses_radians)
261
- {
262
- VALUE result;
263
- RGeo_Proj4Data* data;
264
-
265
- result = Qnil;
266
- Check_Type(str, T_STRING);
267
- data = ALLOC(RGeo_Proj4Data);
268
- if (data) {
269
- data->pj = pj_init_plus(RSTRING_PTR(str));
270
- data->original_str = str;
271
- data->uses_radians = RTEST(uses_radians) ? 1 : 0;
272
- result = Data_Wrap_Struct(klass, mark_proj4_func, destroy_proj4_func, data);
273
- }
274
- return result;
275
- }
276
-
277
-
278
- static void rgeo_init_proj4()
279
- {
280
- VALUE rgeo_module;
281
- VALUE coordsys_module;
282
- VALUE proj4_class;
283
-
284
- rgeo_module = rb_define_module("RGeo");
285
- coordsys_module = rb_define_module_under(rgeo_module, "CoordSys");
286
- proj4_class = rb_define_class_under(coordsys_module, "Proj4", rb_cObject);
287
-
288
- rb_define_alloc_func(proj4_class, alloc_proj4);
289
- rb_define_module_function(proj4_class, "_create", cmethod_proj4_create, 2);
290
- rb_define_method(proj4_class, "initialize_copy", method_proj4_initialize_copy, 1);
291
- rb_define_method(proj4_class, "_set_value", method_proj4_set_value, 2);
292
- rb_define_method(proj4_class, "_original_str", method_proj4_original_str, 0);
293
- rb_define_method(proj4_class, "_canonical_str", method_proj4_canonical_str, 0);
294
- rb_define_method(proj4_class, "_valid?", method_proj4_is_valid, 0);
295
- rb_define_method(proj4_class, "_geographic?", method_proj4_is_geographic, 0);
296
- rb_define_method(proj4_class, "_geocentric?", method_proj4_is_geocentric, 0);
297
- rb_define_method(proj4_class, "_radians?", method_proj4_uses_radians, 0);
298
- rb_define_method(proj4_class, "_get_geographic", method_proj4_get_geographic, 0);
299
- rb_define_module_function(proj4_class, "_transform_coords", cmethod_proj4_transform, 5);
300
- rb_define_module_function(proj4_class, "_proj_version", cmethod_proj4_version, 0);
301
- }
302
-
303
-
304
- #endif
305
-
306
-
307
- void Init_proj4_c_impl()
308
- {
309
- #ifdef RGEO_PROJ4_SUPPORTED
310
- rgeo_init_proj4();
311
- #endif
312
- }
313
-
314
-
315
- RGEO_END_C
@@ -1,293 +0,0 @@
1
- # -----------------------------------------------------------------------------
2
- #
3
- # Proj4 wrapper for RGeo
4
- #
5
- # -----------------------------------------------------------------------------
6
-
7
- module RGeo
8
- module CoordSys
9
- # This is a Ruby wrapper around a Proj4 coordinate system.
10
- # It represents a single geographic coordinate system, which may be
11
- # a flat projection, a geocentric (3-dimensional) coordinate system,
12
- # or a geographic (latitude-longitude) coordinate system.
13
- #
14
- # Generally, these are used to define the projection for a
15
- # Feature::Factory. You can then convert between coordinate systems
16
- # by casting geometries between such factories using the :project
17
- # option. You may also use this object directly to perform low-level
18
- # coordinate transformations.
19
-
20
- class Proj4
21
- def inspect # :nodoc:
22
- "#<#{self.class}:0x#{object_id.to_s(16)} #{canonical_str.inspect}>"
23
- end
24
-
25
- def to_s # :nodoc:
26
- canonical_str
27
- end
28
-
29
- def hash # :nodoc:
30
- @hash ||= canonical_hash.hash
31
- end
32
-
33
- # Returns true if this Proj4 is equivalent to the given Proj4.
34
- #
35
- # Note: this tests for equivalence by comparing only the hash
36
- # definitions of the Proj4 objects, and returning true if those
37
- # definitions are equivalent. In some cases, this may still return
38
- # false even if the actual coordinate systems are identical, since
39
- # there are sometimes multiple ways to express a given coordinate
40
- # system.
41
-
42
- def eql?(rhs_)
43
- rhs_.class == self.class && rhs_.canonical_hash == canonical_hash && rhs_._radians? == _radians?
44
- end
45
- alias_method :==, :eql?
46
-
47
- # Marshal support
48
-
49
- def marshal_dump # :nodoc:
50
- { "rad" => radians?, "str" => original_str || canonical_str }
51
- end
52
-
53
- def marshal_load(data_) # :nodoc:
54
- _set_value(data_["str"], data_["rad"])
55
- end
56
-
57
- # Psych support
58
-
59
- def encode_with(coder_) # :nodoc:
60
- coder_["proj4"] = original_str || canonical_str
61
- coder_["radians"] = radians?
62
- end
63
-
64
- def init_with(coder_) # :nodoc:
65
- if coder_.type == :scalar
66
- _set_value(coder_.scalar, false)
67
- else
68
- _set_value(coder_["proj4"], coder_["radians"])
69
- end
70
- end
71
-
72
- # Returns the "canonical" string definition for this coordinate
73
- # system, as reported by Proj4. This may be slightly different
74
- # from the definition used to construct this object.
75
-
76
- def canonical_str
77
- unless defined?(@canonical_str)
78
- @canonical_str = _canonical_str
79
- if @canonical_str.respond_to?(:force_encoding)
80
- @canonical_str.force_encoding("US-ASCII")
81
- end
82
- end
83
- @canonical_str
84
- end
85
-
86
- # Returns the "canonical" hash definition for this coordinate
87
- # system, as reported by Proj4. This may be slightly different
88
- # from the definition used to construct this object.
89
-
90
- def canonical_hash
91
- unless defined?(@canonical_hash)
92
- @canonical_hash = {}
93
- canonical_str.strip.split(/\s+/).each do |elem_|
94
- @canonical_hash[Regexp.last_match(1)] = Regexp.last_match(3) if elem_ =~ /^\+(\w+)(=(\S+))?$/
95
- end
96
- end
97
- @canonical_hash
98
- end
99
-
100
- # Returns the string definition originally used to construct this
101
- # object. Returns nil if this object wasn't created by a string
102
- # definition; i.e. if it was created using get_geographic.
103
-
104
- def original_str
105
- _original_str
106
- end
107
-
108
- # Returns true if this Proj4 object is a geographic (lat-long)
109
- # coordinate system.
110
-
111
- def geographic?
112
- _geographic?
113
- end
114
-
115
- # Returns true if this Proj4 object is a geocentric (3dz)
116
- # coordinate system.
117
-
118
- def geocentric?
119
- _geocentric?
120
- end
121
-
122
- # Returns true if this Proj4 object uses radians rather than degrees
123
- # if it is a geographic coordinate system.
124
-
125
- def radians?
126
- _radians?
127
- end
128
-
129
- # Get the geographic (unprojected lat-long) coordinate system
130
- # corresponding to this coordinate system; i.e. the one that uses
131
- # the same ellipsoid and datum.
132
-
133
- def get_geographic
134
- _get_geographic
135
- end
136
-
137
- class << self
138
- # Returns true if Proj4 is supported in this installation.
139
- # If this returns false, the other methods such as create
140
- # will not work.
141
-
142
- def supported?
143
- respond_to?(:_create)
144
- end
145
-
146
- # Returns the Proj library version as a string of the format "x.y.z".
147
-
148
- def version
149
- ::RGeo::VERSION
150
- end
151
-
152
- # Create a new Proj4 object, given a definition, which may be
153
- # either a string or a hash. Returns nil if the given definition
154
- # is invalid or Proj4 is not supported.
155
- #
156
- # Recognized options include:
157
- #
158
- # [<tt>:radians</tt>]
159
- # If set to true, then this proj4 will represent geographic
160
- # (latitude/longitude) coordinates in radians rather than
161
- # degrees. If this is a geographic coordinate system, then its
162
- # units will be in radians. If this is a projected coordinate
163
- # system, then its units will be unchanged, but any geographic
164
- # coordinate system obtained using get_geographic will use
165
- # radians as its units. If this is a geocentric or other type of
166
- # coordinate system, this has no effect. Default is false.
167
- # (That is all coordinates are in degrees by default.)
168
-
169
- def create(defn_, opts_ = {})
170
- result_ = nil
171
- if supported?
172
- if defn_.is_a?(::Hash)
173
- defn_ = defn_.map { |k_, v_| v_ ? "+#{k_}=#{v_}" : "+#{k_}" }.join(" ")
174
- end
175
- unless defn_ =~ /^\s*\+/
176
- defn_ = defn_.sub(/^(\s*)/, '\1+').gsub(/(\s+)([^+\s])/, '\1+\2')
177
- end
178
- result_ = _create(defn_, opts_[:radians])
179
- result_ = nil unless result_._valid?
180
- end
181
- result_
182
- end
183
-
184
- # Create a new Proj4 object, given a definition, which may be
185
- # either a string or a hash. Raises Error::UnsupportedOperation
186
- # if the given definition is invalid or Proj4 is not supported.
187
- #
188
- # Recognized options include:
189
- #
190
- # [<tt>:radians</tt>]
191
- # If set to true, then this proj4 will represent geographic
192
- # (latitude/longitude) coordinates in radians rather than
193
- # degrees. If this is a geographic coordinate system, then its
194
- # units will be in radians. If this is a projected coordinate
195
- # system, then its units will be unchanged, but any geographic
196
- # coordinate system obtained using get_geographic will use
197
- # radians as its units. If this is a geocentric or other type of
198
- # coordinate system, this has no effect. Default is false.
199
- # (That is all coordinates are in degrees by default.)
200
-
201
- def new(defn_, opts_ = {})
202
- result_ = create(defn_, opts_)
203
- unless result_
204
- raise Error::UnsupportedOperation, "Proj4 not supported in this installation"
205
- end
206
- result_
207
- end
208
-
209
- # Low-level coordinate transform method.
210
- # Transforms the given coordinate (x, y, [z]) from one proj4
211
- # coordinate system to another. Returns an array with either two
212
- # or three elements.
213
-
214
- def transform_coords(from_proj_, to_proj_, x_, y_, z_ = nil)
215
- if !from_proj_._radians? && from_proj_._geographic?
216
- x_ *= ImplHelper::Math::RADIANS_PER_DEGREE
217
- y_ *= ImplHelper::Math::RADIANS_PER_DEGREE
218
- end
219
- result_ = _transform_coords(from_proj_, to_proj_, x_, y_, z_)
220
- if result_ && !to_proj_._radians? && to_proj_._geographic?
221
- result_[0] *= ImplHelper::Math::DEGREES_PER_RADIAN
222
- result_[1] *= ImplHelper::Math::DEGREES_PER_RADIAN
223
- end
224
- result_
225
- end
226
-
227
- # Low-level geometry transform method.
228
- # Transforms the given geometry between the given two projections.
229
- # The resulting geometry is constructed using the to_factory.
230
- # Any projections associated with the factories themselves are
231
- # ignored.
232
-
233
- def transform(from_proj_, from_geometry_, to_proj_, to_factory_)
234
- case from_geometry_
235
- when Feature::Point
236
- _transform_point(from_proj_, from_geometry_, to_proj_, to_factory_)
237
- when Feature::Line
238
- to_factory_.line(from_geometry_.points.map { |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
239
- when Feature::LinearRing
240
- _transform_linear_ring(from_proj_, from_geometry_, to_proj_, to_factory_)
241
- when Feature::LineString
242
- to_factory_.line_string(from_geometry_.points.map { |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
243
- when Feature::Polygon
244
- _transform_polygon(from_proj_, from_geometry_, to_proj_, to_factory_)
245
- when Feature::MultiPoint
246
- to_factory_.multi_point(from_geometry_.map { |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
247
- when Feature::MultiLineString
248
- to_factory_.multi_line_string(from_geometry_.map { |g_| transform(from_proj_, g_, to_proj_, to_factory_) })
249
- when Feature::MultiPolygon
250
- to_factory_.multi_polygon(from_geometry_.map { |p_| _transform_polygon(from_proj_, p_, to_proj_, to_factory_) })
251
- when Feature::GeometryCollection
252
- to_factory_.collection(from_geometry_.map { |g_| transform(from_proj_, g_, to_proj_, to_factory_) })
253
- end
254
- end
255
-
256
- def _transform_point(from_proj_, from_point_, to_proj_, to_factory_) # :nodoc:
257
- from_factory_ = from_point_.factory
258
- from_has_z_ = from_factory_.property(:has_z_coordinate)
259
- from_has_m_ = from_factory_.property(:has_m_coordinate)
260
- to_has_z_ = to_factory_.property(:has_z_coordinate)
261
- to_has_m_ = to_factory_.property(:has_m_coordinate)
262
- x_ = from_point_.x
263
- y_ = from_point_.y
264
- if !from_proj_._radians? && from_proj_._geographic?
265
- x_ *= ImplHelper::Math::RADIANS_PER_DEGREE
266
- y_ *= ImplHelper::Math::RADIANS_PER_DEGREE
267
- end
268
- coords_ = _transform_coords(from_proj_, to_proj_, x_, y_, from_has_z_ ? from_point_.z : nil)
269
- if coords_
270
- if !to_proj_._radians? && to_proj_._geographic?
271
- coords_[0] *= ImplHelper::Math::DEGREES_PER_RADIAN
272
- coords_[1] *= ImplHelper::Math::DEGREES_PER_RADIAN
273
- end
274
- extras_ = []
275
- extras_ << coords_[2].to_f if to_has_z_
276
- extras_ << from_has_m_ ? from_point_.m : 0.0 if to_has_m_
277
- to_factory_.point(coords_[0], coords_[1], *extras_)
278
- end
279
- end
280
-
281
- def _transform_linear_ring(from_proj_, from_ring_, to_proj_, to_factory_) # :nodoc:
282
- to_factory_.linear_ring(from_ring_.points[0..-2].map { |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
283
- end
284
-
285
- def _transform_polygon(from_proj_, from_polygon_, to_proj_, to_factory_) # :nodoc:
286
- ext_ = _transform_linear_ring(from_proj_, from_polygon_.exterior_ring, to_proj_, to_factory_)
287
- int_ = from_polygon_.interior_rings.map { |r_| _transform_linear_ring(from_proj_, r_, to_proj_, to_factory_) }
288
- to_factory_.polygon(ext_, int_)
289
- end
290
- end
291
- end
292
- end
293
- end
@@ -1,140 +0,0 @@
1
- # -----------------------------------------------------------------------------
2
- #
3
- # SRS database interface
4
- #
5
- # -----------------------------------------------------------------------------
6
-
7
- module RGeo
8
- module CoordSys
9
- module SRSDatabase
10
- # A spatial reference database implementation backed by coordinate
11
- # system files installed as part of the proj4 library. For a given
12
- # Proj4Data object, you specify a single file (e.g. the epsg data
13
- # file), and you can retrieve records by ID number.
14
-
15
- class Proj4Data
16
- # Connect to one of the proj4 data files. You should provide the
17
- # file name, optionally the installation directory if it is not
18
- # in a typical location, and several additional options.
19
- #
20
- # These options are recognized:
21
- #
22
- # [<tt>:dir</tt>]
23
- # The path for the share/proj directory that contains the
24
- # requested data file. By default, the Proj4Data class will
25
- # try a number of directories for you, including
26
- # /usr/local/share/proj, /opt/local/share/proj, /usr/share/proj,
27
- # and a few other variants. However, if you have proj4 installed
28
- # elsewhere, you can provide an explicit directory using this
29
- # option. You may also pass nil as the value, in which case all
30
- # the normal lookup paths will be disabled, and you will have to
31
- # provide the full path as the file name.
32
- # [<tt>:cache</tt>]
33
- # If set to true, this class caches previously looked up entries
34
- # so subsequent lookups do not have to reread the file. If set
35
- # to <tt>:read_all</tt>, then ALL values in the file are read in
36
- # and cached the first time a lookup is done. If set to
37
- # <tt>:preload</tt>, then ALL values in the file are read in
38
- # immediately when the database is created. Default is false,
39
- # indicating that the file will be reread on every lookup.
40
- # [<tt>:authority</tt>]
41
- # If set, its value is taken as the authority name for all
42
- # entries. The authority code will be set to the identifier. If
43
- # not set, then the authority fields of entries will be blank.
44
-
45
- def initialize(filename_, opts_ = {})
46
- dir_ = nil
47
- if opts_.include?(:dir)
48
- dir_ = opts_[:dir]
49
- else
50
- ["/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_|
51
- if ::File.directory?(d_) && ::File.readable?(d_)
52
- dir_ = d_
53
- break
54
- end
55
- end
56
- end
57
- @path = dir_ ? "#{dir_}/#{filename_}" : filename_
58
- @authority = opts_[:authority]
59
- if opts_[:cache]
60
- @cache = {}
61
- case opts_[:cache]
62
- when :read_all
63
- @populate_state = 1
64
- when :preload
65
- _search_file(nil)
66
- @populate_state = 2
67
- else
68
- @populate_state = 0
69
- end
70
- else
71
- @cache = nil
72
- @populate_state = 0
73
- end
74
- end
75
-
76
- # Retrieve the Entry for the given ID number.
77
-
78
- def get(ident_)
79
- ident_ = ident_.to_s
80
- return @cache[ident_] if @cache && @cache.include?(ident_)
81
- result_ = nil
82
- if @populate_state == 0
83
- data_ = _search_file(ident_)
84
- result_ = Entry.new(ident_, authority: @authority, authority_code: @authority ? ident_ : nil, name: data_[1], proj4: data_[2]) if data_
85
- @cache[ident_] = result_ if @cache
86
- elsif @populate_state == 1
87
- _search_file(nil)
88
- result_ = @cache[ident_]
89
- @populate_state = 2
90
- end
91
- result_
92
- end
93
-
94
- # Clear the cache if one exists.
95
-
96
- def clear_cache
97
- @cache.clear if @cache
98
- @populate_state = 1 if @populate_state == 2
99
- end
100
-
101
- def _search_file(ident_) # :nodoc:
102
- ::File.open(@path) do |file_|
103
- cur_name_ = nil
104
- cur_ident_ = nil
105
- cur_text_ = nil
106
- file_.each do |line_|
107
- line_.strip!
108
- if (comment_delim_ = line_.index('#'))
109
- cur_name_ = line_[comment_delim_ + 1..-1].strip
110
- line_ = line_[0..comment_delim_ - 1].strip
111
- end
112
- unless cur_ident_
113
- if line_ =~ /^<(\w+)>(.*)/
114
- cur_ident_ = Regexp.last_match(1)
115
- cur_text_ = []
116
- line_ = Regexp.last_match(2).strip
117
- end
118
- end
119
- next unless cur_ident_
120
- if line_[-2..-1] == "<>"
121
- cur_text_ << line_[0..-3].strip
122
- cur_text_ = cur_text_.join(" ")
123
- if ident_.nil?
124
- @cache[ident_] = Entry.new(ident_, authority: @authority, authority_code: @authority ? id_ : nil, name: cur_name_, proj4: cur_text_)
125
- end
126
- return [ident_, cur_name_, cur_text_] if cur_ident_ == ident_
127
- cur_ident_ = nil
128
- cur_name_ = nil
129
- cur_text_ = nil
130
- else
131
- cur_text_ << line_
132
- end
133
- end
134
- end
135
- nil
136
- end
137
- end
138
- end
139
- end
140
- end