mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-08-13 22:20:37 +02:00
Fly the map to a bounding box when one is supplied
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
const viewer = readFileSync(
|
||||
join(process.cwd(), 'src/components/MaplibreViewer.tsx'),
|
||||
'utf8',
|
||||
);
|
||||
|
||||
describe('MaplibreViewer bounds camera', () => {
|
||||
it('derives zoom from bounds via cameraForBounds', () => {
|
||||
expect(viewer).toContain('cameraForBounds');
|
||||
});
|
||||
|
||||
it('caps the fit, because a tiny bounds otherwise flies to maxZoom 22', () => {
|
||||
expect(viewer).toMatch(/maxZoom:\s*ZOOM_MAX/);
|
||||
});
|
||||
|
||||
it('handles cameraForBounds returning undefined on oversized padding', () => {
|
||||
expect(viewer).toContain('ZOOM_FALLBACK');
|
||||
});
|
||||
|
||||
it('leaves the agent fly-to path untouched', () => {
|
||||
expect(viewer).toContain('zoom: flyToLocation.zoom ?? 8,');
|
||||
});
|
||||
});
|
||||
@@ -437,6 +437,7 @@ export default function Dashboard() {
|
||||
lat: number;
|
||||
lng: number;
|
||||
zoom?: number;
|
||||
bounds?: [number, number, number, number];
|
||||
ts: number;
|
||||
} | null>(null);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { API_BASE } from '@/lib/api';
|
||||
import { clampZoom, ZOOM_MAX, ZOOM_FALLBACK } from '@/lib/mapZoom';
|
||||
import React, { useMemo, useState, useEffect, useCallback, useRef } from 'react';
|
||||
import Map, {
|
||||
Source,
|
||||
@@ -751,16 +752,32 @@ const MaplibreViewer = ({
|
||||
}, [selectedEntity]);
|
||||
|
||||
useEffect(() => {
|
||||
if (flyToLocation && mapRef.current) {
|
||||
// Agent moves (sar_focus_aoi) carry their own zoom: a world-view revert
|
||||
// asks for ~2, a tight AOI for ~9. Ignoring it pinned every move at 8,
|
||||
// which turned "show the whole world" into a patch of empty ocean.
|
||||
mapRef.current.flyTo({
|
||||
center: [flyToLocation.lng, flyToLocation.lat],
|
||||
zoom: flyToLocation.zoom ?? 8,
|
||||
if (!flyToLocation || !mapRef.current) return;
|
||||
const map = mapRef.current.getMap();
|
||||
|
||||
if (flyToLocation.bounds) {
|
||||
// cameraForBounds returns undefined when padding exceeds the viewport,
|
||||
// and silently returns the map's maxZoom (22) for a degenerate box —
|
||||
// hence both the clamped padding and the explicit maxZoom.
|
||||
const { clientWidth, clientHeight } = map.getContainer();
|
||||
const padding = Math.min(64, Math.min(clientWidth, clientHeight) / 6);
|
||||
const cam = map.cameraForBounds(flyToLocation.bounds, { padding, maxZoom: ZOOM_MAX });
|
||||
map.flyTo({
|
||||
center: cam?.center ?? [flyToLocation.lng, flyToLocation.lat],
|
||||
zoom: cam ? clampZoom(cam.zoom ?? ZOOM_FALLBACK) : ZOOM_FALLBACK,
|
||||
duration: 1500,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Agent moves (sar_focus_aoi) carry their own zoom: a world-view revert
|
||||
// asks for ~2, a tight AOI for ~9. Ignoring it pinned every move at 8,
|
||||
// which turned "show the whole world" into a patch of empty ocean.
|
||||
mapRef.current.flyTo({
|
||||
center: [flyToLocation.lng, flyToLocation.lat],
|
||||
zoom: flyToLocation.zoom ?? 8,
|
||||
duration: 1500,
|
||||
});
|
||||
}, [flyToLocation]);
|
||||
|
||||
const earthquakesGeoJSON = useMemo(
|
||||
|
||||
@@ -1334,7 +1334,7 @@ export interface MaplibreViewerProps {
|
||||
activeFilters?: Record<string, string[]>;
|
||||
effects?: MapEffects;
|
||||
onEntityClick: (entity: SelectedEntity | null) => void;
|
||||
flyToLocation: { lat: number; lng: number; zoom?: number; ts?: number } | null;
|
||||
flyToLocation: { lat: number; lng: number; zoom?: number; bounds?: [number, number, number, number]; ts?: number } | null;
|
||||
selectedEntity: SelectedEntity | null;
|
||||
onMouseCoords: (coords: { lat: number; lng: number }) => void;
|
||||
onRightClick: (coords: { lat: number; lng: number }) => void;
|
||||
|
||||
Reference in New Issue
Block a user