How to use the class
To use the RouteBoxer class, first load the RouteBoxer.js file into your page:
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/routeboxer/src/RouteBoxer.js"></script>
Then create a RouteBoxer object, and pass an array of google.maps.LatLng objects and a distance to the RouteBoxer.box() method. If implementing search along a route the overview_polyline property of agoogle.maps.DirectionsRoute object contains a suitable array of LatLng objects:
var directionService = new google.maps.DirectionsService();
var rboxer = new RouteBoxer();
var distance = 20; // km
directionService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
// Box the overview path of the first route
var path = result.routes[0].overview_path;
var boxes = routeBoxer.box(path, distance);
for (var i = 0; i < boxes.length; i++) {
var bounds = box[i];
// Perform search over this bounds
}
}
});
How the RouteBoxer class works
The RouteBoxer class generates the boxes for a route in a number of steps.
STEP 1:
A grid is overlaid on the route with square cells spaced at the specified distance. The grid is centered on the bounding box of the route polyline, and extends one cell further out in each direction than is necessary to cover the entire route.
STEP 2:
Every cell in the grid that the route intersects with is identified. To do this the vertices on the route polyline are traversed, and the cell containing each vertex is marked. If a cell that is marked does not share an edge with the cell for the previous vertex, the intermediate cells are also marked.
STEP 3:
When a cell is marked, each of the 8 cells surrounding it are also marked.
STEP 4:
When all of the route vertices have been traversed, any point within the specified distance of the route is guaranteed to be in one of the marked cells of the grid.
STEP 5:
The marked cells are then merged into a set of non overlapping rectangular boxes. Two different approaches are taken to this. The first approach merges cells that adjoin horizontally into a set of wide boxes, each one cell tall.
STEP 6:
Each box is then compared to the boxes on the row below, and if there is a box of the same width and horizontal position they are merged.
STEP 7:
The second approach follows the same technique, but first merges cells vertically into a set of tall boxes, each one cell wide.
STEP 8:
Each of these boxes are then compared with the boxes in the column to the left, and if there is a box with the same height and vertical position they are merged.
STEP 9:
When the two approaches are complete the number of boxes that resulted from each approach are compared.
STEP 10:
The set of boxes that is smallest in number are returned to the application.
The RouteBoxer class takes a path, such as the Polyline for a route generated by a Directions request, and generates a set of LatLngBounds objects that are guaranteed to contain every point within a given distance of that route. These LatLngBounds objects can then be used to generate requests to spatial search services that support bounds filtering (such as the Google Maps Data API) in order to implement search along a route.
RouteBoxer overlays a grid of the specified size on the route, identifies every grid cell that the route passes through, and generates a set of bounds that cover all of these cells, and their nearest neighbours. Consequently the bounds returned will extend up to ~3x the specified distance from the route in places.
For a description and examples of how to use this library, check out the how-to.
class RouteBoxer
Constructor
Constructor |
Description |
RouteBoxer() |
Creates a new RouteBoxer |
Methods
Methods |
Return Value |
Description |
box(path:google.maps.LatLng[] | google.maps.Polyline, range:Number) |
google.maps.LatLngBounds[] |
Generates boxes for a given route and distance |