-
Notifications
You must be signed in to change notification settings - Fork 62
Offline layers #2176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Offline layers #2176
Conversation
|
Finally ready for review! The offline layers and control is best tested without the mechanisms to start the application offline as described above. The changes in this PR does not depend on caching the application and its assets, as WMSOFFLINE and WFSOFFLINE depends solely on indexedDb. Adding offline support to the application only adds complexity in testing. Most of the changes does not affect exitsting code as this PR mainly adds two new layertypes and a Control, but there are some changes to the old editstore and transactionhandler that potentially can affect normal edit operation (WFS). To test this PR a bunch of new configuration is needed as described above in the first comment on this PR. The control needs to be added and a couple of WMSOFFLINE and WFSOFFLINE layers. Documentation will likely be the layerconfig tables from comment above. |
|
Resolved merge conflicts. Could someone please test this before it degenerates into a pile of non-mergeable garbage. It is only necessary to test that it doesn't break any previous functionality and that the new functionality doesn't introduce any unwanted design patterns. The actual functionality does not have to be tested completely as there are no existing applications that are depending on it. |
|
I don't think we want to lose out on this bit of functionality. Did note however that the loc string keys are in snake case. Edit. An example config would have been appreciated but as I take it there are two mandatory (extra) props of a WFSOFFLINE layer, I tried the editor with the offline control loaded but without any WFSOFFLINE layers. Creating new features and editing existing worked as expected. For some reason I had more success in Firefox, Chrome didn't see any layers to download when the Download rectangle action is taken from the Offline toolbar. But FF did and taking things offline, going offline via the toggle, then editing, then switching to online again and syncing worked well. The message then was "Synchronized It's neat that already downloaded areas are shown when the action to download new areas is taken. As for unwanted design patterns, well if someone else wants to take a stab then go for it. I didn't see anything immediately horrible in the edited files : ) |
Fixes #1901 and fixes #1903
This is a draft PR for offline layers. It is draft as no PR accepted is given but we would like to have others to look at it. This PR contains two offline layer types: WMSOFFLINE and WFSOFFLINE. It also contains a Control that adds a new toolbar with tools to control offline functionality. This PR does not contain code for making an Origo application able to start up offline. That is given as a code example further down in this text. Most of the added functionality is added through the layer classes and the control, but some hooks are added in the editor for handling offline edits. This PR also removes the last remaining files from the old defunct offline implementation.
To test the control and layers, the application itself does not have to be offline capable, just add the control and a couple of offline layers. To be fair, the terminology should probably be "local layers", but since "offline" is well rooted, we'll stick to that. None of the layer types are sometimes online, sometimes offline, they always only use the local storage as source and have to preload some data before anything can be shown. This is because we think it will confuse the users if the layer behaves differently when switching between offline and online modes.
As it is not likely for anyone to preload an entire tiled map, e.g. orthophoto for en entire municipality as background map we recommend using a generalized vector map as background map. It can either be distributed as a bundled asset geojson or a WFSOFFLINE layer with the
offlineUseLayerExtentoption set totrue. This will ignore the drawn rectangle for those layers, which makes it always download the entire extent, which is good for keeping the background map always up to date, but will slow each download down. Using a service-worker cached geojson as background will only be updated when the application "manifest" is updated, but will not slow down downloads. Obviously there is room for improvement here, layers could have a special background flag and be treated differently or the user could be able to select only which layers to download and sync.WMSOFFLINE layers
Has the capability to download tiles from a WMS service, pretty much like a tiled WMS layer. The selection of area to download is done by using the download rectangle tool in the offline toolbar. Be aware that tiles are very bandwith consuming. To reduce bandwidth requirements, the zoom levels can be limited. Also be aware that it may put stress on the WMS server as it burst loads everything.
The layer uses a WmsOfflineSource class which is a specialized class of the abstract class ImageTileOfflineSource, which implements all offline handling. In this way it is easy to implement new tiled image layers by just implementing the code for how to fetch tiles.
WFSOFFLINE layers
Is the WFS equivalent of WMSOFFLINE. In addition it supports offline editing. Offline edits are handled just like ordinary edits, but are persisted in local storage when saved using the ordinary save button or autosave. By synchronizing edits using the offline toolbar's sync tool the locally stored edits are uploaded to the server. After the upload, all offline vector layers are re-read from the server to reflect the current state.
The WMSOFFLINE layer type is built on a specialized source class and an abstract base class that performs most of the functionality. To create new editable layer types only the code for fetching features and pushing edits have to be added and a layer factory function that handles the configuration.
The Offline control
The tool opens the offline toolbar which has five tools
Preload tool: The preload tool allows the user to draw an extent to download in the map. One or more extents can be downloaded.
each downloaded extent is fetched from the server and stored in the browsers persistent storage (indexdDb). When the tool is
active all previously downloaded extents are visible in the map. Before any extent is downloaded the offline layers will contain
no data.
Clear tool: The Clear tool removes all locally stored data for all layers and information about downloaded extents.
View ongoing downloads: As tiles can take some time to download that is done in the background. This tool displays progress
in a dialog. For the time being, it only displays progress for tiled layers as vector layers are usually much faster.
Go offline tool: The go offline tool toggles between offline and online operation of the application. It does not in fact affect
the connectivity in any way, it merely hides all layers that are not offline capable to avoid the map to be slow. If there is a backgroundlayer
tagged as offline it will activated. When toggled to online all visibility of all layers are restored to before offline mode was selected.
Which offline mode is active is persisted between sessions to support offline mode at startup.
Sync edits tool: The sync edits tool will upload locally saved edits to the server for all offline editable layers. Afterwards
all downloaded extents are re-read from the server for editable layers, even if there were no edits. This results
in a sync mechanism that treats all inserts to succeed, all edits win over server side edits regardless of which edit was first,
and all deletes to succeed. If an edited feature was already deleted on the server it is not resurrected, remaining deleted.
WFSOFFLINE Configuration
A WFSOFFLINE layer is a vector layer that uses a local storage in the client browser as source and does not require a network
connection.
The features are preloaded into the local storage from a WFS service. One or more disjoint or overlapping extents can preloaded.
Most options are the same as for WFS, but some additional
options have to be set.
WFSOFFLINE layers can be edited and the edits are saved to persistant local storage offline and can be synchronized with the WFS server
when network is available.
Preloading features and synchronization of edits can be performed using the Offline control or api functions on the layer's
source.
abstractattachmentsallowedEditOperationsattributesattributionclusterOptionsclusterStylecsseditableexportablestrategyshould be set toall. Optional.exportFormatextentfeatureinfoTitlefiltergeometryNamegeometryTypeidisTablefalselegendgroupmaxScaleminScalenameofflineStoreNameofflineUseLayerExtentfalse. Optional.opacityopacityControlprojectionqueryablerelatedLayersremovablerequestMethodsearchablesourcestylestylePickerthematicStylingthematicStylingto true will add buttons to the different thematic styles to be able to turn them on or off. Optional, defaults to false.titletypevisiblezoomToExtentSource options
The following options are available for the
sourceconfiguration for WFS.urlrequestMethodclusterOptionsworkspaceprefixWMSOFFLINE Configuration
A WMSOFFLINE layer is a tiled layer that uses a local storage in the client browser as source and does not require a network
connection.
The tiles are preloaded into the local storage from a WMS service. One or more disjoint or overlapping extents can preloaded.
Most options are the same as for WMS, but due to the offline nature
some options are not available. Preloading tiles can be performed using the Offline control or api functions on the layer's
source.
Beware that preloading tiles can be very bandwidth extensive even at small extents as all tiles on all zoom levels are
preloaded!
abstractattachmentsattributesattributionclipfalse.compressionFactorcssextentformatgroupgutterhasThemeLegendlegendlegendParamsmaxScaleminScalenameofflineMaxZoomofflineMinZoomofflineStoreNameopacityopacityControlremovablequeryablesourcesourceParamsstyletileGridtitletypevisiblezoomToExtentformaturlversiontileGridtypeOffline application
In order for the application itself to be able to start without network connection it must be stored locally in the browser at some point. This easiest accomplished by using a service worker. The code for bootstrapping an offline application is in two steps: first the service worker must be loaded and the the service worker must store the application and all its assets i a local cache. The first part could be bundled in the origo bundle, but we have chosen not to do it right now. The service worker itself must be a separate file and can thus not be bundled, but it could possibly be added as an static file. Problem is that it contains a hardcoded list of assets with versioning so that the assets can be loaded when updated. It can probably be parameterized, but we chose not to try that for now.
index.html
Code neccessary for offline in index.html:
init-offline.js
The init-offline.js file. This is not production ready code, but should work for most applications:
service-worker.js
The service worker itself (service-worker.js). Also, this is not production ready code. At the bottom are all assets that must be available offline. This is taken from our demo application, which uses some geojson layers as offline background map, so they are cached by the service worker instead of making the user preload them manually. When an asset is updated the version number in this file should be bumped to make the service worker download the new version of the asset as it uses a cache-first approach.