fix: Add coordinate validation to prevent Invalid LngLat errors
- Add isValidCoordinate() helper to validate lat/lng ranges - Validate viewport center on map initialization - Skip participants and waypoints with invalid coordinates - Add validation to auto-center and fitToParticipants 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
eeab19ceac
commit
39f8c83ba9
|
|
@ -24,6 +24,20 @@ const DEFAULT_VIEWPORT: MapViewport = {
|
||||||
zoom: 15,
|
zoom: 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Validate coordinates are within valid ranges
|
||||||
|
function isValidCoordinate(lat: number, lng: number): boolean {
|
||||||
|
return (
|
||||||
|
typeof lat === 'number' &&
|
||||||
|
typeof lng === 'number' &&
|
||||||
|
!isNaN(lat) &&
|
||||||
|
!isNaN(lng) &&
|
||||||
|
lat >= -90 &&
|
||||||
|
lat <= 90 &&
|
||||||
|
lng >= -180 &&
|
||||||
|
lng <= 180
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function MapView({
|
export default function MapView({
|
||||||
participants,
|
participants,
|
||||||
waypoints = [],
|
waypoints = [],
|
||||||
|
|
@ -45,6 +59,12 @@ export default function MapView({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!mapContainer.current || map.current) return;
|
if (!mapContainer.current || map.current) return;
|
||||||
|
|
||||||
|
// Validate viewport center coordinates, fall back to default if invalid
|
||||||
|
const [lng, lat] = initialViewport.center;
|
||||||
|
const validCenter = isValidCoordinate(lat, lng)
|
||||||
|
? initialViewport.center
|
||||||
|
: DEFAULT_VIEWPORT.center;
|
||||||
|
|
||||||
map.current = new maplibregl.Map({
|
map.current = new maplibregl.Map({
|
||||||
container: mapContainer.current,
|
container: mapContainer.current,
|
||||||
style: {
|
style: {
|
||||||
|
|
@ -73,8 +93,8 @@ export default function MapView({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
center: initialViewport.center,
|
center: validCenter,
|
||||||
zoom: initialViewport.zoom,
|
zoom: initialViewport.zoom || DEFAULT_VIEWPORT.zoom,
|
||||||
bearing: initialViewport.bearing ?? 0,
|
bearing: initialViewport.bearing ?? 0,
|
||||||
pitch: initialViewport.pitch ?? 0,
|
pitch: initialViewport.pitch ?? 0,
|
||||||
});
|
});
|
||||||
|
|
@ -133,6 +153,12 @@ export default function MapView({
|
||||||
if (!participant.location) return;
|
if (!participant.location) return;
|
||||||
|
|
||||||
const { latitude, longitude } = participant.location;
|
const { latitude, longitude } = participant.location;
|
||||||
|
|
||||||
|
// Skip invalid coordinates
|
||||||
|
if (!isValidCoordinate(latitude, longitude)) {
|
||||||
|
console.warn('Invalid coordinates for participant:', participant.id, latitude, longitude);
|
||||||
|
return;
|
||||||
|
}
|
||||||
let marker = currentMarkers.get(participant.id);
|
let marker = currentMarkers.get(participant.id);
|
||||||
|
|
||||||
if (marker) {
|
if (marker) {
|
||||||
|
|
@ -169,12 +195,15 @@ export default function MapView({
|
||||||
if (autoCenterOnUser && !hasCenteredOnUserRef.current && currentUserId) {
|
if (autoCenterOnUser && !hasCenteredOnUserRef.current && currentUserId) {
|
||||||
const currentUser = participants.find(p => p.id === currentUserId);
|
const currentUser = participants.find(p => p.id === currentUserId);
|
||||||
if (currentUser?.location && map.current) {
|
if (currentUser?.location && map.current) {
|
||||||
console.log('Auto-centering on user location:', currentUser.location.latitude, currentUser.location.longitude);
|
const { latitude, longitude } = currentUser.location;
|
||||||
map.current.flyTo({
|
if (isValidCoordinate(latitude, longitude)) {
|
||||||
center: [currentUser.location.longitude, currentUser.location.latitude],
|
console.log('Auto-centering on user location:', latitude, longitude);
|
||||||
zoom: 16,
|
map.current.flyTo({
|
||||||
});
|
center: [longitude, latitude],
|
||||||
hasCenteredOnUserRef.current = true;
|
zoom: 16,
|
||||||
|
});
|
||||||
|
hasCenteredOnUserRef.current = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [participants, mapLoaded, currentUserId, onParticipantClick, autoCenterOnUser]);
|
}, [participants, mapLoaded, currentUserId, onParticipantClick, autoCenterOnUser]);
|
||||||
|
|
@ -197,6 +226,13 @@ export default function MapView({
|
||||||
// Add/update waypoint markers
|
// Add/update waypoint markers
|
||||||
waypoints.forEach((waypoint) => {
|
waypoints.forEach((waypoint) => {
|
||||||
const { latitude, longitude } = waypoint.location;
|
const { latitude, longitude } = waypoint.location;
|
||||||
|
|
||||||
|
// Skip invalid coordinates
|
||||||
|
if (!isValidCoordinate(latitude, longitude)) {
|
||||||
|
console.warn('Invalid coordinates for waypoint:', waypoint.id, latitude, longitude);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let marker = currentWaypointMarkers.get(waypoint.id);
|
let marker = currentWaypointMarkers.get(waypoint.id);
|
||||||
|
|
||||||
if (marker) {
|
if (marker) {
|
||||||
|
|
@ -271,7 +307,9 @@ export default function MapView({
|
||||||
const fitToParticipants = () => {
|
const fitToParticipants = () => {
|
||||||
if (!map.current || participants.length === 0) return;
|
if (!map.current || participants.length === 0) return;
|
||||||
|
|
||||||
const locatedParticipants = participants.filter((p) => p.location);
|
const locatedParticipants = participants.filter(
|
||||||
|
(p) => p.location && isValidCoordinate(p.location.latitude, p.location.longitude)
|
||||||
|
);
|
||||||
if (locatedParticipants.length === 0) return;
|
if (locatedParticipants.length === 0) return;
|
||||||
|
|
||||||
if (locatedParticipants.length === 1) {
|
if (locatedParticipants.length === 1) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue