Use Openlayers in Offline mode for land-survey applications!
By: Krishna G. Lodha
Tags: GIS, Web Development, Openlayers 3, JavaScript

Leverage the localStorage Capacity of browser to create temporary custom offline survey application

I was recently developing an application for a surveying company who’s work is more concentrated toward forest and villages rather than urban area. We developed the application with all basic facilities such as ability to toggle different basemaps, from street view to satellite view. Ability for user to add geometries on the map ( Point, Multipoint, Line, Multiline, Polygon, MultiPolygon, etc. ) and then save it to the central database alongside the information that user will fill after completion for drawing and before hitting submit button.

Although one problem was unresolved, i.e. ability to be offline and still roam to the places and mark the geometries accurately and cross check it with the one on the basemap. We all know that when we zoom or pinch or drag the map, new set of pngs are requested to server to load and display on the map which of-course requires active internet connection, and apart from this the next challenge was to store all the drawn geometry and related information somewhere and then recall it the next time device is connected to internet. And final head scratcher was to store the layers data visible to us ( coming from servers ) for the given map in such a way that we can see it even when we disconnect from server (go offline!)

Enough with the problems, lets dig solution!!

For Basemap

Basemap are .png images coming from server, that means if we are able to save those images with some metadata about location and zoom level somehow, we can recall them and display on the map. The procedure to do that is as follows:

Create OSM source as we do normally :

osmsource = new ol.source.OSM(); Create a button that will run the function in which we’ll grab information such as current zoom level, map extent, etc.

Saving tiles for given extent and zoom level in localstorage

This will save all the tiles in localstorage like this, which will be there until we do Hard reload or clear the storage

tiles information and extent is saved in localStorage

🥳🥳 Congrats your are halfway there

Now once the data is saved in localStorage, you no longer need to add a layer in your map with source as ol.source.OSM(), you can get those tiles from localStorage using following way:

This will act as a baselayer to the map

This is how you can cache the tiles in localStorage and use when you are not connected to the internet.

For layers coming from servers or API (e.g. geoserver )

Usually when you make call to servers, you are left with the JSON ( in this case GeoJSON) data, which you can save to localStorage in a sting format using JSON.Stringify(). You don’t necessarily need to save complete geojson data, as you can pass the filter of bbox to the API link which will fetch only the data that is inside the extent of the map that you are looking to cache. This way very less data will be saved in the storage.

Similarly you can use this data (after refreshing the webpage) by converting it into object using JSON.parse() and creating a GeoJSON layer on the fly like this

Creating GeoJSON layer from information in localstorage

For Drawn Geometry

Method to work around the drawn geometry is almost similar to the GeoJSON layer, here we’ll add the save to localStorage function at ‘drawend’ method , and by similar method mentioned as above we’ll recall it.

Updates you can expect

Until this Point We are able to get all the desired data that we want in offline mode. Now the question is how to make sure that user will not feel any difference between the application whether he/she is connected to internet or not, meaning we’ll have to write a function that will style the GeoJSONs that we are fetching from localStorage.

I’m working on the code and if it is tiny piece, I’ll update it here or if needed I’ll pen down another blog for it.