Class: Terraformer::Polygon
Constant Summary
Constants inherited
from Geometry
Geometry::MULTI_REGEX
Instance Attribute Summary
Attributes inherited from Geometry
#coordinates, #crs
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Geometry
#convex_hull, #each_coordinate, #geographic?, #get, #intersects?, iter_coordinate, #map_coordinate, #mercator?, #to_feature, #to_geographic, #to_hash, #to_mercator
#arrays_intersect_arrays?, #coordinates_contain_point?, #edge_intersects_edge?, #line_contains_point?
Methods inherited from Primitive
#bbox, #envelope, #to_json, #type
Constructor Details
#initialize(*args) ⇒ Polygon
Returns a new instance of Polygon.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/terraformer/polygon.rb', line 5
def initialize *args
if Coordinate === args[0] || (Array === args[0] && Numeric === args[0][0])
self.coordinates = [Coordinate.from_array(args)]
elsif Array === args[0]
if Coordinate === args[0][0] ||
Array === args[0][0] && Numeric === args[0][0][0]
self.coordinates = Coordinate.from_array args
elsif Array === args[0][0] && Array === args[0][0][0]
self.coordinates = Coordinate.from_array *args
end
else
super *args
end
unless Array === coordinates &&
Array === coordinates[0] &&
Terraformer::Coordinate === coordinates[0][0]
raise ArgumentError.new 'invalid coordinates for Terraformer::Polygon'
end
if line_strings.map(&:linear_ring?).include? false
raise ArgumentError.new 'not linear ring'
end
end
|
Class Method Details
.polygonally_equal?(a, b) ⇒ Boolean
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/terraformer/polygon.rb', line 144
def self.polygonally_equal? a, b
if Terraformer::Coordinate === a ||
Terraformer::Coordinate === b
return a == b
end
raise ArgumentError unless Enumerable === a
raise ArgumentError unless Enumerable === b
return false if a.length != b.length
return false if a[0] != a[-1]
return false if b[0] != b[-1]
equal = true
a = a.clone
b = b.clone
a.pop
b.pop
begin
b.rotate_until_first_equals a[0]
return a == b
rescue IndexError
return false
end
end
|
Instance Method Details
#==(obj) ⇒ Object
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/terraformer/polygon.rb', line 47
def == obj
super obj do |o|
equal = true
equal = Polygon.polygonally_equal? self.coordinates[0], obj.coordinates[0]
if equal
if self.coordinates.length == obj.coordinates.length and obj.coordinates.length > 1
self_holes = self.coordinates[1..-1].sort
obj_holes = obj.coordinates[1..-1].sort
self_holes.each_with_index do |hole, idx|
equal = Polygon.polygonally_equal? hole, obj_holes[idx]
break unless equal
end
end
end
equal
end
end
|
#add_vertex(p) ⇒ Object
Also known as:
<<
122
123
124
|
# File 'lib/terraformer/polygon.rb', line 122
def add_vertex p
insert_vertex -2, p
end
|
#contains?(obj) ⇒ Boolean
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/terraformer/polygon.rb', line 83
def contains? obj
obj = Coordinate.new obj if Array === obj and Numeric === obj[0]
obj = obj.to_point if Coordinate === obj
contained = false
case obj
when Point
contained = Geometry.coordinates_contain_point? coordinates[0], obj.coordinates
contained = !holes.any? {|h| h.contains? obj} if contained and has_holes?
when MultiPoint
contained = obj.points.all? {|p| contains? p}
when LineString
contained = contains?(obj.first_coordinate) && !Geometry.array_intersects_multi_array?(obj.coordinates, coordinates)
when MultiLineString
contained = obj.line_strings.all? {|ls| contains? ls}
when Polygon
contained = obj.within? self
when MultiPolygon
contained = obj.polygons.all? {|p| p.within? self}
else
raise ArgumentError.new "unsupported type: #{obj.type rescue obj.class}"
end
contained
end
|
#first_coordinate ⇒ Object
43
44
45
|
# File 'lib/terraformer/polygon.rb', line 43
def first_coordinate
coordinates[0][0]
end
|
#has_holes? ⇒ Boolean
39
40
41
|
# File 'lib/terraformer/polygon.rb', line 39
def has_holes?
coordinates.length > 1
end
|
#holes ⇒ Object
78
79
80
81
|
# File 'lib/terraformer/polygon.rb', line 78
def holes
return nil unless has_holes?
coordinates[1..-1].map {|hole| Polygon.new hole}
end
|
#insert_vertex(idx, p) ⇒ Object
127
128
129
130
131
|
# File 'lib/terraformer/polygon.rb', line 127
def insert_vertex idx, p
p = p.coordinates if Point === p
raise ArgumentError unless Coordinate === p
coordinates[0].insert idx, p
end
|
#line_strings ⇒ Object
74
75
76
|
# File 'lib/terraformer/polygon.rb', line 74
def line_strings
coordinates.map {|lr| LineString.new lr}
end
|
#remove_vertex(p) ⇒ Object
133
134
135
136
137
|
# File 'lib/terraformer/polygon.rb', line 133
def remove_vertex p
p = p.coordinates if Point === p
raise ArgumentError unless Coordinate === p
coordinates[0].delete p
end
|
#remove_vertex_at(idx) ⇒ Object
139
140
141
|
# File 'lib/terraformer/polygon.rb', line 139
def remove_vertex_at idx
coordinates[0].delete_at idx
end
|
#within?(obj) ⇒ Boolean
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/terraformer/polygon.rb', line 107
def within? obj
case obj
when Polygon
if self == obj
true
elsif obj.contains? first_coordinate
!Geometry.arrays_intersect_arrays?(coordinates, obj.coordinates)
end
when MultiPolygon
obj.polygons.any? {|p| p.contains? self}
else
raise ArgumentError.new "unsupported type: #{obj.type rescue obj.class}"
end
end
|