OpenLayers routing map¶
Important
The content of this page is outdated and is for archiving purposes only.
- Open text editor (i.e. Gedit, Mousepad)
- Google key: you don’t need a valid key if you’re working on localhost
- Note: these examples are not compatible with the latest stable version of OpenLayers (version 2.5). If you want to update the code, please look at: http://trac.openlayers.org/wiki/SphericalMercator
Starting page (00.index.html)¶
- Create a basic html:
- include OpenLayers and Google maps API javascript files
- create an empty div to receive the OpenLayers map
- create an empty init function. The function will be called on page load (see onload in the body tag)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 800px;
height: 512px;
border: 1px solid black;
}
</style>
<script src="./OpenLayers-google/lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=foobar"></script>
<script type="text/javascript">
function init() { }
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>
Design basic map layers (01.index.html)¶
- Create an OpenLayers map object
- Create and Controls to the maps (layer switcher and mouse position)
- Create a Google Satellite layer and add it to the map
- Recenter the map to a specified extent
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 800px;
height: 512px;
border: 1px solid black;
}
</style>
<script src="./OpenLayers-google/lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=foobar"></script>
<script type="text/javascript">
// global variables
var map;
function init() {
map = new OpenLayers.Map('map', {projection: "EPSG: 54004",
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508,
-136554022,
20037508,
136554022)
});
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
// create and add layers to the map
var satellite = new OpenLayers.Layer.GoogleMercator("Google Satellite",
{type: G_NORMAL_MAP});
map.addLayers([satellite]);
// set default position
map.zoomToExtent(new OpenLayers.Bounds(-13737893,
6141906,
-13728396,
6151394));
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>
Create a Vector layer and draw a polygon on it (02.index.html)¶
- Create a custom style for the vector layer
- Create a Vector layer and add it to the map
- Create a WKT parser and read a polygon, this create an OpenLayers.Geometry.Polygon object
- Create a OpenLayers.Feature.Vector with the polygon and add it to the vector layer
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 800px;
height: 512px;
border: 1px solid black;
}
</style>
<script src="./OpenLayers-google/lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=foobar"></script>
<script type="text/javascript">
var result_style = OpenLayers.Util.applyDefaults({
strokeWidth: 3,
strokeColor: "#ff0000",
fillOpacity: 0
}, OpenLayers.Feature.Vector.style['default']);
// global variables
var map, parser, result, downtown;
function init() {
map = new OpenLayers.Map('map', {projection: "EPSG: 54004",
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508,
-136554022,
20037508,
136554022)
});
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
// create and add layers to the map
var satellite = new OpenLayers.Layer.GoogleMercator("Google Satellite",
{type: G_NORMAL_MAP});
downtown = new OpenLayers.Layer.Vector("Downtown data area",
{style: result_style});
result = new OpenLayers.Layer.Vector("Routing results",
{style: result_style});
map.addLayers([satellite, downtown, result]);
// create a feature from a wkt string and add it to the map
parser = new OpenLayers.Format.WKT();
var wkt = "POLYGON((-13737893 6151394, -13737893 6141906, -13728396 6141906, -13728396 6151394, -13737893 6151394))";
var geometry = parser.read(wkt);
var feature = new OpenLayers.Feature.Vector(geometry);
downtown.addFeatures([feature]);
// set default position
map.zoomToExtent(new OpenLayers.Bounds(-13737893,
6141906,
-13728396,
6151394));
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>
“set start/end point” tool (03.index.html)¶
- Create two more vector layers with custom style
- Create the two drawing tools (OpenLayers.Control.!DrawFeature), those tools can only draw point (OpenLayers.Handler.Point)
- The toggleControl function set the active tool
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 800px;
height: 512px;
border: 1px solid black;
}
</style>
<script src="./OpenLayers-google/lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=foobar"></script>
<script type="text/javascript">
var start_style = OpenLayers.Util.applyDefaults({
externalGraphic: "start.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var stop_style = OpenLayers.Util.applyDefaults({
externalGraphic: "stop.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var result_style = OpenLayers.Util.applyDefaults({
strokeWidth: 3,
strokeColor: "#ff0000",
fillOpacity: 0
}, OpenLayers.Feature.Vector.style['default']);
// global variables
var map, parser, start, stop, downtown, result, controls;
function init() {
map = new OpenLayers.Map('map', {projection: "EPSG: 54004",
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508,
-136554022,
20037508,
136554022)
});
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
// create and add layers to the map
var satellite = new OpenLayers.Layer.GoogleMercator("Google Satellite",
{type: G_NORMAL_MAP});
start = new OpenLayers.Layer.Vector("Start point", {style: start_style});
stop = new OpenLayers.Layer.Vector("End point", {style: stop_style});
downtown = new OpenLayers.Layer.Vector("Downtown data area",
{style: result_style});
result = new OpenLayers.Layer.Vector("Routing results",
{style: result_style});
map.addLayers([satellite, start, stop, downtown,result]);
// create a feature from a wkt string and add it to the map
parser = new OpenLayers.Format.WKT();
var wkt = "POLYGON((-13737893 6151394, -13737893 6141906, -13728396 6141906, -13728396 6151394, -13737893 6151394))";
var geometry = parser.read(wkt);
var feature = new OpenLayers.Feature.Vector(geometry);
downtown.addFeatures([feature]);
// set default position
map.zoomToExtent(new OpenLayers.Bounds(-13737893,
6141906,
-13728396,
6151394));
// controls
controls = {
start: new OpenLayers.Control.DrawFeature(start, OpenLayers.Handler.Point),
stop: new OpenLayers.Control.DrawFeature(stop, OpenLayers.Handler.Point)
}
for (var key in controls) {
map.addControl(controls[key]);
}
}
function toggleControl(element) {
for (key in controls) {
if (element.value == key && element.checked) {
controls[key].activate();
} else {
controls[key].deactivate();
}
}
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
<ul>
<li>
<input type="radio" name="control" id="noneToggle"
onclick="toggleControl(this);" checked="checked" />
<label for="noneToggle">navigate</label>
</li>
<li>
<input type="radio" name="control" value="start" id="startToggle"
onclick="toggleControl(this);" />
<label for="startToggle">set start point</label>
</li>
<li>
<input type="radio" name="control" value="stop" id="stopToggle"
onclick="toggleControl(this);" />
<label for="stopToggle">set stop point</label>
</li>
</ul>
</body>
</html>
Customize the tools (04.index.html)¶
- Create a custom OpenLayers.Handler.Point handle: !SinglePoint. This handler only draw one point on the layer
- Add a method selector
- Create the “compute” button with the callback function (empty for now)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 800px;
height: 512px;
border: 1px solid black;
}
</style>
<script src="./OpenLayers-google/lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=foobar"></script>
<script type="text/javascript">
var SinglePoint = OpenLayers.Class.create();
SinglePoint.prototype = OpenLayers.Class.inherit(OpenLayers.Handler.Point, {
createFeature: function(evt) {
this.control.layer.removeFeatures(this.control.layer.features);
OpenLayers.Handler.Point.prototype.createFeature.apply(this, arguments);
}
});
var start_style = OpenLayers.Util.applyDefaults({
externalGraphic: "start.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var stop_style = OpenLayers.Util.applyDefaults({
externalGraphic: "stop.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var result_style = OpenLayers.Util.applyDefaults({
strokeWidth: 3,
strokeColor: "#ff0000",
fillOpacity: 0
}, OpenLayers.Feature.Vector.style['default']);
// global variables
var map, parser, start, stop, downtown, result, controls;
function init() {
map = new OpenLayers.Map('map', {projection: "EPSG: 54004",
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508,
-136554022,
20037508,
136554022)
});
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
// create and add layers to the map
var satellite = new OpenLayers.Layer.GoogleMercator("Google Satellite",
{type: G_NORMAL_MAP});
start = new OpenLayers.Layer.Vector("Start point", {style: start_style});
stop = new OpenLayers.Layer.Vector("End point", {style: stop_style});
downtown = new OpenLayers.Layer.Vector("Downtown data area",
{style: result_style});
result = new OpenLayers.Layer.Vector("Routing results",
{style: result_style});
map.addLayers([satellite, start, stop, downtown,result]);
// create a feature from a wkt string and add it to the map
parser = new OpenLayers.Format.WKT();
var wkt = "POLYGON((-13737893 6151394, -13737893 6141906, -13728396 6141906, -13728396 6151394, -13737893 6151394))";
var geometry = parser.read(wkt);
var feature = new OpenLayers.Feature.Vector(geometry);
downtown.addFeatures([feature]);
// set default position
map.zoomToExtent(new OpenLayers.Bounds(-13737893,
6141906,
-13728396,
6151394));
// controls
controls = {
start: new OpenLayers.Control.DrawFeature(start, SinglePoint),
stop: new OpenLayers.Control.DrawFeature(stop, SinglePoint)
}
for (var key in controls) {
map.addControl(controls[key]);
}
}
function toggleControl(element) {
for (key in controls) {
if (element.value == key && element.checked) {
controls[key].activate();
} else {
controls[key].deactivate();
}
}
}
function compute() { }
</script>
</head>
<body onload="init()">
<div id="map"></div>
<ul>
<li>
<input type="radio" name="control" id="noneToggle"
onclick="toggleControl(this);" checked="checked" />
<label for="noneToggle">navigate</label>
</li>
<li>
<input type="radio" name="control" value="start" id="startToggle"
onclick="toggleControl(this);" />
<label for="startToggle">set start point</label>
</li>
<li>
<input type="radio" name="control" value="stop" id="stopToggle"
onclick="toggleControl(this);" />
<label for="stopToggle">set stop point</label>
</li>
</ul>
<select id="method">
<option value="SPD">Shortest Path Dijkstra - undirected (BBox)</option>
<option value="SPA">Shortest Path A Star - undirected</option>
<option value="SPS">Shortest Path Shooting Star</option>
</select>
<button onclick="compute()">Calculate Route</button>
</body>
</html>
Ask for a route (05.index.html)¶
- Code the compute function:
- Create a request object (result)
- Use the OpenLayers !LoadUrl function to call the php script via AJAX
- The displayRoute function will be called with the output of the php script
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 800px;
height: 512px;
border: 1px solid black;
}
</style>
<script src="./OpenLayers-google/lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=foobar"></script>
<script type="text/javascript">
var SinglePoint = OpenLayers.Class.create();
SinglePoint.prototype = OpenLayers.Class.inherit(OpenLayers.Handler.Point, {
createFeature: function(evt) {
this.control.layer.removeFeatures(this.control.layer.features);
OpenLayers.Handler.Point.prototype.createFeature.apply(this, arguments);
}
});
var start_style = OpenLayers.Util.applyDefaults({
externalGraphic: "start.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var stop_style = OpenLayers.Util.applyDefaults({
externalGraphic: "stop.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var result_style = OpenLayers.Util.applyDefaults({
strokeWidth: 3,
strokeColor: "#ff0000",
fillOpacity: 0
}, OpenLayers.Feature.Vector.style['default']);
// global variables
var map, parser, start, stop, downtown, result, controls;
function init() {
map = new OpenLayers.Map('map', {projection: "EPSG: 54004",
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508,
-136554022,
20037508,
136554022)
});
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
// create and add layers to the map
var satellite = new OpenLayers.Layer.GoogleMercator("Google Satellite",
{type: G_NORMAL_MAP});
start = new OpenLayers.Layer.Vector("Start point", {style: start_style});
stop = new OpenLayers.Layer.Vector("End point", {style: stop_style});
downtown = new OpenLayers.Layer.Vector("Downtown data area",
{style: result_style});
result = new OpenLayers.Layer.Vector("Routing results",
{style: result_style});
map.addLayers([satellite, start, stop, downtown,result]);
// create a feature from a wkt string and add it to the map
parser = new OpenLayers.Format.WKT();
var wkt = "POLYGON((-13737893 6151394, -13737893 6141906, -13728396 6141906, -13728396 6151394, -13737893 6151394))";
var geometry = parser.read(wkt);
var feature = new OpenLayers.Feature.Vector(geometry);
downtown.addFeatures([feature]);
// set default position
map.zoomToExtent(new OpenLayers.Bounds(-13737893,
6141906,
-13728396,
6151394));
// controls
controls = {
start: new OpenLayers.Control.DrawFeature(start, SinglePoint),
stop: new OpenLayers.Control.DrawFeature(stop, SinglePoint)
}
for (var key in controls) {
map.addControl(controls[key]);
}
}
function toggleControl(element) {
for (key in controls) {
if (element.value == key && element.checked) {
controls[key].activate();
} else {
controls[key].deactivate();
}
}
}
function compute() {
var startPoint = start.features[0];
var stopPoint = stop.features[0];
if (startPoint && stopPoint) {
var result = {
startpoint: startPoint.geometry.x + ' ' + startPoint.geometry.y,
finalpoint: stopPoint.geometry.x + ' ' + stopPoint.geometry.y,
method: OpenLayers.Util.getElement('method').value,
region: "victoria",
srid: "54004"
};
OpenLayers.loadURL("./ax_routing.php",
OpenLayers.Util.getParameterString(result),
null,
displayRoute);
}
}
function displayRoute(response) {
if (response && response.responseXML) {
alert(response.responseXML);
}
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
<ul>
<li>
<input type="radio" name="control" id="noneToggle"
onclick="toggleControl(this);" checked="checked" />
<label for="noneToggle">navigate</label>
</li>
<li>
<input type="radio" name="control" value="start" id="startToggle"
onclick="toggleControl(this);" />
<label for="startToggle">set start point</label>
</li>
<li>
<input type="radio" name="control" value="stop" id="stopToggle"
onclick="toggleControl(this);" />
<label for="stopToggle">set stop point</label>
</li>
</ul>
<select id="method">
<option value="SPD">Shortest Path Dijkstra - undirected (BBox)</option>
<option value="SPA">Shortest Path A Star - undirected</option>
<option value="SPS">Shortest Path Shooting Star</option>
</select>
<button onclick="compute()">Calculate Route</button>
</body>
</html>
Show the routing result on the map (06.index.html)¶
- code the displayRoute function:
- Erase the previous result
- Get all the <edge> tag in the XML document
- Parse the <wkt> content of each edge and add them to the result layer
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#map {
width: 800px;
height: 512px;
border: 1px solid black;
}
</style>
<script src="./OpenLayers-google/lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=foobar"></script>
<script type="text/javascript">
var SinglePoint = OpenLayers.Class.create();
SinglePoint.prototype = OpenLayers.Class.inherit(OpenLayers.Handler.Point, {
createFeature: function(evt) {
this.control.layer.removeFeatures(this.control.layer.features);
OpenLayers.Handler.Point.prototype.createFeature.apply(this, arguments);
}
});
var start_style = OpenLayers.Util.applyDefaults({
externalGraphic: "start.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var stop_style = OpenLayers.Util.applyDefaults({
externalGraphic: "stop.png",
graphicWidth: 18,
graphicHeight: 26,
graphicYOffset: -26,
graphicOpacity: 1
}, OpenLayers.Feature.Vector.style['default']);
var result_style = OpenLayers.Util.applyDefaults({
strokeWidth: 3,
strokeColor: "#ff0000",
fillOpacity: 0
}, OpenLayers.Feature.Vector.style['default']);
// global variables
var map, parser, start, stop, downtown, result, controls;
function init() {
map = new OpenLayers.Map('map', {projection: "EPSG: 54004",
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508,
-136554022,
20037508,
136554022)
});
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
// create and add layers to the map
var satellite = new OpenLayers.Layer.GoogleMercator("Google Satellite",
{type: G_NORMAL_MAP});
start = new OpenLayers.Layer.Vector("Start point", {style: start_style});
stop = new OpenLayers.Layer.Vector("End point", {style: stop_style});
downtown = new OpenLayers.Layer.Vector("Downtown data area",
{style: result_style});
result = new OpenLayers.Layer.Vector("Routing results",
{style: result_style});
map.addLayers([satellite, start, stop, downtown,result]);
// create a feature from a wkt string and add it to the map
parser = new OpenLayers.Format.WKT();
var wkt = "POLYGON((-13737893 6151394, -13737893 6141906, -13728396 6141906, -13728396 6151394, -13737893 6151394))";
var geometry = parser.read(wkt);
var feature = new OpenLayers.Feature.Vector(geometry);
downtown.addFeatures([feature]);
// set default position
map.zoomToExtent(new OpenLayers.Bounds(-13737893,
6141906,
-13728396,
6151394));
// controls
controls = {
start: new OpenLayers.Control.DrawFeature(start, SinglePoint),
stop: new OpenLayers.Control.DrawFeature(stop, SinglePoint)
}
for (var key in controls) {
map.addControl(controls[key]);
}
}
function toggleControl(element) {
for (key in controls) {
if (element.value == key && element.checked) {
controls[key].activate();
} else {
controls[key].deactivate();
}
}
}
function compute() {
var startPoint = start.features[0];
var stopPoint = stop.features[0];
if (startPoint && stopPoint) {
var result = {
startpoint: startPoint.geometry.x + ' ' + startPoint.geometry.y,
finalpoint: stopPoint.geometry.x + ' ' + stopPoint.geometry.y,
method: OpenLayers.Util.getElement('method').value,
region: "victoria",
srid: "54004"
};
OpenLayers.loadURL("./ax_routing.php",
OpenLayers.Util.getParameterString(result),
null,
displayRoute);
}
}
function displayRoute(response) {
if (response && response.responseXML) {
// erase the previous results
result.removeFeatures(result.features);
// parse the features
var edges = response.responseXML.getElementsByTagName('edge');
var features = [];
for (var i = 0; i < edges.length; i++) {
var g = parser.read(edges[i].getElementsByTagName('wkt')[0].textContent);
features.push(g);
}
result.addFeatures(features);
}
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
<ul>
<li>
<input type="radio" name="control" id="noneToggle"
onclick="toggleControl(this);" checked="checked" />
<label for="noneToggle">navigate</label>
</li>
<li>
<input type="radio" name="control" value="start" id="startToggle"
onclick="toggleControl(this);" />
<label for="startToggle">set start point</label>
</li>
<li>
<input type="radio" name="control" value="stop" id="stopToggle"
onclick="toggleControl(this);" />
<label for="stopToggle">set stop point</label>
</li>
</ul>
<select id="method">
<option value="SPD">Shortest Path Dijkstra - undirected (BBox)</option>
<option value="SPA">Shortest Path A Star - undirected</option>
<option value="SPS">Shortest Path Shooting Star</option>
</select>
<button onclick="compute()">Calculate Route</button>
</body>
</html>