Server-side OpenLayers

I’ve been interested in server-side JavaScript lately. As a proof of feasibility (to myself) I’ve put together a node.js-based web service that gets geographic objects from PostGIS and provides a GeoJSON representation of these objects.

For this I’ve used node.js, postgres-js and OpenLayers.

node.js is a lib whose goal is “to provide an easy way to build scalable network applications”. node.js relies on an event-driven architecture (through epoll, kqueue, /dev/poll, or select). I’d recommend looking at the jsconf slides to know more about the philosophy and design of node.js.

The “Hello World” node.js web service looks like that:

var sys = require('sys'),
      http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('Hello World');
  res.close();
}).listen(8000);
sys.puts('Server running at http://127.0.0.1:8000/');

Thanks to node.js’s nice interface I think the code is pretty much self-explained.

Assuming the above code is included in a file named file.js, starting the web service is done with

$ node file.js

Now we can use postgres-js to read data from a PostGIS table. postgres-js sends SQL queries to PostgreSQL through TCP. postgres-js is a node.js module, so it can be loaded with require() (just like the built-in sys and http modules).

var sys = require('sys'),
    http = require('http'),
    Postgres = require('postgres');

var db = new Postgres.Connection("dbname", "username", "password");

http.createServer(function (req, res) {
    db.query("SELECT name, astext(geom) AS geom FROM table", function (objs) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.write("it works");
        res.close();
    });
}).listen(8000);
sys.puts('Server running at http://127.0.0.1:8000/');

The last step involves using OpenLayers for deserializing from WKT and serializing to GeoJSON. To use OpenLayers in the node.js application, and load it with the require() function, I packaged OpenLayers as a node.js module. It was easy enough, see the modules doc.

And here’s the final code:

var sys = require('sys'),
    http = require('http'),
    Postgres = require('postgres'),
    OpenLayers = require('openlayers').OpenLayers;

var db = new Postgres.Connection("dbname", "username", "password");

http.createServer(function (req, res) {
    db.query("SELECT name, astext(geom) AS geom FROM table", function (objs) {
        var features = [];
        var wkt = new OpenLayers.Format.WKT();
        for(var i=0,len=objs.length; i<len; i++) {
            features.push(
                new OpenLayers.Feature.Vector(
                    wkt.read(obj[i].geom).geometry, {name: obj[i].name}
                )
            );
        }
        var geojson = new OpenLayers.Format.GeoJSON();
        var output = geojson.write(features);
        res.writeHead(200, {'Content-Type': 'application/json'});
        res.write(output);
        res.close();
    });
}).listen(8000);
sys.puts('Server running at http://127.0.0.1:8000/');

The End. Happy server-side JavaScript to all.

Advertisement

Tags: , , , ,

3 Responses to “Server-side OpenLayers”

  1. Ted X Toth Says:

    What’s ‘table’s schema? Would you have a script for creating and populating ‘table’? Had you thought any about table update handling?

  2. Ted X Toth Says:

    Looks like postgres-js changed significantly since this was written :(

  3. Ted X Toth Says:

    I changed the postgres connection to use a URL and that seems to work with the newer postgres-js. Then I made a link to the openlayers code I downloaded and changed the example to:
    OpenLayers = require(‘./openlayers/lib/OpenLayers’).OpenLayers

    However when I run the server I get:

    ReferenceError: window is not defined
    at /Library/WebServer/Documents/openlayers/lib/OpenLayers.js:30:5
    at Object. (/Library/WebServer/Documents/openlayers/lib/OpenLayers.js:329:2)
    at Module._compile (node.js:639:23)
    at Module._loadScriptSync (node.js:651:16)
    at Module.loadSync (node.js:550:10)
    at loadModule (node.js:495:16)
    at require (node.js:618:12)
    at Object. (/Library/WebServer/Documents/gistst2.js:4:18)
    at Module._compile (node.js:639:23)
    at node.js:667:20

    How did you make openlaysers a node.js module?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.