google map as default and auto zoom
Some checks failed
Build and deploy / Build and Push Docker Images (push) Failing after 39s

This commit is contained in:
2025-12-14 23:19:20 +05:00
parent 57adb221f9
commit e36e5e8fc5
3 changed files with 104 additions and 14 deletions

View File

@@ -6,6 +6,7 @@ import { DrawingHandler } from './DrawingHandler';
import { MapItemsLayer } from './MapItemsLayer';
import { ShareDialog } from './ShareDialog';
import { useMapWebSocket } from '../../hooks/useMapWebSocket';
import { mapItemService } from '../../services/mapItemService';
// Fix Leaflet's default icon paths for production builds
// Since we use custom DivIcons, we just need to prevent 404s
@@ -38,6 +39,49 @@ function MapController() {
return null;
}
function AutoZoom({ mapId, refreshTrigger }: { mapId: string; refreshTrigger: number }) {
const map = useMap();
useEffect(() => {
const zoomToDevices = async () => {
try {
const items = await mapItemService.getMapItems(mapId);
// Filter only devices (exclude cables, wireless mesh, and info markers)
const devices = items.filter(item =>
['switch', 'indoor_ap', 'outdoor_ap', 'other_device'].includes(item.type) &&
item.geometry.type === 'Point'
);
if (devices.length === 0) {
// No devices, keep default view
return;
}
// Create bounds from all device coordinates
const bounds = L.latLngBounds(
devices.map(device => {
const [lng, lat] = device.geometry.coordinates;
return [lat, lng] as [number, number];
})
);
// Fit map to bounds with padding
map.fitBounds(bounds, {
padding: [50, 50],
maxZoom: 18,
});
} catch (error) {
console.error('Failed to auto-zoom to devices:', error);
}
};
zoomToDevices();
}, [mapId, refreshTrigger, map]);
return null;
}
export function MapView({ mapId, activeLayer, mapLayers, showShareDialog = false, shareMapId, onCloseShareDialog }: MapViewProps) {
const [refreshTrigger, setRefreshTrigger] = useState(0);
@@ -89,6 +133,7 @@ export function MapView({ mapId, activeLayer, mapLayers, showShareDialog = false
style={{ background: '#f0f0f0' }}
>
<MapController />
<AutoZoom mapId={mapId} refreshTrigger={refreshTrigger} />
<TileLayer
key={activeLayer}
url={layer.url}

View File

@@ -8,12 +8,6 @@ import { LayerSwitcher } from '../components/map/LayerSwitcher';
type MapLayer = 'osm' | 'google' | 'esri';
const MAP_LAYERS = {
osm: {
name: 'OpenStreetMap',
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 25,
},
google: {
name: 'Google Satellite',
url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
@@ -21,6 +15,12 @@ const MAP_LAYERS = {
maxZoom: 25,
maxNativeZoom: 22,
},
osm: {
name: 'OpenStreetMap',
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 25,
},
esri: {
name: 'ESRI Satellite',
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
@@ -33,7 +33,7 @@ export function Dashboard() {
const [selectedMapId, setSelectedMapId] = useState<string | null>(null);
const [showShareDialog, setShowShareDialog] = useState(false);
const [shareMapId, setShareMapId] = useState<string | null>(null);
const [activeLayer, setActiveLayer] = useState<MapLayer>('osm');
const [activeLayer, setActiveLayer] = useState<MapLayer>('google');
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const handleShareMap = (mapId: string) => {

View File

@@ -10,6 +10,7 @@ import { Toolbar } from '../components/map/Toolbar';
import { useMapWebSocket } from '../hooks/useMapWebSocket';
import { apiClient } from '../services/api';
import { useUIStore } from '../stores/uiStore';
import { mapItemService } from '../services/mapItemService';
// Fix Leaflet's default icon paths for production builds
// Since we use custom DivIcons, we just need to prevent 404s
@@ -23,12 +24,6 @@ L.Icon.Default.mergeOptions({
type MapLayer = 'osm' | 'google' | 'esri';
const MAP_LAYERS = {
osm: {
name: 'OpenStreetMap',
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 25,
},
google: {
name: 'Google Satellite',
url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
@@ -36,6 +31,12 @@ const MAP_LAYERS = {
maxZoom: 25,
maxNativeZoom: 22,
},
osm: {
name: 'OpenStreetMap',
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 25,
},
esri: {
name: 'ESRI Satellite',
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
@@ -56,10 +57,53 @@ function MapController() {
return null;
}
function AutoZoom({ mapId, refreshTrigger }: { mapId: string; refreshTrigger: number }) {
const map = useMap();
useEffect(() => {
const zoomToDevices = async () => {
try {
const items = await mapItemService.getMapItems(mapId);
// Filter only devices (exclude cables, wireless mesh, and info markers)
const devices = items.filter(item =>
['switch', 'indoor_ap', 'outdoor_ap', 'other_device'].includes(item.type) &&
item.geometry.type === 'Point'
);
if (devices.length === 0) {
// No devices, keep default view
return;
}
// Create bounds from all device coordinates
const bounds = L.latLngBounds(
devices.map(device => {
const [lng, lat] = device.geometry.coordinates;
return [lat, lng] as [number, number];
})
);
// Fit map to bounds with padding
map.fitBounds(bounds, {
padding: [50, 50],
maxZoom: 18,
});
} catch (error) {
console.error('Failed to auto-zoom to devices:', error);
}
};
zoomToDevices();
}, [mapId, refreshTrigger, map]);
return null;
}
export function SharedMap() {
const { token } = useParams<{ token: string }>();
const { darkMode, toggleDarkMode } = useUIStore();
const [activeLayer, setActiveLayer] = useState<MapLayer>('osm');
const [activeLayer, setActiveLayer] = useState<MapLayer>('google');
const [refreshTrigger, setRefreshTrigger] = useState(0);
const [mapData, setMapData] = useState<any>(null);
const [loading, setLoading] = useState(true);
@@ -232,6 +276,7 @@ export function SharedMap() {
style={{ background: '#f0f0f0' }}
>
<MapController />
<AutoZoom mapId={mapData.id} refreshTrigger={refreshTrigger} />
<TileLayer
key={activeLayer}
url={MAP_LAYERS[activeLayer].url}