Skip to main content

pgRouting III: PHP + OpenLayers Interface

With the routing database configured and populated, and with geoserver rendering the WMS, now the focus can shift on designing the actual display and functionality.

The conceptual plan is as follows:

The code to extract a user's clicked coordinates was taken from this OpenLayers example. It was then modified to pass the xy coordinates to a second function, designed to create a URL which will execute a PHP script.

[sourcecode language="javascript"]trigger: function(e) { var xy = map.getLonLatFromViewPortPx(e.xy); executeSQL(xy); }[/sourcecode]

Passing the XY variable to the executeSQL() function, we are able to now seperate out the individual X and Y coordinates, and apply them to their respective parameters in our URL string.

[sourcecode language="javascript"]// Build the URL var json_url = "http://localhost/near_vertex_astar.php?"; json_url += "x=" + escape(xy.lon); json_url += "&y=" + escape(;[/sourcecode]

Having constructed the URL, we are now ready to use it to populate an OpenLayers vector layer with data.

[sourcecode language="javascript"]// Make a fresh vector layer, pulling features from our script URL json_layer = new OpenLayers.Layer.Vector("GeoJSON", { styleMap: myStyles, strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.HTTP({ url: json_url, format: new OpenLayers.Format.GeoJSON() }) });[/sourcecode]

Alright! So where are we at right now? A user has clicked the map, and that click's geometry has been extracted and sent to a PHP script on the server for further work. The PHP script will execute SQL in the PostGIS/pgRouting data base to do the following:

Why all the hassle with determining the cost? Can't you just use PostGIS' ST_DWithin() function to find the closet firestation to our user's click and create the route? Well you could, but it might not always be the shortest route.

[caption id="attachment_339" align="alignnone" width="300" caption="Euclidean distance versus Manhattan. Which one is shorter?"]Euclidean distance versus Manhattan. Which one is shorter?[/caption]

This behavior can be respresented in the routing network with the example below. Two different routes are generated from the same source vertex based on the combination of routing algorithm and account for route cost. On the left, the dijkstra algorithm is used to return the route to the closest fire station as the result of an ST_DWithin() query. On the right, the A-Star algorithm is used, and the route costs of all fire stations within a buffer are taken into account. As we can see, a different route and a different station are returned.

Comparing the two search algorithms and cost relationships.

A link to the JS and PHP scripts can be found at the end of this post. This definitely is not the most elegant solution to working with routing, but in terms of an experiment it was a great learning exercise. I'm really excited to dive deeper into PostGIS and pgRouting. The next step in the process will be incorporating OSM data, and adding in addition attributes which affect cost (speed limits, one-way streets, etc).

View the PHP.

View the OL JS.