3

I am not sure If I got the overall web-mapping architecture right. I can easily find tutorials about each part, but nothing on how to connect them.

I have openlayers in the front-end, node.js as a server and postGIS as a DB.

An action is done in the openlayers part, the data are sent to node, they define a query. Node sends this query to postGIS, postGIS answers it. The new data now travels back to the front-end via node to be rendered on openlayers. Openlayers fetch OSM as a base layer and I only save points/lines/polygons in postGIS.

(User clicked on the map, get lon/lat, use them as query parameters, find 4 nearest neighbors, send neighbors back, render them on the map).

Geoserver confuses me. I cannot understand its role in this mix. I cannot see how queries are related to it. I see SQL in all the postGIS tutorials and in OpenLayers and Geoserver I see CQL, that is not on the same level.

Do queries get formed in node but go to postGIS via Geoserver or do they get formed in node, they go to postGIS via node and then postGIS sends the answer in Geoserver to alter the map?

  • 3
    I've found this to be extremely useful in gaining a general understanding of how web mapping works. It does not go into details of the 'nuts and bolts' or specifics of each tool, but provides a general overview. You may already know much of it, but maybe it will help to answer your question: udemy.com/introduction-to-web-programming-for-gis-applications – pdavis Dec 8 '17 at 19:17
  • 2
    wow I really hope somebody gives a good thorough answer as I am a few steps behind you trying to learn web mapping but have not found a tutorial that brings it all together – ziggy Dec 8 '17 at 20:20
5

It is not easy to get the open source based overall web-mapping architecture. When we use open source, we can combine many tools. Sometimes, we just get one or two features of a tool. We have many, many ways to combine the amazing available tools.

Even for the same use case, you can get different software stacks, equally good.

In your use case, you might not need Geoserver at all.

Minimal scenario

In the minimal scenario, you can use OpenLayers on the client side with an OpenStreetMap layer, and node.js on the server side. If you want to display some other features on the map, you can style the features using OpenOpenlayers and get the data as GeoJSON from node.js. Node.js will receive requests, create a proper query and get the data from Postgresql. If you need to create or edit features on the client side, you send those changes to node.js as GeoJSON. Then use node.js to send it back to Postgresql to create or edit records on the database. Using just OpenLayers and node.js, you have a very efficient solution.

Let me show some OpenLayers code. To display additional features:

