4

I'm using Leaflet and trying zooming on a LineString object from a geojson file. Here is an extract of my file (with a lot of LineString objects):

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "day": "Day 1",
        "route": "A - B",
        "id": "a-b",
        "distance": "256 km",
        "profile": "img/profiles/route1.png"
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            13.6184281,
            45.919077,
            0
          ],
          [
            13.6184281,
            45.919077,
            0
          ],
          [
            13.6186132,
            45.9190975,
            0
          ],
          [
            13.6195585,
            45.9191768,
            0
          ],
          [
            13.6198306,
            45.9191968,
            0
          ],
          [
            13.6201896,
            45.9192233,
            0
          ],
          [
            13.620569,
            45.9192515,
            0
          ],
          [
            13.6207494,
            45.91926939999999,
            0
          ],
          [
            13.6213905,
            45.91933280000001,
            0
          ],
          [
            13.6216616,
            45.9193558,
            0
          ],
          [
            13.6224639,
            45.9194158,
            0
          ],
          [
            13.6235211,
            45.9195027,
            0
          ],
          [
            13.6241017,
            45.91955149999999,
            0
          ],
          [
            13.6251088,
            45.9196336,
            0
          ],
          [
            13.6253359,
            45.9196521,
            0
          ],
          [
            13.6261509,
            45.9197173,
            0
          ],
          [
            13.6271895,
            45.919803,
            0
          ],
          [
            13.6275854,
            45.9198347,
            0
          ]
        ]
      }
    }
  ]
}

When I click on a HTML element as follows,

<h4><a class="zoom-to-route" id="a-b">A - B</a></h4>
<h4><a class="zoom-to-route" id="b-c">B - B</a></h4>

I'd like to zoom to the corresponding line extent of my geojson file. I can access the geojson file, but I can't retrieve the whole set of coordinates in order to zoom on them:

$(".zoom-to-route").on("click", function(){
    var routeId = this.id;  
    console.log("searching routeId: " + routeId);
    var i = 0;  
    $.getJSON("data/routeHoliday.geojson", function(data) { 
        $.each(data.features, function (key, val) {
            $.each(val.properties, function(propertyKey, propertyVal) {
                console.log(propertyKey, propertyVal);              
                if (routeId == propertyVal) {
                    console.log("Found " + propertyVal);
                    var zoom = data.features[i].geometry;
                    console.log(zoom);
                    map.fitBounds(zoom.getBounds());                    
                }               
            });
            i++;
        });
    });
});

The console.log is as follows:

searching routeId: a-b
id a-b
Found a-b
Object { type: "LineString", coordinates: Array[5602] }
2
  • So I am assuming the problem is that this line: map.fitBounds(zoom.getBounds()); is not doing what is expected? can you print the zoom.getBounds() part also to the console?
    – ylka
    Commented Jul 17, 2017 at 13:02
  • @ylka Yes, I think the problem is in that line. The console is: TypeError: zoom.getBounds is not a function Commented Jul 17, 2017 at 13:45

3 Answers 3

3

You can build a polyline object from the coordinates and then get the bounds from that object:

$(".zoom-to-route").on("click", function(){
    var routeId = this.id;  
    console.log("searching routeId: " + routeId);
    var i = 0;  
    $.getJSON("data/routeHoliday.geojson", function(data) { 
        $.each(data.features, function (key, val) {
            $.each(val.properties, function(propertyKey, propertyVal) {
                console.log(propertyKey, propertyVal);              
                if (routeId == propertyVal) {
                    console.log("Found " + propertyVal);
                    var coords = data.features[i].geometry.coordinates;
                    var geom = L.GeoJSON.coordsToLatLngs(coords);
                    //or
                    //var geom = coords.map(function (pt) {return [pt[1], pt[0]]});
                    var line = L.polyline(geom);
                    map.fitBounds(line.getBounds());                    
                }               
            });
            i++;
        });
    });
});

If you're adding the geojson to the map, you could also attach the event handlers to each feature using the onEachFeature callback option, getting the bounds of the feature with getBounds().

2
  • I've tried your code, but insted of zooming to the righ area (Slovenia), it zooms to Yemen, inverting latitude and longitude... Commented Jul 17, 2017 at 18:59
  • 1
    Sorry, forgot Leaflet uses (lat,lon) instead of (x,y). I added a map() to flip the coordinate order. Commented Jul 17, 2017 at 19:20
0

Try this:

var zoom = data.features[i].geometry.coordinates;

$(".zoom-to-route").on("click", function(){
    var routeId = this.id;  
    console.log("searching routeId: " + routeId);
    var i = 0;  
    $.getJSON("data/routeHoliday.geojson", function(data) { 
        $.each(data.features, function (key, val) {
            $.each(val.properties, function(propertyKey, propertyVal) {
                console.log(propertyKey, propertyVal);              
                if (routeId == propertyVal) {
                    console.log("Found " + propertyVal);
                    var zoom = data.features[i].geometry.coordinates;
                    console.log(zoom);
                    map.fitBounds(zoom.getBounds());                    
                }               
            });
            i++;
        });
    });
});

See also the documentation.

Edit: I don't know if the problem comes from having Z-coordinates. In this case, I would try to parse the geometry myself. Something like this:

var len = data.features[i].geometry.coordinates[0].length;
var minLong = data.features[i].geometry.coordinates[0][0][0];
var minLat = data.features[i].geometry.coordinates[0][0][1];
var maxLong = data.features[i].geometry.coordinates[0][len-1][0];
var maxLat = data.features[i].geometry.coordinates[0][len-1][1];
var newBounds = [[minLat, minLong], [maxLat, maxLong]];
map.fitBounds(newBounds);
3
  • 1
    I've already tried, but it doesn't work. In this case console.log is: Array [ Array[3], Array[3], Array[3], Array[3], Array[3], Array[3], Array[3], Array[3], Array[3], Array[3], 5592 more… ] TypeError: zoom.getBounds is not a function Commented Jul 17, 2017 at 14:05
  • the problem could be the z coordinates. please see my edit.
    – ylka
    Commented Jul 17, 2017 at 14:06
  • 1
    It's not exactly the bounding box, but it works, thanks! var len = data.features[i].geometry.coordinates.length; var minLong = data.features[i].geometry.coordinates[0][0]; var minLat = data.features[i].geometry.coordinates[0][1]; var maxLong = data.features[i].geometry.coordinates[len-1][0]; var maxLat = data.features[i].geometry.coordinates[len-1][1]; var newBounds = [[minLat, minLong], [maxLat, maxLong]]; map.fitBounds(newBounds); Commented Jul 17, 2017 at 14:37
0

This is an old question but is the default question askers are referred to when asking about zooming on click.
Adding a simple answer for any one wanting to zoom on clicked feature in layer.

layer = L.geoJSON() # or whatever is the way you want to create your layer
layer.on('click',function(e){
  layer = e.propagatedFrom
  map.fitBounds(layer.getBounds())
})

This will work for each feature in your layer, based on its calculated bounds.

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.