Blog updates

Quick post regarding some changes i have both already done and also intend to do over the next week. Call it an early new years resolution ..

Already done:

1.0 Upgraded to WP 2.0. The latest stable release has redone a lot of the interaces and general usability. Extremely impressed, and best of all most existing plugins & themes work fine. Highly recommended update to any other GIS bloggers.

2.0 Updated the theme. I created a new style designed around the new WP2.0 theme called K2. Everything is now pretty much AJAX’d … love it :) There may be some cross browser issues so if you see anything weird just flick me a mail.
3.0 General Site Tidy up. Finally sorted all my articles into categories so things should be a lot easier to find now. Also added a few new plugin enhancements, such as being able to subscribe to comments on articles. Its a feature i like particularly on James’ spatiallyadjusted.com … so hope it comes in use.

Todo in the coming weeks:

More and more articles! I have been pondering what to do with the site’s future for a while now and i came to the conclusion that i’d love to create a more collaborative blog with multiple authors. Currently i have contacted 3-4 other general GIS users in Perth who are interested in contributing to the cause. Perth has quite a large specialised GIS user base so hopefully i can attract some interesting authors.
This is great news because it alleviates the pressure off me to write articles and of course, it will contain a lot more varied posts and tutorials around the place.
So stay tuned guys, a lot more content coming in the New Year.
Have a safe and happy new years … im off to crack the first beer :)

Is it just me ..

Or is there an fixation for GIS communities to use crude, outdated and horrible mailinglists as their method of choice for their “community”. I absolutely can’t stand them.
For developers, mailinglists can be an excellent way to get notifications of CVS updates and other near real time Q/A’s, but for everything else, i can not think of one advantage of using it particularly as an “archive” for general user questions or discussions.

Advantages:

  1. Besides the one above, i cannot think of one?

Disadvantage:

  1. Horrible user navigation for the average joe blogs wanting to ask a question
  2. Search feature is lack lustre at best (if its even enabled). Users end up posting the same questions over and over, simply because they cant find the info they’re after.
  3. Users dont understand how to use them. The number of people replying to the wrong thread, starting a new thread, putting an out of office notification to the whole list, and those who cant figure out how to unsubscribe from the “spam” are just amazing. And thats only the tip of the iceberg!

Now, to all of your diehards who use your favourite reader and know lists inside out thats great guys, but take a step back and ask yourself whether lists are really the best way to develop your GIS community.

The use of WIKI’s are spreading, which is a great mid-term solution. But i would just love to one day find that the use of decent, threaded, categorised forum software has started to take off.

[end vent] :)

Google Maps to extend development into Aus

An article run in the AustralianIT newspaper suggests that Google is finally looking to extend its Maps product offering into Australia, after purchasing a local Sydney spatial team Where2 LLC.

The company would not comment on the recruitment drive, but AustralianIT understands Google is looking for 15 graduates to work in the Sydney headquarters of Google Maps, in addition to the 12 software engineers already working there.

Unfortunately i wasn’t able to find any related job postings, but if anyone has seen them drop me a comment. Im sure theres quite a few GIS developers down here that would like the opportunity to shape future features.

As for the new development team in Sydney, I can only assume its related to integrating the local road dataset (PSMA?) and adding some more local content into the mix such as points of interest, traffic information etc. to bring it into line with its competitors such as Yahoo!.

Will be interesting to see how things develop.

Build your own routing solution

The following tutorial will run you through the steps to setup the core components needed for an opensource routing “solution”. So if you’re like me and have eagerly been awaiting something similar, read on.

The following guide is largely based on the tutorial found at the Cartoweb WIKI and its associated readme. Many thanks need to be directed at the cartoweb developers, in particular Paschain for compiling a working win32 dll and a system than can easily be built upon. Many thanks.

If you would like some background on the djikstra shortest path algorithm try the following resources.

General info
Various C/VB/PHP implementations
Step by step Animation

Lets get started.

1. Download PostgreSQL 8.1 or higher.

The win32 installer is recommended and makes installation easy. A stable PostGIS is included in the installation of PostgreSQL so no more downloads like previous releases :) I usually include all developer options in the install by habit, this shouldnt be neccessary but just make sure plpgsql language is checked when installing.

2. Download the pgdijkstra package from cartoweb

3. Extract pgdijkstra.dll into X:\..\PostgreSQL\8.1\lib

4. Lets create a new database to hold the routing data ..

createdb -U username dbname
Password:
CREATE DATABASE

5. Time to ensure plpgsql is initialised on our new db

createlang plpgsql -U chris roads

6. Last thing we need to do is insert the new routing functions ..

psql -U chris roads -f “D:\Program Files\PostgreSQL\pgdijkstra\dijkstra.sql”
Password for user chris:
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION

