rgeo 3.0.0.pre.rc.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/ext/geos_c_impl/factory.c +41 -5
  4. data/ext/geos_c_impl/factory.h +13 -2
  5. data/ext/geos_c_impl/geometry.c +151 -122
  6. data/ext/geos_c_impl/geometry_collection.c +17 -19
  7. data/ext/geos_c_impl/line_string.c +46 -36
  8. data/ext/geos_c_impl/point.c +0 -2
  9. data/ext/geos_c_impl/polygon.c +10 -11
  10. data/ext/geos_c_impl/polygon.h +1 -1
  11. data/ext/geos_c_impl/ruby_more.c +7 -0
  12. data/ext/geos_c_impl/ruby_more.h +8 -0
  13. data/lib/rgeo/cartesian/analysis.rb +5 -3
  14. data/lib/rgeo/cartesian/bounding_box.rb +74 -79
  15. data/lib/rgeo/cartesian/calculations.rb +20 -26
  16. data/lib/rgeo/cartesian/factory.rb +47 -49
  17. data/lib/rgeo/cartesian/planar_graph.rb +10 -16
  18. data/lib/rgeo/cartesian/sweepline_intersector.rb +1 -3
  19. data/lib/rgeo/cartesian/valid_op.rb +1 -3
  20. data/lib/rgeo/coord_sys/cs/entities.rb +87 -101
  21. data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
  22. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +70 -29
  23. data/lib/rgeo/feature/curve.rb +0 -1
  24. data/lib/rgeo/feature/factory.rb +25 -27
  25. data/lib/rgeo/feature/factory_generator.rb +3 -4
  26. data/lib/rgeo/feature/geometry.rb +41 -30
  27. data/lib/rgeo/feature/geometry_collection.rb +3 -4
  28. data/lib/rgeo/feature/line_string.rb +1 -2
  29. data/lib/rgeo/feature/linear_ring.rb +0 -1
  30. data/lib/rgeo/feature/multi_curve.rb +0 -1
  31. data/lib/rgeo/feature/multi_surface.rb +0 -1
  32. data/lib/rgeo/feature/point.rb +0 -1
  33. data/lib/rgeo/feature/polygon.rb +1 -2
  34. data/lib/rgeo/feature/surface.rb +0 -1
  35. data/lib/rgeo/feature/types.rb +73 -83
  36. data/lib/rgeo/geographic/factory.rb +87 -80
  37. data/lib/rgeo/geographic/interface.rb +40 -23
  38. data/lib/rgeo/geographic/projected_feature_methods.rb +2 -6
  39. data/lib/rgeo/geographic/projected_window.rb +35 -21
  40. data/lib/rgeo/geographic/simple_mercator_projector.rb +25 -13
  41. data/lib/rgeo/geographic/spherical_feature_methods.rb +8 -3
  42. data/lib/rgeo/geographic/spherical_math.rb +17 -20
  43. data/lib/rgeo/geos/capi_factory.rb +50 -50
  44. data/lib/rgeo/geos/ffi_factory.rb +41 -42
  45. data/lib/rgeo/geos/ffi_feature_methods.rb +72 -97
  46. data/lib/rgeo/geos/interface.rb +16 -16
  47. data/lib/rgeo/geos/utils.rb +3 -3
  48. data/lib/rgeo/geos/zm_factory.rb +50 -42
  49. data/lib/rgeo/geos/zm_feature_methods.rb +15 -8
  50. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +4 -4
  51. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
  52. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +18 -24
  53. data/lib/rgeo/impl_helper/basic_point_methods.rb +1 -3
  54. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +15 -16
  55. data/lib/rgeo/impl_helper/utils.rb +3 -9
  56. data/lib/rgeo/impl_helper/valid_op.rb +12 -16
  57. data/lib/rgeo/version.rb +1 -1
  58. data/lib/rgeo/wkrep/wkb_generator.rb +42 -47
  59. data/lib/rgeo/wkrep/wkb_parser.rb +17 -18
  60. data/lib/rgeo/wkrep/wkt_generator.rb +23 -16
  61. data/lib/rgeo/wkrep/wkt_parser.rb +23 -13
  62. metadata +5 -5
