Drawing and editing geometries in XYZ’ dynamic vector tiles with OpenLayers 5.
I hope you find this article as a reference from some work I have done with WFS-T and Geoserver. I don’t really use Geoserver or WFS anymore while we build XYZ, the open source spatial data and application interface at GEOLYTIX.
The implementation of dynamic vector tiles is discussed in a previous medium post. Earlier article highlights the creation and caching of tiles in PostGIS.
This article focuses on the drawing and editing of geometries through an OpenLayers map interface. The complete example which uses REST endpoints provided by the geolytix.xyz/dev instance can be found in following fiddle.
Defining the OL map, layers & sources.
The OpenLayers map consists of three layers which are defined and added to the map object upon its creation.
An OpenStreetMap base layer which is provided by Carto as raster tiles to provide geographic context.
A vector tile layer and source to display MVT provided by the XYZ development instance. XYZ middleware functions will create and cache MVT directly in PostGIS. The clearTileCache function ensures that cached tiles are removed from the MVT data source after successful geometry edits.
A vector source and layer are used to stage newly drawn geometries or modify existing geometries. Once written to the PostGIS table the features will be removed from the vector source.
Draw new features.
Interface buttons add a drawing interaction for the selected geometry type to the OpenLayers map object. Features will be drawn on the vector source. The interaction ‘drawend’ event will send the geometry to the XYZ middleware.
Having a preference for vanilla JS Web APIs we use a XMLHttpRequest (XHR) to POST feature geometries as GeoJSON to the XYZ API. The middleware will create a SQL insert statement to add the new feature to the PostGIS data table. The serial ID of the new feature is returned from a successful insert. Cached tiles which intersect the geometry of the new feature must be removed from the tile cache. In the XHR onload event, the ID is assigned to the vector feature to allow for immediate edits to this feature. The tile cache of the MVT source is cleared which will force OpenLayers to request a new tile set from the XYZ endpoint. XYZ will compose SQL statements to create MVT in PostGIS and store the newly generated tiles in a tile cache table.
Modify existing features.
MVT geometries are optimised for performance by snapping vertices to the tile coordinate space. In order to edit geometries it is required to request a feature from the XYZ middleware as GeoJSON. Using OpenLayers map ‘click’ event we query features at pixel from the vector tile source. The ID of the first feature in the array returned from the OpenLayers method will be passed as a query parameter to the XYZ location select endpoint. In the XHR onload event, the feature is added to the vector source and a modify interaction is added to the map object.
The ‘modifyend’ event of the modify interaction will send a POST request with the updated geometry as GeoJSON to the XYZ middleware. The middleware will update the geometry in the database and retire tiles all tiles from the cache table which intersect either the original or updated geometry.
The deletion method will send a XHR query to the XYZ middleware with a request to remove the feature from the PostGIS data table. XYZ will ensure that tiles which intersect the feature’s geometry are retired from the tile cache.
I am by no means an OpenLayers hack and haven’t done any OL coding in anger for over 2 years. Prior to writing this example with OL 5.3 I have last worked with version 3.5. Please DM, fork the fiddle or comment on the code gists with any ideas for improvement.
I use the latest XYZ development build in my fiddles which may sometimes be unavailable for maintenance.
If you want to get involved with the XYZ project, looking for consultancy services or would like to work with us please get in contact via firstname.lastname@example.org