Created
October 21, 2016 11:48
-
-
Save abonec/cacea1e5ffb5d5186b79aa6d4c38b0d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Spatial::Utils | |
EARTH_RADIUS = 6371.0 | |
DETAILED_THRESHOLD = 3.0 # meters | |
module_function | |
def distance(point1, point2) | |
point1 = to_radians(point1) | |
point2 = to_radians(point2) | |
dlat = point2[0] - point1[0] | |
dlon = point2[1] - point1[1] | |
a = (Math.sin(dlat / 2))**2 + Math.cos(point1[0]) * | |
(Math.sin(dlon / 2))**2 * Math.cos(point2[0]) | |
c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a)) | |
c * EARTH_RADIUS * 1000 | |
end | |
def distance_path(path) | |
dist = 0 | |
prev_point = path[0] | |
path[1..-1].each do |point| | |
dist += distance prev_point, point | |
prev_point = point | |
end | |
dist | |
end | |
def to_radians(point) | |
point.map{|coord|coord * (Math::PI / 180)} | |
end | |
def interpolate_point(point1, point2, fraction) | |
x1 = point1[0] | |
y1 = point1[1] | |
x2 = point2[0] | |
y2 = point2[1] | |
[ | |
(x1 + (x2 - x1) * fraction), | |
(y1 + (y2 - y1) * fraction) | |
] | |
end | |
def make_detalized(path) | |
detailed_path = [path[0]] | |
prev_point = path[0] | |
path[1..-1].each do |point| | |
cur_distance = distance prev_point, point | |
if cur_distance > DETAILED_THRESHOLD | |
min_fraction = DETAILED_THRESHOLD / cur_distance | |
puts min_fraction | |
i = 1 | |
while (fraction = i * min_fraction) <= 1 | |
detailed_path.push interpolate_point(point, prev_point, fraction) | |
i += 1 | |
end | |
end | |
detailed_path.push point | |
prev_point = point | |
end | |
return detailed_path | |
end | |
def make_detalized_from_wkt(wkt) | |
make_detalized parse_wkt wkt | |
end | |
def parse_wkt(wkt_line_string) | |
points = wkt_line_string[/LINESTRING.*\((.*)\)/,1] | |
points.split(',').map{ |point| point.split(' ').reverse.map(&:to_f) } | |
end | |
def path_to_wkt(path) | |
path = path.map{ |point| point.reverse.join(' ') }.join(',') | |
"LINESTRING(#{path})" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment