Search Results for 'routing'

Quick weekly wrapup

Five quickies …

  1. Openlayers gets a nice plug on the popular ajaxian blog. Unfortunately its not exactly well written and it left even me questioning the point of the post. Ah well, publicity is publicity i guess
  2. UMN Mapserver 4.10 was released with a few new goodies such as curved labelling, improved mapscript service support and various other bug fixes. Surprised no one else picked up on this … i’m sure ms4w builds will be updated in the coming week.
  3. For those not attending FOSS4G and missed out on the PgRouting sessions, Lorenzo has pleaded with me to give the project a plug. A bit late i know, but check out the awesome prototype whipped up with Kamap here. Select the tool that looks like a pin to define the start/end points on the map, and then wait for the route to be updated.
  4. Geoserver is at 1.4M2 … and even though its beta, it now has KML reprojection support (yay!). The guys can’t make it much easier for the average joe to serve their data into GE now, winner.
  5. What_nick has been working on the improved WorldWind WMS/WFS plugins and has assured me it will make it into the next release (1.4?). Other good news is the smaller footprint that Bull mentioned in his post because of the move to using WFS for placenames rather than bundling the data with the download.

PGdijkstra Routing performance

I have gotten a surprising amount of questions since i posted my routing articles using Cartoweb’s pgdijkstra PostGIS pl/sql functions. A lot have focused around the speed of the routing calculations, especially in comparison with commercial offerings.

Disclaimer: This should only aid in you decision making. I definately would not consider using pgdjikstra to replace emergency vehicles routing and travelling salesmen type problems. Considerable work would need to be added to flesh out commonly requested features such as turn by turn navigation

Alright, lets see how we went …

Sample dataset: 57k vertices, 44k nodes

Machine specs: P4 Celeron M 2.6ghz Laptop, 512mb RAM, PostgreSQL 8.1

Sample queries are using the following function,

SELECT astext(the_geom) FROM shortest_path_as_geometry(‘roadstable’, startnode, endnode)

uery

Key

From

To

Path Size

(coord pairs)

Query Time

1

219102

181359

792

984.056 ms

2

216366

179845

738

1289.002 ms

3

229280

188416

586

871.655 ms

4

205276

197586

660

1421.800 ms

5

229280

179038

941

2180.597 ms

6

209203

206037

491

1101.798 ms

7

203982

193450

208

755.187 ms

Routing geometry
Click to enlarge!

Considering my laptop is definately not the best benchmark machine, I can only assume that deployment on a proper server environment would result in a significant performance increase across the board.

Interesting stuff! Head over to cartoweb.org to give Sylvain and his crew any feedback or bugs. I havent checked lately but i’m sure the CVS version have had some improvements.

Google maps finally gets aus data

Seems as though Google Maps has finally integrated the PSMA dataset. Just had a quick look and the data seems to be fairly recent.

I feel sorry for the zoomin guys as no doubt their target audience has all but dissappeared over night (until of course businesses read googles licencing arrangements :) ).

Has anyone been able to get routing working? Seems as though its not accepting any kind of local address i throw at it.

Overall i’m not too impressed, but maybe thats because i have access to this sort of data all the time. It certainly will be interesting to see what sort of local “mashups” (god i hate that word) are created.

via geblog

Adding routing overlays to kamap

Finally, my promised follow up to my build your own routing solution article. For those who have had success massaging their data to work the pgdjikstra module, lets rock and roll. I’m writing this on the fly so hopefully by the end we can get a usable, user-friendly routing solution into Kamap.

1. Kamap install.

Grab the latest stable (or CVS if you’re feeling lucky) release and follow the instructions to get it up an running. Paul and the rest of the crew have made this possibly the easiest frontend to get up and running in a flash, but if you do run into problems please contact the list.

Ignore my setup / mess, this was an existing mapfile used for benchmarks. This is possibly what you shouldn’t have setup, but its got the road centrelines so it’ll do for our purposes.
kamap

2. Create a database handler

Since we would like the users to be able to interface with our db, we need to create a little interface to query the roads and execute the shortest_path_as_geometry call. For the sake of simplicity, the following should give you somewhere to start. (Source: querydb.php, if the output below gets munged)

Dont worry if the output format doesnt really make much sense at the moment, we’ll touch on this in the next step.

< ?php
//SQL query
$query = "SELECT astext(the_geom) FROM shortest_path_as_geometry('roads', ".$start.", ".$end.");";
$result = pg_query($query) or die('Query failed: ' . pg_last_error()); // output
echo "n";
echo "n";
echo "	

3. Integrating PG’s kaXmlOverlay code

PG has done some great work looking into how best to integrate vector overlays on kamap, much like google maps does. Technically, there are lots of different options, but PG’s latest code uses a mix of the wz_jsgraphics and the PHP GD library.

This option has arguably the best cross browser support in that the route is actually rendered and thus positioned, as a PNG/gif image. But more on that later.

