Search code examples
javascriptleafletvuejs3coordinates

Leaflet fitBounds is not working in my Vue.js-App, Bounds are not valid


I'm working on an App in Vue.js and I'm trying to add markers to my map and change the map zoom as well as the center of the map accordingly. I don't know how much context you guys need in order to help me here so I'll just provide some.

I use Vue3 and vue-leaflet.

The App gets coordinates from an API, I've created an Array (coordinatesArray) to get the lng and lat values with some additional stuff I need for the marker names, when I use console.log(coordinatesArray) it looks like this:

[
    {
        "id": 0,
        "lat": 49.78053,
        "lng": 9.92648,
        "name": "name"
    },
    {
        "id": 1,
        "lat": 49.786732,
        "lng": 9.95141,
        "name": "name"
    },
    {
        "id": 2,
        "lat": 49.766035,
        "lng": 9.931672,
        "name": "name"
    },
    {
        "id": 3,
        "lat": 49.775997,
        "lng": 9.951882,
        "name": "name"
    },
    {
        "id": 4,
        "lat": 49.776171,
        "lng": 9.926721,
        "name": "name"
    },
    {
        "id": 5,
        "lat": 49.92403,
        "lng": 10.555785,
        "name": "name"
    },
    {
        "id": 6,
        "lat": 49.765477,
        "lng": 9.944773,
        "name": "name"
    },
    {
        "id": 7,
        "lat": 49.793674,
        "lng": 9.951003,
        "name": "name"
    },
    {
        "id": 8,
        "lat": 49.765977,
        "lng": 9.931475,
        "name": "name"
    },
    {
        "id": 9,
        "lat": 49.766228,
        "lng": 9.932109,
        "name": "name"
    },
    {
        "id": 10,
        "lat": 49.764749,
        "lng": 9.932826,
        "name": "name"
    },
    {
        "id": 11,
        "lat": 49.782233,
        "lng": 9.94858,
        "name": "name"
    },
    {
        "id": 12,
        "lat": 50.059835,
        "lng": 10.450635,
        "name": "name"
    }
]

Now I want to use the fitBounds-Method to set the zoom accordingly:

const map = this.$refs.map.leafletObject;
map.whenReady(() => {
    const bounds = new L.LatLngBounds(coordinatesArray.map((coord) => [coord.lat, coord.lng]));
    map.fitBounds(bounds);
});

The map is working as well and when I use console.log(bounds) I get this Object:

{
    "_southWest": {
        "lat": 49.764749,
        "lng": 9.92648
    },
    "_northEast": {
        "lat": 50.059835,
        "lng": 10.555785
    }
}

From my understanding this should all work out but as I always get this error:

Uncaught Error: Bounds are not valid.

Here's how I render the map in my template:

<l-map id="mapItem" ref="map" :zoom="zoom" :center="center">
    <l-tile-layer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"></l-tile-layer>
    <l-marker v-for="marker in markers" :key="marker.id" :lat-lng="[marker.lat, marker.lng]">
        <l-popup>{{ marker.name }}</l-popup>
    </l-marker>
</l-map>

I really can't wrap my head around it.


Solution

  • You are getting Uncaught Error: Bounds are not valid because your data structure is incorrect. You are passing Object but if you closely look at documentation it takes fitBounds(<LatLngBounds> bounds, <fitBounds options> options?). Here LatLngBounds is an array, that represents a rectangular geographical area on a map. So, your bound must be

    [
        [49.764749, 9.92648], [50.059835, 10.555785]
      ] 
    

    not

    {
        "_southWest": {
            "lat": 49.764749,
            "lng": 9.92648
        },
        "_northEast": {
            "lat": 50.059835,
            "lng": 10.555785
        }
    }
    

    See, the following example.

    var map = L.map('map').setView([51.505, -0.09], 13);
    
    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '© OpenStreetMap'
    }).addTo(map);
    
    map.whenReady(() => {
      map.fitBounds([
        [49.764749, 9.92648], [50.059835, 10.555785]
      ]);
    });
    #map {
      height: 180px;
    }
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
    
    <div id="map"></div>