rgeo 0.3.8 → 0.3.9

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.
data/History.rdoc CHANGED
@@ -1,3 +1,11 @@
1
+ === 0.3.9 / 2012-04-10
2
+
3
+ * Implemented LineString#length and MultiLineString#length for simple cartesian and simple spherical factories.
4
+ * Added Cartesian::BoundingBox.create_from_points.
5
+ * Serialization was broken for some 3d geometries when running libgeos 3.2.x (3.3.x was unaffected). Fixed.
6
+ * Fixed an exception when creating adding a geometry to a Cartesian::BoundingBox when a cast is necessary.
7
+ * Added configuration for Travis CI.
8
+
1
9
  === 0.3.8 / 2012-03-23
2
10
 
3
11
  * When using the spherical factory, some negative longitudes might get perturbed slightly due to floating point errors. Fixed. (Reported by Pete Deffendol)
data/README.rdoc CHANGED
@@ -122,6 +122,8 @@ Source code is hosted on Github at http://github.com/dazuma/rgeo
122
122
 
123
123
  Contributions are welcome. Fork the project on Github.
124
124
 
125
+ Build status: {<img src="https://secure.travis-ci.org/dazuma/rgeo.png" />}[http://travis-ci.org/dazuma/rgeo]
126
+
125
127
  Report bugs on Github issues at http://github.org/dazuma/rgeo/issues
126
128
 
127
129
  Support available on the rgeo-users google group at http://groups.google.com/group/rgeo-users
@@ -132,7 +134,9 @@ Contact the author at dazuma at gmail dot com.
132
134
 
133
135
  RGeo is written by Daniel Azuma (http://www.daniel-azuma.com).
134
136
 
135
- Development is supported by Pirq. (http://www.pirq.com).
137
+ Development is supported by Pirq (http://www.pirq.com).
138
+
139
+ Continuous integration service provided by Travis-CI (http://travis-ci.org).
136
140
 
137
141
  RGeo calls the GEOS library to handle most Cartesian geometric
138
142
  calculations, and the Proj4 library to handle projections and coordinate
data/Version CHANGED
@@ -1 +1 @@
1
- 0.3.8
1
+ 0.3.9
@@ -78,6 +78,7 @@ else
78
78
  end
79
79
  have_func('GEOSPreparedContains_r', 'geos_c.h')
80
80
  have_func('GEOSPreparedDisjoint_r', 'geos_c.h')
81
+ have_func('GEOSWKTWriter_setOutputDimension_r', 'geos_c.h')
81
82
  end
82
83
  unless found_geos_
83
84
  puts "**** WARNING: Unable to find GEOS headers or GEOS version is too old."
@@ -316,13 +316,32 @@ static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
316
316
  VALUE result;
317
317
  char* str;
318
318
  size_t size;
319
+ char has_3d;
320
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
321
+ RGeo_Globals* globals;
322
+ VALUE wkb_generator;
323
+ #endif
319
324
 
320
325
  self_data = RGEO_FACTORY_DATA_PTR(self);
321
326
  self_context = self_data->geos_context;
327
+ has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
328
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
329
+ if (has_3d) {
330
+ globals = self_data->globals;
331
+ wkb_generator = globals->marshal_wkb_generator;
332
+ if (NIL_P(wkb_generator)) {
333
+ wkb_generator = rb_funcall(
334
+ rb_const_get_at(globals->geos_module, rb_intern("Utils")),
335
+ rb_intern("marshal_wkb_generator"), 0);
336
+ globals->marshal_wkb_generator = wkb_generator;
337
+ }
338
+ return rb_funcall(wkb_generator, globals->id_generate, 1, obj);
339
+ }
340
+ #endif
322
341
  wkb_writer = self_data->marshal_wkb_writer;
323
342
  if (!wkb_writer) {
324
343
  wkb_writer = GEOSWKBWriter_create_r(self_context);
325
- if (self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M) {
344
+ if (has_3d) {
326
345
  GEOSWKBWriter_setOutputDimension_r(self_context, wkb_writer, 3);
327
346
  }
328
347
  self_data->marshal_wkb_writer = wkb_writer;
@@ -351,13 +370,32 @@ static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
351
370
  VALUE result;
352
371
  char* str;
353
372
  size_t size;
373
+ char has_3d;
374
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
375
+ RGeo_Globals* globals;
376
+ VALUE wkt_generator;
377
+ #endif
354
378
 
355
379
  self_data = RGEO_FACTORY_DATA_PTR(self);
356
380
  self_context = self_data->geos_context;
381
+ has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
382
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
383
+ if (has_3d) {
384
+ globals = self_data->globals;
385
+ wkt_generator = globals->psych_wkt_generator;
386
+ if (NIL_P(wkt_generator)) {
387
+ wkt_generator = rb_funcall(
388
+ rb_const_get_at(globals->geos_module, rb_intern("Utils")),
389
+ rb_intern("psych_wkt_generator"), 0);
390
+ globals->psych_wkt_generator = wkt_generator;
391
+ }
392
+ return rb_funcall(wkt_generator, globals->id_generate, 1, obj);
393
+ }
394
+ #endif
357
395
  wkt_writer = self_data->psych_wkt_writer;
358
396
  if (!wkt_writer) {
359
397
  wkt_writer = GEOSWKTWriter_create_r(self_context);
360
- if (self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M) {
398
+ if (has_3d) {
361
399
  GEOSWKTWriter_setOutputDimension_r(self_context, wkt_writer, 3);
362
400
  }
363
401
  self_data->psych_wkt_writer = wkt_writer;
@@ -561,6 +599,11 @@ RGeo_Globals* rgeo_init_geos_factory()
561
599
  globals->id_enum_for = rb_intern("enum_for");
562
600
  globals->sym_force_new = ID2SYM(rb_intern("force_new"));
563
601
  globals->sym_keep_subtype = ID2SYM(rb_intern("keep_subtype"));
602
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
603
+ globals->psych_wkt_generator = Qnil;
604
+ globals->marshal_wkb_generator = Qnil;
605
+ #endif
606
+
564
607
 
565
608
  // Add C methods to the factory.
566
609
  geos_factory_class = rb_const_get_at(globals->geos_module, rb_intern("Factory"));
@@ -80,6 +80,10 @@ typedef struct {
80
80
  ID id_enum_for;
81
81
  VALUE sym_force_new;
82
82
  VALUE sym_keep_subtype;
83
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
84
+ VALUE psych_wkt_generator;
85
+ VALUE marshal_wkb_generator;
86
+ #endif
83
87
  } RGeo_Globals;
84
88
 
85
89
 
@@ -47,6 +47,9 @@
47
47
  #ifdef HAVE_GEOSPREPAREDDISJOINT_R
48
48
  #define RGEO_GEOS_SUPPORTS_PREPARED2
49
49
  #endif
50
+ #ifdef HAVE_GEOSWKTWWRITER_SETOUTPUTDIMENSION_R
51
+ #define RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
52
+ #endif
50
53
 
51
54
  #ifdef __cplusplus
52
55
  #define RGEO_BEGIN_C extern "C" {
@@ -54,6 +54,20 @@ module RGeo
54
54
  class BoundingBox
55
55
 
56
56
 
57
+ # Create a bounding box given two corner points.
58
+ # The bounding box will be given the factory of the first point.
59
+ # You may also provide the same options available to
60
+ # BoundingBox.new.
61
+
62
+ def self.create_from_points(point1_, point2_, opts_={})
63
+ factory_ = point1_.factory
64
+ box_ = new(factory_, opts_)
65
+ box_._add_geometry(point1_)
66
+ box_.add(point2_)
67
+ box_
68
+ end
69
+
70
+
57
71
  # Create a new empty bounding box with the given factory.
58
72
  #
59
73
  # The factory defines the coordinate system for the bounding box,
@@ -216,7 +230,7 @@ module RGeo
216
230
  if geometry_.factory == @factory
217
231
  _add_geometry(geometry_)
218
232
  else
219
- _add_geometry(Factory.cast(geometry_, @factory))
233
+ _add_geometry(Feature.cast(geometry_, @factory))
220
234
  end
221
235
  end
222
236
  self
@@ -152,6 +152,7 @@ module RGeo
152
152
  include ::RGeo::ImplHelper::BasicGeometryCollectionMethods
153
153
  include ::RGeo::ImplHelper::BasicMultiLineStringMethods
154
154
  include ::RGeo::Cartesian::GeometryMethods
155
+ include ::RGeo::Cartesian::MultiLineStringMethods
155
156
 
156
157
  Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self, true)
157
158
 
@@ -114,12 +114,24 @@ module RGeo
114
114
 
115
115
 
116
116
  def length
117
- @segments.inject(0.0){ |sum_, seg_| sum_ + seg_.length }
117
+ _segments.inject(0.0){ |sum_, seg_| sum_ + seg_.length }
118
118
  end
119
119
 
120
120
 
121
121
  end
122
122
 
123
+
124
+ module MultiLineStringMethods # :nodoc:
125
+
126
+
127
+ def length
128
+ inject(0.0){ |sum_, geom_| sum_ + geom_.length }
129
+ end
130
+
131
+
132
+ end
133
+
134
+
123
135
  end
124
136
 
125
137
  end
@@ -212,6 +212,7 @@ module RGeo
212
212
  include ImplHelper::BasicGeometryCollectionMethods
213
213
  include ImplHelper::BasicMultiLineStringMethods
214
214
  include SphericalGeometryMethods
215
+ include SphericalMultiLineStringMethods
215
216
 
216
217
 
217
218
  Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self, true)
@@ -89,6 +89,22 @@ module RGeo
89
89
  end
90
90
 
91
91
 
92
+ def length
93
+ _arcs.inject(0.0){ |sum_, arc_| sum_ + arc_.length } * SphericalMath::RADIUS
94
+ end
95
+
96
+
97
+ end
98
+
99
+
100
+ module SphericalMultiLineStringMethods
101
+
102
+
103
+ def length
104
+ inject(0.0){ |sum_, geom_| sum_ + geom_.length }
105
+ end
106
+
107
+
92
108
  end
93
109
 
94
110
 
@@ -196,6 +196,11 @@ module RGeo
196
196
  end
197
197
 
198
198
 
199
+ def length
200
+ @s.dist_to_point(@e)
201
+ end
202
+
203
+
199
204
  end
200
205
 
201
206
 
data/lib/rgeo/geos.rb CHANGED
@@ -64,6 +64,7 @@ end
64
64
  # :stopdoc:
65
65
 
66
66
  # Implementation files
67
+ require 'rgeo/geos/utils'
67
68
  require 'rgeo/geos/factory'
68
69
  require 'rgeo/geos/interface'
69
70
  begin
@@ -79,7 +80,6 @@ require 'rgeo/geos/zm_impl'
79
80
  begin
80
81
  require 'ffi-geos'
81
82
  ::RGeo::Geos::FFI_SUPPORTED = true
82
- ::RGeo::Geos::FFIUtils._init
83
83
  rescue ::LoadError
84
84
  ::RGeo::Geos::FFI_SUPPORTED = false
85
85
  rescue
@@ -96,4 +96,7 @@ elsif ::RGeo::Geos::FFI_SUPPORTED
96
96
  ::RGeo::Geos.preferred_native_interface = :ffi
97
97
  end
98
98
 
99
+ # Init internal utilities
100
+ ::RGeo::Geos::Utils._init
101
+
99
102
  # :startdoc:
@@ -39,66 +39,6 @@ module RGeo
39
39
  module Geos
40
40
 
41
41
 
42
- module FFIUtils # :nodoc:
43
-
44
- class << self
45
-
46
-
47
- def coord_seqs_equal?(cs1_, cs2_, check_z_)
48
- len1_ = cs1_.length
49
- len2_ = cs2_.length
50
- if len1_ == len2_
51
- (0...len1_).each do |i_|
52
- return false unless cs1_.get_x(i_) == cs2_.get_x(i_) &&
53
- cs1_.get_y(i_) == cs2_.get_y(i_) &&
54
- (!check_z_ || cs1_.get_z(i_) == cs2_.get_z(i_))
55
- end
56
- true
57
- else
58
- false
59
- end
60
- end
61
-
62
-
63
- def compute_dimension(geom_)
64
- result_ = -1
65
- case geom_.type_id
66
- when ::Geos::GeomTypes::GEOS_POINT
67
- result_ = 0
68
- when ::Geos::GeomTypes::GEOS_MULTIPOINT
69
- result_ = 0 unless geom_.empty?
70
- when ::Geos::GeomTypes::GEOS_LINESTRING, ::Geos::GeomTypes::GEOS_LINEARRING
71
- result_ = 1
72
- when ::Geos::GeomTypes::GEOS_MULTILINESTRING
73
- result_ = 1 unless geom_.empty?
74
- when ::Geos::GeomTypes::GEOS_POLYGON
75
- result_ = 2
76
- when ::Geos::GeomTypes::GEOS_MULTIPOLYGON
77
- result_ = 2 unless geom_.empty?
78
- when ::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION
79
- geom_.each do |g_|
80
- dim_ = compute_dimension(g_)
81
- result_ = dim_ if result_ < dim_
82
- end
83
- end
84
- result_
85
- end
86
-
87
-
88
- def _init
89
- @supports_prepared_level_1 = ::Geos::FFIGeos.respond_to?(:GEOSPreparedContains_r)
90
- @supports_prepared_level_2 = ::Geos::FFIGeos.respond_to?(:GEOSPreparedDisjoint_r)
91
- end
92
-
93
- attr_reader :supports_prepared_level_1
94
- attr_reader :supports_prepared_level_2
95
-
96
-
97
- end
98
-
99
- end
100
-
101
-
102
42
  class FFIGeometryImpl # :nodoc:
103
43
 
104
44
  include Feature::Instance
@@ -123,7 +63,7 @@ module RGeo
123
63
  # Marshal support
124
64
 
125
65
  def marshal_dump # :nodoc:
126
- [@factory, @factory._write_for_marshal(@fg_geom)]
66
+ [@factory, @factory._write_for_marshal(self)]
127
67
  end
128
68
 
129
69
  def marshal_load(data_) # :nodoc:
@@ -139,7 +79,7 @@ module RGeo
139
79
 
140
80
  def encode_with(coder_) # :nodoc:
141
81
  coder_['factory'] = @factory
142
- str_ = @factory._write_for_psych(@fg_geom)
82
+ str_ = @factory._write_for_psych(self)
143
83
  str_ = str_.encode('US-ASCII') if str_.respond_to?(:encode)
144
84
  coder_['wkt'] = str_
145
85
  end
@@ -174,7 +114,7 @@ module RGeo
174
114
 
175
115
 
176
116
  def dimension
177
- FFIUtils.compute_dimension(@fg_geom)
117
+ Utils.ffi_compute_dimension(@fg_geom)
178
118
  end
179
119
 
180
120
 
@@ -258,7 +198,7 @@ module RGeo
258
198
  def disjoint?(rhs_)
259
199
  fg_ = factory._convert_to_fg_geometry(rhs_)
260
200
  if fg_
261
- prep_ = _request_prepared if FFIUtils.supports_prepared_level_2
201
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
262
202
  prep_ ? prep_.disjoint?(fg_) : @fg_geom.disjoint?(fg_)
263
203
  else
264
204
  false
@@ -269,7 +209,7 @@ module RGeo
269
209
  def intersects?(rhs_)
270
210
  fg_ = factory._convert_to_fg_geometry(rhs_)
271
211
  if fg_
272
- prep_ = _request_prepared if FFIUtils.supports_prepared_level_1
212
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_1
273
213
  prep_ ? prep_.intersects?(fg_) : @fg_geom.intersects?(fg_)
274
214
  else
275
215
  false
@@ -280,7 +220,7 @@ module RGeo
280
220
  def touches?(rhs_)
281
221
  fg_ = factory._convert_to_fg_geometry(rhs_)
282
222
  if fg_
283
- prep_ = _request_prepared if FFIUtils.supports_prepared_level_2
223
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
284
224
  prep_ ? prep_.touches?(fg_) : @fg_geom.touches?(fg_)
285
225
  else
286
226
  false
@@ -291,7 +231,7 @@ module RGeo
291
231
  def crosses?(rhs_)
292
232
  fg_ = factory._convert_to_fg_geometry(rhs_)
293
233
  if fg_
294
- prep_ = _request_prepared if FFIUtils.supports_prepared_level_2
234
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
295
235
  prep_ ? prep_.crosses?(fg_) : @fg_geom.crosses?(fg_)
296
236
  else
297
237
  false
@@ -302,7 +242,7 @@ module RGeo
302
242
  def within?(rhs_)
303
243
  fg_ = factory._convert_to_fg_geometry(rhs_)
304
244
  if fg_
305
- prep_ = _request_prepared if FFIUtils.supports_prepared_level_2
245
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
306
246
  prep_ ? prep_.within?(fg_) : @fg_geom.within?(fg_)
307
247
  else
308
248
  false
@@ -313,7 +253,7 @@ module RGeo
313
253
  def contains?(rhs_)
314
254
  fg_ = factory._convert_to_fg_geometry(rhs_)
315
255
  if fg_
316
- prep_ = _request_prepared if FFIUtils.supports_prepared_level_1
256
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_1
317
257
  prep_ ? prep_.contains?(fg_) : @fg_geom.contains?(fg_)
318
258
  else
319
259
  false
@@ -324,7 +264,7 @@ module RGeo
324
264
  def overlaps?(rhs_)
325
265
  fg_ = factory._convert_to_fg_geometry(rhs_)
326
266
  if fg_
327
- prep_ = _request_prepared if FFIUtils.supports_prepared_level_2
267
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
328
268
  prep_ ? prep_.overlaps?(fg_) : @fg_geom.overlaps?(fg_)
329
269
  else
330
270
  false
@@ -449,7 +389,7 @@ module RGeo
449
389
 
450
390
  def rep_equals?(rhs_)
451
391
  rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
452
- FFIUtils.coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
392
+ Utils.ffi_coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
453
393
  end
454
394
 
455
395
 
@@ -525,7 +465,7 @@ module RGeo
525
465
 
526
466
  def rep_equals?(rhs_)
527
467
  rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
528
- FFIUtils.coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
468
+ Utils.ffi_coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
529
469
  end
530
470
 
531
471
 
@@ -599,12 +599,16 @@ module RGeo
599
599
  end
600
600
 
601
601
 
602
- def _write_for_marshal(obj_) # :nodoc:
603
- unless defined?(@marshal_wkb_writer)
604
- @marshal_wkb_writer = ::Geos::WkbWriter.new
605
- @marshal_wkb_writer.output_dimensions = (@_has_3d ? 3 : 2)
602
+ def _write_for_marshal(geom_) # :nodoc:
603
+ if Utils.ffi_supports_set_output_dimension || !@_has_3d
604
+ unless defined?(@marshal_wkb_writer)
605
+ @marshal_wkb_writer = ::Geos::WkbWriter.new
606
+ @marshal_wkb_writer.output_dimensions = 3 if @_has_3d
607
+ end
608
+ @marshal_wkb_writer.write(geom_.fg_geom)
609
+ else
610
+ Utils.marshal_wkb_generator.generate(geom_)
606
611
  end
607
- @marshal_wkb_writer.write(obj_)
608
612
  end
609
613
 
610
614
 
@@ -616,12 +620,16 @@ module RGeo
616
620
  end
617
621
 
618
622
 
619
- def _write_for_psych(obj_) # :nodoc:
620
- unless defined?(@psych_wkt_writer)
621
- @psych_wkt_writer = ::Geos::WktWriter.new
622
- @psych_wkt_writer.output_dimensions = (@_has_3d ? 3 : 2)
623
+ def _write_for_psych(geom_) # :nodoc:
624
+ if Utils.ffi_supports_set_output_dimension || !@_has_3d
625
+ unless defined?(@psych_wkt_writer)
626
+ @psych_wkt_writer = ::Geos::WktWriter.new
627
+ @psych_wkt_writer.output_dimensions = 3 if @_has_3d
628
+ end
629
+ @psych_wkt_writer.write(geom_.fg_geom)
630
+ else
631
+ Utils.psych_wkt_generator.generate(geom_)
623
632
  end
624
- @psych_wkt_writer.write(obj_)
625
633
  end
626
634
 
627
635
 
@@ -0,0 +1,112 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Various Geos-related internal utilities
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010-2012 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ module RGeo
38
+
39
+ module Geos
40
+
41
+
42
+ module Utils # :nodoc:
43
+
44
+ class << self
45
+
46
+
47
+ def ffi_coord_seqs_equal?(cs1_, cs2_, check_z_)
48
+ len1_ = cs1_.length
49
+ len2_ = cs2_.length
50
+ if len1_ == len2_
51
+ (0...len1_).each do |i_|
52
+ return false unless cs1_.get_x(i_) == cs2_.get_x(i_) &&
53
+ cs1_.get_y(i_) == cs2_.get_y(i_) &&
54
+ (!check_z_ || cs1_.get_z(i_) == cs2_.get_z(i_))
55
+ end
56
+ true
57
+ else
58
+ false
59
+ end
60
+ end
61
+
62
+
63
+ def ffi_compute_dimension(geom_)
64
+ result_ = -1
65
+ case geom_.type_id
66
+ when ::Geos::GeomTypes::GEOS_POINT
67
+ result_ = 0
68
+ when ::Geos::GeomTypes::GEOS_MULTIPOINT
69
+ result_ = 0 unless geom_.empty?
70
+ when ::Geos::GeomTypes::GEOS_LINESTRING, ::Geos::GeomTypes::GEOS_LINEARRING
71
+ result_ = 1
72
+ when ::Geos::GeomTypes::GEOS_MULTILINESTRING
73
+ result_ = 1 unless geom_.empty?
74
+ when ::Geos::GeomTypes::GEOS_POLYGON
75
+ result_ = 2
76
+ when ::Geos::GeomTypes::GEOS_MULTIPOLYGON
77
+ result_ = 2 unless geom_.empty?
78
+ when ::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION
79
+ geom_.each do |g_|
80
+ dim_ = ffi_compute_dimension(g_)
81
+ result_ = dim_ if result_ < dim_
82
+ end
83
+ end
84
+ result_
85
+ end
86
+
87
+
88
+ def _init
89
+ if FFI_SUPPORTED
90
+ @ffi_supports_prepared_level_1 = ::Geos::FFIGeos.respond_to?(:GEOSPreparedContains_r)
91
+ @ffi_supports_prepared_level_2 = ::Geos::FFIGeos.respond_to?(:GEOSPreparedDisjoint_r)
92
+ @ffi_supports_set_output_dimension = ::Geos::FFIGeos.respond_to?(:GEOSWKTWriter_setOutputDimension_r)
93
+ end
94
+ @psych_wkt_generator = WKRep::WKTGenerator.new(:convert_case => :upper)
95
+ @marshal_wkb_generator = WKRep::WKBGenerator.new
96
+ end
97
+
98
+ attr_reader :ffi_supports_prepared_level_1
99
+ attr_reader :ffi_supports_prepared_level_2
100
+ attr_reader :ffi_supports_set_output_dimension
101
+ attr_reader :psych_wkt_generator
102
+ attr_reader :marshal_wkb_generator
103
+
104
+
105
+ end
106
+
107
+ end
108
+
109
+
110
+ end
111
+
112
+ end
@@ -48,9 +48,9 @@ module RGeo
48
48
  @factory = create_factory
49
49
  point1_ = @factory.point(0, 0)
50
50
  point2_ = @factory.point(1, 0)
51
- point3_ = @factory.point(-4, 2)
52
- point4_ = @factory.point(-5, 3)
53
- point5_ = @factory.point(-3, 5)
51
+ point3_ = @factory.point(-4, 2) # (-4, 2)
52
+ point4_ = @factory.point(-7, 6) # (-5, 3)
53
+ point5_ = @factory.point(5, 11) # (-3, 5)
54
54
  @linestring1 = @factory.line_string([point1_, point2_])
55
55
  @linestring2 = @factory.line_string([point3_, point4_, point5_])
56
56
  @linearring1 = @factory.linear_ring([point5_, point3_, point4_, point5_])
@@ -137,7 +137,7 @@ module RGeo
137
137
 
138
138
 
139
139
  def test_wkt_creation_simple
140
- parsed_geom_ = @factory.parse_wkt('MULTILINESTRING((0 0, 1 0), (-4 2, -5 3, -3 5))')
140
+ parsed_geom_ = @factory.parse_wkt('MULTILINESTRING((0 0, 1 0), (-4 2, -7 6, 5 11))')
141
141
  built_geom_ = @factory.multi_line_string([@linestring1, @linestring2])
142
142
  assert(built_geom_.eql?(parsed_geom_))
143
143
  end
@@ -210,6 +210,14 @@ module RGeo
210
210
  end
211
211
 
212
212
 
213
+ def test_length
214
+ geom1_ = @factory.multi_line_string([@linestring1, @linestring2])
215
+ assert_equal(19, geom1_.length)
216
+ geom2_ = @factory.multi_line_string([])
217
+ assert_equal(0, geom2_.length)
218
+ end
219
+
220
+
213
221
  end
214
222
 
215
223
  end
@@ -81,7 +81,9 @@ module RGeo
81
81
 
82
82
 
83
83
  def _assert_close_enough(a_, b_)
84
- assert_in_delta(a_, b_, ::Math.sqrt(a_*a_+b_*b_)*0.00000001)
84
+ delta_ = ::Math.sqrt(a_*a_+b_*b_)*0.00000001
85
+ delta_ = 0.000000000001 if delta_ < 0.000000000001
86
+ assert_in_delta(a_, b_, delta_)
85
87
  end
86
88
 
87
89
 
@@ -55,6 +55,9 @@ module RGeo
55
55
  include ::RGeo::Tests::Common::MultiLineStringTests
56
56
 
57
57
 
58
+ undef_method :test_length
59
+
60
+
58
61
  end
59
62
 
60
63
  end
@@ -55,6 +55,9 @@ module RGeo
55
55
  include ::RGeo::Tests::Common::MultiLineStringTests
56
56
 
57
57
 
58
+ undef_method :test_length
59
+
60
+
58
61
  end
59
62
 
60
63
  end
@@ -58,6 +58,7 @@ module RGeo
58
58
  undef_method :test_fully_equal
59
59
  undef_method :test_geometrically_equal
60
60
  undef_method :test_not_equal
61
+ undef_method :test_length
61
62
 
62
63
 
63
64
  end
@@ -0,0 +1,121 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Tests for basic GeoJSON usage
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010-2012 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ require 'test/unit'
38
+ require 'rgeo'
39
+
40
+
41
+ module RGeo
42
+ module Tests # :nodoc:
43
+
44
+ class TestCartesianBBox < ::Test::Unit::TestCase # :nodoc:
45
+
46
+
47
+ def setup
48
+ @factory = ::RGeo::Cartesian.factory
49
+ end
50
+
51
+
52
+ def test_empty_bbox
53
+ bbox_ = ::RGeo::Cartesian::BoundingBox.new(@factory)
54
+ assert_equal(true, bbox_.empty?)
55
+ assert_equal(false, bbox_.has_z)
56
+ assert_nil(bbox_.min_x)
57
+ assert_equal(@factory, bbox_.factory)
58
+ assert_nil(bbox_.min_point)
59
+ assert_equal(true, bbox_.to_geometry.is_empty?)
60
+ assert_equal(true, bbox_.contains?(bbox_))
61
+ assert_equal(false, bbox_.contains?(@factory.point(1, 1)))
62
+ end
63
+
64
+
65
+ def test_point_bbox
66
+ empty_bbox_ = ::RGeo::Cartesian::BoundingBox.new(@factory)
67
+ bbox_ = ::RGeo::Cartesian::BoundingBox.new(@factory)
68
+ bbox_.add(@factory.point(1, 1))
69
+ assert_equal(false, bbox_.empty?)
70
+ assert_equal(false, bbox_.has_z)
71
+ assert_equal(1.0, bbox_.min_x)
72
+ assert_equal(1.0, bbox_.min_y)
73
+ assert_equal(1.0, bbox_.max_x)
74
+ assert_equal(1.0, bbox_.max_y)
75
+ assert_equal(@factory, bbox_.factory)
76
+ assert_equal(@factory.point(1, 1), bbox_.min_point)
77
+ assert_equal(@factory.point(1, 1), bbox_.max_point)
78
+ assert_equal(@factory.point(1, 1), bbox_.to_geometry)
79
+ assert_equal(true, bbox_.contains?(empty_bbox_))
80
+ assert_equal(false, empty_bbox_.contains?(bbox_))
81
+ assert_equal(true, bbox_.contains?(@factory.point(1, 1)))
82
+ assert_equal(false, bbox_.contains?(@factory.point(2, 1)))
83
+ end
84
+
85
+
86
+ def test_rect_bbox
87
+ empty_bbox_ = ::RGeo::Cartesian::BoundingBox.new(@factory)
88
+ bbox_ = ::RGeo::Cartesian::BoundingBox.new(@factory)
89
+ bbox_.add(@factory.point(1, 4))
90
+ bbox_.add(@factory.point(2, 3))
91
+ assert_equal(false, bbox_.empty?)
92
+ assert_equal(false, bbox_.has_z)
93
+ assert_equal(1.0, bbox_.min_x)
94
+ assert_equal(3.0, bbox_.min_y)
95
+ assert_equal(2.0, bbox_.max_x)
96
+ assert_equal(4.0, bbox_.max_y)
97
+ assert_equal(@factory, bbox_.factory)
98
+ assert_equal(@factory.point(1, 3), bbox_.min_point)
99
+ assert_equal(@factory.point(2, 4), bbox_.max_point)
100
+ assert_equal(1.0, bbox_.to_geometry.area)
101
+ assert_equal(true, bbox_.contains?(empty_bbox_))
102
+ assert_equal(false, empty_bbox_.contains?(bbox_))
103
+ assert_equal(true, bbox_.contains?(@factory.point(1, 3)))
104
+ assert_equal(false, bbox_.contains?(@factory.point(2, 1)))
105
+ end
106
+
107
+
108
+ def test_bbox_from_points
109
+ bbox_ = ::RGeo::Cartesian::BoundingBox.new(@factory)
110
+ bbox_.add(@factory.point(1, 4))
111
+ bbox_.add(@factory.point(2, 3))
112
+ bbox2_ = ::RGeo::Cartesian::BoundingBox.create_from_points(
113
+ @factory.point(2, 3), @factory.point(1, 4))
114
+ assert_equal(bbox_, bbox2_)
115
+ end
116
+
117
+
118
+ end
119
+
120
+ end
121
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgeo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.8
4
+ version: 0.3.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-23 00:00:00.000000000 Z
12
+ date: 2012-04-11 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: RGeo is a geospatial data library for Ruby. It provides an implementation
15
15
  of the Open Geospatial Consortium's Simple Features Specification, used by most
@@ -80,6 +80,7 @@ files:
80
80
  - lib/rgeo/geos/ffi_factory.rb
81
81
  - lib/rgeo/geos/impl_additions.rb
82
82
  - lib/rgeo/geos/interface.rb
83
+ - lib/rgeo/geos/utils.rb
83
84
  - lib/rgeo/geos/zm_factory.rb
84
85
  - lib/rgeo/geos/zm_impl.rb
85
86
  - lib/rgeo/geos.rb
@@ -188,6 +189,7 @@ files:
188
189
  - test/spherical_geographic/tc_point.rb
189
190
  - test/spherical_geographic/tc_polygon.rb
190
191
  - test/tc_cartesian_analysis.rb
192
+ - test/tc_cartesian_bbox.rb
191
193
  - test/tc_mixins.rb
192
194
  - test/tc_oneoff.rb
193
195
  - test/tc_types.rb
@@ -288,6 +290,7 @@ test_files:
288
290
  - test/spherical_geographic/tc_point.rb
289
291
  - test/spherical_geographic/tc_polygon.rb
290
292
  - test/tc_cartesian_analysis.rb
293
+ - test/tc_cartesian_bbox.rb
291
294
  - test/tc_mixins.rb
292
295
  - test/tc_oneoff.rb
293
296
  - test/tc_types.rb