From 9e5989ece3ed09b88ff67b7e7239e64812448270 Mon Sep 17 00:00:00 2001 From: orangecoding Date: Mon, 26 Jan 2026 11:54:47 +0100 Subject: [PATCH] zoom into map where most markers are --- ui/src/views/listings/Map.jsx | 50 ++++++++++++++++++++----------- ui/src/views/listings/mapUtils.js | 31 +++++++++++++++++++ 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/ui/src/views/listings/Map.jsx b/ui/src/views/listings/Map.jsx index b61566e..f7cb9d0 100644 --- a/ui/src/views/listings/Map.jsx +++ b/ui/src/views/listings/Map.jsx @@ -8,7 +8,7 @@ import { renderToString } from 'react-dom/server'; import maplibregl from 'maplibre-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; 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 { IconFilter, IconLink } from '@douyinfe/semi-icons'; import { IconDelete } from '@douyinfe/semi-icons'; @@ -248,26 +248,42 @@ export default function MapView() { }, [jobId]); useEffect(() => { - if (!map.current || !homeAddress?.coords) return; + if (!map.current) return; - // We only want to zoom/fly when distanceFilter OR homeAddress actually change, - // not on every render. useEffect dependency array handles this. - if (distanceFilter > 0) { - const bounds = getBoundsFromCenter([homeAddress.coords.lng, homeAddress.coords.lat], distanceFilter); + if (homeAddress?.coords) { + // We only want to zoom/fly when distanceFilter OR homeAddress actually change, + // not on every render. useEffect dependency array handles this. + if (distanceFilter > 0) { + const bounds = getBoundsFromCenter([homeAddress.coords.lng, homeAddress.coords.lat], distanceFilter); - map.current.fitBounds(bounds, { - padding: 20, - maxZoom: 15, - duration: 1000, - }); + map.current.fitBounds(bounds, { + padding: 20, + maxZoom: 15, + duration: 1000, + }); + } else { + map.current.flyTo({ + center: [homeAddress.coords.lng, homeAddress.coords.lat], + zoom: 12, + duration: 1000, + }); + } } else { - map.current.flyTo({ - center: [homeAddress.coords.lng, homeAddress.coords.lat], - zoom: 12, - duration: 1000, - }); + const filtered = filterListings(); + const coords = filtered + .filter((l) => l.latitude != null && l.longitude != null && l.latitude !== -1 && l.longitude !== -1) + .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(() => { if (!map.current) return; diff --git a/ui/src/views/listings/mapUtils.js b/ui/src/views/listings/mapUtils.js index 575c9e7..b5b0c3c 100644 --- a/ui/src/views/listings/mapUtils.js +++ b/ui/src/views/listings/mapUtils.js @@ -97,3 +97,34 @@ export const getBoundsFromCenter = (center, radiusInKm, padding = 0.15) => { [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], + ]; +};