6

I am building a webgis portal too show a big number of polylines (road network) and points (villages, cities etc.). All my data are stored in a POSTGIS and throuh geoserver and Openlayers I display them on the map. For displaying I use two WFS vector layer (one for each geometry). I decided to use WFS instead of a WMS (WMSGetFeatureInfo) as this is what geoserver manual suggests here (regarding the GetFeatureInfo and GetFeature).

The problem comes when the number of features becomes relative big (around 10000 thousand features). My question is how can I deal with such a big number of features. I know one solution is BBOX but I am afraid this can slow things down by sending multiple requests.

Is there another strategy out there?

2
  • Do you actually need to interact with the features on the client, or just view them? Jan 23, 2015 at 12:23
  • I need to interact with them. Change attributes of features, get information etc.
    – user1919
    Jan 23, 2015 at 12:25

3 Answers 3

4

I will describe the way I dealed with the problem. As I mentioned before I have approximately 10000 geometries that I want to display on a map. My data are stored in a POSTGIS database and I use Geoserver (localserver) and Openlayers to display them. Also I need to interact with the data. Get attribute info for each feature and in some cased to manipulate them.

I wrote two different scripts one using WMS layers and the other using WFS layers. I run some speed tests (for the requests) using Firebug and as expected the WFS request was taking much much more. So much more that is not acceptable for my app (see screenshots WFS/WMS )

enter image description here

enter image description here

After reading the above answers and comments I decided to do the following:

  • I created WMS Layers for my data
  • I registered a zoom event
  • After the user reaching a predifined zoom level I send a WFS request with a BBOX strategy

This is my code. I hope it helps someone else with similar issue.

<script defer="defer" type="text/javascript">
<!-- DEFINE PROXY.CGI URL -->
OpenLayers.ProxyHost = "http://localhost/cgi-bin/proxy.cgi?url=";
<!-- DEFINE GLOBAL VARIABLES -->
var map,wms, control;

<!-- DEFINE FUNCTION INIT -->
function init(){
    map = new OpenLayers.Map('map',{}); // define map 
    wms = new OpenLayers.Layer.WMS( "OpenLayers WMS","http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic'} ); // define map layer


    // layer nodes
    wms_layer_komvoi = new OpenLayers.Layer.WMS( "Κόμβοι","http://localhost:8080/geoserver/wms", 
            {layers: 'rural:komvoi_real',
            transparent: true},
            {projection: new OpenLayers.Projection("EPSG:900913")});
        // layer network    
        wms_layer_network = new OpenLayers.Layer.WMS( "Ολόκληρο Δίκτυο","http://localhost:8080/geoserver/wms", 
            {layers: 'rural:foc_network',
            transparent: true},
            {projection: new OpenLayers.Projection("EPSG:900913")},
            {
            }); 

        // add layers
        map.addLayers([wms_layer_komvoi,wms_layer_network,wms]); // first you put the layer with the points
        map.zoomToExtent( new OpenLayers.Bounds(36.190737, 35.353912,35.150577, 50.274810));

        <!-- CONTROL LAYER SWITCHER -->
        map.addControl(new OpenLayers.Control.LayerSwitcher());
        <!-- REGISTER AN EVENT TO LOAD WFS VECTOR LAYERS -->
        map.events.register("zoomend", map, function(){ // event zoomend 
            zoom = map.getZoom();
            var layerNetwork = map.getLayersByName('Δίκτυο'); // check if the layer exists
            if((zoom==11) && (layerNetwork.length==0)){
                <!-- OVERLAY WFS LAYER WITH NETWORK FROM GEOSERVER BBOX STRATEGY -->
                wfs_layer_network = new OpenLayers.Layer.Vector("Δίκτυο", {
                    visibility: true,
                    //displayInLayerSwitcher: true,                     
                    strategies: [new OpenLayers.Strategy.BBOX()],
                    protocol: new OpenLayers.Protocol.WFS({
                        version: "1.1.0",
                        url: "http://localhost:8080/geoserver/wfs", 
                        featurePrefix: "rural", //workspace from geoserver
                        featureType: "foc_network", //layer name from geoserver
                        featureNS : "http://www.opengeospatial.net/rural", //namespace from geoserver
                    })
                })
                map.removeLayer(wms_layer_network);
                map.addLayer(wfs_layer_network);
            }
            if ((zoom<11) && (layerNetwork.length!==0)){
                map.removeLayer(wfs_layer_network);
                map.addLayer(wms_layer_network);
            }
        });
}// end init    
</script>   
2

You could also use WMS or even preseeded tiles and just grab the single features you need to edit from wfs.

http://dev.openlayers.org/releases/OpenLayers-2.10/examples/getfeature-wfs.html

1

With your stack, I'd suggest try to use GeoJSON as transport format but anyway, 10K are a lot of features to be handled by the client browser. I'd think on a WMS rendering for low scales and only when user is really going to do something meaningful with the data (selections probably) at larger scales then download only the vector features present on the bbox.

Also, something to take in account is the simplification of geometries for your road network according to the scale is being rendered. It all depends on your use case, interactivity on the client side, etc. You can search on this site for other questions related with vector features, lot of good answers here (definitely better than mine).

2
  • Thanks for the answer. I need to interact with all features (view/change attributes etc.) So to understand correctly you suggest to use a WMSGetFeatureInfo and in a specific zoom level to call the vector layer. Right? Rendering the data in the server should improve the speed dramatically? Also what about clustering? Would this be a solution alternative to BBOX?
    – user1919
    Jan 23, 2015 at 12:28
  • 2
    I'm suggesting drawing thousands of features on the server and only get the real features when you need to edit them. You should use WFS protocol as late as you can, filtering the number of features you have to retrieve. Rendering data on the server doesn't have to be fast, it depends on your data source, the complexity of the symbols, etc. Clustering is a way to present lots of data in a limited space, it's more about what you want to mean with your map that the technical problem of the performance of your set up.
    – Jorge Sanz
    Jan 26, 2015 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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