PG has posted a demo of the capabilities at his site (http://sistel.dyndns.info/ka-map/indext.html).

You will need to download the kaXmlOverlay.js, drawGeom.php and the wz_jsgraphics library.

Edit your existing kamap index.html and add,

The code is pretty self explanatory, we simply define the path to the XML (querydb.php) and attach it to the map initialised handler. PG has a slightly alternative setup on his demo website, adding a refresh function to automatically refresh the XML doc at a set period. This is a real handy feature if you’re tracking a live GPS feed, but in our case it just adds extra overhead.

4. Time to test

Since the code contains a few point of failures its best to start at the beginning,

  1. Chose a start and end edge id from your postgis table and try running http://your.host/kamap/querydb.php?ST=startid&EN=endid. You should get a well formatted text/xml response with the routing coordinates. If the edge ids dont exist or the geometry function did not work, you will get an error here.
  2. Now you have determined that you have got the coords, time to try kamap. Load up the modified index from step #3 and tail the apache logs. Amongst all the js queries, there should be one eventual request for the querydb, and then for the drawgeom (something like drawgeom.php?gt=L&st=5&bp=5&sc=25&cl=15,1800,0..). If after 30 seconds or so you dont appear to see any overlays, strip out the exact request from your log and try to run it in isolation. eg. http://localhost/kamap/drawgeom.php?gt=L&st=5&bp=5&… if GD is configured properly you should get an image output like below (PNG)
  3. gdoutput.png

  4. If its still not working, there probably just a URL thats throwing a 404. Keep checking the logs for what its requesting just to make sure its not trying to find a file in / and not /kamap

5. The result

Apologies in advance as i just didnt have time to implement a more dynamic approach such as a user entering a start/end address. I hope someone else out there has the time and the inclination to extend this stuff. The possiblities are endless.

6. Problems and future additions?

  1. Needs a better way of converting geo2pix. The existing js function has meant that potentially you could have 40 + coordinate pairs being converted (DB->XML->JS->Drawgeom->Image) to pixel space, and then passed via a URL parameter to drawgeom.php. Very inefficient, and can also go beyond the URL size limit … maybe short term the use of POST might be more suitable?
  2. Line simplification. Further work needs to see how suitable the PostGIS simplify() function is. Conceptually, a function to guesstimate a suitable tolerance for the zoom level, and then retrieve the new coords would be suitable but how easy at guessing said tolerance would be interesting.
  3. JS bloat. I’d prefer to move as much code as possible server side, especially for “calculations”. Being able to pass the current client params such as pixel/cell size, coords, scale etc. would mean much of the xmlOverlay.js code done by PG could be done server side, and potentially drawn in the same thread (eg. no need for a separate drawgeom.php … the initial query would pass the results direct)
  4. An extension to the current querying abilities, where users can click on the map for their start and end points, and the click points would be translated into geo and then fed back into a postgis function to grab the closest road edge. This was what i wanted to do for this article, but alas theres never time.

Spatial indexing

Update: Further investigation revealed that my GiST indexes weren’t built correctly and so i have since updated the timings on the postgis results. Thanks to Sean for pointing out my boo boo.

I have noticed a bit of interest especially on PostGIS‘ new implementation of a GiST spatial index to speed up its performance. What i think is lacking is that there is little to no documentation on how “much” faster spatial indexing (not to be confused with attribute indexes) performs.

So here we go, a simple benchmark in less than 15 mins :)

First up, my datasets. For the base data, i will use the roads dataset from my previous routing article.

The benchmark tests in this case will be a simple, arbitrary bbox on the following datasets interfacing with Mapserver 4.6 (win32).

Word of warning: Please dont take these results as gospel, its merely to highlight the performance differences across the board.

FYI:

  • All data is in CRS 4326 (WGS84)
  • The timings will be extracted using the debug output from mapserver
  • Note the number of features in each query, the first obviously not being very realistic
  • A WMS requests are for single layers only with the BBOX values below
  1. 115.69402,-32.1273,116.09642,-31.86770 Features: 57564
  2. 115.82508,-32.0358,115.93653,-31.97567 Features: 8408
  3. 115.81400,-32.0493,115.86604,-32.02131 Features: 1389
  4. 115.82171,-32.0405,115.84112,-32.03009 Features: 338
  Shapefile (no index) Shapefile (qix index^) PostGIS 8.1 (no index) PostGIS 8.1 (GiST index)*
1. 2.938s 2.201s 5.297s 4.275s
2. 0.694s 0.294s 2.812s 1.656s
3. 0.601s 0.140s 1.796s 0.987s
4. 0.219s 0.032s 0.914s 0.223s
  • ^ Created with the standard quadtree sizes determine by the shptree utility
  • * Created with “CREATE INDEX roadsindex ON roadsindex USING GIST( the_geom GIST_GEOMETRY_OPS );” as per postgis documentation

I think the table speaks for itself, but im a little bit cautious about drawing too many conclusions. Most people are aware that PostGIS is slower than shapefiles, but thats a given. Most users who use PostGIS are using it for other reasons (such as for its geoprocessing functions).

The PostGIS guys have claimed about a 10% performance loss over shapefiles. In this little test it was indeed more than this, but i have no doubts that in the hands of a more experienced postGIS expert that they could certainly narrow down the gap further.
Fact of the matter is, spatial indexing is an important part of performance optimisation but should be considered with other methods such as view scale limiting, simplified symbolisation and feature generalisation. Unfortunately i dont have access to a mapserver hooked up with ArcSDE 9 or Oracle Spatial … could of made things interesting :)

Please, i make no attempts at claiming i am the master of all that is postgis and mapserver. If there is something glaringly obvious that i did not configure or did not include, please let me know and i will be happy to update the results.