Separate overlapping nearby observation markers on the map
This commit is contained in:
@@ -1665,6 +1665,11 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.root :global(.nearby-marker-shell) {
|
||||||
|
display: inline-block;
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes nearby-fade-in {
|
@keyframes nearby-fade-in {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|||||||
@@ -111,6 +111,43 @@ function buildNearbyIconHtml(detail: CityDetail, station: NearbyStation) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNearbyMarkerDisplayOffset(
|
||||||
|
detail: CityDetail,
|
||||||
|
station: NearbyStation,
|
||||||
|
index: number,
|
||||||
|
) {
|
||||||
|
const cityLat = Number(detail.lat);
|
||||||
|
const cityLon = Number(detail.lon);
|
||||||
|
const stationLat = Number(station.lat);
|
||||||
|
const stationLon = Number(station.lon);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Number.isFinite(cityLat) ||
|
||||||
|
!Number.isFinite(cityLon) ||
|
||||||
|
!Number.isFinite(stationLat) ||
|
||||||
|
!Number.isFinite(stationLon)
|
||||||
|
) {
|
||||||
|
return { x: 0, y: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const latDiff = Math.abs(cityLat - stationLat);
|
||||||
|
const lonDiff = Math.abs(cityLon - stationLon);
|
||||||
|
const isNearCityAnchor = latDiff < 0.02 && lonDiff < 0.02;
|
||||||
|
|
||||||
|
if (!isNearCityAnchor) {
|
||||||
|
return { x: 0, y: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const presets = [
|
||||||
|
{ x: 54, y: -26 },
|
||||||
|
{ x: -54, y: -26 },
|
||||||
|
{ x: 54, y: 24 },
|
||||||
|
{ x: -54, y: 24 },
|
||||||
|
];
|
||||||
|
|
||||||
|
return presets[index % presets.length];
|
||||||
|
}
|
||||||
|
|
||||||
export function useLeafletMap({
|
export function useLeafletMap({
|
||||||
cities,
|
cities,
|
||||||
cityDetailsByName,
|
cityDetailsByName,
|
||||||
@@ -348,11 +385,21 @@ export function useLeafletMap({
|
|||||||
const sLon = Number(station.lon);
|
const sLon = Number(station.lon);
|
||||||
// Ignore invalid (0,0) or null coordinates which cause global zoom-out
|
// Ignore invalid (0,0) or null coordinates which cause global zoom-out
|
||||||
if (!Number.isFinite(sLat) || !Number.isFinite(sLon)) return;
|
if (!Number.isFinite(sLat) || !Number.isFinite(sLon)) return;
|
||||||
if (Math.abs(sLat) < 0.1 && Math.abs(sLon) < 0.1) return;
|
if (Math.abs(sLat) < 0.1 && Math.abs(sLon) < 0.1) return;
|
||||||
|
|
||||||
|
const displayOffset = getNearbyMarkerDisplayOffset(detail, station, latLngs.length);
|
||||||
|
const styleAttr =
|
||||||
|
displayOffset.x || displayOffset.y
|
||||||
|
? ` style="transform: translate(${displayOffset.x}px, ${displayOffset.y}px);"`
|
||||||
|
: "";
|
||||||
|
|
||||||
const icon = L.divIcon({
|
const icon = L.divIcon({
|
||||||
className: "",
|
className: "",
|
||||||
html: buildNearbyIconHtml(detail, station),
|
html: `
|
||||||
|
<div class="nearby-marker-shell"${styleAttr}>
|
||||||
|
${buildNearbyIconHtml(detail, station)}
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
iconAnchor: [16, 19],
|
iconAnchor: [16, 19],
|
||||||
iconSize: [240, 38],
|
iconSize: [240, 38],
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user