rgeo 2.3.0 → 3.0.0.pre.rc.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/.yardopts +6 -0
- data/README.md +1 -0
- data/ext/geos_c_impl/analysis.c +8 -6
- data/ext/geos_c_impl/analysis.h +1 -3
- data/ext/geos_c_impl/errors.c +10 -8
- data/ext/geos_c_impl/errors.h +7 -3
- data/ext/geos_c_impl/extconf.rb +3 -0
- data/ext/geos_c_impl/factory.c +251 -182
- data/ext/geos_c_impl/factory.h +43 -62
- data/ext/geos_c_impl/geometry.c +56 -24
- data/ext/geos_c_impl/geometry.h +8 -3
- data/ext/geos_c_impl/geometry_collection.c +41 -148
- data/ext/geos_c_impl/geometry_collection.h +1 -14
- data/ext/geos_c_impl/globals.c +91 -0
- data/ext/geos_c_impl/globals.h +45 -0
- data/ext/geos_c_impl/line_string.c +28 -29
- data/ext/geos_c_impl/line_string.h +1 -3
- data/ext/geos_c_impl/main.c +10 -9
- data/ext/geos_c_impl/point.c +9 -8
- data/ext/geos_c_impl/point.h +1 -3
- data/ext/geos_c_impl/polygon.c +15 -51
- data/ext/geos_c_impl/polygon.h +1 -3
- data/ext/geos_c_impl/preface.h +8 -0
- data/lib/rgeo/cartesian/analysis.rb +2 -2
- data/lib/rgeo/cartesian/calculations.rb +54 -17
- data/lib/rgeo/cartesian/factory.rb +0 -7
- data/lib/rgeo/cartesian/feature_classes.rb +66 -46
- data/lib/rgeo/cartesian/feature_methods.rb +56 -20
- data/lib/rgeo/cartesian/interface.rb +0 -6
- data/lib/rgeo/cartesian/planar_graph.rb +379 -0
- data/lib/rgeo/cartesian/sweepline_intersector.rb +149 -0
- data/lib/rgeo/cartesian/valid_op.rb +71 -0
- data/lib/rgeo/cartesian.rb +3 -0
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +6 -6
- data/lib/rgeo/error.rb +15 -0
- data/lib/rgeo/feature/curve.rb +12 -2
- data/lib/rgeo/feature/geometry.rb +38 -28
- data/lib/rgeo/feature/geometry_collection.rb +13 -5
- data/lib/rgeo/feature/line_string.rb +3 -3
- data/lib/rgeo/feature/multi_curve.rb +6 -1
- data/lib/rgeo/feature/multi_surface.rb +3 -3
- data/lib/rgeo/feature/point.rb +4 -4
- data/lib/rgeo/feature/surface.rb +3 -3
- data/lib/rgeo/geographic/factory.rb +0 -7
- data/lib/rgeo/geographic/interface.rb +4 -18
- data/lib/rgeo/geographic/proj4_projector.rb +0 -2
- data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
- data/lib/rgeo/geographic/projected_feature_methods.rb +63 -30
- data/lib/rgeo/geographic/simple_mercator_projector.rb +0 -2
- data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
- data/lib/rgeo/geographic/spherical_feature_methods.rb +68 -2
- data/lib/rgeo/geos/capi_factory.rb +21 -31
- data/lib/rgeo/geos/capi_feature_classes.rb +64 -11
- data/lib/rgeo/geos/ffi_factory.rb +0 -28
- data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
- data/lib/rgeo/geos/ffi_feature_methods.rb +53 -10
- data/lib/rgeo/geos/interface.rb +18 -10
- data/lib/rgeo/geos/zm_factory.rb +0 -12
- data/lib/rgeo/geos/zm_feature_methods.rb +30 -5
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +18 -8
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -1
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +37 -26
- data/lib/rgeo/impl_helper/basic_point_methods.rb +13 -3
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +8 -3
- data/lib/rgeo/impl_helper/valid_op.rb +354 -0
- data/lib/rgeo/impl_helper/validity_check.rb +138 -0
- data/lib/rgeo/impl_helper.rb +1 -0
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +1 -1
- data/lib/rgeo/wkrep/wkt_generator.rb +6 -6
- metadata +30 -7
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# -----------------------------------------------------------------------------
|
4
|
+
#
|
5
|
+
# Simple Sweepline Intersector Class
|
6
|
+
#
|
7
|
+
# -----------------------------------------------------------------------------
|
8
|
+
|
9
|
+
module RGeo
|
10
|
+
module Cartesian
|
11
|
+
# Implements a Sweepline intersector to find all intersections
|
12
|
+
# in a group of segments. The idea is to use a horizontal line starting
|
13
|
+
# at y = +Infinity that sweeps down to y = -Infinity and every time it hits
|
14
|
+
# a new line, it will check if it intersects with any of the segments
|
15
|
+
# the line currently intersects at that y value.
|
16
|
+
# This is a more simplistic implementation that uses an array to hold
|
17
|
+
# observed segments instead of a sorted BST, so performance may be significantly
|
18
|
+
# worse in the case of lots of segments overlapping in y-ranges.
|
19
|
+
class SweeplineIntersector
|
20
|
+
Event = Struct.new(:point, :segment, :is_start)
|
21
|
+
Intersection = Struct.new(:point, :s1, :s2)
|
22
|
+
|
23
|
+
def initialize(segments)
|
24
|
+
@segments = segments
|
25
|
+
end
|
26
|
+
attr_reader :segments
|
27
|
+
|
28
|
+
# Returns the "proper" intersections from the list of segments.
|
29
|
+
#
|
30
|
+
# This will only return intersections that are not the start/end or
|
31
|
+
# end/start of the 2 segments. This could be useful for finding intersections
|
32
|
+
# in a ring for example, because knowing that segments are connected in a linestring
|
33
|
+
# is not always helpful, but those are reported by default.
|
34
|
+
#
|
35
|
+
# Note: This is not the true definition of a proper intersection. A
|
36
|
+
# truly proper intersection does not include colinear intersections and
|
37
|
+
# the intersection must lie in the interior of both segments.
|
38
|
+
#
|
39
|
+
# @return [Array<RGeo::Cartesian::SweeplineIntersector::Intersection>]
|
40
|
+
def proper_intersections
|
41
|
+
return @proper_intersections if defined?(@proper_intersections)
|
42
|
+
|
43
|
+
@proper_intersections = []
|
44
|
+
intersections.each do |intersection|
|
45
|
+
s1 = intersection.s1
|
46
|
+
s2 = intersection.s2
|
47
|
+
pt = intersection.point
|
48
|
+
|
49
|
+
unless (pt == s1.s && pt == s2.e) || (pt == s1.e && pt == s2.s)
|
50
|
+
@proper_intersections << intersection
|
51
|
+
end
|
52
|
+
end
|
53
|
+
@proper_intersections
|
54
|
+
end
|
55
|
+
|
56
|
+
# Computes the intersections of the input segments.
|
57
|
+
#
|
58
|
+
# Creates an event queue from the +events+ and adds segments to the
|
59
|
+
# +observed_segments+ array while their ending event has not been popped
|
60
|
+
# from the queue.
|
61
|
+
#
|
62
|
+
# Compares the new segment from the +is_start+ event to each observed segment
|
63
|
+
# then adds it to +observed_segments+. Records any intersections in to the
|
64
|
+
# returned array.
|
65
|
+
#
|
66
|
+
# @return [Array<RGeo::Cartesian::SweeplineIntersector::Intersection>]
|
67
|
+
def intersections
|
68
|
+
return @intersections if defined?(@intersections)
|
69
|
+
|
70
|
+
@intersections = []
|
71
|
+
observed_segments = Set.new
|
72
|
+
events.each do |e|
|
73
|
+
seg = e.segment
|
74
|
+
|
75
|
+
if e.is_start
|
76
|
+
observed_segments.each do |oseg|
|
77
|
+
int_pt = seg.segment_intersection(oseg)
|
78
|
+
if int_pt
|
79
|
+
intersect = Intersection.new(int_pt, seg, oseg)
|
80
|
+
@intersections << intersect
|
81
|
+
end
|
82
|
+
end
|
83
|
+
observed_segments << seg
|
84
|
+
else
|
85
|
+
observed_segments.delete(seg)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
@intersections
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns an ordered array of events from the input segments. Events
|
92
|
+
# are the start and endpoints of each segment with an is_start tag to
|
93
|
+
# indicate if this is the starting or ending event for that segment.
|
94
|
+
#
|
95
|
+
# Ordering is done by greatest-y -> smallest-x -> is_start = true.
|
96
|
+
#
|
97
|
+
# @return [Array]
|
98
|
+
def events
|
99
|
+
return @events if defined?(@events)
|
100
|
+
|
101
|
+
@events = []
|
102
|
+
segments.each do |segment|
|
103
|
+
event_pair = create_event_pair(segment)
|
104
|
+
@events.concat(event_pair)
|
105
|
+
end
|
106
|
+
|
107
|
+
@events.sort! do |a, b|
|
108
|
+
if a.point == b.point
|
109
|
+
if a.is_start
|
110
|
+
-1
|
111
|
+
else
|
112
|
+
1
|
113
|
+
end
|
114
|
+
elsif a.point.y == b.point.y
|
115
|
+
a.point.x <=> b.point.x
|
116
|
+
else
|
117
|
+
b.point.y <=> a.point.y
|
118
|
+
end
|
119
|
+
end
|
120
|
+
@events
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# Creates a pair of events from a segment
|
126
|
+
#
|
127
|
+
# @param segment [Segment]
|
128
|
+
#
|
129
|
+
# @return [Array]
|
130
|
+
def create_event_pair(segment)
|
131
|
+
s = segment.s
|
132
|
+
e = segment.e
|
133
|
+
|
134
|
+
s_event = Event.new(s, segment)
|
135
|
+
e_event = Event.new(e, segment)
|
136
|
+
|
137
|
+
if s.y > e.y || (s.y == e.y && s.x < e.x)
|
138
|
+
s_event.is_start = true
|
139
|
+
e_event.is_start = false
|
140
|
+
else
|
141
|
+
s_event.is_start = false
|
142
|
+
e_event.is_start = true
|
143
|
+
end
|
144
|
+
|
145
|
+
[s_event, e_event]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RGeo
|
4
|
+
module Cartesian
|
5
|
+
module ValidOp
|
6
|
+
include ImplHelper::ValidOp
|
7
|
+
|
8
|
+
def validity_helper
|
9
|
+
ValidOpHelpers
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ValidOpHelpers
|
14
|
+
include ImplHelper::ValidOpHelpers
|
15
|
+
|
16
|
+
module_function(*ImplHelper::ValidOpHelpers.singleton_methods) # rubocop:disable Style/AccessModifierDeclarations
|
17
|
+
|
18
|
+
module_function
|
19
|
+
|
20
|
+
# Checks that there are no invalid intersections between the components
|
21
|
+
# of a polygon.
|
22
|
+
#
|
23
|
+
# @param [RGeo::Feature::Polygon] poly
|
24
|
+
#
|
25
|
+
# @return [String] invalid_reason
|
26
|
+
def check_consistent_area(poly)
|
27
|
+
# Get set of unique coords
|
28
|
+
pts = poly.exterior_ring.coordinates.to_set
|
29
|
+
poly.interior_rings.each do |ring|
|
30
|
+
pts += ring.coordinates
|
31
|
+
end
|
32
|
+
num_points = pts.size
|
33
|
+
|
34
|
+
# if additional nodes were added, there must be an intersection
|
35
|
+
# through a boundary.
|
36
|
+
if poly.send(:graph).incident_edges.size > num_points
|
37
|
+
return Error::SELF_INTERSECTION
|
38
|
+
end
|
39
|
+
|
40
|
+
rings = [poly.exterior_ring] + poly.interior_rings
|
41
|
+
return Error::SELF_INTERSECTION if rings.uniq.size != rings.size
|
42
|
+
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Checks that the interior of a polygon is connected.
|
47
|
+
#
|
48
|
+
# Process to do this is to walk around an interior cycle of the
|
49
|
+
# exterior shell in the polygon's geometry graph. It will keep track
|
50
|
+
# of all the nodes it visited and if that set is a superset of the
|
51
|
+
# coordinates in the exterior_ring, the interior is connected, otherwise
|
52
|
+
# it is split somewhere.
|
53
|
+
#
|
54
|
+
# @param [RGeo::Feature::Polygon] poly
|
55
|
+
#
|
56
|
+
# @return [String] invalid_reason
|
57
|
+
def check_connected_interiors(poly)
|
58
|
+
exterior_coords = poly.exterior_ring.coordinates.to_set
|
59
|
+
|
60
|
+
visited = Set.new
|
61
|
+
poly.send(:graph).geom_edges.first.exterior_edge.and_connected do |hedge|
|
62
|
+
visited << hedge.origin.coordinates
|
63
|
+
end
|
64
|
+
|
65
|
+
return Error::DISCONNECTED_INTERIOR unless exterior_coords.subset?(visited)
|
66
|
+
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/rgeo/cartesian.rb
CHANGED
@@ -8,8 +8,11 @@
|
|
8
8
|
|
9
9
|
require_relative "cartesian/calculations"
|
10
10
|
require_relative "cartesian/feature_methods"
|
11
|
+
require_relative "cartesian/valid_op"
|
11
12
|
require_relative "cartesian/feature_classes"
|
12
13
|
require_relative "cartesian/factory"
|
13
14
|
require_relative "cartesian/interface"
|
14
15
|
require_relative "cartesian/bounding_box"
|
15
16
|
require_relative "cartesian/analysis"
|
17
|
+
require_relative "cartesian/sweepline_intersector"
|
18
|
+
require_relative "cartesian/planar_graph"
|
@@ -24,7 +24,7 @@ module RGeo
|
|
24
24
|
return value
|
25
25
|
end
|
26
26
|
unless @cur_token.is_a?(TypeString)
|
27
|
-
raise Error::ParseError
|
27
|
+
raise Error::ParseError, "Found token #{@cur_token} when we expected a value"
|
28
28
|
end
|
29
29
|
type = @cur_token
|
30
30
|
next_token
|
@@ -48,7 +48,7 @@ module RGeo
|
|
48
48
|
when "TOWGS84"
|
49
49
|
bursa_wolf_params = args.find_all(Numeric)
|
50
50
|
unless bursa_wolf_params.size == 7
|
51
|
-
raise Error::ParseError
|
51
|
+
raise Error::ParseError, "Expected 7 Bursa Wolf parameters but found #{bursa_wolf_params.size}"
|
52
52
|
end
|
53
53
|
obj = WGS84ConversionInfo.create(*bursa_wolf_params)
|
54
54
|
when "UNIT"
|
@@ -87,7 +87,7 @@ module RGeo
|
|
87
87
|
unit = args.find_first(Unit)
|
88
88
|
axes = args.find_all(AxisInfo)
|
89
89
|
unless axes.size > 0
|
90
|
-
raise Error::ParseError
|
90
|
+
raise Error::ParseError, "Expected at least one AXIS in a LOCAL_CS"
|
91
91
|
end
|
92
92
|
obj = LocalCoordinateSystem.create(name, local_datum, unit, axes, *args.create_optionals)
|
93
93
|
when "GEOCCS"
|
@@ -97,7 +97,7 @@ module RGeo
|
|
97
97
|
linear_unit = args.find_first(LinearUnit)
|
98
98
|
axes = args.find_all(AxisInfo)
|
99
99
|
unless axes.size == 0 || axes.size == 3
|
100
|
-
raise Error::ParseError
|
100
|
+
raise Error::ParseError, "GEOCCS must contain either 0 or 3 AXIS parameters"
|
101
101
|
end
|
102
102
|
obj = GeocentricCoordinateSystem.create(name, horizontal_datum, prime_meridian, linear_unit, axes[0], axes[1], axes[2], *args.create_optionals)
|
103
103
|
when "VERT_CS"
|
@@ -113,7 +113,7 @@ module RGeo
|
|
113
113
|
angular_unit = args.find_first(AngularUnit)
|
114
114
|
axes = args.find_all(AxisInfo)
|
115
115
|
unless axes.size == 0 || axes.size == 2
|
116
|
-
raise Error::ParseError
|
116
|
+
raise Error::ParseError, "GEOGCS must contain either 0 or 2 AXIS parameters"
|
117
117
|
end
|
118
118
|
obj = GeographicCoordinateSystem.create(name, angular_unit, horizontal_datum, prime_meridian, axes[0], axes[1], *args.create_optionals)
|
119
119
|
when "PROJCS"
|
@@ -125,7 +125,7 @@ module RGeo
|
|
125
125
|
linear_unit = args.find_first(LinearUnit)
|
126
126
|
axes = args.find_all(AxisInfo)
|
127
127
|
unless axes.size == 0 || axes.size == 2
|
128
|
-
raise Error::ParseError
|
128
|
+
raise Error::ParseError, "PROJCS must contain either 0 or 2 AXIS parameters"
|
129
129
|
end
|
130
130
|
obj = ProjectedCoordinateSystem.create(name, geographic_coordinate_system, projection, linear_unit, axes[0], axes[1], *args.create_optionals)
|
131
131
|
else
|
data/lib/rgeo/error.rb
CHANGED
@@ -29,5 +29,20 @@ module RGeo
|
|
29
29
|
# Parsing failed
|
30
30
|
class ParseError < RGeoError
|
31
31
|
end
|
32
|
+
|
33
|
+
# Standard error messages from
|
34
|
+
# https://github.com/locationtech/jts/blob/0afbfb1956ec24912a8b4dc4edff0f1200442857/modules/core/src/main/java/org/locationtech/jts/operation/valid/TopologyValidationError.java#L98-L110
|
35
|
+
TOPOLOGY_VALIDATION_ERR = "Topology Validation Error"
|
36
|
+
REPEATED_POINT = "Repeated Point"
|
37
|
+
HOLE_OUTSIDE_SHELL = "Hole lies outside shell"
|
38
|
+
NESTED_HOLES = "Holes are nested"
|
39
|
+
DISCONNECTED_INTERIOR = "Interior is disconnected"
|
40
|
+
SELF_INTERSECTION = "Self-intersection"
|
41
|
+
RING_SELF_INTERSECTION = "Ring Self-intersection"
|
42
|
+
NESTED_SHELLS = "Nested shells"
|
43
|
+
DUPLICATE_RINGS = "Duplicate Rings"
|
44
|
+
TOO_FEW_POINTS = "Too few distinct points in geometry component"
|
45
|
+
INVALID_COORDINATE = "Invalid Coordinate"
|
46
|
+
UNCLOSED_RING = "Ring is not closed"
|
32
47
|
end
|
33
48
|
end
|
data/lib/rgeo/feature/curve.rb
CHANGED
@@ -90,8 +90,13 @@ module RGeo
|
|
90
90
|
# Returns a boolean value. Note that this is different from the SFS
|
91
91
|
# specification, which stipulates an integer return value.
|
92
92
|
|
93
|
+
def closed?
|
94
|
+
raise Error::UnsupportedOperation, "Method Curve#closed? not defined."
|
95
|
+
end
|
96
|
+
|
93
97
|
def is_closed?
|
94
|
-
|
98
|
+
warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
99
|
+
closed?
|
95
100
|
end
|
96
101
|
|
97
102
|
# === SFS 1.1 Description
|
@@ -105,8 +110,13 @@ module RGeo
|
|
105
110
|
# Returns a boolean value. Note that this is different from the SFS
|
106
111
|
# specification, which stipulates an integer return value.
|
107
112
|
|
113
|
+
def ring?
|
114
|
+
raise Error::UnsupportedOperation, "Method Curve#ring? not defined."
|
115
|
+
end
|
116
|
+
|
108
117
|
def is_ring?
|
109
|
-
|
118
|
+
warn "The is_ring? method is deprecated, please use the ring? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
119
|
+
ring?
|
110
120
|
end
|
111
121
|
end
|
112
122
|
end
|
@@ -90,7 +90,7 @@ module RGeo
|
|
90
90
|
# operations on them.)
|
91
91
|
|
92
92
|
def factory
|
93
|
-
raise Error::UnsupportedOperation, "Method
|
93
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#factory not defined."
|
94
94
|
end
|
95
95
|
|
96
96
|
# === SFS 1.1 Description
|
@@ -105,7 +105,7 @@ module RGeo
|
|
105
105
|
# point geometries, 1 for curves, and 2 for surfaces.
|
106
106
|
|
107
107
|
def dimension
|
108
|
-
raise Error::UnsupportedOperation, "Method
|
108
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#dimension not defined."
|
109
109
|
end
|
110
110
|
|
111
111
|
# === SFS 1.1 Description
|
@@ -122,7 +122,7 @@ module RGeo
|
|
122
122
|
# call the +type_name+ method of the returned module.
|
123
123
|
|
124
124
|
def geometry_type
|
125
|
-
raise Error::UnsupportedOperation, "Method
|
125
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#geometry_type not defined."
|
126
126
|
end
|
127
127
|
|
128
128
|
# === SFS 1.1 Description
|
@@ -137,7 +137,7 @@ module RGeo
|
|
137
137
|
# stored in either the same or some other datastore.
|
138
138
|
|
139
139
|
def srid
|
140
|
-
raise Error::UnsupportedOperation, "Method
|
140
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#srid not defined."
|
141
141
|
end
|
142
142
|
|
143
143
|
# === SFS 1.1 Description
|
@@ -151,7 +151,7 @@ module RGeo
|
|
151
151
|
# Returns an object that supports the Geometry interface.
|
152
152
|
|
153
153
|
def envelope
|
154
|
-
raise Error::UnsupportedOperation, "Method
|
154
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#envelope not defined."
|
155
155
|
end
|
156
156
|
|
157
157
|
# === SFS 1.1 Description
|
@@ -164,7 +164,7 @@ module RGeo
|
|
164
164
|
# Returns an ASCII string.
|
165
165
|
|
166
166
|
def as_text
|
167
|
-
raise Error::UnsupportedOperation, "Method
|
167
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#as_text not defined."
|
168
168
|
end
|
169
169
|
|
170
170
|
# === SFS 1.1 Description
|
@@ -177,7 +177,7 @@ module RGeo
|
|
177
177
|
# Returns a binary string.
|
178
178
|
|
179
179
|
def as_binary
|
180
|
-
raise Error::UnsupportedOperation, "Method
|
180
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#as_binary not defined."
|
181
181
|
end
|
182
182
|
|
183
183
|
# === SFS 1.1 Description
|
@@ -191,8 +191,13 @@ module RGeo
|
|
191
191
|
# Returns a boolean value. Note that this is different from the SFS
|
192
192
|
# specification, which stipulates an integer return value.
|
193
193
|
|
194
|
+
def empty?
|
195
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#empty? not defined."
|
196
|
+
end
|
197
|
+
|
194
198
|
def is_empty?
|
195
|
-
|
199
|
+
warn "The is_empty? method is deprecated, please use the empty? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
200
|
+
empty?
|
196
201
|
end
|
197
202
|
|
198
203
|
# === SFS 1.1 Description
|
@@ -208,8 +213,13 @@ module RGeo
|
|
208
213
|
# Returns a boolean value. Note that this is different from the SFS
|
209
214
|
# specification, which stipulates an integer return value.
|
210
215
|
|
216
|
+
def simple?
|
217
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#simple? not defined."
|
218
|
+
end
|
219
|
+
|
211
220
|
def is_simple?
|
212
|
-
|
221
|
+
warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
222
|
+
simple?
|
213
223
|
end
|
214
224
|
|
215
225
|
# === SFS 1.1 Description
|
@@ -224,7 +234,7 @@ module RGeo
|
|
224
234
|
# Returns an object that supports the Geometry interface.
|
225
235
|
|
226
236
|
def boundary
|
227
|
-
raise Error::UnsupportedOperation, "Method
|
237
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#boundary not defined."
|
228
238
|
end
|
229
239
|
|
230
240
|
# === SFS 1.1 Description
|
@@ -243,7 +253,7 @@ module RGeo
|
|
243
253
|
# from different factories is undefined.
|
244
254
|
|
245
255
|
def equals?(another_geometry)
|
246
|
-
raise Error::UnsupportedOperation, "Method
|
256
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#equals? not defined."
|
247
257
|
end
|
248
258
|
|
249
259
|
# === SFS 1.1 Description
|
@@ -262,7 +272,7 @@ module RGeo
|
|
262
272
|
# from different factories is undefined.
|
263
273
|
|
264
274
|
def disjoint?(another_geometry)
|
265
|
-
raise Error::UnsupportedOperation, "Method
|
275
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#disjoint? not defined."
|
266
276
|
end
|
267
277
|
|
268
278
|
# === SFS 1.1 Description
|
@@ -281,7 +291,7 @@ module RGeo
|
|
281
291
|
# from different factories is undefined.
|
282
292
|
|
283
293
|
def intersects?(another_geometry)
|
284
|
-
raise Error::UnsupportedOperation, "Method
|
294
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#intersects? not defined."
|
285
295
|
end
|
286
296
|
|
287
297
|
# === SFS 1.1 Description
|
@@ -300,7 +310,7 @@ module RGeo
|
|
300
310
|
# from different factories is undefined.
|
301
311
|
|
302
312
|
def touches?(another_geometry)
|
303
|
-
raise Error::UnsupportedOperation, "Method
|
313
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#touches? not defined."
|
304
314
|
end
|
305
315
|
|
306
316
|
# === SFS 1.1 Description
|
@@ -319,7 +329,7 @@ module RGeo
|
|
319
329
|
# from different factories is undefined.
|
320
330
|
|
321
331
|
def crosses?(another_geometry)
|
322
|
-
raise Error::UnsupportedOperation, "Method
|
332
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#crosses? not defined."
|
323
333
|
end
|
324
334
|
|
325
335
|
# === SFS 1.1 Description
|
@@ -338,7 +348,7 @@ module RGeo
|
|
338
348
|
# from different factories is undefined.
|
339
349
|
|
340
350
|
def within?(another_geometry)
|
341
|
-
raise Error::UnsupportedOperation, "Method
|
351
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#within? not defined."
|
342
352
|
end
|
343
353
|
|
344
354
|
# === SFS 1.1 Description
|
@@ -357,7 +367,7 @@ module RGeo
|
|
357
367
|
# from different factories is undefined.
|
358
368
|
|
359
369
|
def contains?(another_geometry)
|
360
|
-
raise Error::UnsupportedOperation, "Method
|
370
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#contains? not defined."
|
361
371
|
end
|
362
372
|
|
363
373
|
# === SFS 1.1 Description
|
@@ -376,7 +386,7 @@ module RGeo
|
|
376
386
|
# from different factories is undefined.
|
377
387
|
|
378
388
|
def overlaps?(another_geometry)
|
379
|
-
raise Error::UnsupportedOperation, "Method
|
389
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#overlaps? not defined."
|
380
390
|
end
|
381
391
|
|
382
392
|
# === SFS 1.1 Description
|
@@ -402,7 +412,7 @@ module RGeo
|
|
402
412
|
# from different factories is undefined.
|
403
413
|
|
404
414
|
def relate?(another_geometry, _intersection_pattern_matrix_)
|
405
|
-
raise Error::UnsupportedOperation, "Method
|
415
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#relate not defined."
|
406
416
|
end
|
407
417
|
|
408
418
|
# === SFS 1.1 Description
|
@@ -421,7 +431,7 @@ module RGeo
|
|
421
431
|
# distance between objects from different factories is undefined.
|
422
432
|
|
423
433
|
def distance(another_geometry)
|
424
|
-
raise Error::UnsupportedOperation, "Method
|
434
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#distance not defined."
|
425
435
|
end
|
426
436
|
|
427
437
|
# === SFS 1.1 Description
|
@@ -436,7 +446,7 @@ module RGeo
|
|
436
446
|
# Returns an object that supports the Geometry interface.
|
437
447
|
|
438
448
|
def buffer(_distance_)
|
439
|
-
raise Error::UnsupportedOperation, "Method
|
449
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#buffer not defined."
|
440
450
|
end
|
441
451
|
|
442
452
|
# === SFS 1.1 Description
|
@@ -449,7 +459,7 @@ module RGeo
|
|
449
459
|
# Returns an object that supports the Geometry interface.
|
450
460
|
|
451
461
|
def convex_hull
|
452
|
-
raise Error::UnsupportedOperation, "Method
|
462
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#convex_hull not defined."
|
453
463
|
end
|
454
464
|
|
455
465
|
# === SFS 1.1 Description
|
@@ -467,7 +477,7 @@ module RGeo
|
|
467
477
|
# operations on objects from different factories is undefined.
|
468
478
|
|
469
479
|
def intersection(another_geometry)
|
470
|
-
raise Error::UnsupportedOperation, "Method
|
480
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#intersection not defined."
|
471
481
|
end
|
472
482
|
|
473
483
|
# === SFS 1.1 Description
|
@@ -485,7 +495,7 @@ module RGeo
|
|
485
495
|
# operations on objects from different factories is undefined.
|
486
496
|
|
487
497
|
def union(another_geometry)
|
488
|
-
raise Error::UnsupportedOperation, "Method
|
498
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#union not defined."
|
489
499
|
end
|
490
500
|
|
491
501
|
# === SFS 1.1 Description
|
@@ -503,7 +513,7 @@ module RGeo
|
|
503
513
|
# operations on objects from different factories is undefined.
|
504
514
|
|
505
515
|
def difference(another_geometry)
|
506
|
-
raise Error::UnsupportedOperation, "Method
|
516
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#difference not defined."
|
507
517
|
end
|
508
518
|
|
509
519
|
# === SFS 1.1 Description
|
@@ -521,7 +531,7 @@ module RGeo
|
|
521
531
|
# operations on objects from different factories is undefined.
|
522
532
|
|
523
533
|
def sym_difference(another_geometry)
|
524
|
-
raise Error::UnsupportedOperation, "Method
|
534
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#sym_difference not defined."
|
525
535
|
end
|
526
536
|
|
527
537
|
# Returns true if this geometric object is representationally
|
@@ -533,7 +543,7 @@ module RGeo
|
|
533
543
|
# from different factories is undefined.
|
534
544
|
|
535
545
|
def rep_equals?(another_geometry)
|
536
|
-
raise Error::UnsupportedOperation, "Method
|
546
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#rep_equals? not defined."
|
537
547
|
end
|
538
548
|
|
539
549
|
# Unions a collection of Geometry or a single Geometry
|
@@ -550,7 +560,7 @@ module RGeo
|
|
550
560
|
# returns nil.
|
551
561
|
#
|
552
562
|
def unary_union
|
553
|
-
raise Error::UnsupportedOperation, "Method
|
563
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#unary_union not defined."
|
554
564
|
end
|
555
565
|
|
556
566
|
# This method should behave almost the same as the rep_equals?
|
@@ -44,7 +44,7 @@ module RGeo
|
|
44
44
|
# Returns an integer.
|
45
45
|
|
46
46
|
def num_geometries
|
47
|
-
raise Error::UnsupportedOperation, "Method
|
47
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#num_geometries not defined."
|
48
48
|
end
|
49
49
|
|
50
50
|
# === SFS 1.1 Description
|
@@ -59,7 +59,7 @@ module RGeo
|
|
59
59
|
# in that it does not support negative indexes.
|
60
60
|
|
61
61
|
def geometry_n(n)
|
62
|
-
raise Error::UnsupportedOperation, "Method
|
62
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#geometry_n not defined."
|
63
63
|
end
|
64
64
|
|
65
65
|
# Alias of the num_geometries method.
|
@@ -79,13 +79,13 @@ module RGeo
|
|
79
79
|
# returns nil, where [-1] returns the last element of the collection.
|
80
80
|
|
81
81
|
def [](n)
|
82
|
-
raise Error::UnsupportedOperation, "Method
|
82
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#[] not defined."
|
83
83
|
end
|
84
84
|
|
85
85
|
# Nodes the linework in a list of Geometries
|
86
86
|
#
|
87
87
|
def node
|
88
|
-
raise Error::UnsupportedOperation, "Method
|
88
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#node not defined."
|
89
89
|
end
|
90
90
|
|
91
91
|
# Iterates over the geometries of this GeometryCollection.
|
@@ -96,7 +96,15 @@ module RGeo
|
|
96
96
|
# include the Enumerable mixin.
|
97
97
|
|
98
98
|
def each(&block)
|
99
|
-
raise Error::UnsupportedOperation, "Method
|
99
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#each not defined."
|
100
|
+
end
|
101
|
+
|
102
|
+
# Gives a point that is guaranteed to be within the geometry.
|
103
|
+
#
|
104
|
+
# Extends OGC SFS 1.1 and follows PostGIS standards.
|
105
|
+
# @see https://postgis.net/docs/ST_PointOnSurface.html
|
106
|
+
def point_on_surface
|
107
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#each not defined."
|
100
108
|
end
|
101
109
|
end
|
102
110
|
end
|
@@ -34,7 +34,7 @@ module RGeo
|
|
34
34
|
# Returns an integer.
|
35
35
|
|
36
36
|
def num_points
|
37
|
-
raise Error::UnsupportedOperation, "Method
|
37
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#num_points not defined."
|
38
38
|
end
|
39
39
|
|
40
40
|
# === SFS 1.1 Description
|
@@ -48,14 +48,14 @@ module RGeo
|
|
48
48
|
# Does not support negative indexes.
|
49
49
|
|
50
50
|
def point_n(n)
|
51
|
-
raise Error::UnsupportedOperation, "Method
|
51
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#point_n not defined."
|
52
52
|
end
|
53
53
|
|
54
54
|
# Returns the constituent points as an array of objects that
|
55
55
|
# support the Point interface.
|
56
56
|
|
57
57
|
def points
|
58
|
-
raise Error::UnsupportedOperation, "Method
|
58
|
+
raise Error::UnsupportedOperation, "Method #{self.class}#points not defined."
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|