Server.myFeaturesAsGeoJson({
    foo: form.get('foo'),
    bar: form.get('bar')
}, function (result, event) {
    if (result.success) {
        if (result.data.features) {
            var features = (new ol.format.GeoJSON()).readFeatures(result.data);
            myFeaturesLayer.getSource().addFeatures(features);

If you change the layer on the client side using OpenLayers ol.interaction.Draw or ol.interaction.Modify, you need to pass those changes to node.js with:

var features = myFeaturesLayer.getSource().getFeatures();
if (features.length) {
    var details = (new ol.format.GeoJSON()).writeFeatures(features);
    Server.saveGeoJsonDetail({
        features: details
    }, function (result, event) {
        if (result.success) {
            console.log('Saved!');

Some notes on node.js code:

To write the geographic features on the database, you need to prepare the query in node.js, but Postgresql will handle the GeoJSON format. So for writing a feature is simple as:

"ST_GeomFromGeoJSON(" + JSON.stringify(element["geometry"]) + ")"

In node.js, to send features as GeoJSON to OpenLayers, you can create the proper FeatureCollection structure in you code, but I prefer to write a more complicated query and get the GeoJSON out of the database with something like:

var sql = '';
sql += 'SELECT row_to_json(fc) as geojson ';
sql += "FROM ( SELECT 'FeatureCollection' As type, array_to_json(array_agg(f)) As features ";
sql += 'FROM ( ';
sql += "SELECT 'Feature' As type, ST_AsGeoJSON(lgeom.the_geom)::json As geometry, row_to_json(lprop) As properties ";
sql += 'FROM plantas.pedidodetail As lgeom ';
sql += 'INNER JOIN ( ';
sql += 'SELECT id, gid FROM plantas.pedidodetail ';
sql += 'where gid = ' + gid;
sql += ' ) As lprop ';
sql += 'ON lgeom.gid = lprop.gid ';
sql += ') As f )  As fc';

You can also use ogr2ogr node module to return data as GeoJSON from Postgresql to OpenLayers.

Why Geoserver?

Get your own raster or vector data as WMS

You need Geoserver or another map server if you need other layers from your own data. You create the layer on Geoserver and add it to the map using OpenLayers.

Performance

You need a map server if you have many features. Reading and writing features in node.js, as I showed, is feasible for a few number of features. If you have many features to show, you need to have a WMS layer to show them at large scales. When the user zooms in, and the number of features in the view is small, you can disable the WMS layer and switch to the GeoJSON based vector layer. When the user zooms out, you disable the vector layer and show the WMS layer again.

If you have a large number of features, the features (or the style) are too complex to style, or if you have a group of layers, you might consider to use GeoWebCache well integrated in Geoserver. For performance issues, you need a tile cache.

WFS support

If you don't want to write your own code to manage the GeoJSON staff, you can use the Geoserver's WFS support. Using WFS, you don't need to do the queries in node.js to read or write the features. WFS will handle that. You can create a WFS layer with:

var vectorSource = new ol.source.Vector({
    format: new ol.format.GeoJSON({
        defaultDataProjection: 'EPSG:3763'
    }),
    url: function (extent) {
        return 'http://geoserver.domain.pt:8080/geoserver/wfs?service=WFS&' +
            'version=1.1.0&request=GetFeature&typename=marte:edificado&' +
            'outputFormat=application/json&srsname=EPSG:3763&' +
            'EXCEPTIONS=application/json&' +
            'bbox=' + extent.join(',') + ',EPSG:3763';
    },
    strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ())
});
var vectorWFS = new ol.layer.Vector({
    source: vectorSource,
    style: simpleStyleFunction,
    maxResolution: 1.09956468849 // The maximum resolution (exclusive) below which this layer will be visible.
});
olMap.addLayer(vectorWFS);

WFS limitations

If you have some kind of relations between feature classes, WFS might not be able to handle that. WFS works with simple features. Support for complex features is under development by the Geoserver team, but many client do not support these complex features yet.

WFS primary key limitation

WFS requests must return features with unique ids. If you don't have unique ids, features will be repeated in OpenLayers and you will have problems updating features. For those cases, check how to add unique ids to your WFS layers on the Geoserver documentation.

Geoserver memory (and CPU) requirements

Geoserver is written in JAVA. Geoserver's memory footprint is (very) high. When you buy a dedicated server, the price will change if you use Geoserver or not.

  • Thank you for the amazing answer. A couple of comments. (1)My concern is what happens if I use the minimal node+OL+PostGIS and I have a query like "get all buildings in the area" so I get 150 POINTS and a huge GeoJSON. Will this make the OL slower I guess ? (2) I think you use OL to contact with node. Is this a requirement or I can use good old AJAX to send geoJSON from node to postGIS and vice versa ? (3) Why use OL+WFS to query Geoserver, when the query abilities are lower than PostGIS? – slevin Dec 10 '17 at 13:29
  • (3 continued) : with OL+WFS you can do simple stuff like "show all points on this area", but you can not do more complex stuff like "nearest neighbor". So, this is why I try to avoid the OL+WFS and use the more advanced techniques of pure postGIS. Oh, and thank you again for your answer and time. Cheers. – slevin Dec 10 '17 at 13:31
  • 1
    (1) If you get 150 points, it might look like a huge GeoJSON, but it isn’t. The client can handle that data quite fast. The same data as GML (the default with WFS), the parsing will be slower. (2) You can use regular AJAX calls. I use a wrapper function around those calls, but behind the scenes there is a traditional AJAX call. (3) WFS is nice, but some people developing standards lives in la-la land. In practice, you need to do complex queries joining tables. And if you use WFS transactional support (for updates, as supported by Geoserver), it is even more restrictive in real scenarios. – jgrocha Dec 10 '17 at 16:53
  • What if in (1) I have 3000 points? (3) So, let me get this straight, you agree with me that WFS has less abilities than pure postGIS? Thanks again. – slevin Dec 10 '17 at 18:03
  • 1
    I've wrote a Performance section on my answer, just in case you have thousands of features. If you are building a more complex application or dealing with large number of features, you need a map server (just the WMS/WMTS services). I agree with you. Pure PostGIS is more powerful and flexible to handle geographic features, not WFS (for any number of features). – jgrocha Dec 10 '17 at 19:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.