rgeo 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ === 0.2.7 / 2011-04-09
2
+
3
+ * POSSIBLE INCOMPATIBLE CHANGE: GeometryCollection#geometry_n, Polygon#interior_ring_n, and LineString#point_n, in some implementations, allowed negative indexes (which counted backwards from the end of the collection as per Ruby arrays.) This was against the SFS interface, and so the behavior has been removed. However, GeometryCollection#[], because it is supposed to model Ruby arrays, now explicitly DOES allow negative indexes. This means GeometryCollection#[] is no longer exactly the same as GeometryCollection#geometry_n. These clarifications have also been made in the RDoc.
4
+ * The GEOS implementations of GeometryCollection#geometry_n and Polygon#interior_ring_n segfaulted when given an index out of bounds. Bounds Check Fail fixed. (Reported by sharpone74.)
5
+
1
6
  === 0.2.6 / 2011-03-31
2
7
 
3
8
  * Ring direction analysis crashed if any of the line segments were zero length. Fixed. (Reported by spara.)
data/README.rdoc CHANGED
@@ -70,17 +70,20 @@ Install RGeo as a gem:
70
70
  gem install rgeo
71
71
 
72
72
  Note: By default, the gem installation looks for the GEOS library in the
73
- following locations: <tt>/usr/local</tt>, <tt>/usr/local/geos</tt>, <tt>/opt/local</tt>, <tt>/opt/geos</tt>, <tt>/opt</tt>, <tt>/usr</tt>.
73
+ following locations: <tt>/usr/local</tt>, <tt>/usr/local/geos</tt>,
74
+ <tt>/opt/local</tt>, <tt>/opt/geos</tt>, <tt>/opt</tt>, <tt>/usr</tt>.
74
75
 
75
76
  If GEOS has been installed in a different location, you must provide its
76
77
  installation prefix directory using the "--with-geos-dir" option. This
77
- option must be preceded by "--" to separate it, as a build switch, from
78
- the switches interpreted by the gem command. For example:
78
+ option must be preceded by "<tt>--</tt>" to separate it, as a build
79
+ switch, from the switches interpreted by the gem command. For example:
79
80
 
80
81
  gem install rgeo -- --with-geos-dir=/path/to/my/geos/installation
81
82
 
82
83
  Similarly, the gem installation looks for the Proj4 library in the
83
- following locations by default: <tt>/usr/local</tt>, <tt>/usr/local/proj</tt>, <tt>/usr/local/proj4</tt>, <tt>/opt/local</tt>, <tt>/opt/proj</tt>, <tt>/opt/proj4</tt>, <tt>/opt</tt>, <tt>/usr</tt>.
84
+ following locations by default: <tt>/usr/local</tt>,
85
+ <tt>/usr/local/proj</tt>, <tt>/usr/local/proj4</tt>, <tt>/opt/local</tt>,
86
+ <tt>/opt/proj</tt>, <tt>/opt/proj4</tt>, <tt>/opt</tt>, <tt>/usr</tt>.
84
87
 
85
88
  If Proj4 is installed in a different location, you must provide its
86
89
  installation prefix directory using the "--with-proj-dir" option.
data/Version CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.2.7
@@ -183,7 +183,7 @@ static VALUE method_geometry_collection_num_geometries(VALUE self)
183
183
  }
184
184
 
185
185
 
