0

I am using GPX data to display routes with OpenLayers 3 and my attempts of zooming to fit the GPS trace have been thus far unsuccessful. I only ever got it working in debug mode on Firefox, where it always zooms correctly, however when just loading the web page nothing happens. Also when drag-dropping a GPX file on the maps the zoom works again, but the same code without projection transformation does not work when displaying the original GPX without the dragAndDropInteraction interaction.

Here is the code snippet that is supposed to make the map zoom to fit the trace:

   //fit view
    var extent = vector.getSource().getExtent();
    var mapProjection = map.getView().getProjection();    
    ConvertedExtent = ol.proj.transformExtent(extent, 'EPSG:3857', 'EPSG:4326'); 
    mapSize = map.getSize();
    map.getView().fitExtent(extent, mapSize);

After calling .getSource().getExtent() the extent array contains the following: [1215055.5815933049, 6137851.406357965, 1286274.229579136, 6175156.521239913] which I transform to: [10.91503, 48.185981, 11.554798, 48.40892199999999]

In Chrome for some reason the extent array contains infinite values: extent = [ Infinity Infinity -Infinity -Infinity]

function CreateDriveMap(urlToXml)
{
    var transformedCenter = ol.proj.transform(centerPos, 'EPSG:4326', 'EPSG:3857');

    // PROJECTION
    var projection = ol.proj.get('EPSG:3857');

    // SOURCE
    var source = new ol.source.OSM();

    // TILE
    // layer sources that provide pre-rendered, tiled images in grids 
    // that are organized by zoom levels for specific resolutions.
    layer = new ol.layer.Tile({
        source: source,
        name: 'OpenStreetMap'
    });

    // VIEW
    view = new ol.View({
        center: transformedCenter,
        zoom: 5
    });

    // STYLE
    var style = {
        'Point': [new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({
                    color: 'rgba(255,255,0,0.4)'
                }),
                radius: 2,
                stroke: new ol.style.Stroke({
                    color: '#f00',
                    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
                })
            })
        })],
        'LineString': [new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'rgba(255,0,0,0.7)',
                width: '3'
            })
        })],
        'MultiLineString': [new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: '#0f0',
                width: 'rgba(255,0,0,0.7)'
            })
        })],
        '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
            })
        })],
        '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
            })
        })]
    };

    // Style Function
    var styleFunction = function (feature, resolution) {
        var featureStyleFunction = feature.getStyleFunction();
        if (featureStyleFunction) {
            return featureStyleFunction.call(feature, resolution);
        } else {
            return defaultStyle[feature.getGeometry().getType()];
        }
    };

    // GPX layer
    var vector = new ol.layer.Vector({
        source: new ol.source.GPX({
            projection: projection,
            url: urlToXml                //'data/gpx/fells_loop.gpx'
        }),
        style: function (feature, resolution) {
            return style[feature.getGeometry().getType()];
        }
    });


    // CREATE MAP
    var map = new ol.Map({
        // targeted div
        target: 'map',

        // the layers 
        layers: [layer, vector],

        // the view 
        view: view,

        //projection: new OpenLayers.Projection("EPSG:900913"),
        projection: projection

        // interactions
        //interactions: ol.interaction.defaults().extend([dragAndDropInteraction])
    });


    //var View = map.getView();
      // View.fitExtent(vector.getExtent(),  /* @type {ol.Size} */ (map.getSize()));

    // CENTER & PUT START MARKER, DOES NOT WORK
    // ol.Layer.events.register("loadend", vector, function () {
    //    this.map.zoomToExtent(this.getDataExtent());
    //    var startPoint = this.features[0].geometry.components[0];
    //    layerMarkers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(startPoint.x, startPoint.y), icon));
    //});

    // Add controls
    var zoomslider = new ol.control.ZoomSlider();
    map.addControl(zoomslider);
    var scaleLine = new ol.control.ScaleLine();
    map.addControl(scaleLine);

    //FIT VIEW TO GPX
    var extent = vector.getSource().getExtent();
    var mapProjection = map.getView().getProjection();
    ConvertedExtent = ol.proj.transformExtent(extent, 'EPSG:3857', 'EPSG:4326'); 
    mapSize = map.getSize();
    map.getView().fitExtent(extent, mapSize);

    // STYLE FUNCTION
    var stylefunction = function (feature, resolution) {
        var featurestylefunction = feature.getstylefunction();
        if (featurestylefunction) {
            return featurestylefunction.call(feature, resolution);
        } else {
            return style[feature.getgeometry().gettype()];
        }
    };

    // DRAG & DROP
    var dragAndDropInteraction = new ol.interaction.DragAndDrop({
        formatConstructors: 
            [
              ol.format.GPX,
              ol.format.GeoJSON,
              ol.format.IGC,
              ol.format.KML,
              ol.format.TopoJSON
            ]
    });

    dragAndDropInteraction.on('addfeatures', function (event) {
        var vectorSource = new ol.source.Vector({
            features: event.features,
            projection: event.projection
        });
        map.getLayers().push(new ol.layer.Vector({
            source: vectorSource,
            style: styleFunction
        }));
        var view = map.getView();
        view.fitExtent(
            vectorSource.getExtent(), /** @type {ol.Size} */ (map.getSize()));
    });
}
1
  • which version of OL are you using? this can not be the latest (3.5) as there is no GPX source but a GPX format. i believe you call the extent function before any data is loaded to the source. my recommendation. update to 3.5. use format.GPX to read the features and add these to the overlay source and thereafter call the zoom to extent function from there. Commented Jun 15, 2015 at 21:18

1 Answer 1

3

I had a similar problem in version 3.8.2. I solved it by putting getExtent into the event:

vector.getSource().on("change", function(evt) {
    extent = vector.getSource().getExtent();
    map.getView().fit(extent, map.getSize());
});

In older version you just use fitExtent instead of fit.

1
  • Indeed, that should fix the problem. Explanation: vector source is loaded asynchronously by AJAX call. In code from user2624067, extent is calculated immediately after creation of GPX layer. Data is not loaded yet, and therefore you get void extent. You have to wait, until loading is completed, like in given sample. Commented Feb 3, 2016 at 8:55

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.