geospatial 1.13.0 → 1.14.0
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/lib/geospatial/location.rb +15 -0
- data/lib/geospatial/polygon.rb +32 -2
- data/lib/geospatial/version.rb +1 -1
- data/spec/geospatial/location_spec.rb +23 -0
- data/spec/geospatial/polygon_spec.rb +32 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ef4b5ff93a87b5fb2733e6bbbe587be842c11ba2365131be98760bb66ee7143
|
4
|
+
data.tar.gz: 8468357c04f732b2a843ef154b7e93b8732dc334b9e76da989f22428b3eb18bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c97d956c5ef2b8b959d85f4ce07877020000b0d24ba5496edf82ef824b3d23c7c7f9471e5e48ae53f9524aab2703dd11449dc476d7288a7d91a0c7fb58e8c13
|
7
|
+
data.tar.gz: 368fc193f939b360aa1945198c054aa7bf0f05620d1307b95a0ed89f1a09a374b605c2baecc3244e2ba81bc0fe70546ff357e705d3e423d3543163cf64394a89
|
data/lib/geospatial/location.rb
CHANGED
@@ -202,5 +202,20 @@ module Geospatial
|
|
202
202
|
def - other
|
203
203
|
Distance.new(self.distance_from(other))
|
204
204
|
end
|
205
|
+
|
206
|
+
# Compute count midpoints between self and other.
|
207
|
+
# @param count [Integer] the number of segments to generate.
|
208
|
+
def midpoints_to(other, count)
|
209
|
+
return to_enum(:midpoints_to, other, count) unless block_given?
|
210
|
+
|
211
|
+
distance = other.distance_from(self)
|
212
|
+
bearing = other.bearing_from(self)
|
213
|
+
|
214
|
+
step = distance / count
|
215
|
+
|
216
|
+
(1...count).each do |i|
|
217
|
+
yield self.location_by(bearing, step * i)
|
218
|
+
end
|
219
|
+
end
|
205
220
|
end
|
206
221
|
end
|
data/lib/geospatial/polygon.rb
CHANGED
@@ -95,10 +95,12 @@ module Geospatial
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
def simplify
|
98
|
+
def simplify
|
99
99
|
simplified_points = @points.first(1)
|
100
100
|
|
101
|
-
|
101
|
+
(1...@points.size).each do |index|
|
102
|
+
point = @points[index]
|
103
|
+
|
102
104
|
next_point = @points[(index+1) % @points.size]
|
103
105
|
|
104
106
|
if yield(simplified_points.last, point, next_point)
|
@@ -109,6 +111,34 @@ module Geospatial
|
|
109
111
|
self.class.new(simplified_points, bounding_box)
|
110
112
|
end
|
111
113
|
|
114
|
+
# @example
|
115
|
+
# polygon.subdivide do |a, b|
|
116
|
+
# a = Geospatial::Location.new(*a)
|
117
|
+
# b = Geospatial::Location.new(*b)
|
118
|
+
# if a.distance_from(b) > maximum_distance
|
119
|
+
# a.midpoints(b, 2)
|
120
|
+
# end
|
121
|
+
# end
|
122
|
+
def subdivide
|
123
|
+
simplified_points = @points.first(1)
|
124
|
+
|
125
|
+
(1..@points.size).each do |index|
|
126
|
+
point = @points[index % @points.size]
|
127
|
+
next_point = @points[(index+1) % @points.size]
|
128
|
+
|
129
|
+
if points = yield(simplified_points.last, point, next_point)
|
130
|
+
simplified_points.concat(points)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Polygons are represented by a closed sequence of points, but we need to subdivide by the last point at the first point too. However, we don't add the first point a 2nd time.
|
134
|
+
if index < @points.size
|
135
|
+
simplified_points << point
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
self.class.new(simplified_points, bounding_box)
|
140
|
+
end
|
141
|
+
|
112
142
|
def self.is_left(p0, p1, p2)
|
113
143
|
a = p1 - p0
|
114
144
|
b = p2 - p0
|
data/lib/geospatial/version.rb
CHANGED
@@ -69,6 +69,29 @@ RSpec.describe Geospatial::Location do
|
|
69
69
|
expect(south.bearing_from(north)).to be_within(0.1).of(180)
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
describe '#midpoints_to' do
|
74
|
+
let(:north) {Geospatial::Location.new(10, 10)}
|
75
|
+
let(:south) {Geospatial::Location.new(-10, -10)}
|
76
|
+
|
77
|
+
it "can generate one midpoint" do
|
78
|
+
midpoints = north.midpoints_to(south, 4).to_a
|
79
|
+
|
80
|
+
expect(midpoints.size).to be == 3
|
81
|
+
|
82
|
+
expect(midpoints[0].distance_from(
|
83
|
+
Geospatial::Location.new(4.9616, 5.0190)
|
84
|
+
)).to be < 10
|
85
|
+
|
86
|
+
expect(midpoints[1].distance_from(
|
87
|
+
Geospatial::Location.new(0, 0)
|
88
|
+
)).to be < 10
|
89
|
+
|
90
|
+
expect(midpoints[2].distance_from(
|
91
|
+
Geospatial::Location.new(-4.9616, -5.0190)
|
92
|
+
)).to be < 10
|
93
|
+
end
|
94
|
+
end
|
72
95
|
end
|
73
96
|
|
74
97
|
require 'bigdecimal'
|
@@ -105,28 +105,49 @@ RSpec.describe Geospatial::Polygon do
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
RSpec.shared_context "visualize polygon" do
|
108
|
+
RSpec.shared_context "visualize polygon" do |depth = 12|
|
109
109
|
it "can generate visualisation" do
|
110
110
|
map = Geospatial::Map.for_earth(30)
|
111
111
|
|
112
112
|
coordinates = region_string.split(/\s+/).collect{|coordinate| Vector.elements(coordinate.split(',').collect(&:to_f).first(2))}
|
113
113
|
region = Geospatial::Polygon.new(coordinates)
|
114
114
|
|
115
|
+
maximum_distance = 100_000
|
116
|
+
|
117
|
+
region = region.subdivide do |a, b|
|
118
|
+
a = Geospatial::Location.new(*a)
|
119
|
+
b = Geospatial::Location.new(*b)
|
120
|
+
|
121
|
+
distance = a.distance_from(b)
|
122
|
+
|
123
|
+
if distance > maximum_distance
|
124
|
+
a.midpoints_to(b, (distance / maximum_distance).ceil).map{|p| Vector[*p]}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
115
128
|
Geospatial::Visualization.for_map(map) do |pdf, origin|
|
116
129
|
region.edges do |pa, pb|
|
117
130
|
pdf.line (origin + pa).to_a, (origin + pb).to_a
|
118
131
|
end
|
119
132
|
|
120
133
|
count = 0
|
121
|
-
map.traverse(region, depth:
|
134
|
+
map.traverse(region, depth: depth) do |child, prefix, order|
|
122
135
|
count += 1
|
123
136
|
size = child.size
|
124
137
|
top_left = (origin + child.min) + Vector[0, size[1]]
|
125
138
|
pdf.rectangle(top_left.to_a, *size.to_a)
|
126
|
-
# puts "#{top_left.to_a} #{size.to_a}"
|
139
|
+
# $stderr.puts "#{top_left.to_a} #{size.to_a}"
|
127
140
|
end
|
128
141
|
|
129
|
-
# puts "count=#{count}"
|
142
|
+
# $stderr.puts "count=#{count}"
|
143
|
+
|
144
|
+
pdf.fill_and_stroke
|
145
|
+
|
146
|
+
pdf.fill_color 'aaaaff'
|
147
|
+
|
148
|
+
region.points.each do |p|
|
149
|
+
pdf.fill_circle((origin + p).to_a, 0.01)
|
150
|
+
end
|
130
151
|
|
131
152
|
pdf.fill_and_stroke
|
132
153
|
end.render_file "#{self.class.description}.pdf"
|
@@ -144,3 +165,10 @@ RSpec.describe "Whanganui Polygon" do
|
|
144
165
|
|
145
166
|
include_context "visualize polygon"
|
146
167
|
end
|
168
|
+
|
169
|
+
|
170
|
+
RSpec.describe "New Zealand Bounding Box" do
|
171
|
+
let(:region_string) {"165.7930426042,-47.8671059558 179.1461410947,-47.8671059558 179.1461410947,-33.4566032676 165.7930426042,-33.4566032676"}
|
172
|
+
|
173
|
+
include_context "visualize polygon", 20
|
174
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geospatial
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: covered
|