@@ -250,6 +250,7 @@ method_line_string_project_point(VALUE self, VALUE point)
250
250
  RGeo_GeometryData* self_data;
251
251
  const GEOSGeometry* self_geom;
252
252
  const GEOSGeometry* geos_point;
253
+ int state = 0;
253
254
 
254
255
  double location;
255
256
 
@@ -258,8 +259,12 @@ method_line_string_project_point(VALUE self, VALUE point)
258
259
  self_geom = self_data->geom;
259
260
 
260
261
  if (self_geom && point) {
261
- geos_point =
262
- rgeo_convert_to_geos_geometry(factory, point, rgeo_geos_point_class);
262
+ geos_point = rgeo_convert_to_geos_geometry(
263
+ factory, point, rgeo_geos_point_class, &state);
264
+ if (state) {
265
+ rb_jump_tag(state);
266
+ }
267
+
263
268
  location = GEOSProject(self_geom, geos_point);
264
269
  result = DBL2NUM(location);
265
270
  }
@@ -392,7 +397,6 @@ method_line_hash(VALUE self)
392
397
  static GEOSCoordSequence*
393
398
  coord_seq_from_array(VALUE factory, VALUE array, char close)
394
399
  {
395
- RGeo_FactoryData* factory_data;
396
400
  VALUE point_type;
397
401
  unsigned int len;
398
402
  char has_z;
@@ -404,9 +408,9 @@ coord_seq_from_array(VALUE factory, VALUE array, char close)
404
408
  const GEOSCoordSequence* entry_cs;
405
409
  double x;
406
410
  GEOSCoordSequence* coord_seq;
411
+ int state = 0;
407
412
 
408
413
  Check_Type(array, T_ARRAY);
409
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
410
414
  point_type = rgeo_feature_point_module;
411
415
  len = (unsigned int)RARRAY_LEN(array);
412
416
  has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags &
@@ -418,22 +422,26 @@ coord_seq_from_array(VALUE factory, VALUE array, char close)
418
422
  }
