Reputation: 1850
Say I have the following code for a mapbox map:
mapboxgl.accessToken = '<token>';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-v9',
center: [-96, 37.8],
zoom: 2,
interactive: true
});
var geojson = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-77.03238901390978, 38.913188059745586]
},
"properties": {
"id": 1,
"color": "#007cbf",
"text": "1"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-78.03238901390978, 39.913188059745586]
},
"properties": {
"id": 2,
"color": "red",
"text": "2"
}
}
]
}
map.on('style.load', function (e) {
map.addSource('markers', {
"type": "geojson",
"data": geojson
});
geojson.features.forEach(function(marker){
map.addLayer({
"id": String(marker.properties.id)+'-circle',
"source": "markers",
"type": "circle",
"paint": {
"circle-radius": 20,
"circle-color": marker.properties.color,
"circle-opacity": 0.8,
"circle-stroke-width": 0,
},
"filter": ["==", "id", marker.properties.id],
});
map.addLayer({
"id": String(marker.properties.id)+'-text',
"source": "markers",
"type": "symbol",
"layout": {
'text-field': marker.properties.text,
'text-size': 20
},
"filter": ["==", "id", marker.properties.id]
})
});
});
How would I scale the map to fit a set of points on a map? I can't find any solutions for mapboxgl. Also, I'm not 100% sure that I should be creating a separate layer for each marker, but I couldn't find a way to put all the makers into one layer. Thanks in advance.
Upvotes: 3
Views: 4576
Reputation: 3790
I think what you are looking for is map.fitBounds
that will create a bounding box to adapt map view to a list of coordinates.
map.fitBounds([
[-77.03238901390978, 38.913188059745586],
[-78.03238901390978, 39.913188059745586]
]);
But if you could have a bunch of points in a source as it seems based in your code, then you need to first push all the coordinates of each marker to an array, and then use coordinates.reduce
var coordinates = coords;
var bounds = coordinates.reduce(function(bounds, coord) {
return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]));
map.fitBounds(bounds, {
padding: 20
});
I have created a fiddle for you with this solution, how to fit mapbox bounds to a list of coords, it works your using your own code and coords.
Regarding the creation of a layer for each marker, definitely you should try to avoid that practice and create a single layer only to host all the markers.
Upvotes: 6
Reputation: 61
To use Mapbox GL JS map.fitBounds(bounds, options?)
you can also use an array of [lng, lat]
pairs which represent the most southwestern and most northeastern corners of the specified geographical bounds.
Always keep in mind:
lng
(lon): longitude (London = 0, Bern = 7.45, New York = -74)
→ the lower, the more western
lat
: latitude (Equator = 0, Bern = 46.95, Capetown = -33.9)
→ the lower, the more southern
To calculate these I created the following functions to get the most southwestern and most northeastern corners of a collection of coordinates and merge them into an array:
getSWCoordinates(coordinatesCollection) {
const lowestLng = Math.min(
...coordinatesCollection.map((coordinates) => coordinates[0])
);
const lowestLat = Math.min(
...coordinatesCollection.map((coordinates) => coordinates[1])
);
return [lowestLng, lowestLat];
}
getNECoordinates(coordinatesCollection) {
const highestLng = Math.max(
...coordinatesCollection.map((coordinates) => coordinates[0])
);
const highestLat = Math.max(
...coordinatesCollection.map((coordinates) => coordinates[1])
);
return [highestLng, highestLat];
}
calcBoundsFromCoordinates(coordinatesCollection) {
return [
getSWCoordinates(coordinatesCollection),
getNECoordinates(coordinatesCollection),
];
}
To use the function, you can just call calcBoundsFromCoordinates
and enter an array containing all your markers coordinates:
calcBoundsFromCoordinates([
[8.03287, 46.62789],
[7.53077, 46.63439],
[7.57724, 46.63914],
[7.76408, 46.55193],
[7.74324, 46.7384]
])
// returns [[7.53077, 46.55193], [8.03287, 46.7384]]
Upvotes: 2