3

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] }
  • 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 Jul 17 '17 at 13:02
  • @ylka Yes, I think the problem is in that line. The console is: TypeError: zoom.getBounds is not a function – Michela Zanni Jul 17 '17 at 13:45
2

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().

  • I've tried your code, but insted of zooming to the righ area (Slovenia), it zooms to Yemen, inverting latitude and longitude... – Michela Zanni Jul 17 '17 at 18:59
  • 1
    Sorry, forgot Leaflet uses (lat,lon) instead of (x,y). I added a map() to flip the coordinate order. – Marc Pfister Jul 17 '17 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);
  • 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 – Michela Zanni Jul 17 '17 at 14:05
  • the problem could be the z coordinates. please see my edit. – ylka Jul 17 '17 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); – Michela Zanni Jul 17 '17 at 14:37

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.