From 6b2161f4ccee377917534a4c8ea9a46854547ca4 Mon Sep 17 00:00:00 2001 From: tarunsinghofficial Date: Thu, 8 Aug 2024 21:00:34 +0530 Subject: [PATCH] Adds Route Map overlay feature Fixes #24 - Trip Details List and Map Overlay Fixes #29 - The bus's route should also be projected onto the map Fixes #30 - Hide unrelated stops on the map while a route line is being displayed Co-authored-by: tarunsinghofficial --- src/components/map/GoogleMap.svelte | 55 +++++++++--- src/components/map/RouteMap.svelte | 83 +++++++++++++++++++ src/components/oba/StopPane.svelte | 4 + src/components/oba/TripDetailsPane.svelte | 3 - src/lib/googleMaps.js | 16 ++++ src/routes/+page.svelte | 33 +++++++- src/routes/api/oba/shape/[shapeId]/+server.js | 24 ++++++ 7 files changed, 203 insertions(+), 15 deletions(-) create mode 100644 src/components/map/RouteMap.svelte create mode 100644 src/routes/api/oba/shape/[shapeId]/+server.js diff --git a/src/components/map/GoogleMap.svelte b/src/components/map/GoogleMap.svelte index 16924f8..ab886e1 100644 --- a/src/components/map/GoogleMap.svelte +++ b/src/components/map/GoogleMap.svelte @@ -7,19 +7,24 @@ PUBLIC_OBA_REGION_CENTER_LAT as initialLat, PUBLIC_OBA_REGION_CENTER_LNG as initialLng } from '$env/static/public'; - import { pushState } from '$app/navigation'; + import { debounce } from '$lib/utils'; + import { pushState } from '$app/navigation'; import { createMap, loadGoogleMapsLibrary, nightModeStyles } from '$lib/googleMaps'; import LocationButton from '$lib/LocationButton/LocationButton.svelte'; import StopMarker from './StopMarker.svelte'; + import RouteMap from './RouteMap.svelte'; - import { debounce } from '$lib/utils'; + export let selectedTrip; + export let selectedRoute = null; + export let showRoute = false; const dispatch = createEventDispatcher(); let map = null; let markers = []; + let allStops = []; async function loadStopsForLocation(lat, lng) { const response = await fetch(`/api/oba/stops-for-location?lat=${lat}&lng=${lng}`); @@ -50,19 +55,41 @@ async function loadStopsAndAddMarkers(lat, lng) { const json = await loadStopsForLocation(lat, lng); - const stops = json.data.list; + const newStops = json.data.list; - for (const s of stops) { - if (markerExists(s)) { - continue; - } + allStops = [...new Map([...allStops, ...newStops].map((stop) => [stop.id, stop])).values()]; + + clearAllMarkers(); - addMarker(s); + if (showRoute && selectedRoute) { + const stopsToShow = allStops.filter((s) => s.routeIds.includes(selectedRoute.id)); + stopsToShow.forEach((s) => addMarker(s)); + } else { + newStops.forEach((s) => addMarker(s)); } } - function markerExists(s) { - return markers.some((marker) => marker.s.id === s.id); + function clearAllMarkers() { + markers.forEach(({ marker, overlay, element }) => { + marker?.setMap(null); + + if (overlay) { + overlay.setMap(null); + overlay.draw = () => {}; + overlay.onRemove?.(); + } + element?.parentNode?.removeChild(element); + }); + markers = []; + } + + $: if (selectedRoute && showRoute) { + clearAllMarkers(); + const stopsToShow = allStops.filter((s) => s.routeIds.includes(selectedRoute.id)); + stopsToShow.forEach((s) => addMarker(s)); + } else if (!showRoute || !selectedRoute) { + clearAllMarkers(); + allStops.forEach((s) => addMarker(s)); } function addMarker(s) { @@ -107,6 +134,9 @@ container.style.position = 'absolute'; this.getPanes().overlayMouseTarget.appendChild(container); }; + overlay.onRemove = function () { + container?.parentNode?.removeChild(container); + }; markers.push({ s, marker, overlay, element: container }); } @@ -161,6 +191,11 @@
+ +{#if selectedTrip} + +{/if} +