class Manipulation::Straightener
Constants
- BASIC_CLUSTER_CHECK_RATIO
- BASIC_CLUSTER_CHECK_SIZE
- BASIC_SAMPLE_SIZE
Attributes
cluster_groups[R]
points[R]
Public Class Methods
new(points)
click to toggle source
# File lib/simple_trail/manipulation/straightener.rb, line 7 def initialize(points) @points = points @latlng_points = @points.map { |p| Geokit::LatLng.new(p[:lat], p[:lon]) } end
Public Instance Methods
points_without_clusters()
click to toggle source
# File lib/simple_trail/manipulation/straightener.rb, line 12 def points_without_clusters @average_distance_between ||= average_distance_between @possible_clusters = detect_clusters straighten_points! end
Private Instance Methods
average_distance_between()
click to toggle source
# File lib/simple_trail/manipulation/straightener.rb, line 56 def average_distance_between sample_points = (0..@points.size - 2).to_a.sample(BASIC_SAMPLE_SIZE) sample_points.map do |i| start = @latlng_points[i] finish = @latlng_points[i + 1] start.distance_to(finish) end.inject(:+) / sample_points.size end
detect_clusters()
click to toggle source
# File lib/simple_trail/manipulation/straightener.rb, line 65 def detect_clusters (0..@points.size - BASIC_CLUSTER_CHECK_SIZE - 1).to_a.map do |i| start = @latlng_points[i] finish = @latlng_points[i + BASIC_CLUSTER_CHECK_SIZE] distance = start.distance_to(finish) i if distance < @average_distance_between * BASIC_CLUSTER_CHECK_SIZE * BASIC_CLUSTER_CHECK_RATIO end end
group_clusters()
click to toggle source
# File lib/simple_trail/manipulation/straightener.rb, line 28 def group_clusters @cluster_groups = [] @possible_clusters.each do |index| @group ||= [] if index.nil? unless @group.empty? @cluster_groups << @group @group = [] end next else @group << index end end @cluster_groups << @group unless @group.empty? end
straighten_points!()
click to toggle source
# File lib/simple_trail/manipulation/straightener.rb, line 45 def straighten_points! cluster_groups.each do |cluster_group| cluster_coords = @points.values_at(*cluster_group) avg_lat = cluster_coords.map { |cc| cc[:lat].to_f }.inject(:+) / cluster_coords.size avg_lon = cluster_coords.map { |cc| cc[:lon].to_f }.inject(:+) / cluster_coords.size @points[cluster_group.first][:lat] = avg_lat.to_s @points[cluster_group.first][:lon] = avg_lon.to_s cluster_group.drop(1).each { |index| @points.delete_at(index) } end end