Skip to content

Instantly share code, notes, and snippets.

@abonec
Created October 21, 2016 11:48
Show Gist options
  • Save abonec/cacea1e5ffb5d5186b79aa6d4c38b0d2 to your computer and use it in GitHub Desktop.
Save abonec/cacea1e5ffb5d5186b79aa6d4c38b0d2 to your computer and use it in GitHub Desktop.
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