rgeo 0.3.4 → 0.3.5

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.
@@ -1,3 +1,9 @@
1
+ === 0.3.5 / 2012-02-27
2
+
3
+ * Reworked the terminology on equivalence levels. The documentation now names the three levels "spatial", "representational", and "objective" equivalence.
4
+ * Some geometry implementations didn't implement the == operator, resulting in various problems, including inability to set ActiveRecord attributes when using an implementation (such as simple_spherical polygons) that doesn't provide spatial equivalence tests. Fixed. The interfaces now specify that all implementations must implement the == operator and the eql? method, and should degrade to stronger forms of equivalence if weaker forms are not available. (Reported by Phil Murray.)
5
+ * Added Geometry#rep_equals? to test representational equivalence without the fallback behavior of Geometry#eql?
6
+
1
7
  === 0.3.4 / 2012-02-21
2
8
 
3
9
  * The FFI-GEOS implementation now uses prepared geometries.
@@ -26,8 +26,7 @@ Use the core *rgeo* gem to:
26
26
  Several optional modules are currently available:
27
27
 
28
28
  * Generate and interpret GeoJSON data for communication with common
29
- location-based web services such as SimpleGeo, using the
30
- <b>rgeo-geojson</b> gem.
29
+ location-based web services using the <b>rgeo-geojson</b> gem.
31
30
  * Read GIS datasets from ESRI shapefiles using the <b>rgeo-shapefile</b>
32
31
  gem.
33
32
  * Extend ActiveRecord to handle spatial data in MySQL Spatial, SpatiaLite,
@@ -101,7 +100,8 @@ The RGeo suite of tools is evolving rapidly. The current to-do list for
101
100
  the core library includes:
102
101
 
103
102
  * YAML and Marshal serialization support across all major entities.
104
- * Better JRuby support.
103
+ * Full JRuby support.
104
+ * Better error handling and reporting.
105
105
  * Ellipsoidal geography implementation, possibly utilizing geographiclib.
106
106
  * Windows build support.
107
107
 
@@ -110,7 +110,7 @@ we are planning on introducing more add-on modules, including:
110
110
 
111
111
  * GeoRSS and KML format support.
112
112
  * Integration with third-party APIs.
113
- * Possible additional ActiveRecord adapters.
113
+ * Possible additional ActiveRecord adapters (esp. JDBC adapters)
114
114
 
115
115
  === Development and support
116
116
 
@@ -130,7 +130,7 @@ Contact the author at dazuma at gmail dot com.
130
130
 
