mirror of
https://github.com/dpup/meshstream.git
synced 2026-08-10 02:32:54 +02:00
refactor(web): replace Google Maps with MapLibre, clean up map components
- Migrate all three map components (Map, GoogleMap, NetworkMap) to MapLibre GL JS - Extract shared CARTO_DARK_STYLE constants into lib/mapStyle.ts - Move buildCircleCoords to lib/mapUtils.ts (was duplicated across components) - Rename exports: Map → LocationMap, GoogleMap → NodeLocationMap - Remove dead props (width, height, nightMode) from LocationMap interface - Lazy-mount GL contexts via IntersectionObserver to prevent WebGL exhaustion - Fix Math.spread RangeError in NetworkMap bounds calculation - Remove showLinks conditional render in favour of visibility layout property - Remove cursor state; set canvas cursor style directly on map interactions - Remove Google Maps API key env vars from .env.example and .env.local - Move Vite dev server to port 5747 (avoids cached redirect on 3000) - Fix CORS/404: set VITE_API_BASE_URL="" so browser uses Vite proxy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,8 +13,6 @@ export const SITE_DESCRIPTION =
|
||||
import.meta.env.VITE_SITE_DESCRIPTION ||
|
||||
"Realtime Meshtastic activity via MQTT.";
|
||||
export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || "";
|
||||
export const GOOGLE_MAPS_ID = import.meta.env.VITE_GOOGLE_MAPS_ID || "demo-map-id";
|
||||
export const GOOGLE_MAPS_API_KEY = import.meta.env.VITE_GOOGLE_MAPS_API_KEY || "";
|
||||
|
||||
// API endpoints
|
||||
export const API_ENDPOINTS = {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { StyleSpecification } from "maplibre-gl";
|
||||
|
||||
const CARTO_TILES = [
|
||||
"https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
||||
"https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
||||
"https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
|
||||
];
|
||||
|
||||
const CARTO_SOURCE = {
|
||||
type: "raster" as const,
|
||||
tiles: CARTO_TILES,
|
||||
tileSize: 256,
|
||||
attribution:
|
||||
'© <a href="https://carto.com/attributions">CARTO</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>',
|
||||
maxzoom: 19,
|
||||
};
|
||||
|
||||
/** Base CartoDB Dark Matter style — raster tiles, no labels */
|
||||
export const CARTO_DARK_STYLE: StyleSpecification = {
|
||||
version: 8,
|
||||
sources: { carto: CARTO_SOURCE },
|
||||
layers: [{ id: "carto-dark", type: "raster", source: "carto" }],
|
||||
};
|
||||
|
||||
/** CartoDB Dark Matter style with glyph support for GL text labels */
|
||||
export const CARTO_DARK_STYLE_LABELLED: StyleSpecification = {
|
||||
version: 8,
|
||||
glyphs: "https://protomaps.github.io/basemaps-assets/fonts/{fontstack}/{range}.pbf",
|
||||
sources: { carto: CARTO_SOURCE },
|
||||
layers: [{ id: "carto-dark", type: "raster", source: "carto" }],
|
||||
};
|
||||
+24
-54
@@ -45,63 +45,33 @@ export const calculateZoomFromAccuracy = (accuracyMeters: number): number => {
|
||||
return 10;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a Google Maps Static API URL for a given latitude and longitude
|
||||
* @param latitude The latitude in decimal degrees
|
||||
* @param longitude The longitude in decimal degrees
|
||||
* @param zoom The zoom level (1-20)
|
||||
* @param width The image width in pixels
|
||||
* @param height The image height in pixels
|
||||
* @param nightMode Whether to use dark styling for the map
|
||||
* @param precisionBits Optional precision bits to determine how to display the marker
|
||||
* @returns A URL string for the Google Maps Static API
|
||||
* Approximate a geographic circle as a GeoJSON polygon ring.
|
||||
* @param lng Center longitude
|
||||
* @param lat Center latitude
|
||||
* @param radiusMeters Radius in meters
|
||||
* @param points Number of polygon vertices (more = smoother)
|
||||
*/
|
||||
export const getStaticMapUrl = (
|
||||
latitude: number,
|
||||
longitude: number,
|
||||
zoom: number = 15,
|
||||
width: number = 300,
|
||||
height: number = 200,
|
||||
nightMode: boolean = true,
|
||||
precisionBits?: number
|
||||
): string => {
|
||||
// Get API key from environment variable
|
||||
const apiKey = import.meta.env.VITE_GOOGLE_MAPS_API_KEY || "";
|
||||
|
||||
// Build the URL
|
||||
const mapUrl = new URL("https://maps.googleapis.com/maps/api/staticmap");
|
||||
|
||||
// Add parameters
|
||||
mapUrl.searchParams.append("center", `${latitude},${longitude}`);
|
||||
mapUrl.searchParams.append("zoom", zoom.toString());
|
||||
mapUrl.searchParams.append("size", `${width}x${height}`);
|
||||
mapUrl.searchParams.append("key", apiKey);
|
||||
mapUrl.searchParams.append("format", "png");
|
||||
mapUrl.searchParams.append("scale", "2"); // Retina display support
|
||||
|
||||
// Only add marker if we don't have precision information
|
||||
if (precisionBits === undefined) {
|
||||
mapUrl.searchParams.append(
|
||||
"markers",
|
||||
`color:green|${latitude},${longitude}`
|
||||
);
|
||||
export function buildCircleCoords(
|
||||
lng: number,
|
||||
lat: number,
|
||||
radiusMeters: number,
|
||||
points = 64
|
||||
): [number, number][] {
|
||||
const earthRadius = 6371000;
|
||||
const coords: [number, number][] = [];
|
||||
for (let i = 0; i <= points; i++) {
|
||||
const angle = (i / points) * 2 * Math.PI;
|
||||
const dx = radiusMeters * Math.cos(angle);
|
||||
const dy = radiusMeters * Math.sin(angle);
|
||||
const pLat = lat + (dy / earthRadius) * (180 / Math.PI);
|
||||
const pLng = lng + (dx / (earthRadius * Math.cos((lat * Math.PI) / 180))) * (180 / Math.PI);
|
||||
coords.push([pLng, pLat]);
|
||||
}
|
||||
// With static maps we can't draw circles directly, so we use a marker with different color
|
||||
// even when we have precision information, but we'll show it differently in the interactive map
|
||||
else {
|
||||
mapUrl.searchParams.append(
|
||||
"markers",
|
||||
`color:green|${latitude},${longitude}`
|
||||
);
|
||||
}
|
||||
|
||||
// Apply night mode styling using the simpler approach
|
||||
if (nightMode) {
|
||||
mapUrl.searchParams.append("style", "invert_lightness:true");
|
||||
}
|
||||
|
||||
return mapUrl.toString();
|
||||
};
|
||||
coords.push(coords[0]); // close the ring
|
||||
return coords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Google Maps URL to open the location in Google Maps
|
||||
|
||||
Reference in New Issue
Block a user