419
423
  for (i = 0; i < len; ++i) {
420
424
  good = 0;
425
+
421
426
  entry_geom = rgeo_convert_to_geos_geometry(
422
- factory, rb_ary_entry(array, i), point_type);
423
- if (entry_geom) {
424
- entry_cs = GEOSGeom_getCoordSeq(entry_geom);
425
- if (entry_cs) {
426
- if (GEOSCoordSeq_getX(entry_cs, 0, &x)) {
427
- coords[i * dims] = x;
428
- if (GEOSCoordSeq_getY(entry_cs, 0, &x)) {
429
- coords[i * dims + 1] = x;
430
- good = 1;
431
- if (has_z) {
432
- if (GEOSCoordSeq_getZ(entry_cs, 0, &x)) {
433
- coords[i * dims + 2] = x;
434
- } else {
435
- good = 0;
436
- }
427
+ factory, rb_ary_entry(array, i), point_type, &state);
428
+ if (state) {
429
+ FREE(coords);
430
+ rb_jump_tag(state);
431
+ }
432
+
433
+ entry_cs = GEOSGeom_getCoordSeq(entry_geom);
434
+ if (entry_cs) {
435
+ if (GEOSCoordSeq_getX(entry_cs, 0, &x)) {
436
+ coords[i * dims] = x;
437
+ if (GEOSCoordSeq_getY(entry_cs, 0, &x)) {
438
+ coords[i * dims + 1] = x;
439
+ good = 1;
440
+ if (has_z) {
441
+ if (GEOSCoordSeq_getZ(entry_cs, 0, &x)) {
442
+ coords[i * dims + 2] = x;
443
+ } else {
444
+ good = 0;
437
445
  }
438
446
  }
439
447
  }
@@ -474,13 +482,11 @@ cmethod_create_line_string(VALUE module, VALUE factory, VALUE array)
474
482
  {
475
483
  VALUE result;
476
484
  GEOSCoordSequence* coord_seq;
477
- RGeo_FactoryData* factory_data;
478
485
  GEOSGeometry* geom;
479
486
 
480
487
  result = Qnil;
481
488
  coord_seq = coord_seq_from_array(factory, array, 0);
482
489
  if (coord_seq) {
483
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
484
490
  geom = GEOSGeom_createLineString(coord_seq);
485
491
  if (geom) {
486
492
  result =
@@ -495,13 +501,11 @@ cmethod_create_linear_ring(VALUE module, VALUE factory, VALUE array)
495
501
  {
496
502
  VALUE result;
497
503
  GEOSCoordSequence* coord_seq;
498
- RGeo_FactoryData* factory_data;
499
504
  GEOSGeometry* geom;
500
505
 
501
506
  result = Qnil;
502
507
  coord_seq = coord_seq_from_array(factory, array, 1);
503
508
  if (coord_seq) {
504
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
505
509
  geom = GEOSGeom_createLinearRing(coord_seq);
506
510
  if (geom) {
507
511
  result =
@@ -549,25 +553,31 @@ cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE end)
549
553
  const GEOSGeometry* end_geom;
550
554
  GEOSCoordSequence* coord_seq;
551
555
  GEOSGeometry* geom;
556
+ int state = 0;
552
557
 
553
558
  result = Qnil;
554
559
  factory_data = RGEO_FACTORY_DATA_PTR(factory);
555
560
  has_z = (char)(factory_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
556
561
  point_type = rgeo_feature_point_module;
557
562
 
558
- start_geom = rgeo_convert_to_geos_geometry(factory, start, point_type);
559
- if (start_geom) {
560
- end_geom = rgeo_convert_to_geos_geometry(factory, end, point_type);
561
- if (end_geom) {
562
- coord_seq = GEOSCoordSeq_create(2, 3);
563
- if (coord_seq) {
564
- populate_geom_into_coord_seq(start_geom, coord_seq, 0, has_z);
565
- populate_geom_into_coord_seq(end_geom, coord_seq, 1, has_z);
566
- geom = GEOSGeom_createLineString(coord_seq);
567
- if (geom) {
568
- result = rgeo_wrap_geos_geometry(factory, geom, rgeo_geos_line_class);
569
- }
570
- }
563
+ start_geom =
564
+ rgeo_convert_to_geos_geometry(factory, start, point_type, &state);
565
+ if (state) {
566
+ rb_jump_tag(state);
567
+ }
568
+
569
+ end_geom = rgeo_convert_to_geos_geometry(factory, end, point_type, &state);
570
+ if (state) {
571
+ rb_jump_tag(state);
572
+ }
573
+
574
+ coord_seq = GEOSCoordSeq_create(2, 3);
575
+ if (coord_seq) {
576
+ populate_geom_into_coord_seq(start_geom, coord_seq, 0, has_z);
577
+ populate_geom_into_coord_seq(end_geom, coord_seq, 1, has_z);
578
+ geom = GEOSGeom_createLineString(coord_seq);
579
+ if (geom) {
580
+ result = rgeo_wrap_geos_geometry(factory, geom, rgeo_geos_line_class);
571
581
  }
572
582
  }
573
583
 
@@ -208,12 +208,10 @@ VALUE
208
208
  rgeo_create_geos_point(VALUE factory, double x, double y, double z)
209
209
  {
210
210
  VALUE result;
211
- RGeo_FactoryData* factory_data;
212
211
  GEOSCoordSequence* coord_seq;
213
212
  GEOSGeometry* geom;
214
213
 
215
214
  result = Qnil;
216
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
217
215
  coord_seq = GEOSCoordSeq_create(1, 3);
218
216
  if (coord_seq) {
219
217
  if (GEOSCoordSeq_setX(coord_seq, 0, x)) {
@@ -237,27 +237,23 @@ cmethod_create(VALUE module,
237
237
  VALUE exterior,
238
238
  VALUE interior_array)
239
239
  {
240
- RGeo_FactoryData* factory_data;
241
240
  VALUE linear_ring_type;
242
241
  GEOSGeometry* exterior_geom;
243
242
  unsigned int len;
244
243
  GEOSGeometry** interior_geoms;
245
244
  unsigned int actual_len;
246
245
  unsigned int i;
246
+ unsigned int j;
247
247
  GEOSGeometry* interior_geom;
248
248
  GEOSGeometry* polygon;
249
249
  int state = 0;
250
250
 
251
251
  Check_Type(interior_array, T_ARRAY);
252
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
253
252
  linear_ring_type = rgeo_feature_linear_ring_module;
254
253
  exterior_geom = rgeo_convert_to_detached_geos_geometry(
255
254
  exterior, factory, linear_ring_type, NULL, &state);
256
255
  if (state) {
257
- rb_exc_raise(rb_errinfo());
258
- }
259
- if (!exterior_geom) {
260
- return Qnil;
256
+ rb_jump_tag(state);
261
257
  }
262
258
 
263
259
  len = (unsigned int)RARRAY_LEN(interior_array);
@@ -271,12 +267,15 @@ cmethod_create(VALUE module,
271
267
  linear_ring_type,
272
268
  NULL,
273
269
  &state);
274
- if (interior_geom) {
275
- interior_geoms[actual_len++] = interior_geom;
276
- }
277
270
  if (state) {
278
- break;
271
+ for (j = 0; j < i; j++) {
272
+ GEOSGeom_destroy(interior_geoms[j]);
273
+ }
274
+ GEOSGeom_destroy(exterior_geom);
275
+ FREE(interior_geoms);
276
+ rb_jump_tag(state);
279
277
  }
278
+ interior_geoms[actual_len++] = interior_geom;
280
279
  }
281
280
  if (len == actual_len) {
282
281
  polygon =
@@ -295,7 +294,7 @@ cmethod_create(VALUE module,
295
294
  }
296
295
  GEOSGeom_destroy(exterior_geom);
297
296
  if (state) {
298
- rb_exc_raise(rb_errinfo());
297
+ rb_jump_tag(state);
299
298
  }
300
299
  return Qnil;
301
300
  }
@@ -18,7 +18,7 @@ void
18
18
  rgeo_init_geos_polygon();
19
19
 
20
20
  /*
21
- Comopares the values of two GEOS polygons. The two given geometries MUST
21
+ Compares the values of two GEOS polygons. The two given geometries MUST
22
22
  be polygon types.
23
23
  Returns Qtrue if the polygons are equal, Qfalse if they are inequal, or
24
24
  Qnil if an error occurs.
@@ -55,6 +55,13 @@ rb_protect_funcall(VALUE recv, ID mid, int* state, int n, ...)
55
55
  return rb_protect(inner_funcall, (VALUE)&args, state);
56
56
  }
57
57
 
58
+ VALUE
59
+ rb_exc_raise_value(VALUE exc)
60
+ {
61
+ rb_exc_raise(exc);
62
+ return Qnil;
63
+ }
64
+
58
65
  RGEO_END_C
59
66
 
60
67
  #endif
@@ -12,6 +12,14 @@ RGEO_BEGIN_C
12
12
  VALUE
13
13
  rb_protect_funcall(VALUE recv, ID mid, int* state, int n, ...);
14
14
 
15
+ /*
16
+ Raises an error based on the exception passed in, but also returns
17
+ a VALUE rather than void. This is so we can pass it into rb_protect
18
+ without getting type mismatch warnings.
19
+ */
20
+ VALUE
21
+ rb_exc_raise_value(VALUE exc);
22
+
15
23
  RGEO_END_C
16
24
 
17
25
  #endif
@@ -10,7 +10,6 @@ module RGeo
10
10
  module Cartesian
11
11
  # This provides includes some spatial analysis algorithms supporting
12
12
  # Cartesian data.
13
-
14
13
  module Analysis
15
14
  class << self
16
15
  # Check orientation of a ring, returns `true` if it is counter-clockwise
@@ -79,8 +78,11 @@ module RGeo
79
78
  sin = 0.0
80
79
  cos = 1.0
81
80
  angs.each_slice(2) do |(x, y)|
82
- ready = y > 0.0 && (sin > 0.0 || sin == 0.0 && direction == -1) || y < 0.0 && (sin < 0.0 || sin == 0.0 && direction == 1)
83
- if y != 0.0
81
+ ready = y > 0.0 &&
82
+ (sin > 0.0 || sin == 0 && direction == -1) ||
83
+ y < 0.0 &&
84
+ (sin < 0.0 || sin == 0 && direction == 1)
85
+ unless y == 0
84
86
  s = sin * x + cos * y
85
87
  c = cos * x - sin * y
86
88
  r = Math.sqrt(s * s + c * c)
@@ -19,8 +19,40 @@ module RGeo
19
19
  # adding the geometries to it. You may then query it for the bounds,
20
20
  # or use it to determine whether it encloses other geometries or
21
21
  # bounding boxes.
22
-
23
22
  class BoundingBox
23
+ # Returns the bounding box's factory.
24
+ attr_reader :factory
25
+
26
+ # Returns true if this bounding box tracks Z coordinates.
27
+ attr_reader :has_z
28
+
29
+ # Returns true if this bounding box tracks M coordinates.
30
+ attr_reader :has_m
31
+
32
+ # Returns the minimum X, or nil if this bounding box is empty.
33
+ attr_reader :min_x
34
+
35
+ # Returns the maximum X, or nil if this bounding box is empty.
36
+ attr_reader :max_x
37
+
38
+ # Returns the minimum Y, or nil if this bounding box is empty.
39
+ attr_reader :min_y
40
+
41
+ # Returns the maximum Y, or nil if this bounding box is empty.
42
+ attr_reader :max_y
43
+
44
+ # Returns the minimum Z, or nil if this bounding box is empty.
45
+ attr_reader :min_z
46
+
47
+ # Returns the maximum Z, or nil if this bounding box is empty.
48
+ attr_reader :max_z
49
+
50
+ # Returns the minimum M, or nil if this bounding box is empty.
51
+ attr_reader :min_m
52
+
53
+ # Returns the maximum M, or nil if this bounding box is empty.
54
+ attr_reader :max_m
55
+
24
56
  # Create a bounding box given two corner points.
25
57
  # The bounding box will be given the factory of the first point.
26
58
  # You may also provide the same options available to
@@ -69,19 +101,15 @@ module RGeo
69
101
  end
70
102
  end
71
103
 
72
- def eql?(rhs) # :nodoc:
73
- rhs.is_a?(BoundingBox) && @factory == rhs.factory &&
74
- @min_x == rhs.min_x && @max_x == rhs.max_x &&
75
- @min_y == rhs.min_y && @max_y == rhs.max_y &&
76
- @min_z == rhs.min_z && @max_z == rhs.max_z &&
77
- @min_m == rhs.min_m && @max_m == rhs.max_m
104
+ def eql?(other) # :nodoc:
105
+ other.is_a?(BoundingBox) && @factory == other.factory &&
106
+ @min_x == other.min_x && @max_x == other.max_x &&
107
+ @min_y == other.min_y && @max_y == other.max_y &&
108
+ @min_z == other.min_z && @max_z == other.max_z &&
109
+ @min_m == other.min_m && @max_m == other.max_m
78
110
  end
79
111
  alias == eql?
80
112
 
81
- # Returns the bounding box's factory.
82
-
83
- attr_reader :factory
84
-
85
113
  # Returns true if this bounding box is still empty.
86
114
 
87
115
  def empty?
@@ -105,22 +133,6 @@ module RGeo
105
133
  @min_x && (@min_x == @max_x || @min_y == @max_y)
106
134
  end
107
135
 
108
- # Returns true if this bounding box tracks Z coordinates.
109
-
110
- attr_reader :has_z
111
-
112
- # Returns true if this bounding box tracks M coordinates.
113
-
114
- attr_reader :has_m
115
-
116
- # Returns the minimum X, or nil if this bounding box is empty.
117
-
118
- attr_reader :min_x
119
-
120
- # Returns the maximum X, or nil if this bounding box is empty.
121
-
122
- attr_reader :max_x
123
-
124
136
  # Returns the midpoint X, or nil if this bounding box is empty.
125
137
 
126
138
  def center_x
@@ -133,14 +145,6 @@ module RGeo
133
145
  @max_x ? @max_x - @min_x : 0
134
146
  end
135
147
 
136
- # Returns the minimum Y, or nil if this bounding box is empty.
137
-
138
- attr_reader :min_y
139
-
140
- # Returns the maximum Y, or nil if this bounding box is empty.
141
-
142
- attr_reader :max_y
143
-
144
148
  # Returns the midpoint Y, or nil if this bounding box is empty.
145
149
 
146
150
  def center_y
@@ -153,14 +157,6 @@ module RGeo
153
157
  @max_y ? @max_y - @min_y : 0
154
158
  end
155
159
 
156
- # Returns the minimum Z, or nil if this bounding box is empty.
157
-
158
- attr_reader :min_z
159
-
160
- # Returns the maximum Z, or nil if this bounding box is empty.
161
-
162
- attr_reader :max_z
163
-
164
160
  # Returns the midpoint Z, or nil if this bounding box is empty or has no Z.
165
161
 
166
162
  def center_z
@@ -170,16 +166,12 @@ module RGeo
170
166
  # Returns the Z span, 0 if this bounding box is empty, or nil if it has no Z.
171
167
 
172
168
  def z_span
173
- @has_z ? (@max_z ? @max_z - @min_z : 0) : nil
174
- end
169
+ return unless @has_z
175
170
 
176
- # Returns the minimum M, or nil if this bounding box is empty.
177
-
178
- attr_reader :min_m
171
+ return 0 unless @max_z
179
172
 
180
- # Returns the maximum M, or nil if this bounding box is empty.
181
-
182
- attr_reader :max_m
173
+ @max_z - @min_z
174
+ end
183
175
 
184
176
  # Returns the midpoint M, or nil if this bounding box is empty or has no M.
185
177
 
@@ -190,31 +182,37 @@ module RGeo
190
182
  # Returns the M span, 0 if this bounding box is empty, or nil if it has no M.
191
183
 
192
184
  def m_span
193
- @has_m ? (@max_m ? @max_m - @min_m : 0) : nil
185
+ return unless @has_m
186
+
187
+ return 0 unless @max_m
188
+
189
+ @max_m - @min_m
194
190
  end
195
191
 
196
192
  # Returns a point representing the minimum extent in all dimensions,
197
193
  # or nil if this bounding box is empty.
198
194
 
199
195
  def min_point
200
- if @min_x
201
- extras = []
202
- extras << @min_z if @has_z
203
- extras << @min_m if @has_m
204
- @factory.point(@min_x, @min_y, *extras)
205
- end
196
+ return unless @min_x
197
+
198
+ extras = []
199
+ extras << @min_z if @has_z
200
+ extras << @min_m if @has_m
201
+
202
+ @factory.point(@min_x, @min_y, *extras)
206
203
  end
207
204
 
208
205
  # Returns a point representing the maximum extent in all dimensions,
209
206
  # or nil if this bounding box is empty.
210
207
 
211
208
  def max_point
212
- if @min_x
213
- extras = []
214
- extras << @max_z if @has_z
215
- extras << @max_m if @has_m
216
- @factory.point(@max_x, @max_y, *extras)
217
- end
209
+ return unless @min_x
210
+
211
+ extras = []
212
+ extras << @max_z if @has_z
213
+ extras << @max_m if @has_m
214
+
215
+ @factory.point(@max_x, @max_y, *extras)
218
216
  end
219
217
 
220
218
  # Adjusts the extents of this bounding box to encompass the given
@@ -280,21 +278,18 @@ module RGeo
280
278
  # have M. Default is false.
281
279
 
282
280
  def contains?(rhs, opts = {})
283
- if Feature::Geometry === rhs
284
- contains?(BoundingBox.new(@factory).add(rhs))
285
- elsif rhs.empty?
286
- true
287
- elsif empty?
288
- false
289
- elsif @min_x > rhs.min_x || @max_x < rhs.max_x || @min_y > rhs.min_y || @max_y < rhs.max_y
290
- false
291
- elsif @has_m && rhs.has_m && !opts[:ignore_m] && (@min_m > rhs.min_m || @max_m < rhs.max_m)
292
- false
293
- elsif @has_z && rhs.has_z && !opts[:ignore_z] && (@min_z > rhs.min_z || @max_z < rhs.max_z) # rubocop:disable Style/IfWithBooleanLiteralBranches
294
- false
295
- else
296
- true
297
- end
281
+ return contains?(BoundingBox.new(@factory).add(rhs)) if Feature::Geometry === rhs
282
+
283
+ return true if rhs.empty?
284
+
285
+ return false if empty?
286
+
287
+ cmp_xymz =
288
+ (@min_x > rhs.min_x || @max_x < rhs.max_x || @min_y > rhs.min_y || @max_y < rhs.max_y) ||
289
+ (@has_m && rhs.has_m && !opts[:ignore_m] && (@min_m > rhs.min_m || @max_m < rhs.max_m)) ||
290
+ (@has_z && rhs.has_z && !opts[:ignore_z] && (@min_z > rhs.min_z || @max_z < rhs.max_z))
291
+
292
+ !cmp_xymz
298
293
  end
299
294
 
300
295
  # Returns this bounding box subdivided, as an array of bounding boxes.
@@ -23,17 +23,14 @@ module RGeo
23
23
  @lensq = @dx * @dx + @dy * @dy
24
24
  end
25
25
 
26
- attr_reader :s
27
- attr_reader :e
28
- attr_reader :dx
29
- attr_reader :dy
26
+ attr_reader :s, :e, :dx, :dy
30
27
 
31
28
  def to_s
32
29
  "#{@s} - #{@e}"
33
30
  end
34
31
 
35
- def eql?(rhs)
36
- rhs.is_a?(Segment) && @s == rhs.s && @e == rhs.e
32
+ def eql?(other)
33
+ other.is_a?(Segment) && @s == other.s && @e == other.e
37
34
  end
38
35
  alias == eql?
39
36
 
@@ -45,23 +42,23 @@ module RGeo
45
42
  # a positive value if the point is to the right, or
46
43
  # 0 if the point is collinear to the segment.
47
44
 
48
- def side(p)
49
- px = p.x
50
- py = p.y
45
+ def side(point)
46
+ px = point.x
47
+ py = point.y
51
48
  (@sx - px) * (@ey - py) - (@sy - py) * (@ex - px)
52
49
  end
53
50
 
54
- def tproj(p)
51
+ def tproj(point)
55
52
  if @lensq == 0
56
53
  nil
57
54
  else
58
- (@dx * (p.x - @sx) + @dy * (p.y - @sy)) / @lensq
55
+ (@dx * (point.x - @sx) + @dy * (point.y - @sy)) / @lensq
59
56
  end
60
57
  end
61
58
 
62
- def contains_point?(p)
63
- if side(p) == 0
64
- t = tproj(p)
59
+ def contains_point?(point)
60
+ if side(point) == 0
61
+ t = tproj(point)
65
62
  t && t >= 0.0 && t <= 1.0
66
63
  else
67
64
  false
@@ -84,11 +81,9 @@ module RGeo
84
81
  s2 = seg.s
85
82
  # Handle degenerate cases
86
83
  if seg.degenerate?
87
- if @lensq == 0 && @s == s2
88
- return @s
89
- else
90
- return contains_point?(s2) ? s2 : nil
91
- end
84
+ return @s if @lensq == 0 && @s == s2
85
+
86
+ return contains_point?(s2) ? s2 : nil
92
87
  elsif @lensq == 0
93
88
  return seg.contains_point?(@s) ? @s : nil
94
89
  end
@@ -132,13 +127,12 @@ module RGeo
132
127
  # If this is the case, return the closest point from
133
128
  # either segment.
134
129
  int_pt = @s.factory.point(x, y)
135
- if contains_point?(int_pt)
136
- int_pt
137
- else
138
- # find closest of @s, @e, seg.s, seg.e
139
- [@e, seg.s, seg.e].reduce(@s) do |closest, pt|
140
- int_pt.distance(pt) < int_pt.distance(closest) ? pt : closest
141
- end
130
+
131
+ return int_pt if contains_point?(int_pt)
132
+
133
+ # find closest of @s, @e, seg.s, seg.e
134
+ [@e, seg.s, seg.e].reduce(@s) do |closest, pt|
135
+ int_pt.distance(pt) < int_pt.distance(closest) ? pt : closest
142
136
  end
143
137
  end
144
138
  end