psql -U chris roads -f “D:\Program Files\PostgreSQL\pgdijkstra\dijkstra_postgis.sql”
Password for user chris:
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE TYPE
CREATE FUNCTION
CREATE FUNCTION

Now assuming all the installation went A’ok then its time to start inserting our data and creating the graphs! Again, all credits go to the cartoweb guys, especially Paschain for their hard work. The following steps are reworked from the official readme

7. If you havent already converted your data into a postgis table, lets use shp2pgsql on my road dataset and create a “roads” table. Be prepared to wait a while if its a large dataset while each feature is inserted.

shp2pgsql D:\roads.shp roads > roads.sql

then run the SQL inserts into the db

psql -d roadsdb -f roads.sql

8. If you come from a background used to using web frontends such as phpMyAdmin, id highly suggest installing phpPgAdmin. While the diehards will scoff, it does tend to make handling the usual db functions a lot easier

9. Almost all road datasets wont have the necessary target_id and source_id for the graph creation. Luckily there is a assign_vertex_id function to automatically generate each id from the start and end node of the line string.

Add 3 new columns to your roads table source_id(integer) target_id(integer) if you dont already have similar from/to node columns that you can rename. If you dont, use the following function to generate source/target id’s based on the distance given.

For example, using the below will group all nodes within a distance of 0.1 to the same vertex id. Obviously, depending on your units and accuracy you may wish to drop the number down to something more suitable. The smaller the unit, the longer the procedure will take :)

SELECT assign_vertex_id(’graph2′, 0.1);

Luckily my road dataset already had such from/to nodes so all was needed was a simple column rename.

gid target_id source_id astext
535
178964
179077
MULTILINESTRING((115.929608562 -31.81452766))
661
179216
179154
MULTILINESTRING((115.831206523 -31.87982646))
702
179255
179213
MULTILINESTRING((115.868336883 -31.87188829))
789
179329
179333
MULTILINESTRING((115.895629241 -31.8718535256))

10. Now we are ready to begin generating the graph edges and vertices.

SELECT create_graph_tables(’roads’, ‘int4′);

This procedure will create 2 new tables, roads_vertices and roads_edges. If your source and target id’s are not using int4 as a type, you will need to modify the SQL procedure and remove the int4 dependancy. Otherwise, cross your fingers and wait for the tables to be populated.

id source target cost reverse_cost
1
1274
1275
NULL
NULL
2
1276
1277
NULL
NULL
3
1278
1279
NULL
NULL

11. As you can see we need to populating the cost weighting for each edge. There is a update_cost_from_distance function by default that simply calculates the length of the edge and uses this as the weight. Obviously if you would like to formulate a more complex algorithm for your weights such as using distance, road type, speed etc. then you will need to edit this function. Its easy to do so feel free to have a play.

Lets use plain distance for now,

SELECT update_cost_from_distance(’roads’);

id source target cost reverse_cost
1
1274
1275
0.000655682025166796
NULL
2
1276
1277
0.00270400042483912
NULL
3
1278
1279
0.00684668815982494
NULL

12. We’re pretty much done. Time to generate a shortest path! Using shortest_path_as_geometry we can pass the start and end points for our route. The function expects the node target/source id’s from the original roads table. So lets manually select a couple and try running it.

SELECT gid, astext(the_geom) FROM shortest_path_as_geometry(’roads’, 179551, 179681);

You should now be looking at a list of MULTILINESTRING objects which make up the shortest path from your start to end vertex.

13. Visualising your shortest path is the next logical step. There are a number of ways doing this, such as passing the geometry to a vrml/javascript function or rendering it as an image. Luckily Paschain has included an easy way to insert the static path inside a Mapserver layer.

LAYER NAME "route" TYPE LINE STATUS DEFAULT CONNECTIONTYPE postgis CONNECTION "host=localhost dbname=roads user=chris password=pass " DATA "the_geom from (SELECT the_geom, gid from shortest_path_as_geometry('roads', 219102, 183552)) as route using unique gid using srid=-1" TEMPLATE "t" CLASS NAME "0" STYLE SYMBOL "circle" SIZE 7 COLOR 255 255 0 END END END

Please note that this method is very inefficient as each map refresh will recalculate the route and so putting a lot of unnecessary load on the database. Only use this a proof of concept for now :)

Lets compare the “shortest path” with a common driving directions site, whereis.com.au. As you can see, the route is different purely because of our simple algorithm to generate the weights.

I plan to release some at least two more articles that build on this introduction.The first will investigate how to tweak the weighting algorithm to more closely match the commercial routing option and the second will look at implementing a more dynamic, user friendly javascript option built into Ka-Map.

Stay tuned, hope i havent put too many of you to sleep :)