zoom into map where most markers are

This commit is contained in:
orangecoding
2026-01-26 11:54:47 +01:00
parent afc200c9e1
commit 9e5989ece3
2 changed files with 64 additions and 17 deletions

View File

@@ -8,7 +8,7 @@ import { renderToString } from 'react-dom/server';
import maplibregl from 'maplibre-gl'; import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css'; import 'maplibre-gl/dist/maplibre-gl.css';
import { useSelector, useActions } from '../../services/state/store.js'; import { useSelector, useActions } from '../../services/state/store.js';
import { distanceMeters, generateCircleCoords, getBoundsFromCenter } from './mapUtils.js'; import { distanceMeters, generateCircleCoords, getBoundsFromCenter, getBoundsFromCoords } from './mapUtils.js';
import { Select, Space, Typography, Button, Popover, Divider, Switch, Banner, Toast } from '@douyinfe/semi-ui-19'; import { Select, Space, Typography, Button, Popover, Divider, Switch, Banner, Toast } from '@douyinfe/semi-ui-19';
import { IconFilter, IconLink } from '@douyinfe/semi-icons'; import { IconFilter, IconLink } from '@douyinfe/semi-icons';
import { IconDelete } from '@douyinfe/semi-icons'; import { IconDelete } from '@douyinfe/semi-icons';
@@ -248,26 +248,42 @@ export default function MapView() {
}, [jobId]); }, [jobId]);
useEffect(() => { useEffect(() => {
if (!map.current || !homeAddress?.coords) return; if (!map.current) return;
// We only want to zoom/fly when distanceFilter OR homeAddress actually change, if (homeAddress?.coords) {
// not on every render. useEffect dependency array handles this. // We only want to zoom/fly when distanceFilter OR homeAddress actually change,
if (distanceFilter > 0) { // not on every render. useEffect dependency array handles this.
const bounds = getBoundsFromCenter([homeAddress.coords.lng, homeAddress.coords.lat], distanceFilter); if (distanceFilter > 0) {
const bounds = getBoundsFromCenter([homeAddress.coords.lng, homeAddress.coords.lat], distanceFilter);
map.current.fitBounds(bounds, { map.current.fitBounds(bounds, {
padding: 20, padding: 20,
maxZoom: 15, maxZoom: 15,
duration: 1000, duration: 1000,
}); });
} else {
map.current.flyTo({
center: [homeAddress.coords.lng, homeAddress.coords.lat],
zoom: 12,
duration: 1000,
});
}
} else { } else {
map.current.flyTo({ const filtered = filterListings();
center: [homeAddress.coords.lng, homeAddress.coords.lat], const coords = filtered
zoom: 12, .filter((l) => l.latitude != null && l.longitude != null && l.latitude !== -1 && l.longitude !== -1)
duration: 1000, .map((l) => [l.longitude, l.latitude]);
});
if (coords.length > 0) {
const bounds = getBoundsFromCoords(coords);
map.current.fitBounds(bounds, {
padding: 50,
maxZoom: 15,
duration: 1000,
});
}
} }
}, [homeAddress?.address, distanceFilter]); }, [homeAddress?.address, distanceFilter, listings]);
useEffect(() => { useEffect(() => {
if (!map.current) return; if (!map.current) return;

View File

@@ -97,3 +97,34 @@ export const getBoundsFromCenter = (center, radiusInKm, padding = 0.15) => {
[lng + offsetLng, lat + offsetLat], [lng + offsetLng, lat + offsetLat],
]; ];
}; };
/**
* Calculates the bounding box for a set of coordinates.
*
* @param {number[][]} coords - Array of [longitude, latitude] coordinates
* @param {number} [padding=0.1] - Padding to add to the bounds
* @returns {number[][]} Bounding box coordinates [[minLon, minLat], [maxLon, maxLat]]
*/
export const getBoundsFromCoords = (coords, padding = 0.1) => {
if (!coords || coords.length === 0) return null;
let minLng = Infinity;
let minLat = Infinity;
let maxLng = -Infinity;
let maxLat = -Infinity;
coords.forEach(([lng, lat]) => {
if (lng < minLng) minLng = lng;
if (lng > maxLng) maxLng = lng;
if (lat < minLat) minLat = lat;
if (lat > maxLat) maxLat = lat;
});
const lngDiff = maxLng - minLng;
const latDiff = maxLat - minLat;
return [
[minLng - lngDiff * padding, minLat - latDiff * padding],
[maxLng + lngDiff * padding, maxLat + latDiff * padding],
];
};