rgeo 1.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +144 -0
- data/ext/geos_c_impl/analysis.c +78 -0
- data/ext/geos_c_impl/analysis.h +42 -0
- data/ext/geos_c_impl/errors.c +35 -0
- data/ext/geos_c_impl/errors.h +22 -0
- data/ext/geos_c_impl/extconf.rb +6 -3
- data/ext/geos_c_impl/factory.c +14 -5
- data/ext/geos_c_impl/factory.h +5 -1
- data/ext/geos_c_impl/geometry.c +20 -2
- data/ext/geos_c_impl/geometry_collection.c +0 -17
- data/ext/geos_c_impl/main.c +5 -2
- data/ext/geos_c_impl/preface.h +3 -0
- data/lib/rgeo.rb +11 -13
- data/lib/rgeo/cartesian.rb +13 -23
- data/lib/rgeo/cartesian/analysis.rb +44 -20
- data/lib/rgeo/cartesian/bounding_box.rb +83 -79
- data/lib/rgeo/cartesian/calculations.rb +40 -38
- data/lib/rgeo/cartesian/factory.rb +134 -169
- data/lib/rgeo/cartesian/feature_classes.rb +2 -18
- data/lib/rgeo/cartesian/feature_methods.rb +37 -39
- data/lib/rgeo/cartesian/interface.rb +11 -9
- data/lib/rgeo/coord_sys.rb +9 -8
- data/lib/rgeo/coord_sys/cs/entities.rb +345 -303
- data/lib/rgeo/coord_sys/cs/factories.rb +30 -28
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +128 -126
- data/lib/rgeo/coord_sys/srs_database/{interface.rb → entry.rb} +26 -32
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +19 -17
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +21 -19
- data/lib/rgeo/error.rb +7 -1
- data/lib/rgeo/feature.rb +40 -51
- data/lib/rgeo/feature/curve.rb +2 -0
- data/lib/rgeo/feature/factory.rb +15 -13
- data/lib/rgeo/feature/factory_generator.rb +7 -5
- data/lib/rgeo/feature/geometry.rb +31 -29
- data/lib/rgeo/feature/geometry_collection.rb +6 -4
- data/lib/rgeo/feature/line.rb +2 -0
- data/lib/rgeo/feature/line_string.rb +3 -1
- data/lib/rgeo/feature/linear_ring.rb +12 -0
- data/lib/rgeo/feature/multi_curve.rb +2 -0
- data/lib/rgeo/feature/multi_line_string.rb +2 -0
- data/lib/rgeo/feature/multi_point.rb +2 -0
- data/lib/rgeo/feature/multi_polygon.rb +2 -0
- data/lib/rgeo/feature/multi_surface.rb +2 -0
- data/lib/rgeo/feature/point.rb +2 -0
- data/lib/rgeo/feature/polygon.rb +3 -1
- data/lib/rgeo/feature/surface.rb +2 -0
- data/lib/rgeo/feature/types.rb +107 -103
- data/lib/rgeo/geographic.rb +27 -37
- data/lib/rgeo/geographic/factory.rb +154 -199
- data/lib/rgeo/geographic/interface.rb +141 -137
- data/lib/rgeo/geographic/proj4_projector.rb +28 -23
- data/lib/rgeo/geographic/projected_feature_classes.rb +2 -18
- data/lib/rgeo/geographic/projected_feature_methods.rb +64 -54
- data/lib/rgeo/geographic/projected_window.rb +4 -2
- data/lib/rgeo/geographic/simple_mercator_projector.rb +41 -39
- data/lib/rgeo/geographic/spherical_feature_classes.rb +3 -18
- data/lib/rgeo/geographic/spherical_feature_methods.rb +90 -67
- data/lib/rgeo/geographic/spherical_math.rb +81 -87
- data/lib/rgeo/geos.rb +40 -53
- data/lib/rgeo/geos/capi_factory.rb +111 -136
- data/lib/rgeo/geos/capi_feature_classes.rb +22 -36
- data/lib/rgeo/geos/ffi_factory.rb +276 -297
- data/lib/rgeo/geos/ffi_feature_classes.rb +2 -20
- data/lib/rgeo/geos/ffi_feature_methods.rb +177 -169
- data/lib/rgeo/geos/interface.rb +25 -23
- data/lib/rgeo/geos/utils.rb +47 -39
- data/lib/rgeo/geos/zm_factory.rb +171 -185
- data/lib/rgeo/geos/zm_feature_classes.rb +2 -20
- data/lib/rgeo/geos/zm_feature_methods.rb +76 -72
- data/lib/rgeo/impl_helper.rb +8 -18
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +84 -75
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +21 -23
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +95 -48
- data/lib/rgeo/impl_helper/basic_point_methods.rb +29 -25
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +68 -27
- data/lib/rgeo/impl_helper/math.rb +2 -0
- data/lib/rgeo/impl_helper/utils.rb +9 -15
- data/lib/rgeo/version.rb +3 -1
- data/lib/rgeo/wkrep.rb +24 -34
- data/lib/rgeo/wkrep/wkb_generator.rb +87 -84
- data/lib/rgeo/wkrep/wkb_parser.rb +93 -93
- data/lib/rgeo/wkrep/wkt_generator.rb +67 -63
- data/lib/rgeo/wkrep/wkt_parser.rb +172 -168
- metadata +30 -36
- data/lib/rgeo/feature/mixins.rb +0 -143
@@ -559,22 +559,6 @@ static VALUE method_multi_polygon_centroid(VALUE self)
|
|
559
559
|
}
|
560
560
|
|
561
561
|
|
562
|
-
static VALUE method_multi_polygon_point_on_surface(VALUE self)
|
563
|
-
{
|
564
|
-
VALUE result;
|
565
|
-
RGeo_GeometryData* self_data;
|
566
|
-
const GEOSGeometry* self_geom;
|
567
|
-
|
568
|
-
result = Qnil;
|
569
|
-
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
570
|
-
self_geom = self_data->geom;
|
571
|
-
if (self_geom) {
|
572
|
-
result = rgeo_wrap_geos_geometry(self_data->factory, GEOSPointOnSurface_r(self_data->geos_context, self_geom), Qnil);
|
573
|
-
}
|
574
|
-
return result;
|
575
|
-
}
|
576
|
-
|
577
|
-
|
578
562
|
static VALUE cmethod_geometry_collection_create(VALUE module, VALUE factory, VALUE array)
|
579
563
|
{
|
580
564
|
return create_geometry_collection(module, GEOS_GEOMETRYCOLLECTION, factory, array);
|
@@ -648,7 +632,6 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
|
|
648
632
|
rb_define_method(geos_multi_polygon_methods, "geometry_type", method_multi_polygon_geometry_type, 0);
|
649
633
|
rb_define_method(geos_multi_polygon_methods, "area", method_multi_polygon_area, 0);
|
650
634
|
rb_define_method(geos_multi_polygon_methods, "centroid", method_multi_polygon_centroid, 0);
|
651
|
-
rb_define_method(geos_multi_polygon_methods, "point_on_surface", method_multi_polygon_point_on_surface, 0);
|
652
635
|
rb_define_method(geos_multi_polygon_methods, "hash", method_multi_polygon_hash, 0);
|
653
636
|
rb_define_method(geos_multi_polygon_methods, "coordinates", method_multi_polygon_coordinates, 0);
|
654
637
|
}
|
data/ext/geos_c_impl/main.c
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
Main initializer for GEOS wrapper
|
3
3
|
*/
|
4
4
|
|
5
|
-
|
6
5
|
#include "preface.h"
|
7
6
|
|
8
7
|
#ifdef RGEO_GEOS_SUPPORTED
|
@@ -10,18 +9,20 @@
|
|
10
9
|
#include <ruby.h>
|
11
10
|
#include <geos_c.h>
|
12
11
|
|
12
|
+
#include "errors.h"
|
13
|
+
|
13
14
|
#include "factory.h"
|
14
15
|
#include "geometry.h"
|
15
16
|
#include "point.h"
|
16
17
|
#include "line_string.h"
|
17
18
|
#include "polygon.h"
|
18
19
|
#include "geometry_collection.h"
|
20
|
+
#include "analysis.h"
|
19
21
|
|
20
22
|
#endif
|
21
23
|
|
22
24
|
RGEO_BEGIN_C
|
23
25
|
|
24
|
-
|
25
26
|
void Init_geos_c_impl()
|
26
27
|
{
|
27
28
|
#ifdef RGEO_GEOS_SUPPORTED
|
@@ -33,6 +34,8 @@ void Init_geos_c_impl()
|
|
33
34
|
rgeo_init_geos_line_string(globals);
|
34
35
|
rgeo_init_geos_polygon(globals);
|
35
36
|
rgeo_init_geos_geometry_collection(globals);
|
37
|
+
rgeo_init_geos_analysis(globals);
|
38
|
+
rgeo_init_geos_errors();
|
36
39
|
#endif
|
37
40
|
}
|
38
41
|
|
data/ext/geos_c_impl/preface.h
CHANGED
data/lib/rgeo.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# RGeo is a spatial data library for Ruby. It focuses on the storage and
|
2
4
|
# manipulation of spatial data types such as points, lines, and polygons.
|
3
5
|
#
|
@@ -73,16 +75,12 @@
|
|
73
75
|
# database, and based on the postgresql adapter. Available as the
|
74
76
|
# activerecord-postgis-adapter gem.
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
require "rgeo/wkrep"
|
86
|
-
require "rgeo/geos"
|
87
|
-
require "rgeo/cartesian"
|
88
|
-
require "rgeo/geographic"
|
78
|
+
require_relative "rgeo/version"
|
79
|
+
require_relative "rgeo/error"
|
80
|
+
require_relative "rgeo/feature"
|
81
|
+
require_relative "rgeo/coord_sys"
|
82
|
+
require_relative "rgeo/impl_helper"
|
83
|
+
require_relative "rgeo/wkrep"
|
84
|
+
require_relative "rgeo/geos"
|
85
|
+
require_relative "rgeo/cartesian"
|
86
|
+
require_relative "rgeo/geographic"
|
data/lib/rgeo/cartesian.rb
CHANGED
@@ -1,25 +1,15 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Cartesian features for RGeo
|
4
|
-
#
|
5
|
-
# -----------------------------------------------------------------------------
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
7
|
-
module
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# for Cartesian-specific analysis tools.
|
3
|
+
# The Cartesian module is a gateway to implementations that use the
|
4
|
+
# Cartesian (i.e. flat) coordinate system. It provides convenient
|
5
|
+
# access to Cartesian factories such as the Geos implementation and
|
6
|
+
# the simple Cartesian implementation. It also provides a namespace
|
7
|
+
# for Cartesian-specific analysis tools.
|
13
8
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
require "rgeo/cartesian/feature_classes"
|
22
|
-
require "rgeo/cartesian/factory"
|
23
|
-
require "rgeo/cartesian/interface"
|
24
|
-
require "rgeo/cartesian/bounding_box"
|
25
|
-
require "rgeo/cartesian/analysis"
|
9
|
+
require_relative "cartesian/calculations"
|
10
|
+
require_relative "cartesian/feature_methods"
|
11
|
+
require_relative "cartesian/feature_classes"
|
12
|
+
require_relative "cartesian/factory"
|
13
|
+
require_relative "cartesian/interface"
|
14
|
+
require_relative "cartesian/bounding_box"
|
15
|
+
require_relative "cartesian/analysis"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# Cartesian geometric analysis utilities
|
@@ -11,6 +13,28 @@ module RGeo
|
|
11
13
|
|
12
14
|
module Analysis
|
13
15
|
class << self
|
16
|
+
# Check orientation of a ring, returns `true` if it is counter-clockwise
|
17
|
+
# and false otherwise.
|
18
|
+
#
|
19
|
+
# If the factory used is GEOS based, use the GEOS implementation to
|
20
|
+
# check that. Otherwise, this methods falls back to `ring_direction`.
|
21
|
+
#
|
22
|
+
# == Note
|
23
|
+
#
|
24
|
+
# This method does not ensure a correct result for an invalid geometry.
|
25
|
+
# You should make sure your ring is valid beforehand using `is_ring?`
|
26
|
+
# if you are using a LineString, or directly `valid?` for a
|
27
|
+
# `linear_ring?`.
|
28
|
+
# This will be subject to changes in v3.
|
29
|
+
def ccw?(ring)
|
30
|
+
if RGeo::Geos.is_capi_geos?(ring) && RGeo::Geos::Analysis.ccw_supported?
|
31
|
+
RGeo::Geos::Analysis.ccw?(ring)
|
32
|
+
else
|
33
|
+
RGeo::Cartesian::Analysis.ring_direction(ring) == 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
alias counter_clockwise? ccw?
|
37
|
+
|
14
38
|
# Given a LineString, which must be a ring, determine whether the
|
15
39
|
# ring proceeds clockwise or counterclockwise.
|
16
40
|
# Returns 1 for counterclockwise, or -1 for clockwise.
|
@@ -19,33 +43,33 @@ module RGeo
|
|
19
43
|
# The return value is undefined if the object is not a ring, or
|
20
44
|
# is not in a Cartesian coordinate system.
|
21
45
|
|
22
|
-
def ring_direction(
|
23
|
-
|
24
|
-
return 0 if
|
46
|
+
def ring_direction(ring)
|
47
|
+
size = ring.num_points - 1
|
48
|
+
return 0 if size == 0
|
25
49
|
|
26
50
|
# Extract unit-length segments from the ring.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
if
|
35
|
-
|
51
|
+
segs = []
|
52
|
+
size.times do |i|
|
53
|
+
p0 = ring.point_n(i)
|
54
|
+
p1 = ring.point_n(i + 1)
|
55
|
+
x = p1.x - p0.x
|
56
|
+
y = p1.y - p0.y
|
57
|
+
r = Math.sqrt(x * x + y * y)
|
58
|
+
if r > 0.0
|
59
|
+
segs << x / r << y / r
|
36
60
|
else
|
37
|
-
|
61
|
+
size -= 1
|
38
62
|
end
|
39
63
|
end
|
40
|
-
|
64
|
+
segs << segs[0] << segs[1]
|
41
65
|
|
42
66
|
# Extract angles from the segments by subtracting the segments.
|
43
67
|
# Note angles are represented as cos/sin pairs so we don't
|
44
68
|
# have to calculate any trig functions.
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
69
|
+
angs = []
|
70
|
+
size.times do |i|
|
71
|
+
x0, y0, x1, y1 = segs[i * 2, 4]
|
72
|
+
angs << x0 * x1 + y0 * y1 << x0 * y1 - x1 * y0
|
49
73
|
end
|
50
74
|
|
51
75
|
# Now add the angles and count revolutions.
|
@@ -54,12 +78,12 @@ module RGeo
|
|
54
78
|
direction = nil
|
55
79
|
sin = 0.0
|
56
80
|
cos = 1.0
|
57
|
-
|
81
|
+
angs.each_slice(2) do |(x, y)|
|
58
82
|
ready = y > 0.0 && (sin > 0.0 || sin == 0.0 && direction == -1) || y < 0.0 && (sin < 0.0 || sin == 0.0 && direction == 1)
|
59
83
|
if y != 0.0
|
60
84
|
s = sin * x + cos * y
|
61
85
|
c = cos * x - sin * y
|
62
|
-
r =
|
86
|
+
r = Math.sqrt(s * s + c * c)
|
63
87
|
sin = s / r
|
64
88
|
cos = c / r
|
65
89
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# Cartesian bounding box
|
@@ -24,9 +26,9 @@ module RGeo
|
|
24
26
|
# You may also provide the same options available to
|
25
27
|
# BoundingBox.new.
|
26
28
|
|
27
|
-
def self.create_from_points(
|
28
|
-
|
29
|
-
new(
|
29
|
+
def self.create_from_points(point1, point2, opts = {})
|
30
|
+
factory = point1.factory
|
31
|
+
new(factory, opts).add_geometry(point1).add(point2)
|
30
32
|
end
|
31
33
|
|
32
34
|
# Create a bounding box given a geometry to surround.
|
@@ -34,9 +36,9 @@ module RGeo
|
|
34
36
|
# You may also provide the same options available to
|
35
37
|
# BoundingBox.new.
|
36
38
|
|
37
|
-
def self.create_from_geometry(
|
38
|
-
|
39
|
-
new(
|
39
|
+
def self.create_from_geometry(geom, opts = {})
|
40
|
+
factory = geom.factory
|
41
|
+
new(factory, opts).add_geometry(geom)
|
40
42
|
end
|
41
43
|
|
42
44
|
# Create a new empty bounding box with the given factory.
|
@@ -56,23 +58,23 @@ module RGeo
|
|
56
58
|
# If true, ignore m coordinates even if the factory supports them.
|
57
59
|
# Default is false.
|
58
60
|
|
59
|
-
def initialize(
|
60
|
-
@factory =
|
61
|
-
if (
|
62
|
-
@has_z, @has_m, @min_x, @max_x, @min_y, @max_y, @min_z, @max_z, @min_m, @max_m =
|
61
|
+
def initialize(factory, opts = {})
|
62
|
+
@factory = factory
|
63
|
+
if (values = opts[:raw])
|
64
|
+
@has_z, @has_m, @min_x, @max_x, @min_y, @max_y, @min_z, @max_z, @min_m, @max_m = values
|
63
65
|
else
|
64
|
-
@has_z = !
|
65
|
-
@has_m = !
|
66
|
+
@has_z = !opts[:ignore_z] && factory.property(:has_z_coordinate) ? true : false
|
67
|
+
@has_m = !opts[:ignore_m] && factory.property(:has_m_coordinate) ? true : false
|
66
68
|
@min_x = @max_x = @min_y = @max_y = @min_z = @max_z = @min_m = @max_m = nil
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
70
|
-
def eql?(
|
71
|
-
|
72
|
-
@min_x ==
|
73
|
-
@min_y ==
|
74
|
-
@min_z ==
|
75
|
-
@min_m ==
|
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
|
76
78
|
end
|
77
79
|
alias == eql?
|
78
80
|
|
@@ -196,10 +198,10 @@ module RGeo
|
|
196
198
|
|
197
199
|
def min_point
|
198
200
|
if @min_x
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
@factory.point(@min_x, @min_y, *
|
201
|
+
extras = []
|
202
|
+
extras << @min_z if @has_z
|
203
|
+
extras << @min_m if @has_m
|
204
|
+
@factory.point(@min_x, @min_y, *extras)
|
203
205
|
end
|
204
206
|
end
|
205
207
|
|
@@ -208,10 +210,10 @@ module RGeo
|
|
208
210
|
|
209
211
|
def max_point
|
210
212
|
if @min_x
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
@factory.point(@max_x, @max_y, *
|
213
|
+
extras = []
|
214
|
+
extras << @max_z if @has_z
|
215
|
+
extras << @max_m if @has_m
|
216
|
+
@factory.point(@max_x, @max_y, *extras)
|
215
217
|
end
|
216
218
|
end
|
217
219
|
|
@@ -219,16 +221,16 @@ module RGeo
|
|
219
221
|
# object, which may be a geometry or another bounding box.
|
220
222
|
# Returns self.
|
221
223
|
|
222
|
-
def add(
|
223
|
-
case
|
224
|
+
def add(geometry)
|
225
|
+
case geometry
|
224
226
|
when BoundingBox
|
225
|
-
add(
|
226
|
-
add(
|
227
|
+
add(geometry.min_point)
|
228
|
+
add(geometry.max_point)
|
227
229
|
when Feature::Geometry
|
228
|
-
if
|
229
|
-
|
230
|
+
if geometry.factory == @factory
|
231
|
+
add_geometry(geometry)
|
230
232
|
else
|
231
|
-
|
233
|
+
add_geometry(Feature.cast(geometry, @factory))
|
232
234
|
end
|
233
235
|
end
|
234
236
|
self
|
@@ -241,23 +243,23 @@ module RGeo
|
|
241
243
|
|
242
244
|
def to_geometry
|
243
245
|
if @min_x
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
246
|
+
extras = []
|
247
|
+
extras << @min_z if @has_z
|
248
|
+
extras << @min_m if @has_m
|
249
|
+
point_min = @factory.point(@min_x, @min_y, *extras)
|
248
250
|
if infinitesimal?
|
249
|
-
|
251
|
+
point_min
|
250
252
|
else
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
253
|
+
extras = []
|
254
|
+
extras << @max_z if @has_z
|
255
|
+
extras << @max_m if @has_m
|
256
|
+
point_max = @factory.point(@max_x, @max_y, *extras)
|
255
257
|
if degenerate?
|
256
|
-
@factory.line(
|
258
|
+
@factory.line(point_min, point_max)
|
257
259
|
else
|
258
|
-
@factory.polygon(@factory.linear_ring([
|
259
|
-
@factory.point(@max_x, @min_y, *
|
260
|
-
@factory.point(@min_x, @max_y, *
|
260
|
+
@factory.polygon(@factory.linear_ring([point_min,
|
261
|
+
@factory.point(@max_x, @min_y, *extras), point_max,
|
262
|
+
@factory.point(@min_x, @max_y, *extras), point_min]))
|
261
263
|
end
|
262
264
|
end
|
263
265
|
else
|
@@ -277,18 +279,18 @@ module RGeo
|
|
277
279
|
# Ignore the M coordinate when testing, even if both objects
|
278
280
|
# have M. Default is false.
|
279
281
|
|
280
|
-
def contains?(
|
281
|
-
if Feature::Geometry ===
|
282
|
-
contains?(BoundingBox.new(@factory).add(
|
283
|
-
elsif
|
282
|
+
def contains?(rhs, opts = {})
|
283
|
+
if Feature::Geometry === rhs
|
284
|
+
contains?(BoundingBox.new(@factory).add(rhs))
|
285
|
+
elsif rhs.empty?
|
284
286
|
true
|
285
287
|
elsif empty?
|
286
288
|
false
|
287
|
-
elsif @min_x >
|
289
|
+
elsif @min_x > rhs.min_x || @max_x < rhs.max_x || @min_y > rhs.min_y || @max_y < rhs.max_y
|
288
290
|
false
|
289
|
-
elsif @has_m &&
|
291
|
+
elsif @has_m && rhs.has_m && !opts[:ignore_m] && (@min_m > rhs.min_m || @max_m < rhs.max_m)
|
290
292
|
false
|
291
|
-
elsif @has_z &&
|
293
|
+
elsif @has_z && rhs.has_z && !opts[:ignore_z] && (@min_z > rhs.min_z || @max_z < rhs.max_z)
|
292
294
|
false
|
293
295
|
else
|
294
296
|
true
|
@@ -309,7 +311,7 @@ module RGeo
|
|
309
311
|
# greater than this factor, the bounding box is divided only in
|
310
312
|
# half instead of fourths.
|
311
313
|
|
312
|
-
def subdivide(
|
314
|
+
def subdivide(opts = {})
|
313
315
|
return [] if empty?
|
314
316
|
if infinitesimal?
|
315
317
|
return [
|
@@ -317,17 +319,17 @@ module RGeo
|
|
317
319
|
@min_x, @max_x, @min_y, @max_y, @min_z, @max_z, @min_m, @max_m])
|
318
320
|
]
|
319
321
|
end
|
320
|
-
|
321
|
-
|
322
|
-
if
|
323
|
-
if x_span > y_span *
|
322
|
+
factor = opts[:bisect_factor]
|
323
|
+
factor ||= 1 if degenerate?
|
324
|
+
if factor
|
325
|
+
if x_span > y_span * factor
|
324
326
|
return [
|
325
327
|
BoundingBox.new(@factory, raw: [@has_z, @has_m,
|
326
328
|
@min_x, center_x, @min_y, @max_y, @min_z, @max_z, @min_m, @max_m]),
|
327
329
|
BoundingBox.new(@factory, raw: [@has_z, @has_m,
|
328
330
|
center_x, @max_x, @min_y, @max_y, @min_z, @max_z, @min_m, @max_m])
|
329
331
|
]
|
330
|
-
elsif y_span > x_span *
|
332
|
+
elsif y_span > x_span * factor
|
331
333
|
return [
|
332
334
|
BoundingBox.new(@factory, raw: [@has_z, @has_m,
|
333
335
|
@min_x, @max_x, @min_y, center_y, @min_z, @max_z, @min_m, @max_m]),
|
@@ -348,49 +350,51 @@ module RGeo
|
|
348
350
|
]
|
349
351
|
end
|
350
352
|
|
351
|
-
def
|
352
|
-
case
|
353
|
+
def add_geometry(geometry)
|
354
|
+
case geometry
|
353
355
|
when Feature::Point
|
354
|
-
|
356
|
+
add_point(geometry)
|
355
357
|
when Feature::LineString
|
356
|
-
|
358
|
+
geometry.points.each { |p| add_point(p) }
|
357
359
|
when Feature::Polygon
|
358
|
-
|
360
|
+
geometry.exterior_ring.points.each { |p| add_point(p) }
|
359
361
|
when Feature::MultiPoint
|
360
|
-
|
362
|
+
geometry.each { |p| add_point(p) }
|
361
363
|
when Feature::MultiLineString
|
362
|
-
|
364
|
+
geometry.each { |line| line.points.each { |p| add_point(p) } }
|
363
365
|
when Feature::MultiPolygon
|
364
|
-
|
366
|
+
geometry.each { |poly| poly.exterior_ring.points.each { |p| add_point(p) } }
|
365
367
|
when Feature::GeometryCollection
|
366
|
-
|
368
|
+
geometry.each { |g| add_geometry(g) }
|
367
369
|
end
|
368
370
|
self
|
369
371
|
end
|
370
372
|
|
371
|
-
|
373
|
+
private
|
374
|
+
|
375
|
+
def add_point(point)
|
372
376
|
if @min_x
|
373
|
-
|
374
|
-
@min_x =
|
375
|
-
@max_x =
|
376
|
-
y_ =
|
377
|
+
x = point.x
|
378
|
+
@min_x = x if x < @min_x
|
379
|
+
@max_x = x if x > @max_x
|
380
|
+
y_ = point.y
|
377
381
|
@min_y = y_ if y_ < @min_y
|
378
382
|
@max_y = y_ if y_ > @max_y
|
379
383
|
if @has_z
|
380
|
-
z_ =
|
384
|
+
z_ = point.z
|
381
385
|
@min_z = z_ if z_ < @min_z
|
382
386
|
@max_z = z_ if z_ > @max_z
|
383
387
|
end
|
384
388
|
if @has_m
|
385
|
-
m_ =
|
389
|
+
m_ = point.m
|
386
390
|
@min_m = m_ if m_ < @min_m
|
387
391
|
@max_m = m_ if m_ > @max_m
|
388
392
|
end
|
389
393
|
else
|
390
|
-
@min_x = @max_x =
|
391
|
-
@min_y = @max_y =
|
392
|
-
@min_z = @max_z =
|
393
|
-
@min_m = @max_m =
|
394
|
+
@min_x = @max_x = point.x
|
395
|
+
@min_y = @max_y = point.y
|
396
|
+
@min_z = @max_z = point.z if @has_z
|
397
|
+
@min_m = @max_m = point.m if @has_m
|
394
398
|
end
|
395
399
|
end
|
396
400
|
end
|