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.
Best Answer
Given that you are requesting WMS tiles, you can use a cache service like WMS-C (WMS Cached), Tile Map Service (TMS) or Web Map Tile Service (WMTS); the latter is an OGC standard. There are several implementations of these standards; to mention some, there are GeoWebCache, TileCache or MapProxy.
Because you are using GeoServer, I think that the best solution in your case would be GeoWebCache, that has a very good integration with GeoServer. Among the standards mentioned before, perhaps WMTS is the one that suits your needs the most, because WMTS can cache the results of GetFeatureInfo requests. Currently GeoWebCache 'fully implements WMTS using KVP'.