131
131
  RGeo is written by Daniel Azuma (http://www.daniel-azuma.com).
132
132
 
133
- Development of RGeo is sponsored by GeoPage, Inc. (http://www.geopage.com).
133
+ Development is supported by Pirq. (http://www.pirq.com).
134
134
 
135
135
  RGeo calls the GEOS library to handle most Cartesian geometric
136
136
  calculations, and the Proj4 library to handle projections and coordinate
@@ -143,7 +143,7 @@ gems, by J Smith (http://github.com/dark-panda).
143
143
 
144
144
  === License
145
145
 
146
- Copyright 2010-2011 Daniel Azuma
146
+ Copyright 2010-2012 Daniel Azuma
147
147
 
148
148
  All rights reserved.
149
149
 
@@ -186,23 +186,23 @@ I do not have space here to describe the different comparison operations in deta
186
186
  b = "foo"
187
187
  a == b # => true
188
188
  a.eql?(b) # => true
189
- a.equals?(b) # => false (because they are different objects)
190
- a.equals?(a) # => true
189
+ a.equal?(b) # => false (because they are different objects)
190
+ a.equal?(a) # => true
191
191
 
192
- In general, Ruby has three forms of equality: value equality (tested by the <tt>==</tt> operator), object equality (tested by the <tt>eql?</tt> method), and object identity (tested by the <tt>equals?</tt> method).
192
+ In general, Ruby has three forms of equality: value equality (tested by the <tt>==</tt> operator), object equality (tested by the <tt>eql?</tt> method), and object identity (tested by the <tt>equal?</tt> method).
193
193
 
194
- Similarly, \RGeo's equality checking comes in several forms: geometric equality, object equality, and object identity. Geometric equality is tested by the SFS method <tt>equal?</tt>, as well as the <tt>==</tt> operator. This type of equality indicates two objects that may be different representations of the same geometry, for example, a LineString and its reverse, or a Point and a MultiPoint that contains only that same point. Object equality, tested by <tt>eql?</tt>, means the same representation but possibly distinct objects. Object identity, tested by <tt>equals?</tt>, represents the same object, as with other Ruby types.
194
+ Similarly, \RGeo's equality checking comes in several forms: geometric equality, representational equality, and object identity. Geometric equality is tested by the SFS method <tt>equals?</tt>, as well as the <tt>==</tt> operator. This type of equality indicates two objects that may be different representations of the same geometry, for example, a LineString and its reverse, or a Point and a MultiPoint that contains only that same point. Representational equality, tested by <tt>eql?</tt>, means the same representation but possibly distinct objects. Object identity, tested by <tt>equal?</tt>, represents the same object, as with other Ruby types.
195
195
 
196
196
  p1 = factory.point(1, 1)
197
197
  p2 = factory.point(1, 1)
198
198
  mp = factory.multi_point([p1])
199
199
  p1 == p2 # => true
200
- p1.equal?(mp) # => true
200
+ p1.equals?(mp) # => true
201
201
  p1 == mp # => true
202
202
  p1.eql?(mp) # => false
203
203
  p1.eql?(p2) # => true
204
- p1.equals?(p2) # => false
205
- p1.equals?(p1) # => true
204
+ p1.equal?(p2) # => false
205
+ p1.equal?(p1) # => true
206
206
 
207
207
  === 3.3. Binary Spatial Operations
208
208
 
data/Version CHANGED
@@ -1 +1 @@
1
- 0.3.4
1
+ 0.3.5
@@ -969,6 +969,7 @@ void rgeo_init_geos_geometry(RGeo_Globals* globals)
969
969
  rb_define_method(geos_geometry_class, "is_simple?", method_geometry_is_simple, 0);
970
970
  rb_define_method(geos_geometry_class, "equals?", method_geometry_equals, 1);
971
971
  rb_define_method(geos_geometry_class, "==", method_geometry_equals, 1);
972
+ rb_define_method(geos_geometry_class, "rep_equals?", method_geometry_eql, 1);
972
973
  rb_define_method(geos_geometry_class, "eql?", method_geometry_eql, 1);
973
974
  rb_define_method(geos_geometry_class, "disjoint?", method_geometry_disjoint, 1);
974
975
  rb_define_method(geos_geometry_class, "intersects?", method_geometry_intersects, 1);
@@ -492,6 +492,7 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
492
492
  // Methods for GeometryCollectionImpl
493
493
  rb_define_module_function(geos_geometry_collection_class, "create", cmethod_geometry_collection_create, 2);
494
494
  rb_include_module(geos_geometry_collection_class, rb_define_module("Enumerable"));
495
+ rb_define_method(geos_geometry_collection_class, "rep_equals?", method_geometry_collection_eql, 1);
495
496
  rb_define_method(geos_geometry_collection_class, "eql?", method_geometry_collection_eql, 1);
496
497
  rb_define_method(geos_geometry_collection_class, "geometry_type", method_geometry_collection_geometry_type, 0);
497
498
  rb_define_method(geos_geometry_collection_class, "num_geometries", method_geometry_collection_num_geometries, 0);
@@ -569,6 +569,7 @@ void rgeo_init_geos_line_string(RGeo_Globals* globals)
569
569
 
570
570
  rb_define_module_function(geos_line_string_class, "create", cmethod_create_line_string, 2);
571
571
  rb_define_module_function(geos_line_string_class, "_copy_from", cmethod_line_string_copy_from, 2);
572
+ rb_define_method(geos_line_string_class, "rep_equals?", method_line_string_eql, 1);
572
573
  rb_define_method(geos_line_string_class, "eql?", method_line_string_eql, 1);
573
574
  rb_define_method(geos_line_string_class, "geometry_type", method_line_string_geometry_type, 0);
574
575
  rb_define_method(geos_line_string_class, "length", method_line_string_length, 0);
@@ -185,6 +185,7 @@ void rgeo_init_geos_point(RGeo_Globals* globals)
185
185
 
186
186
  rb_define_module_function(geos_point_class, "create", cmethod_create, 4);
187
187
 
188
+ rb_define_method(geos_point_class, "rep_equals?", method_point_eql, 1);
188
189
  rb_define_method(geos_point_class, "eql?", method_point_eql, 1);
189
190
  rb_define_method(geos_point_class, "geometry_type", method_point_geometry_type, 0);
190
191
  rb_define_method(geos_point_class, "x", method_point_x, 0);
@@ -284,6 +284,7 @@ void rgeo_init_geos_polygon(RGeo_Globals* globals)
284
284
 
285
285
  rb_define_module_function(geos_polygon_class, "create", cmethod_create, 3);
286
286
 
287
+ rb_define_method(geos_polygon_class, "rep_equals?", method_polygon_eql, 1);
287
288
  rb_define_method(geos_polygon_class, "eql?", method_polygon_eql, 1);
288
289
  rb_define_method(geos_polygon_class, "geometry_type", method_polygon_geometry_type, 0);
289
290
  rb_define_method(geos_polygon_class, "area", method_polygon_area, 0);
@@ -78,25 +78,37 @@ module RGeo
78
78
  # As a general rule, objects must have factories that are
79
79
  # Factory#eql? in order to be spatially equivalent.
80
80
  #
81
- # * <b>Objective equivalence</b> is a stronger form of equivalence,
82
- # indicating that the objects are the same representation, but may
83
- # be different objects. All objectively equivalent objects are
81
+ # * <b>Representational equivalence</b> is a stronger form, indicating
82
+ # that the objects have the same representation, but may be
83
+ # different objects. All representationally equivalent objects are
84
84
  # spatially equivalent, but not all spatially equivalent objects are
85
- # objectively equivalent. For example, none of the examples in the
86
- # spatial equivalence section above are objectively equivalent.
87
- # However, two separate objects that both represent POINT(1 2) are
88
- # objectively equivalent as well as spatially equivalent.
85
+ # representationally equivalent. For example, none of the examples
86
+ # in the spatial equivalence section above are representationally
87
+ # equivalent. However, two separate objects that both represent
88
+ # POINT(1 2) are representationally equivalent as well as spatially
89
+ # equivalent.
89
90
  #
90
- # * <b>Objective identity</b> is the strongest form, indicating that
91
- # the references refer to the same object. Of course, all pairs of
92
- # references with the same objective identity are both objectively
93
- # equivalent and spatially equivalent.
91
+ # * <b>Objective equivalence</b> is the strongest form, indicating
92
+ # that the references refer to the same object. Of course, all
93
+ # pairs of references with the same objective identity are also
94
+ # both representationally and spatially equivalent.
94
95
  #
95
96
  # Different methods test for different types of equivalence:
96
97
  #
97
98
  # * <tt>equals?</tt> and <tt>==</tt> test for spatial equivalence.
98
- # * <tt>eql?</tt> tests for objective equivalence.
99
- # * <tt>equal?</tt> tests for objective identity.
99
+ # * <tt>rep_equals?</tt> and <tt>eql?</tt> test for representational
100
+ # equivalence.
101
+ # * <tt>equal?</tt> tests for objective equivalence.
102
+ #
103
+ # All ruby objects must provide a suitable test for objective
104
+ # equivalence. Normally, this is simply provided by the Ruby Object
105
+ # base class. Geometry implementations should normally also provide
106
+ # tests for representational and spatial equivalence, if possible.
107
+ # The <tt>==</tt> operator and the <tt>eql?</tt> method are standard
108
+ # Ruby methods that are often expected to be usable for every object.
109
+ # Therefore, if an implementation cannot provide a suitable test for
110
+ # their equivalence types, they must degrade to use a stronger form
111
+ # of equivalence.
100
112
 
101
113
  module Geometry
102
114
 
@@ -115,14 +127,6 @@ module RGeo
115
127
  end
116
128
 
117
129
 
118
- # Returns true if this geometric object is objectively equivalent
119
- # to the given object.
120
-
121
- def eql?(another_geometry_)
122
- raise Error::UnsupportedOperation, "Method Geometry#eql? not defined."
123
- end
124
-
125
-
126
130
  # === SFS 1.1 Description
127
131
  #
128
132
  # The inherent dimension of this geometric object, which must be less
@@ -279,7 +283,7 @@ module RGeo
279
283
  # Although implementations are free to attempt to handle
280
284
  # another_geometry values that do not share the same factory as
281
285
  # this geometry, strictly speaking, the result of comparing objects
282
- # of different factories is undefined.
286
+ # from different factories is undefined.
283
287
 
284
288
  def equals?(another_geometry_)
285
289
  raise Error::UnsupportedOperation, "Method Geometry#equals? not defined."
@@ -299,7 +303,7 @@ module RGeo
299
303
  # Although implementations are free to attempt to handle
300
304
  # another_geometry values that do not share the same factory as
301
305
  # this geometry, strictly speaking, the result of comparing objects
302
- # of different factories is undefined.
306
+ # from different factories is undefined.
303
307
 
304
308
  def disjoint?(another_geometry_)
305
309
  raise Error::UnsupportedOperation, "Method Geometry#disjoint? not defined."
@@ -319,7 +323,7 @@ module RGeo
319
323
  # Although implementations are free to attempt to handle
320
324
  # another_geometry values that do not share the same factory as
321
325
  # this geometry, strictly speaking, the result of comparing objects
322
- # of different factories is undefined.
326
+ # from different factories is undefined.
323
327
 
324
328
  def intersects?(another_geometry_)
325
329
  raise Error::UnsupportedOperation, "Method Geometry#intersects? not defined."
@@ -339,7 +343,7 @@ module RGeo
339
343
  # Although implementations are free to attempt to handle
340
344
  # another_geometry values that do not share the same factory as
341
345
  # this geometry, strictly speaking, the result of comparing objects
342
- # of different factories is undefined.
346
+ # from different factories is undefined.
343
347
 
344
348
  def touches?(another_geometry_)
345
349
  raise Error::UnsupportedOperation, "Method Geometry#touches? not defined."
@@ -359,7 +363,7 @@ module RGeo
359
363
  # Although implementations are free to attempt to handle
360
364
  # another_geometry values that do not share the same factory as
361
365
  # this geometry, strictly speaking, the result of comparing objects
362
- # of different factories is undefined.
366
+ # from different factories is undefined.
363
367
 
364
368
  def crosses?(another_geometry_)
365
369
  raise Error::UnsupportedOperation, "Method Geometry#crosses? not defined."
@@ -379,7 +383,7 @@ module RGeo
379
383
  # Although implementations are free to attempt to handle
380
384
  # another_geometry values that do not share the same factory as
381
385
  # this geometry, strictly speaking, the result of comparing objects
382
- # of different factories is undefined.
386
+ # from different factories is undefined.
383
387
 
384
388
  def within?(another_geometry_)
385
389
  raise Error::UnsupportedOperation, "Method Geometry#within? not defined."
@@ -399,7 +403,7 @@ module RGeo
399
403
  # Although implementations are free to attempt to handle
400
404
  # another_geometry values that do not share the same factory as
401
405
  # this geometry, strictly speaking, the result of comparing objects
402
- # of different factories is undefined.
406
+ # from different factories is undefined.
403
407
 
404
408
  def contains?(another_geometry_)
405
409
  raise Error::UnsupportedOperation, "Method Geometry#contains? not defined."
@@ -419,7 +423,7 @@ module RGeo
419
423
  # Although implementations are free to attempt to handle
420
424
  # another_geometry values that do not share the same factory as
421
425
  # this geometry, strictly speaking, the result of comparing objects
422
- # of different factories is undefined.
426
+ # from different factories is undefined.
423
427
 
424
428
  def overlaps?(another_geometry_)
425
429
  raise Error::UnsupportedOperation, "Method Geometry#overlaps? not defined."
@@ -446,7 +450,7 @@ module RGeo
446
450
  # Although implementations are free to attempt to handle
447
451
  # another_geometry values that do not share the same factory as
448
452
  # this geometry, strictly speaking, the result of comparing objects
449
- # of different factories is undefined.
453
+ # from different factories is undefined.
450
454
 
451
455
  def relate(another_geometry_, intersection_pattern_matrix_)
452
456
  raise Error::UnsupportedOperation, "Method Geometry#relate not defined."
@@ -466,7 +470,7 @@ module RGeo
466
470
  # Although implementations are free to attempt to handle
467
471
  # another_geometry values that do not share the same factory as
468
472
  # this geometry, strictly speaking, the result of measuring the
469
- # distance between objects of different factories is undefined.
473
+ # distance between objects from different factories is undefined.
470
474
 
471
475
  def distance(another_geometry_)
472
476
  raise Error::UnsupportedOperation, "Method Geometry#distance not defined."
@@ -515,7 +519,7 @@ module RGeo
515
519
  # Although implementations are free to attempt to handle
516
520
  # another_geometry values that do not share the same factory as
517
521
  # this geometry, strictly speaking, the result of performing
518
- # operations on objects of different factories is undefined.
522
+ # operations on objects from different factories is undefined.
519
523
 
520
524
  def intersection(another_geometry_)
521
525
  raise Error::UnsupportedOperation, "Method Geometry#intersection not defined."
@@ -534,7 +538,7 @@ module RGeo
534
538
  # Although implementations are free to attempt to handle
535
539
  # another_geometry values that do not share the same factory as
536
540
  # this geometry, strictly speaking, the result of performing
537
- # operations on objects of different factories is undefined.
541
+ # operations on objects from different factories is undefined.
538
542
 
539
543
  def union(another_geometry_)
540
544
  raise Error::UnsupportedOperation, "Method Geometry#union not defined."
@@ -553,7 +557,7 @@ module RGeo
553
557
  # Although implementations are free to attempt to handle
554
558
  # another_geometry values that do not share the same factory as
555
559
  # this geometry, strictly speaking, the result of performing
556
- # operations on objects of different factories is undefined.
560
+ # operations on objects from different factories is undefined.
557
561
 
558
562
  def difference(another_geometry_)
559
563
  raise Error::UnsupportedOperation, "Method Geometry#difference not defined."
@@ -572,21 +576,78 @@ module RGeo
572
576
  # Although implementations are free to attempt to handle
573
577
  # another_geometry values that do not share the same factory as
574
578
  # this geometry, strictly speaking, the result of performing
575
- # operations on objects of different factories is undefined.
579
+ # operations on objects from different factories is undefined.
576
580
 
577
581
  def sym_difference(another_geometry_)
578
582
  raise Error::UnsupportedOperation, "Method Geometry#sym_difference not defined."
579
583
  end
580
584
 
581
585
 
582
- # This operator should behave almost the same as the equals? method.
583
- # The difference is that the == operator is required to handle rhs
584
- # values that are not geometry objects (returning false in such cases)
585
- # in order to fulfill the standard Ruby contract for the == operator,
586
- # whereas the equals? method may assume that any rhs is a geometry.
586
+ # Returns true if this geometric object is representationally
587
+ # equivalent to the given object.
588
+ #
589
+ # Although implementations are free to attempt to handle
590
+ # another_geometry values that do not share the same factory as
591
+ # this geometry, strictly speaking, the result of comparing objects
592
+ # from different factories is undefined.
593
+
594
+ def rep_equals?(another_geometry_)
595
+ raise Error::UnsupportedOperation, "Method Geometry#rep_equals? not defined."
596
+ end
597
+
598
+
599
+ # This method should behave almost the same as the rep_equals?
600
+ # method, with two key differences.
601
+ #
602
+ # First, the <tt>eql?</tt> method is required to handle rhs values
603
+ # that are not geometry objects (returning false in such cases) in
604
+ # order to fulfill the standard Ruby contract for the method,
605
+ # whereas the rep_equals? method may assume that any rhs is a
606
+ # geometry.
607
+ #
608
+ # Second, the <tt>eql?</tt> method should always be defined. That
609
+ # is, it should never raise Error::UnsupportedOperation. In cases
610
+ # where the underlying implementation cannot provide a
611
+ # representational equivalence test, this method must fall back on
612
+ # objective equivalence.
613
+
614
+ def eql?(rhs_)
615
+ if rhs_.kind_of?(::RGeo::Feature::Instance)
616
+ begin
617
+ rep_equals?(rhs_)
618
+ rescue Error::UnsupportedOperation
619
+ equal?(rhs_)
620
+ end
621
+ else
622
+ false
623
+ end
624
+ end
625
+
626
+
627
+ # This operator should behave almost the same as the equals? method,
628
+ # with two key differences.
629
+ #
630
+ # First, the == operator is required to handle rhs values that are
631
+ # not geometry objects (returning false in such cases) in order to
632
+ # fulfill the standard Ruby contract for the == operator, whereas
633
+ # the equals? method may assume that any rhs is a geometry.
634
+ #
635
+ # Second, the == operator should always be defined. That is, it
636
+ # should never raise Error::UnsupportedOperation. In cases where
637
+ # the underlying implementation cannot provide a spatial equivalence
638
+ # test, the == operator must fall back on representational or
639
+ # objective equivalence.
587
640
 
588
641
  def ==(rhs_)
589
- rhs_.kind_of?(::RGeo::Feature::Instance) ? equals?(rhs_) : false
642
+ if rhs_.kind_of?(::RGeo::Feature::Instance)
643
+ begin
644
+ equals?(rhs_)
645
+ rescue Error::UnsupportedOperation
646
+ eql?(rhs_)
647
+ end
648
+ else
649
+ false
650
+ end
590
651
  end
591
652
 
592
653
 
@@ -164,21 +164,6 @@ module RGeo
164
164
  end
165
165
 
166
166
 
167
- def _request_prepared # :nodoc:
168
- case @_fg_prep
169
- when 0
170
- nil
171
- when 1
172
- @_fg_prep = 2
173
- nil
174
- when 2
175
- @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom)
176
- else
177
- @_fg_prep
178
- end
179
- end
180
-
181
-
182
167
  def envelope
183
168
  fg_geom_ = @fg_geom.envelope
184
169
  # GEOS returns an "empty" point for an empty collection's envelope.
@@ -359,6 +344,11 @@ module RGeo
359
344
  end
360
345
 
361
346
 
347
+ def eql?(rhs_)
348
+ rep_equals?(rhs_)
349
+ end
350
+
351
+
362
352
  def _detach_fg_geom # :nodoc:
363
353
  fg_ = @fg_geom
364
354
  @fg_geom = nil
@@ -366,6 +356,21 @@ module RGeo
366
356
  end
367
357
 
368
358
 
359
+ def _request_prepared # :nodoc:
360
+ case @_fg_prep
361
+ when 0
362
+ nil
363
+ when 1
364
+ @_fg_prep = 2
365
+ nil
366
+ when 2
367
+ @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom)
368
+ else
369
+ @_fg_prep
370
+ end
371
+ end
372
+
373
+
369
374
  end
370
375
 
371
376
 
@@ -407,7 +412,7 @@ module RGeo
407
412
  end
408
413
 
409
414
 
410
- def eql?(rhs_)
415
+ def rep_equals?(rhs_)
411
416
  rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
412
417
  FFIUtils.coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
413
418
  end
@@ -483,7 +488,7 @@ module RGeo
483
488
  end
484
489
 
485
490
 
486
- def eql?(rhs_)
491
+ def rep_equals?(rhs_)
487
492
  rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
488
493
  FFIUtils.coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
489
494
  end
@@ -573,15 +578,15 @@ module RGeo
573
578
  end
574
579
 
575
580
 
576
- def eql?(rhs_)
581
+ def rep_equals?(rhs_)
577
582
  if rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
578
- rhs_.exterior_ring.eql?(self.exterior_ring)
583
+ rhs_.exterior_ring.rep_equals?(self.exterior_ring)
579
584
  then
580
585
  sn_ = @fg_geom.num_interior_rings
581
586
  rn_ = rhs_.num_interior_rings
582
587
  if sn_ == rn_
583
588
  sn_.times do |i_|
584
- return false unless interior_ring_n(i_).eql?(rhs_.interior_ring_n(i_))
589
+ return false unless interior_ring_n(i_).rep_equals?(rhs_.interior_ring_n(i_))
585
590
  end
586
591
  return true
587
592
  end
@@ -604,12 +609,12 @@ module RGeo
604
609
  end
605
610
 
606
611
 
607
- def eql?(rhs_)
612
+ def rep_equals?(rhs_)
608
613
  if rhs_.class == self.class && rhs_.factory.eql?(@factory)
609
614
  size_ = @fg_geom.num_geometries
610
615
  if size_ == rhs_.num_geometries
611
616
  size_.times do |n_|
612
- return false unless geometry_n(n_).eql?(rhs_.geometry_n(n_))
617
+ return false unless geometry_n(n_).rep_equals?(rhs_.geometry_n(n_))
613
618
  end
614
619
  return true
615
620
  end
@@ -75,11 +75,6 @@ module RGeo
75
75
  end
76
76
 
77
77
 
78
- def eql?(rhs_)
79
- rhs_.is_a?(self.class) && @factory.eql?(rhs_.factory) && @zgeometry.eql?(rhs_.z_geometry) && @mgeometry.eql?(rhs_.m_geometry)
80
- end
81
-
82
-
83
78
  def dimension
84
79
  @zgeometry.dimension
85
80
  end
@@ -205,7 +200,14 @@ module RGeo
205
200
  end
206
201
 
207
202
 
203
+ def rep_equals?(rhs_)
204
+ rhs_.is_a?(self.class) && @factory.eql?(rhs_.factory) && @zgeometry.rep_equals?(rhs_.z_geometry) && @mgeometry.rep_equals?(rhs_.m_geometry)
205
+ end
206
+
207
+
208
+ alias_method :eql?, :rep_equals?
208
209
  alias_method :==, :equals?
210
+
209
211
  alias_method :-, :difference
210
212
  alias_method :+, :union
211
213
  alias_method :*, :intersection
@@ -55,15 +55,6 @@ module RGeo
55
55
  end
56
56
 
57
57
 
58
- def eql?(rhs_)
59
- if rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @elements.size == rhs_.num_geometries
60
- rhs_.each_with_index{ |p_, i_| return false unless @elements[i_].eql?(p_) }
61
- else
62
- false
63
- end
64
- end
65
-
66
-
67
58
  def num_geometries
68
59
  @elements.size
69
60
  end
@@ -106,6 +97,15 @@ module RGeo
106
97
  end
107
98
 
108
99
 
100
+ def rep_equals?(rhs_)
101
+ if rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @elements.size == rhs_.num_geometries
102
+ rhs_.each_with_index{ |p_, i_| return false unless @elements[i_].rep_equals?(p_) }
103
+ else
104
+ false
105
+ end
106
+ end
107
+
108
+
109
109
  end
110
110
 
111
111
 
@@ -62,15 +62,6 @@ module RGeo
62
62
  end
63
63
 
64
64
 
65
- def eql?(rhs_)
66
- if rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @points.size == rhs_.num_points
67
- rhs_.points.each_with_index{ |p_, i_| return false unless @points[i_].eql?(p_) }
68
- else
69
- false
70
- end
71
- end
72
-
73
-
74
65
  def num_points
75
66
  @points.size
76
67
  end
@@ -133,6 +124,15 @@ module RGeo
133
124
  end
134
125
 
135
126
 
127
+ def rep_equals?(rhs_)
128
+ if rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @points.size == rhs_.num_points
129
+ rhs_.points.each_with_index{ |p_, i_| return false unless @points[i_].rep_equals?(p_) }
130
+ else
131
+ false
132
+ end
133
+ end
134
+
135
+
136
136
  end
137
137
 
138
138
 
@@ -75,11 +75,6 @@ module RGeo
75
75
  end
76
76
 
77
77
 
78
- def eql?(rhs_)
79
- rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @x == rhs_.x && @y == rhs_.y && @z == rhs_.z && @m == rhs_.m
80
- end
81
-
82
-
83
78
  def dimension
84
79
  0
85
80
  end
@@ -130,6 +125,11 @@ module RGeo
130
125
  end
131
126
 
132
127
 
128
+ def rep_equals?(rhs_)
129
+ rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @x == rhs_.x && @y == rhs_.y && @z == rhs_.z && @m == rhs_.m
130
+ end
131
+
132
+
133
133
  end
134
134
 
135
135
 
@@ -59,15 +59,6 @@ module RGeo
59
59
  end
60
60
 
61
61
 
62
- def eql?(rhs_)
63
- if rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @exterior_ring.eql?(rhs_.exterior_ring) && @interior_rings.size == rhs_.num_interior_rings
64
- rhs_.interior_rings.each_with_index{ |r_, i_| return false unless @interior_rings[i_].eql?(r_) }
65
- else
66
- false
67
- end
68
- end
69
-
70
-
71
62
  def exterior_ring
72
63
  @exterior_ring
73
64
  end
@@ -113,6 +104,15 @@ module RGeo
113
104
  end
114
105
 
115
106
 
107
+ def rep_equals?(rhs_)
108
+ if rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @exterior_ring.rep_equals?(rhs_.exterior_ring) && @interior_rings.size == rhs_.num_interior_rings
109
+ rhs_.interior_rings.each_with_index{ |r_, i_| return false unless @interior_rings[i_].rep_equals?(r_) }
110
+ else
111
+ false
112
+ end
113
+ end
114
+
115
+
116
116
  end
117
117
 
118
118
 
@@ -118,10 +118,18 @@ module RGeo
118
118
  end
119
119
 
120
120
 
121
- def test_fully_equal
121
+ def test_required_equivalences
122
122
  geom1_ = @factory.collection([@point1, @line1])
123
123
  geom2_ = @factory.collection([@point1, @line1])
124
124
  assert(geom1_.eql?(geom2_))
125
+ assert(geom1_ == geom2_)
126
+ end
127
+
128
+
129
+ def test_fully_equal
130
+ geom1_ = @factory.collection([@point1, @line1])
131
+ geom2_ = @factory.collection([@point1, @line1])
132
+ assert(geom1_.rep_equals?(geom2_))
125
133
  assert(geom1_.equals?(geom2_))
126
134
  end
127
135
 
@@ -129,7 +137,7 @@ module RGeo
129
137
  def test_geometrically_equal
130
138
  geom1_ = @factory.collection([@point2, @line2])
131
139
  geom2_ = @factory.collection([@point2, @line1, @line2])
132
- assert(!geom1_.eql?(geom2_))
140
+ assert(!geom1_.rep_equals?(geom2_))
133
141
  assert(geom1_.equals?(geom2_))
134
142
  end
135
143
 
@@ -137,7 +145,7 @@ module RGeo
137
145
  def test_empty_equal
138
146
  geom1_ = @factory.collection([])
139
147
  geom2_ = @factory.collection([])
140
- assert(geom1_.eql?(geom2_))
148
+ assert(geom1_.rep_equals?(geom2_))
141
149
  assert(geom1_.equals?(geom2_))
142
150
  end
143
151
 
@@ -145,7 +153,7 @@ module RGeo
145
153
  def test_not_equal
146
154
  geom1_ = @factory.collection([@point1, @line1])
147
155
  geom2_ = @factory.collection([@point2, @line1])
148
- assert(!geom1_.eql?(geom2_))
156
+ assert(!geom1_.rep_equals?(geom2_))
149
157
  assert(!geom1_.equals?(geom2_))
150
158
  end
151
159
 
@@ -151,7 +151,7 @@ module RGeo
151
151
  end
152
152
 
153
153
 
154
- def test_fully_equal
154
+ def test_required_equivalences
155
155
  point1_ = @factory.point(0, 0)
156
156
  point2_ = @factory.point(0, 1)
157
157
  point3_ = @factory.point(1, 0)
@@ -161,6 +161,20 @@ module RGeo
161
161
  point6_ = @factory.point(1, 0)
162
162
  line2_ = @factory.line_string([point4_, point5_, point6_])
163
163
  assert(line1_.eql?(line2_))
164
+ assert(line1_ == line2_)
165
+ end
166
+
167
+
168
+ def test_fully_equal
169
+ point1_ = @factory.point(0, 0)
170
+ point2_ = @factory.point(0, 1)
171
+ point3_ = @factory.point(1, 0)
172
+ line1_ = @factory.line_string([point1_, point2_, point3_])
173
+ point4_ = @factory.point(0, 0)
174
+ point5_ = @factory.point(0, 1)
175
+ point6_ = @factory.point(1, 0)
176
+ line2_ = @factory.line_string([point4_, point5_, point6_])
177
+ assert(line1_.rep_equals?(line2_))
164
178
  assert(line1_.equals?(line2_))
165
179
  end
166
180
 
@@ -172,7 +186,7 @@ module RGeo
172
186
  point4_ = @factory.point(0, 0)
173
187
  point5_ = @factory.point(0, 1)
174
188
  line2_ = @factory.line(point4_, point5_)
175
- assert(!line1_.eql?(line2_))
189
+ assert(!line1_.rep_equals?(line2_))
176
190
  assert(line1_.equals?(line2_))
177
191
  end
178
192
 
@@ -186,7 +200,7 @@ module RGeo
186
200
  point5_ = @factory.point(0, 1)
187
201
  point6_ = @factory.point(1, 0)
188
202
  line2_ = @factory.linear_ring([point4_, point5_, point6_, point4_])
189
- assert(!line1_.eql?(line2_))
203
+ assert(!line1_.rep_equals?(line2_))
190
204
  assert(line1_.equals?(line2_))
191
205
  end
192
206
 
@@ -200,7 +214,7 @@ module RGeo
200
214
  point5_ = @factory.point(0, 1)
201
215
  point6_ = @factory.point(1, 0)
202
216
  line2_ = @factory.line_string([point4_, point5_, point6_, point5_])
203
- assert(!line1_.eql?(line2_))
217
+ assert(!line1_.rep_equals?(line2_))
204
218
  assert(line1_.equals?(line2_))
205
219
  end
206
220
 
@@ -208,7 +222,7 @@ module RGeo
208
222
  def test_empty_equal
209
223
  line1_ = @factory.line_string([])
210
224
  line2_ = @factory.line_string([])
211
- assert(line1_.eql?(line2_))
225
+ assert(line1_.rep_equals?(line2_))
212
226
  assert(line1_.equals?(line2_))
213
227
  end
214
228
 
@@ -221,7 +235,7 @@ module RGeo
221
235
  point5_ = @factory.point(0, 1)
222
236
  point6_ = @factory.point(1, 0)
223
237
  line2_ = @factory.line_string([point4_, point5_, point6_])
224
- assert(!line1_.eql?(line2_))
238
+ assert(!line1_.rep_equals?(line2_))
225
239
  assert(!line1_.equals?(line2_))
226
240
  end
227
241
 
@@ -104,10 +104,18 @@ module RGeo
104
104
  end
105
105
 
106
106
 
107
- def test_fully_equal
107
+ def test_required_equivalences
108
108
  geom1_ = @factory.multi_line_string([@linestring1, @linestring2])
109
109
  geom2_ = @factory.multi_line_string([@linestring1, @linestring2])
110
110
  assert(geom1_.eql?(geom2_))
111
+ assert(geom1_ == geom2_)
112
+ end
113
+
114
+
115
+ def test_fully_equal
116
+ geom1_ = @factory.multi_line_string([@linestring1, @linestring2])
117
+ geom2_ = @factory.multi_line_string([@linestring1, @linestring2])
118
+ assert(geom1_.rep_equals?(geom2_))
111
119
  assert(geom1_.equals?(geom2_))
112
120
  end
113
121
 
@@ -115,7 +123,7 @@ module RGeo
115
123
  def test_geometrically_equal
116
124
  geom1_ = @factory.multi_line_string([@linestring1, @linestring2, @linearring1])
117
125
  geom2_ = @factory.multi_line_string([@line1, @linearring1])
118
- assert(!geom1_.eql?(geom2_))
126
+ assert(!geom1_.rep_equals?(geom2_))
119
127
  assert(geom1_.equals?(geom2_))
120
128
  end
121
129
 
@@ -123,7 +131,7 @@ module RGeo
123
131
  def test_not_equal
124
132
  geom1_ = @factory.multi_line_string([@linestring2])
125
133
  geom2_ = @factory.multi_line_string([@linearring1])
126
- assert(!geom1_.eql?(geom2_))
134
+ assert(!geom1_.rep_equals?(geom2_))
127
135
  assert(!geom1_.equals?(geom2_))
128
136
  end
129
137
 
@@ -96,10 +96,18 @@ module RGeo
96
96
  end
97
97
 
98
98
 
99
- def test_fully_equal
99
+ def test_required_equivalences
100
100
  geom1_ = @factory.multi_point([@point1, @point2])
101
101
  geom2_ = @factory.multi_point([@point1, @point2])
102
102
  assert(geom1_.eql?(geom2_))
103
+ assert(geom1_ == geom2_)
104
+ end
105
+
106
+
107
+ def test_fully_equal
108
+ geom1_ = @factory.multi_point([@point1, @point2])
109
+ geom2_ = @factory.multi_point([@point1, @point2])
110
+ assert(geom1_.rep_equals?(geom2_))
103
111
  assert(geom1_.equals?(geom2_))
104
112
  end
105
113
 
@@ -107,7 +115,7 @@ module RGeo
107
115
  def test_geometrically_equal
108
116
  geom1_ = @factory.multi_point([@point1, @point4])
109
117
  geom2_ = @factory.multi_point([@point1, @point4, @point5])
110
- assert(!geom1_.eql?(geom2_))
118
+ assert(!geom1_.rep_equals?(geom2_))
111
119
  assert(geom1_.equals?(geom2_))
112
120
  end
113
121
 
@@ -115,7 +123,7 @@ module RGeo
115
123
  def test_not_equal
116
124
  geom1_ = @factory.multi_point([@point1, @point2])
117
125
  geom2_ = @factory.multi_point([@point1])
118
- assert(!geom1_.eql?(geom2_))
126
+ assert(!geom1_.rep_equals?(geom2_))
119
127
  assert(!geom1_.equals?(geom2_))
120
128
  end
121
129
 
@@ -111,10 +111,18 @@ module RGeo
111
111
  end
112
112
 
113
113
 
114
- def test_equal
114
+ def test_required_equivalences
115
115
  geom1_ = @factory.multi_polygon([@poly1, @poly2])
116
116
  geom2_ = @factory.multi_polygon([@poly1, @poly2])
117
117
  assert(geom1_.eql?(geom2_))
118
+ assert(geom1_ == geom2_)
119
+ end
120
+
121
+
122
+ def test_equal
123
+ geom1_ = @factory.multi_polygon([@poly1, @poly2])
124
+ geom2_ = @factory.multi_polygon([@poly1, @poly2])
125
+ assert(geom1_.rep_equals?(geom2_))
118
126
  assert(geom1_.equals?(geom2_))
119
127
  end
120
128
 
@@ -122,7 +130,7 @@ module RGeo
122
130
  def test_not_equal
123
131
  geom1_ = @factory.multi_polygon([@poly1])
124
132
  geom2_ = @factory.multi_polygon([@poly2])
125
- assert(!geom1_.eql?(geom2_))
133
+ assert(!geom1_.rep_equals?(geom2_))
126
134
  assert(!geom1_.equals?(geom2_))
127
135
  end
128
136
 
@@ -153,9 +153,11 @@ module RGeo
153
153
  point3_ = @factory.point(13, 12)
154
154
  assert(point1_.equals?(point2_))
155
155
  assert(point1_ == point2_)
156
+ assert(point1_.rep_equals?(point2_))
156
157
  assert(point1_.eql?(point2_))
157
158
  assert(!point1_.equals?(point3_))
158
159
  assert(point1_ != point3_)
160
+ assert(!point1_.rep_equals?(point3_))
159
161
  assert(!point1_.eql?(point3_))
160
162
  assert(point1_ != 'hello')
161
163
  assert(!point1_.eql?('hello'))
@@ -82,7 +82,7 @@ module RGeo
82
82
  end
83
83
 
84
84
 
85
- def test_fully_equal
85
+ def test_required_equivalences
86
86
  point1_ = @factory.point(0, 0)
87
87
  point2_ = @factory.point(0, 1)
88
88
  point3_ = @factory.point(1, 0)
@@ -94,6 +94,22 @@ module RGeo
94
94
  exterior2_ = @factory.linear_ring([point4_, point5_, point6_, point4_])
95
95
  poly2_ = @factory.polygon(exterior2_)
96
96
  assert(poly1_.eql?(poly2_))
97
+ assert(poly1_ == poly2_)
98
+ end
99
+
100
+
101
+ def test_fully_equal
102
+ point1_ = @factory.point(0, 0)
103
+ point2_ = @factory.point(0, 1)
104
+ point3_ = @factory.point(1, 0)
105
+ exterior1_ = @factory.linear_ring([point1_, point2_, point3_, point1_])
106
+ poly1_ = @factory.polygon(exterior1_)
107
+ point4_ = @factory.point(0, 0)
108
+ point5_ = @factory.point(0, 1)
109
+ point6_ = @factory.point(1, 0)
110
+ exterior2_ = @factory.linear_ring([point4_, point5_, point6_, point4_])
111
+ poly2_ = @factory.polygon(exterior2_)
112
+ assert(poly1_.rep_equals?(poly2_))
97
113
  assert(poly1_.equals?(poly2_))
98
114
  end
99
115
 
@@ -106,7 +122,7 @@ module RGeo
106
122
  poly1_ = @factory.polygon(exterior1_)
107
123
  exterior2_ = @factory.linear_ring([point2_, point3_, point1_, point2_])
108
124
  poly2_ = @factory.polygon(exterior2_)
109
- assert(!poly1_.eql?(poly2_))
125
+ assert(!poly1_.rep_equals?(poly2_))
110
126
  assert(poly1_.equals?(poly2_))
111
127
  end
112
128
 
@@ -119,7 +135,7 @@ module RGeo
119
135
  poly1_ = @factory.polygon(exterior1_)
120
136
  exterior2_ = @factory.linear_ring([point1_, point3_, point2_, point1_])
121
137
  poly2_ = @factory.polygon(exterior2_)
122
- assert(!poly1_.eql?(poly2_))
138
+ assert(!poly1_.rep_equals?(poly2_))
123
139
  assert(poly1_.equals?(poly2_))
124
140
  end
125
141
 
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.4
4
+ version: 0.3.5
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-02-22 00:00:00.000000000 Z
12
+ date: 2012-02-27 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