rgeo 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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