1

I have created a web mapping application using OpenLayers 3 which is displaying the data that is stored in a database. Now I want to display additional data that is going to be provided by the users in the form of shapefiles. The data should only be displayed on the main application and not stored in the database as I do not want to make any changes in the database. I know it can be done through WMS but how it can be done without altering the database?

1

shp2geojson.js can take a File object as url, so you could simply drag and drop zipped shapefiles onto the map from a network drive http://mikenunn.16mb.com/demo/shp.html

<!DOCTYPE html>
<html>
  <head>
    <title>Load SHP overlay</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v6.3.1/css/ol.css" type="text/css">
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v6.3.1/build/ol.js"></script>
    <script src="https://gipong.github.io/shp2geojson.js/lib/jszip.js"></script>
    <script src="https://gipong.github.io/shp2geojson.js/lib/jszip-utils.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.1/proj4.js"></script>
    <script src="https://gipong.github.io/shp2geojson.js/preprocess.js"></script>
    <script src="https://gipong.github.io/shp2geojson.js/preview.js"></script>
    <style>
      html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <script>  
    
      const featureStyle = new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: 'red',
          width: 1
        })
      });

      const map = new ol.Map({
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        target: 'map',
        view: new ol.View({
          center: [0, 0],
          zoom: 2
        })
      });

      map.getViewport().addEventListener('dragover', function(event) {
        event.preventDefault();
      });

      map.getViewport().addEventListener('drop', function(event) {
        event.preventDefault();
        const files = event.dataTransfer.files;
        for (let i = 0, ii = files.length; i < ii; ++i) {
          const file = files.item(i);
          loadshp({url: file, encoding: 'utf-8'}, function(geojson) {
            const features = new ol.format.GeoJSON().readFeatures(
              geojson,
              { featureProjection: map.getView().getProjection() }
            );
            const vectorSource = new ol.source.Vector({
              features: features
            });
            map.addLayer(
              new ol.layer.Vector({
                source: vectorSource,
                style: featureStyle
              })
            );
            map.getView().fit(vectorSource.getExtent());
          });
        }
      });

    </script>
  </body>
</html>
| improve this answer | |
0

From a (very) high level, for users to upload their own shapefiles and have your server manage the display/tiling/interactivity, as if it's any other layer, you will need to..

  1. Create a dialog in your UI where they can select a file from their system to upload to your server.

  2. Write a web service of some sort that.. a) receives the uploaded file b) stores it somewhere appropriate on your server with proper permissions, and.. c) adds any configurations to your server implementation that are necessary to green-light a new layer from a shapefile source

  1. In some cases, you might need to trigger a "reload" of the server's configuration at some level. You may also need to force a refresh of your client's browser or programmatically push the resulting new layer details into their UI, like into the legend, into the OpenLayers map itself, etc.

Step 2c) could include adding supplemental style configurations, or SLD's, as well as any other setting you would add do to create a new layer as the server admin.

Will your users also be uploading their own styling configurations?? If so, that adds some UI complexities. My expectation is that step 2c) will be the hard part.

Optionally.. it might be possible to have your users add shapefiles to their OpenLayers client directly, without funneling anything through the server. Here's a discussion with some implementation details you might want to review. Or some of these. This approach would require much less work, but big shapefiles might create a slow or "clunky" user experience; these solutions also don't tend to look very pretty, at least not right out of the box when the shapefiles take whatever default styles the map client imposes. You could try to develop around that, of course.

| improve this answer | |
0

I know what you mean. My first recommendation is applying an appropriate client-server architecture that follows OGC standards. Among OGC standards, WMS and WFS are very popular to retrieve spatial data stored in database in order to display as a map layer.

If you don't want to store shape file into database, you may have two alternatives: Using Geoserver software or applying JSON file format.

Geoserver provides you with a type of store that can use shape files directly without any database. What you need to do is only create a workspace > create a directory of spatial files > set directory of files. The benefits of this choice is following standard services like WMS and WFS as OGC suggests.

enter image description here

If you don't want to use Geoserver for any reason, you can opt for Geojson files. This method is a file-based system. To achieve this you can use QGIS APIs in server-side to convert uploaded .shp to .json. I break such a system into 4 components:

1. A component for uploading .shp file (client-side).

2. A component which stores .shp file in a directory at back-end (server-side).

3. A component that converts .shp file to .json file (server-side).

4. A component for retrieving .json file and create a map layer (client-side).

The Geojson file enables us to store spatial data (containing lat/long or easting/northing) and attributes at the same time in a javascript object structure. This format has at least two benefits:

  • It does support different types of geometry (point, line, polygon) and complex forms of them (multipoint, multiline, and multipolygon).
  • It is fully supported by any browsers and also handled by mapping libraries such as openlayer and leaflet.

Attention: Please note that a large shape files with multiple attribute columns leads to a large Geojson file and it will probably have negative effects on your application performance and may cause annoying lags when users want to do zooming or panning on map.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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