Tuesday, July 26, 2011

Node.js + Express + Leaflet + PostGIS = Awesome Maps

Recently I blogged about using GeoJSON to create a very lean application for serving dynamic maps.  To date, all of my posts have related in some way to Microsoft technologies because that is my environment, day-in, day-out, but I thought it would be interesting to create a similar solution to the last blog post using technologies I haven't used before - why? - because it's good to learn something new, and these libraries are really cool!

The Objective

As you would recall from last time, the objective was to create a map with an Open Street Map (OSM) base layer, which overlays the cadastral boundaries as a layer that is retrieved when the user pans or zooms around the map.

The previous solution achieved this using Tile5 to render the map on the browser, and make ajax requests to an ASP.Net MVC application which would retrieve the cadastral boundaries for the current view extent from SQL Server, and return them as GeoJSON structured objects to Tile5 to render on the map.

The new solution uses a mapping library called Leaflet, which makes requests to a Node.js application written using the Express framework, which makes requests to a PostgreSQL/PostGIS database server to supply the requested spatial data, so the solution is using Javascript from end to end .


Leaflet is a lot like Tile5 - it is a javascript mapping library released by CloudMade and exposes functionality to define maps in a browser.  The library allows developers to include OSM data layers via CloudMade services, and has facilities to render GeoJSON, just like Tile5 did in the previous post.


Express is a javascript web development framework built on Node which gives you the ability to write web sites in a similar way to ASP.Net MVC.  The interesting thing about this solution is that it uses javascript both on the client (in the browser) and the server (hosted by Node)

View templates in Express can be written in Jade or Haml, of which I chose the latter because I am using JetBrains' WebStorm as an IDE, and it had native support for Haml syntax checking.  Being a noob I thought that would help :)


The reason I chose PostgreSQL is that it appears to have a very rich spatial implementation with the PostGIS module, seeing as there were javascript libraries to perform database access I decided it would suite my purposes.

The first step in the development process was install PostgreSQL, and PostGIS and import my Queensland cadastral data into it.  The spatial indexing in PostGIS is a little different from SQL Server, and is worthy of a future blog post, suffice to say there are some idiosyncrasies in my spatial queries below that warrant a second glance.

Lets check out the code…

Installing Express

Express can be installed by installing Node, and NPM (Node Package Manager), which simplifies the installation of Node based packages.  Once these are installed you can install Express.

I found that there were some dependencies for Node and NPM that I didn't have on my fresh installation, so I had to install the following -
sudo apt-get update
sudo apt-get install git-core curl build-essential openssl libssl-dev
I also encountered a problem installing Express because I cloned the latest version of Node from GitHub, and it wasn't compatible with the later version, so I had to download version 0.4.10 which I extracted and then ran the following commands to install -
sudo make install
node -v
The final command should show the version of Node that is installed.

To install NPM -
curl "http://npmjs.org/install.sh" | sudo sh
npm -v
The final command should show the version of NPM that is installed.

I then installed Express -
npm install -g express
Express can then be used to spawn a template application, and install its dependencies using the following commands -
express /home/tjackson/geojsonexample && cd /home/tjackson/geojsonexample
npm install -d
This will create an Express application with a basic structure -

  • node_modules - contains all the framework libraries
  • public - contains all the folders that will be exposed on the web server, i.e. images, javascripts, stylesheets
  • views - contains all the view templates
  • app.js - is the main application script that is executed in Node, and contains all the route logic, and possibly your controllers


Express doesn't come with the concept of Controllers straight out of the box, but there is an MVC example in the GitHub source branch that shows how to achieve a structure with Controllers in separate javascript files which are imported when the server starts up.  The routes must then be configured to point at the required controllers.

This example is so basic, with only two server actions, that the business logic has been included in the app.js file.
The changes I made to the originally generated app.js file were
  • importing pg, which is the PostgreSQL database access library
  • setting the view engine to haml, but this didn't execute my haml files correctly, so I installed haml-js (npm install hamljs)

You can see that the RetrieveCadastre action passes the body through to the function, which represents the bounds of the map to retrieve cadastral information from the database, which you can see being used to build up the SQL statement.

The interesting part of the SQL statement is that it looks like it is using the same filter twice in the where expression.  In fact the first part is using the && operator which instructs the query engine to use the spatial index to do an index seek using the bounding box of the filter to find features whose bounding boxes also intersect the filter.  This will result in more matches than we expect because some feature's bounding rectangles will intersect our area without the shape inside actually intersecting the area, so what we do is then filter the index results such that the underlying geometries are intersecting our spatial area.  For my specific purposes the first filter would be enough, but I included the example for posterity.

The other interesting thing about the SQL is that the selection is returning the GeoJSON of the resulting objects using the ST_AsGeoJSON function.  This is really cool because it saves me from having to parse the result into a GeoJSON structure to send back to the client.

