rgeo 0.6.0 → 1.0.0.rc1

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
- 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