rgeo 3.0.0.pre.rc.3 → 3.0.1
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.
- checksums.yaml +4 -4
- data/README.md +11 -3
- data/ext/geos_c_impl/extconf.rb +1 -0
- data/ext/geos_c_impl/factory.c +43 -5
- data/ext/geos_c_impl/factory.h +13 -2
- data/ext/geos_c_impl/geometry.c +178 -122
- data/ext/geos_c_impl/geometry_collection.c +17 -19
- data/ext/geos_c_impl/line_string.c +46 -36
- data/ext/geos_c_impl/point.c +0 -2
- data/ext/geos_c_impl/polygon.c +10 -11
- data/ext/geos_c_impl/polygon.h +1 -1
- data/ext/geos_c_impl/preface.h +3 -0
- data/ext/geos_c_impl/ruby_more.c +7 -0
- data/ext/geos_c_impl/ruby_more.h +8 -0
- data/lib/rgeo/cartesian/analysis.rb +5 -3
- data/lib/rgeo/cartesian/bounding_box.rb +74 -79
- data/lib/rgeo/cartesian/calculations.rb +20 -26
- data/lib/rgeo/cartesian/factory.rb +47 -49
- data/lib/rgeo/cartesian/planar_graph.rb +10 -16
- data/lib/rgeo/cartesian/sweepline_intersector.rb +1 -3
- data/lib/rgeo/cartesian/valid_op.rb +1 -3
- data/lib/rgeo/coord_sys/cs/entities.rb +91 -101
- data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +70 -29
- data/lib/rgeo/feature/curve.rb +0 -1
- data/lib/rgeo/feature/factory.rb +25 -27
- data/lib/rgeo/feature/factory_generator.rb +3 -4
- data/lib/rgeo/feature/geometry.rb +41 -30
- data/lib/rgeo/feature/geometry_collection.rb +3 -4
- data/lib/rgeo/feature/line_string.rb +1 -2
- data/lib/rgeo/feature/linear_ring.rb +0 -1
- data/lib/rgeo/feature/multi_curve.rb +0 -1
- data/lib/rgeo/feature/multi_surface.rb +0 -1
- data/lib/rgeo/feature/point.rb +0 -1
- data/lib/rgeo/feature/polygon.rb +1 -2
- data/lib/rgeo/feature/surface.rb +0 -1
- data/lib/rgeo/feature/types.rb +69 -85
- data/lib/rgeo/geographic/factory.rb +87 -80
- data/lib/rgeo/geographic/interface.rb +44 -27
- data/lib/rgeo/geographic/projected_feature_methods.rb +2 -6
- data/lib/rgeo/geographic/projected_window.rb +35 -21
- data/lib/rgeo/geographic/simple_mercator_projector.rb +27 -15
- data/lib/rgeo/geographic/spherical_feature_methods.rb +8 -3
- data/lib/rgeo/geographic/spherical_math.rb +17 -20
- data/lib/rgeo/geos/capi_factory.rb +50 -50
- data/lib/rgeo/geos/ffi_factory.rb +50 -49
- data/lib/rgeo/geos/ffi_feature_methods.rb +72 -98
- data/lib/rgeo/geos/interface.rb +16 -16
- data/lib/rgeo/geos/utils.rb +5 -5
- data/lib/rgeo/geos/zm_factory.rb +50 -42
- data/lib/rgeo/geos/zm_feature_methods.rb +15 -9
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +4 -4
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +18 -24
- data/lib/rgeo/impl_helper/basic_point_methods.rb +1 -3
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +15 -16
- data/lib/rgeo/impl_helper/utils.rb +3 -9
- data/lib/rgeo/impl_helper/valid_op.rb +12 -16
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +42 -47
- data/lib/rgeo/wkrep/wkb_parser.rb +17 -18
- data/lib/rgeo/wkrep/wkt_generator.rb +23 -16
- data/lib/rgeo/wkrep/wkt_parser.rb +23 -13
- metadata +6 -6
@@ -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
|
-
|
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 (
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
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 =
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
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
|
|
data/ext/geos_c_impl/point.c
CHANGED
@@ -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)) {
|
data/ext/geos_c_impl/polygon.c
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
297
|
+
rb_jump_tag(state);
|
299
298
|
}
|
300
299
|
return Qnil;
|
301
300
|
}
|
data/ext/geos_c_impl/polygon.h
CHANGED
@@ -18,7 +18,7 @@ void
|
|
18
18
|
rgeo_init_geos_polygon();
|
19
19
|
|
20
20
|
/*
|
21
|
-
|
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.
|
data/ext/geos_c_impl/preface.h
CHANGED
data/ext/geos_c_impl/ruby_more.c
CHANGED
data/ext/geos_c_impl/ruby_more.h
CHANGED
@@ -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 &&
|
83
|
-
|
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?(
|
73
|
-
|
74
|
-
@min_x ==
|
75
|
-
@min_y ==
|
76
|
-
@min_z ==
|
77
|
-
@min_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
|
-
|
174
|
-
end
|
169
|
+
return unless @has_z
|
175
170
|
|
176
|
-
|
177
|
-
|
178
|
-
attr_reader :min_m
|
171
|
+
return 0 unless @max_z
|
179
172
|
|
180
|
-
|
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
|
-
|
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
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
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?(
|
36
|
-
|
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(
|
49
|
-
px =
|
50
|
-
py =
|
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(
|
51
|
+
def tproj(point)
|
55
52
|
if @lensq == 0
|
56
53
|
nil
|
57
54
|
else
|
58
|
-
(@dx * (
|
55
|
+
(@dx * (point.x - @sx) + @dy * (point.y - @sy)) / @lensq
|
59
56
|
end
|
60
57
|
end
|
61
58
|
|
62
|
-
def contains_point?(
|
63
|
-
if side(
|
64
|
-
t = tproj(
|
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
|
-
|
89
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|