Thursday 4 April 2019

openlayers 2 - What server and API to use for displaying complex polygons with dynamic symbology?


Background



I need to interface a map into an existing website which allows the user to query a database and which currently results in a table listing population statistics per county.


For example, display the population under 15, for 2003 - the result is a table listing each county's population values.


I need to display a map showing county polygons which are symbolised with those values. If the user modifies the query, the map needs to update (eg, if the year is changed to 2004, or the statistic is changed to population over 65).


Performance will be a factor, so the map should update rapidly when the query is run/modified. The map should support mouse-over events on the counties, so that statistics can be displayed in a popup as the user's mouse moves.


My questions


What are the options for the GIS server (to serve the polygons) and the mapping API (to embed the map on the website)?


Options


I like the look of Leaflet, but it seems that the county polygons would need to be supplied as coordinates/rings. Would this be too slow when zoomed to national scale? Can Leaflet handle on-the-fly simplification (as with feature layers in ArcGIS Server)?


Using OpenLayers with GeoServer could work too, but the performance is quite slow for hover events, and it appears that the symbology is hard-coded in the WFS service(?) I'd need the ability to update the symbology when the query was modified.


ArcGIS Server 10.1 has advanced on-the-fly symbology options, but hasn't been released yet. The client will be wary of deploying beta software on a production site.



Thanks for any advice.



Answer



A few thoughts (warning: brain dump)


1) You mentioned that Leaflet requires coordinates for counties. If you want to support real-time hover events then you need to render your polygons client-side. Whichever framework you choose to do this (Leaflet / ArcGIS JS / ArcGIS Flex / OpenLayers - all of which can render client-side graphics if given the coordinates) you will need the coordinates sent to the client.


The framework you choose will determine how features are actually drawn on the client and this will have a big impact on performance. The user's browser will also have a big impact in this model. A recent(ish) HTML5-capable Chrome or Firefox might perform 10x better than IE < 9. Also the complexity of your polygons will have an effect. Generalised (or simplified) polygons will look a bit crap but render faster (and the coordinates will download to the client faster). You can gzip / deflate the coordinates and make sure they are being served as JSON instead of XML (depending on the server that's providing the data) to improve download times.


You ask about on-the-fly generalisation in Leaflet - even if this is supported I'd say it's a bad idea as Leaflet is JS so all data still has to be sent to the client first, and then the browser will lock up while it runs through some heavy-duty processing. Having pre-simplified data on the server would definitely be preferable.


I've done this before for all local authorities in the UK and if you don't simplify your polygons the client-side rendering can be slooooooooow. On the upside - if you are rendering on the client and you have your statistical data also on the client (or quickly accessible from a server) you have lots of flexibility to change polygon fills in response to a user action (like adding a halo on hover)


Most map servers will support this client-side rendering model (i.e. they will allow you to request coordinate and attribute data for specific features instead of a rendered image) but the response format will vary. ArcGIS server will give you a custom JSON format which is fairly small, GeoServer can give you GeoJSON on request, and many map servers could give you GML (verbose) through a WFS interface.


2) For the rendering performance you want a server-side rendering model would probably be best. This is usually true as it can handle up-scaling the data volume much better than client-side and you don't have to worry about generalising the polygons.


This raises the issue of styling - how can changes in user selections be reflected in the server-generated map? One option is obviously to pre-cook all your data and have a layer for every combination of selections - not much fun. With GeoServer you have a great feature in Web Map Service (WMS, which many servers support) and parameterised SLD (which I think is unique to GeoServer).



When rendering an image in GeoServer (or any decent WMS-compliant server) you can specify a stylesheet to use in rendering the map. This stylesheet (SLD) can have filter rules so if attribute A has a value between 0 and 19 shade it red. If it has a value between 20 and 39 shade it orange etc... With GeoServer you can pass parameters in your WMS request to dynamically alter the SLD - which would allow you to change which attribute you were styling, the bounds for the value ranges, and which colours / icons / fill images were being used in every single map request. Whatever your client framework is (you have many options as multiple js mapping frameworks support a WMS server-side source) will have to listen to changes in user selections and then request a new image from the map server with the updated styling parameters.


I'm sure you're thinking this option will be slow but I was really surprised by GeoServer's rendering performance even with dynamic stylesheets. Make sure your data isn't being reprojected on-the-fly or anything silly like that and you should get good speed.


The one requirement this approach doesn't meet is for hover-over events. WMS supports GetFeatureInfo requests where the map server can tell you what is in the image under the mouse cursor, but this is a round-trip to the server and you don't want to be firing off these requests whenever the mouse moves. You would want to do something like start a timer whenever the mouse stops over the map, and if the cursor keeps the same position for maybe 300 ms then send that request. There will obviously be a delay but hopefully you can live with it.


I can elaborate on any of the above if required


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...