class RouteBoxer::Core
Constants
- R
Attributes
boxes_x[RW]
boxes_y[RW]
grid[RW]
lat_grid[RW]
lng_grid[RW]
Public Class Methods
new()
click to toggle source
# File lib/route_boxer/core.rb, line 8 def initialize @lat_grid = [] @lng_grid = [] @boxes_x = [] @boxes_y = [] end
Public Instance Methods
box(collection, range)
click to toggle source
# File lib/route_boxer/core.rb, line 15 def box(collection, range) vertices = collection.to_a @grid = build_grid(vertices, range) find_intersecting_cells(vertices) merge_intersecting_cells return (@boxes_x.length <= @boxes_y.length ? @boxes_y : @boxes_x) end
to_params()
click to toggle source
# File lib/route_boxer/core.rb, line 25 def to_params boxes = {} (@boxes_x.length <= @boxes_y.length ? @boxes_y : @boxes_x).each_with_index do |box, i| boxes[i.to_s] = { northeast_lat: box.north_east.lat, northeast_lng: box.north_east.lng, southwest_lat: box.south_west.lat, southwest_lng: box.south_west.lng } end boxes end
Private Instance Methods
build_grid(vertices, range)
click to toggle source
# File lib/route_boxer/core.rb, line 36 def build_grid(vertices, range) route_bounds = RouteBoxer::LatLngBounds.new vertices.each do |v| route_bounds.extend(v) end route_bounds_center = route_bounds.get_center @lat_grid << route_bounds_center.lat @lat_grid << route_bounds_center.rhumb_destination_point(0, range, R).lat i = 2 while @lat_grid[i - 2] < route_bounds.get_north_east.lat @lat_grid << route_bounds_center.rhumb_destination_point(0, range * i, R).lat i += 1 end i = 1 while @lat_grid[1] > route_bounds.get_south_west.lat @lat_grid.unshift(route_bounds_center.rhumb_destination_point(180, range * i, R).lat) i += 1 end @lng_grid << route_bounds_center.lng @lng_grid << route_bounds_center.rhumb_destination_point(90, range, R).lng i = 2 while @lng_grid[i - 2] < route_bounds.get_north_east.lng @lng_grid << route_bounds_center.rhumb_destination_point(90, range * i, R).lng i += 1 end i = 1 while @lng_grid[1] > route_bounds.get_south_west.lng @lng_grid.unshift(route_bounds_center.rhumb_destination_point(270, range * i, R).lng) i += 1 end lng_grid_length = @lng_grid.length lat_grid_length = @lat_grid.length grid = create_empty_array(lng_grid_length) i = 0 while i < grid.length grid[i] = create_empty_array(lat_grid_length) i += 1 end grid end
create_empty_array(length)
click to toggle source
# File lib/route_boxer/core.rb, line 87 def create_empty_array(length) [nil] * length end
fill_in_grid_squares(start_x, stop_x, y)
click to toggle source
# File lib/route_boxer/core.rb, line 195 def fill_in_grid_squares(start_x, stop_x, y) if start_x < stop_x x = start_x while x <= stop_x mark_cell([x, y]) x += 1 end else x = start_x while x >= stop_x mark_cell([x, y]) x -= 1 end end end
find_intersecting_cells(vertices)
click to toggle source
# File lib/route_boxer/core.rb, line 91 def find_intersecting_cells(vertices) hint_xy = get_cell_coords(vertices[0]) mark_cell(hint_xy) i = 1 while i < vertices.length grid_xy = get_grid_coords_from_hint(vertices[i], vertices[i - 1], hint_xy) if grid_xy[0] == hint_xy[0] && grid_xy[1] == hint_xy[1] i += 1 next elsif (((hint_xy[0] - grid_xy[0]).abs == 1 && hint_xy[1] == grid_xy[1]) || (hint_xy[0] == grid_xy[0] && (hint_xy[1] - grid_xy[1]).abs == 1)) mark_cell(grid_xy) else get_grid_intersects(vertices[i - 1], vertices[i], hint_xy, grid_xy) end hint_xy = grid_xy i += 1 end end
get_cell_bounds(cell)
click to toggle source
# File lib/route_boxer/core.rb, line 315 def get_cell_bounds(cell) south_west = RouteBoxer::LatLng.new(@lat_grid[cell[1]], @lng_grid[cell[0]]) north_east = RouteBoxer::LatLng.new(@lat_grid[cell[1] + 1], @lng_grid[cell[0] + 1]) return RouteBoxer::LatLngBounds.new(south_west, north_east) end
get_cell_coords(latlng)
click to toggle source
# File lib/route_boxer/core.rb, line 113 def get_cell_coords(latlng) x = 0 while @lng_grid[x] < latlng.lng x += 1 end y = 0 while @lat_grid[y] < latlng.lat y += 1 end [x - 1, y - 1] end
get_grid_coords_from_hint(latlng, hint_latlng, hint)
click to toggle source
# File lib/route_boxer/core.rb, line 127 def get_grid_coords_from_hint(latlng, hint_latlng, hint) x = nil y = nil if latlng.lng > hint_latlng.lng x = hint[0] while @lng_grid[x + 1] < latlng.lng x += 1 end else x = hint[0] while @lng_grid[x] > latlng.lng x -= 1 end end if latlng.lat > hint_latlng.lat y = hint[1] while @lat_grid[y + 1] < latlng.lat y += 1 end else y = hint[1] while @lat_grid[y] > latlng.lat y -= 1 end end [x, y] end
get_grid_intersect(start, brng, grid_line_lat)
click to toggle source
# File lib/route_boxer/core.rb, line 190 def get_grid_intersect(start, brng, grid_line_lat) d = R * ((deg2rad(grid_line_lat) - deg2rad(start.lat))) / Math.cos(deg2rad(brng)) start.rhumb_destination_point(brng, d) end
get_grid_intersects(start, stop, start_xy, stop_xy)
click to toggle source
# File lib/route_boxer/core.rb, line 158 def get_grid_intersects(start, stop, start_xy, stop_xy) brng = start.rhumb_bearing_to(stop) hint = start hint_xy = start_xy if stop.lat > start.lat i = start_xy[1] + 1 while i <= stop_xy[1] edge_point = get_grid_intersect(start, brng, @lat_grid[i]) edge_xy = get_grid_coords_from_hint(edge_point, hint, hint_xy) fill_in_grid_squares(hint_xy[0], edge_xy[0], i - 1) hint = edge_point hint_xy = edge_xy i += 1 end fill_in_grid_squares(hint_xy[0], stop_xy[0], i - 1) else i = start_xy[1] while i > stop_xy[1] edge_point = get_grid_intersect(start, brng, @lat_grid[i]) edge_xy = get_grid_coords_from_hint(edge_point, hint, hint_xy) fill_in_grid_squares(hint_xy[0], edge_xy[0], i) hint = edge_point hint_xy = edge_xy i -= 1 end fill_in_grid_squares(hint_xy[0], stop_xy[0], i) end end
mark_cell(cell)
click to toggle source
# File lib/route_boxer/core.rb, line 211 def mark_cell(cell) x = cell[0] y = cell[1] @grid[x - 1][y - 1] = 1 @grid[x][y - 1] = 1 @grid[x + 1][y - 1] = 1 @grid[x - 1][y] = 1 @grid[x][y] = 1 @grid[x + 1][y] = 1 @grid[x - 1][y + 1] = 1 @grid[x][y + 1] = 1 @grid[x + 1][y + 1] = 1 @grid end
merge_boxes_x(box)
click to toggle source
# File lib/route_boxer/core.rb, line 280 def merge_boxes_x(box) if box != nil i = 0 while i < @boxes_x.length if @boxes_x[i].get_north_east.lng == box.get_south_west.lng && @boxes_x[i].south_west.lat == box.south_west.lat && @boxes_x[i].get_north_east.lat == box.get_north_east.lat @boxes_x[i].extend(box.get_north_east) return end i += 1 end @boxes_x << box end end
merge_boxes_y(box)
click to toggle source
# File lib/route_boxer/core.rb, line 297 def merge_boxes_y(box) if box != nil i = 0 while i < @boxes_y.length if @boxes_y[i].get_north_east.lat == box.get_south_west.lat && @boxes_y[i].get_south_west.lng == box.get_south_west.lng && @boxes_y[i].get_north_east.lng == box.get_north_east.lng @boxes_y[i].extend(box.get_north_east) return end i += 1 end @boxes_y << box end end
merge_intersecting_cells()
click to toggle source
# File lib/route_boxer/core.rb, line 226 def merge_intersecting_cells current_box = nil y = 0 while y < @grid[0].length x = 0 while x < @grid.length if @grid[x][y] box = get_cell_bounds([x, y]) if current_box current_box.extend(box.get_north_east) else current_box = box end else merge_boxes_y(current_box) current_box = nil end x += 1 end merge_boxes_y(current_box) current_box = nil y += 1 end x = 0 while x < @grid.length y = 0 while y < @grid[0].length if @grid[x][y] if current_box box = get_cell_bounds([x, y]) current_box.extend(box.get_north_east) else current_box = get_cell_bounds([x, y]) end else merge_boxes_x(current_box) current_box = nil end y += 1 end merge_boxes_x(current_box) current_box = nil x += 1 end end