186
- static VALUE method_geometry_collection_geometry_n(VALUE self, VALUE n)
186
+ static VALUE impl_geometry_n(VALUE self, VALUE n, char allow_negatives)
187
187
  {
188
188
  VALUE result = Qnil;
189
189
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
@@ -191,13 +191,35 @@ static VALUE method_geometry_collection_geometry_n(VALUE self, VALUE n)
191
191
  if (self_geom) {
192
192
  VALUE klasses = self_data->klasses;
193
193
  int i = NUM2INT(n);
194
- const GEOSGeometry* elem_geom = GEOSGetGeometryN_r(self_data->geos_context, self_geom, i);
195
- result = rgeo_wrap_geos_geometry_clone(self_data->factory, elem_geom, NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
194
+ if (allow_negatives || i >= 0) {
195
+ GEOSContextHandle_t self_context = self_data->geos_context;
196
+ int len = GEOSGetNumGeometries_r(self_context, self_geom);
197
+ if (i < 0) {
198
+ i += len;
199
+ }
200
+ if (i >= 0 && i < len) {
201
+ result = rgeo_wrap_geos_geometry_clone(self_data->factory,
202
+ GEOSGetGeometryN_r(self_context, self_geom, i),
203
+ NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
204
+ }
205
+ }
196
206
  }
197
207
  return result;
198
208
  }
199
209
 
200
210
 
211
+ static VALUE method_geometry_collection_geometry_n(VALUE self, VALUE n)
212
+ {
213
+ impl_geometry_n(self, n, 0);
214
+ }
215
+
216
+
217
+ static VALUE method_geometry_collection_brackets(VALUE self, VALUE n)
218
+ {
219
+ impl_geometry_n(self, n, 1);
220
+ }
221
+
222
+
201
223
  static VALUE method_geometry_collection_each(VALUE self)
202
224
  {
203
225
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
@@ -386,7 +408,7 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
386
408
  rb_define_method(geos_geometry_collection_class, "num_geometries", method_geometry_collection_num_geometries, 0);
387
409
  rb_define_method(geos_geometry_collection_class, "size", method_geometry_collection_num_geometries, 0);
388
410
  rb_define_method(geos_geometry_collection_class, "geometry_n", method_geometry_collection_geometry_n, 1);
389
- rb_define_method(geos_geometry_collection_class, "[]", method_geometry_collection_geometry_n, 1);
411
+ rb_define_method(geos_geometry_collection_class, "[]", method_geometry_collection_brackets, 1);
390
412
  rb_define_method(geos_geometry_collection_class, "each", method_geometry_collection_each, 0);
391
413
 
392
414
  // Methods for MultiPointImpl
@@ -150,7 +150,6 @@ static VALUE method_line_string_point_n(VALUE self, VALUE n)
150
150
  unsigned int size;
151
151
  if (GEOSCoordSeq_getSize_r(self_context, coord_seq, &size)) {
152
152
  if (i < size) {
153
- unsigned int dims;
154
153
  result = get_point_from_coordseq(self, coord_seq, i, has_z);
155
154
  }
156
155
  }
@@ -144,7 +144,16 @@ static VALUE method_polygon_interior_ring_n(VALUE self, VALUE n)
144
144
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
145
145
  const GEOSGeometry* self_geom = self_data->geom;
146
146
  if (self_geom) {
147
- result = rgeo_wrap_geos_geometry_clone(self_data->factory, GEOSGetInteriorRingN_r(self_data->geos_context, self_geom, NUM2INT(n)), RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_linear_ring);
147
+ int i = NUM2INT(n);
148
+ if (i >= 0) {
149
+ GEOSContextHandle_t self_context = self_data->geos_context;
150
+ int num = GEOSGetNumInteriorRings_r(self_context, self_geom);
151
+ if (i < num) {
152
+ result = rgeo_wrap_geos_geometry_clone(self_data->factory,
153
+ GEOSGetInteriorRingN_r(self_context, self_geom, i),
154
+ RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_linear_ring);
155
+ }
156
+ }
148
157
  }
149
158
  return result;
150
159
  }
@@ -88,7 +88,9 @@ module RGeo
88
88
  # === Notes
89
89
  #
90
90
  # Returns an object that supports the Geometry interface, or nil
91
- # if the given n is out of range.
91
+ # if the given N is out of range. N is zero-based.
92
+ # Also note that this method is different from GeometryCollection#[]
93
+ # in that it does not support negative indexes.
92
94
 
93
95
  def geometry_n(n_)
94
96
  raise Error::UnsupportedOperation, "Method GeometryCollection#geometry_n not defined."
@@ -102,10 +104,18 @@ module RGeo
102
104
  end
103
105
 
104
106
 
105
- # Alias of the geometry_n method.
107
+ # Returns the Nth geometry in this GeometryCollection, or nil if the
108
+ # given N is out of range. N is zero-based.
109
+ #
110
+ # This behaves slightly different from GeometryCollection#geometry_n.
111
+ # GeometryCollection#geometry_n accepts only nonnegative indexes,
112
+ # as specified by the SFS. However, GeometryCollection#[] also accepts
113
+ # negative indexes counting backwards from the end of the collection,
114
+ # the same way Ruby's array indexing works. Hence, geometry_n(-1)
115
+ # returns nil, where [-1] returns the last element of the collection.
106
116
 
107
117
  def [](n_)
108
- geometry_n(n_)
118
+ raise Error::UnsupportedOperation, "Method GeometryCollection#[] not defined."
109
119
  end
110
120
 
111
121
 
@@ -79,7 +79,8 @@ module RGeo
79
79
  # === Notes
80
80
  #
81
81
  # Returns an object that supports the Point interface, or nil
82
- # if the given n is out of range.
82
+ # if the given N is out of range. N is zero-based.
83
+ # Does not support negative indexes.
83
84
 
84
85
  def point_n(n_)
85
86
  raise Error::UnsupportedOperation, "Method LineString#point_n not defined."
@@ -118,7 +118,8 @@ module RGeo
118
118
  # === Notes
119
119
  #
120
120
  # Returns an object that supports the LinearRing interface, or nil
121
- # if the given n is out of range.
121
+ # if the given N is out of range. N is zero-based.
122
+ # Does not support negative indexes.
122
123
 
123
124
  def interior_ring_n(n_)
124
125
  raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined."
@@ -70,6 +70,11 @@ module RGeo
70
70
 
71
71
 
72
72
  def geometry_n(n_)
73
+ n_ < 0 ? nil : @elements[n_]
74
+ end
75
+
76
+
77
+ def [](n_)
73
78
  @elements[n_]
74
79
  end
75
80
 
@@ -77,7 +77,7 @@ module RGeo
77
77
 
78
78
 
79
79
  def point_n(n_)
80
- @points[n_]
80
+ n_ < 0 ? nil : @points[n_]
81
81
  end
82
82
 
83
83
 
@@ -79,7 +79,7 @@ module RGeo
79
79
 
80
80
 
81
81
  def interior_ring_n(n_)
82
- @interior_rings[n_]
82
+ n_ < 0 ? nil : @interior_rings[n_]
83
83
  end
84
84
 
85
85
 
@@ -77,6 +77,14 @@ module RGeo
77
77
  end
78
78
 
79
79
 
80
+ def test_bounds_check
81
+ geom_ = @factory.collection([@point1, @line1])
82
+ assert_nil(geom_.geometry_n(200))
83
+ assert_nil(geom_.geometry_n(-1))
84
+ assert(@line1.eql?(geom_[-1]))
85
+ end
86
+
87
+
80
88
  def test_creation_save_klass
81
89
  geom_ = @factory.collection([@point1, @line3])
82
90
  assert_not_nil(geom_)
@@ -53,6 +53,8 @@ module RGeo
53
53
  assert_equal(2, line1_.num_points)
54
54
  assert_equal(point1_, line1_.point_n(0))
55
55
  assert_equal(point2_, line1_.point_n(1))
56
+ assert_nil(line1_.point_n(-1))
57
+ assert_nil(line1_.point_n(2))
56
58
  assert_equal(point1_, line1_.start_point)
57
59
  assert_equal(point2_, line1_.end_point)
58
60
  end
@@ -55,6 +55,8 @@ module RGeo
55
55
  assert_equal(::RGeo::Feature::Polygon, polygon_.geometry_type)
56
56
  assert(exterior_.eql?(polygon_.exterior_ring))
57
57
  assert_equal(0, polygon_.num_interior_rings)
58
+ assert_nil(polygon_.interior_ring_n(0))
59
+ assert_nil(polygon_.interior_ring_n(-1))
58
60
  end
59
61
 
60
62
 
@@ -75,6 +77,8 @@ module RGeo
75
77
  assert(exterior_.eql?(polygon_.exterior_ring))
76
78
  assert_equal(1, polygon_.num_interior_rings)
77
79
  assert(interior_.eql?(polygon_.interior_ring_n(0)))
80
+ assert_nil(polygon_.interior_ring_n(1))
81
+ assert_nil(polygon_.interior_ring_n(-1))
78
82
  end
79
83
 
80
84
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rgeo
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.6
5
+ version: 0.2.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Daniel Azuma
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-31 00:00:00 -07:00
13
+ date: 2011-04-09 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16