After the statement is executed, you can see that it forms a javascript object for each result feature, using JSON.parse, and then adds this to a feature collection object, which is structured according to the GeoJSON standard.  This collection is then returned to the client for rendering.  Wow, that’s even leaner than last time round!


The only view I have is for displaying the initial map.  As you can see it is much like the Tile5 example from last time around, but with some slight interface changes for Leaflet's differences.
The obvious main difference is the use of Haml rather than Razor for the view template itself.  The one interesting experience I had with Haml was problems with the indenting, which took me back to the days of Fortran77.  The thing I had to watch was the linespace between my javascript functions, and that there was the same amount of indenting on the blank lines (spaces from left) as the number of spaces to the start of the function statements.  I guess this is so that the resulting html is indented according to the developer's intentions, considering closing tags are not required in the Haml markup.


The final thing to do was include my client side dependencies in the public folder, so my Express application looked like the structure blelow-


As you can see, the code to achieve the solution is even leaner than the previous solution, mainly due to PostGIS being able to return the database results already formatted into GeoJSON.

The example application gives a little peek into the sophistication that can be achieved using javascript as both a client and server side solution.  It is also surprisingly zippy considering that I have the entire set of Queensland cadastral boundaries in the PostgresSQL database on a low spec VirtualBox instance of Ubuntu desktop, with the cadastral boundaries refreshing in under a second on maps of the extent of the example below.


  1. This was a great read. I've been needing to take a closer look at node.

    I thought I'd mention that in your app.js when you're building the spatial SQL, you can leave out most of line 55 as PostGIS' ST_Intersects automatically makes use of any spatial indexes you've built.

  2. Thanks for the feedback Jason. With regard to info about PostGIS and how ST_Intersects should utilise the index - I had some problems with this which is why I added the bounding box filter to the statement as well. I discussed it a little more in my latest post http://goo.gl/tJRga, but I am wondering if the issue (i.e. not using the spatial index) might have been caused by me using the geography data type instead of a geometry type.

  3. This comment has been removed by the author.

  4. ciao, ho letto il tuo interessante articolo, premetto che non sono pratico ne di gis ne di siti web ma ci sto provando, sto usando leaflet, postgis e dreamweaver cs6 ma non so come fare, ho scaricato il tuo esempio da github e seguito tutte le tue istruzioni ma non riesco a farlo funzionare, inoltre avrei bisogno dell'index.html per vedere nel mio browser.Mi potresti aiutare o consigliare una guida ?

  5. you'll need to change app.register to app.engine with Express 3.0

  6. Am working on a project on maps. I come across this tutorial in mapbox : https://www.mapbox.com/mapbox.js/example/v1.0.0/linking-to-external-data/

    Merely looking at it, since it looks like a jason format, i thought it would be possible that i would get information from the database and create a json file using php and calling it back to javascript using ajax. The problem is it won't accept the newly encoded json though its generating the correct format for the json. So are there any other ways of doing this?

  7. This is good stuff Todd.
    I just started with node.js, and I am very ESRI-based programmer, who is discovering the world of open-source outside ESRI.
    My target is to build a project with node.js, leaflet, and Angular to add these three technologies together.
    What you did is going to help me a lot.

  8. Does Nodejs work with Geoserver ? (angularjs + openlayers + nodejs + geoserver + postgis) , i wanna use the WFS-T service for map drawing tool.

  9. Where is the geojsonexample and cadastral data? link please

  10. Awesome post,its so much informative for the followers and so much helpful also.I appreciate you for this great post.Thanks for sharing.Keep it up.

  11. Thank you for sharing this information. This article is very interesting and useful. Keep up the good work!

  12. After reading this blog I am very strong in this topics and this blog is really helpful to all... Explanation are very clear so it is easy to understand.. Thanks for sharing this blog...
    node js developer london

  13. It is really a nice and useful piece of information. Thank you for giving me the information.
    Look at this page, the largest selection of steel products, 1.4410

  14. This comment has been removed by the author.

  15. This comment has been removed by the author.

  16. Good info.

    Freshpani is providing online water delivery service currently in BTM, Bangalore you can find more details at Freshpani.com
    Online Water Delivery | Bangalore Drinking Water Home Delivery Service | Packaged Drinking Water | Bottled Water Supplier

  17. This is excellent information. It is amazing and wonderful to visit your site...
    Event management company in chennai

  18. Sebab mungkin susunan kartu yang didapatkan pemain lawan akan jauh lebih baik ketimbang susunan kartu anda.
    bandar ceme terpercaya
    paito warna terlengkap
    bocoran sgp

  19. Thanks for sharing information with us. If someone wants to know about Taxi Service App and Health Management Software I think this is the right place for you.
    Taxi Dispatch App | Taxi Service Providers | Safety and Health Management System

  20. This is a nice post in an interesting line of content.Thanks for sharing this article, great way of bring this topic to discussion.

    Mobile Application Development Company In Bangalore
    App Development Company In India
    Android App Development In Bangalore

  21. Nice information. Thanks for sharing such an amazing article. For Latest Telugu News and updates please visit our website: TV9 Telugu Media News

  22. Nice information. Thanks for sharing such an amazing article. For Latest Hindi News and updates please visit our website: TV9 Bharatvarsh Media News

  23. Nice information. Thanks for sharing such an amazing article. For Latest Marathi News and updates please visit our website: TV9 Marathi Media News

  24. I have read this article it is really helpful for getting amazing tips on related topic. You have described everything in a professional way.Web Designers in Bangalore | Website Design Company Bangalore | Web Design Company In Bangalore | Web Designing Company In Bangalore

  25. Enjoyed reading the article above, really explains everything in detail, the article is very interesting and effective. Thank you and good luck for the upcoming articles nodejs training

  26. Enjoyed reading the article above, really explains everything in detail, the article is very interesting and effective. Thank you and good luck for the upcoming articles nodejs training

  27. It is amazing and wonderful to visit your Blog.Thanks for sharing this information,this is useful to me.
    Our Services are:- Digital Marketing Company | SEO Company | PPC Company

  28. Really it is very useful for us..... the information that you have shared is really useful for everyone. If someone wants to know about Taxi Booking App and Taxi Dispatch Software I think this is the right place for you.

  29. Great Info!!! Thanks for sharing information with us. If someone wants to know about Taxi Booking App and Taxi Booking Solutions I think this is the right place for you.

  30. Thanks for sharing it.I got Very valuable information from your blog.your post is really very Informative. I’m satisfied with the information that you provide for me.

    Best Mean Stack Training in Pune

  31. The importance of SEO off page seo This example of a high ranking site seems to go against all perceived wisdom on site ranking i.e. it seems to suggest that on page optimization has no effect on ranking what so ever.

  32. I read the article and really enjoyed your blog articles. Looking for the next post.
    Node JS Online training
    Node JS training in Hyderabad

  33. Wonderful Post. Thanks for sharing

  34. Snapdeal online lucky draw Winner List 2020 here came up with an Offer where you can win Snapdeal lottery 2020 and more prize by just playing a game & win prizes
    Snapdeal winner 2020
    Snapdeal lucky draw winner 2020
    Snapdeal lucky draw contest 2020
    snapdeal winner prizes 2020

  35. really i enjoed this article such a nice post and information keep it up!
    Mobile app development company in Bangalore

  36. Thanks ....., great post. Going to be implementing some of this soon in a new site, looking forward to it!very nice… i really like your blog…CheapWays Digital Marketing Company in Nagpur

  37. Thanks for share this article. I would like to share this post click here to know more Scientific Publishers

  38. Fantastic post, very informative. I wonder why the other specialists of this sector do not notice this. You must continue your writing. I am sure, you have a great writer. keep posting!

  39. Disneyslot - Game Play -Slot Machine - Tembakikan - Agen Playtech - Joker123 - Kingkong - Casino Online

    Hanya Dengan Min Dp 10,000- dan Wd 50,000-, Anda Berkesempatan Meraih Keberuntungan/Kemenangan Di Disneyslot. Memudahkan Transaksi Melalui Bank BCA - BNI - MANDIRI - BRI - DANAMON - PULSA TELKOMSEL/XL dan OVO Payment.

    :: Hot Promo News ::
    • Big Bonus Deposit 50%
    • Next Bonus Deposit 20%
    • Bonus Cashback 5% Setiap Senin

    Kontak Kami :
    Whatsapp : +62813 9701 4667

    Link Alternatif Disneyslot :

    Yuk Jangan Tunggu Lagi Daftar Sekarang Juga Dan Nikmati Kemenangan/Keberuntungan Bersama Disneyslot!!Dapatkan Bonus Tertinggi SlotGame Hanya Di Disneyslot.com

    #slotgame #agenjoker123 #bandarjudionline #agenkongkong #agenplaytech #situsgameslot #websitejudislot #agentembakikanonline #slotplaystar #agencasinoonline #agengpslot #bandarcasino #slotdisney #rajaslotgame #dewaslot #situsjoker #jackpot #promo #bonus #slot #machine #superbonus #sagaming #ebetcasino #asiagaming #allbet #sagaming #evocasino #baccarat #dragontiger #sicbo #tembakikan

  40. I am searching for an article like this for the last 4 hours on the net, but I couldn't. Suddenly I read this one. Thanks a lot for this Article. I really appreciate your writing skills. we are the cryptocurrency expert if you want to know about cryptocurrency ETF fund or cryptocurrency etc. please visit our website to read the full articles about the topic.

  41. You are very articulate and explain your ideas and opinions clearly leaving no room for miscommunication.
    Please Kindly check My web: buy instagram followers targeted

  42. You are very articulate and explain your ideas and opinions clearly leaving no room for miscommunication. Please Kindly check My web: social media presence

  43. Very informative and well-written post! Quite an interesting and nice topic chosen for the post. Your need social service our many type service here please check buy facebook followers