2

I'm aware that Openlayers 3 has the ability to read and parse gpx files using the drag/drop event and I've incorporated this functionality into my map. What I'd also like to do is give the user the ability to 'upload' the file in a more conventional way by browsing through their filesystem.

I've hooked up the basic functionality and the resulting file can be output to a div as text but how do I get the final step of instructing Openlayers to read this information and subsequently display it on a map?

There seems to be very little information regarding this and reading the ol-debug.js file hasn't shed any light. Can anyone give me any pointers please?

1 Answer 1

4

create a file selector and then read the file selected. GPX files are text files so there should be any problem with that. Also it is important to know what is the projection of your gpx file as well as the projection of your map. In my example I expect to get gps entries in epsg:4326 and reproject them to EPSG:3857

  1. your html

      <input type="file" id="files" name="files[]" multiple />
      <output id="list"></output>
      <div id="map" class="map"></div>
    
  2. your js

    var gpxFormat = new ol.format.GPX();
    var gpxFeatures;
    function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object
    
    // files is a FileList of File objects. List some properties.
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
    console.log("files[i]",files[i]);
    var reader = new FileReader();
    reader.readAsText(files[i], "UTF-8");
    reader.onload = function (evt) {
       console.log(evt.target.result);
       gpxFeatures = gpxFormat.readFeatures(evt.target.result,{
       dataProjection:'EPSG:4326',
       featureProjection:'EPSG:3857'
       });
       gpxLayer.getSource().addFeatures(gpxFeatures);
       console.log("gpxFeatures",gpxFeatures)
    }
      output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
                  f.size, ' bytes, last modified: ',
                  f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
                  '</li>');
    }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
     }
    
    
    var defaultStyle = {
        'Point': new ol.style.Style({
          image: new ol.style.Circle({
            fill: new ol.style.Fill({
              color: 'rgba(255,255,0,0.5)'
            }),
            radius: 5,
            stroke: new ol.style.Stroke({
              color: '#ff0',
              width: 1
            })
          })
        }),
        'LineString': new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: '#f00',
            width: 3
          })
        }),
        'Polygon': new ol.style.Style({
          fill: new ol.style.Fill({
            color: 'rgba(0,255,255,0.5)'
          }),
          stroke: new ol.style.Stroke({
            color: '#0ff',
            width: 1
          })
        }),
        'MultiPoint': new ol.style.Style({
          image: new ol.style.Circle({
            fill: new ol.style.Fill({
              color: 'rgba(255,0,255,0.5)'
            }),
            radius: 5,
            stroke: new ol.style.Stroke({
              color: '#f0f',
              width: 1
            })
          })
        }),
        'MultiLineString': new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: '#0f0',
            width: 3
          })
        }),
        'MultiPolygon': new ol.style.Style({
          fill: new ol.style.Fill({
            color: 'rgba(0,0,255,0.5)'
          }),
          stroke: new ol.style.Stroke({
            color: '#00f',
            width: 1
          })
        })
      };
    
      var styleFunction = function(feature, resolution) {
        var featureStyleFunction = feature.getStyleFunction();
        if (featureStyleFunction) {
          return featureStyleFunction.call(feature, resolution);
        } else {
          return defaultStyle[feature.getGeometry().getType()];
        }
      };
    
    var gpxLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
    
        }),
        style: styleFunction
    });
    var map = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
              source: new ol.source.MapQuest({ layer: 'sat' })
          }),
          gpxLayer
        ],
        view: new ol.View({
            center: ol.proj.fromLonLat([37.41, 8.82]),
            zoom: 4
        })
    });
    
    document.getElementById('files').addEventListener('change', handleFileSelect, false);
    
  3. And a fiddle. I know it is a mess but didnt have the time to tidy it up. You should get the idea.

2
  • Thanks a lot Pavlos. I'd followed most of the steps but crucially I didn't specify .getSource() before addFeatures(). I also forgot about the projections which of course means the incoming data was useless. Great answer! Succinct, easy to understand and with a great example. Thanks again ;)
    – dvmac01
    Commented Jan 5, 2016 at 16:33
  • no probms my friend. glad to help
    – pavlos
    Commented Jan 5, 2016 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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