@@ -22,8 +22,11 @@ import { DetailsPanel } from "./details-panel";
2222import Legend from "./legend-text.mdx" ;
2323import { useInDarkMode } from "@macrostrat/ui-components" ;
2424import { usePageContext } from "vike-react/usePageContext" ;
25- import { navigate } from "vike/client/router" ;
26- import { formatCoordForZoomLevel } from "@macrostrat/mapbox-utils" ;
25+ import {
26+ AnyMapPosition ,
27+ formatCoordForZoomLevel ,
28+ MapPosition ,
29+ } from "@macrostrat/mapbox-utils" ;
2730
2831const h = hyper . styled ( styles ) ;
2932
@@ -32,56 +35,15 @@ mapboxgl.accessToken = mapboxAccessToken;
3235const baseURL = "/dev/map/rockd-strabospot" ;
3336
3437export function Page ( ) {
35- const { routeParams } = usePageContext ( ) ;
36- const { lng, lat } = routeParams ;
37-
38- let initialPosition = null ;
39- if ( lng != null && lat != null ) {
40- try {
41- // Try to get the zoom level from the hash
42- const q = new URLSearchParams ( window . location . hash . slice ( 1 ) ) ;
43- const zoom = q . has ( "z" ) ? parseInt ( q . get ( "z" ) ) : 7 ;
44-
45- initialPosition = { lng : parseFloat ( lng ) , lat : parseFloat ( lat ) , zoom } ;
46- } catch {
47- console . error ( "Failed to parse initial position" ) ;
48- }
49- }
38+ const [ inspectPosition , onSelectPosition ] = useMapLocationManager ( ) ;
5039
5140 const style = useRockdStraboSpotStyle ( ) ;
5241 const inDarkMode = useInDarkMode ( ) ;
5342
5443 const [ isOpen , setOpen ] = useState ( true ) ;
5544
56- const [ inspectPosition , setInspectPosition ] =
57- useState < mapboxgl . LngLat | null > ( initialPosition ) ;
58-
5945 const [ data , setData ] = useState ( null ) ;
6046
61- const onSelectPosition = useCallback (
62- (
63- position : mapboxgl . LngLat | null ,
64- event : Event | undefined ,
65- map : mapboxgl . Map | undefined
66- ) => {
67- setInspectPosition ( position ) ;
68- let newPathname = "/dev/map/rockd-strabospot" ;
69- let currentPathname = window . location . pathname ;
70-
71- if ( map != null && position != null ) {
72- const z = map . getZoom ( ) ?? 7 ;
73- const lng = formatCoordForZoomLevel ( position . lng , z ) ;
74- const lat = formatCoordForZoomLevel ( position . lat , z ) ;
75- newPathname += `/loc/${ lng } /${ lat } ` ;
76- }
77- newPathname += buildHashParams ( map , position ) ;
78- if ( currentPathname !== newPathname ) {
79- window . history . pushState ( { } , "" , newPathname ) ;
80- }
81- } ,
82- [ ]
83- ) ;
84-
8547 return h (
8648 MapAreaContainer ,
8749 {
@@ -114,10 +76,10 @@ export function Page() {
11476 style,
11577 projection : { name : "globe" } ,
11678 mapboxToken : mapboxAccessToken ,
117- mapPosition : initialPosition ,
79+ mapPosition : inspectPosition ,
11880 bounds : [ - 125 , 24 , - 66 , 49 ] ,
119- onMapMoved ( mapPosition , map ) {
120- window . location . hash = buildHashParams ( map , inspectPosition ) ;
81+ onMapMoved ( pos , map ) {
82+ setURL ( inspectPosition , map ) ;
12183 } ,
12284 } ,
12385 [
@@ -128,13 +90,68 @@ export function Page() {
12890 } ) ,
12991 h ( MapMarker , {
13092 position : inspectPosition ,
131- setPosition : onSelectPosition ,
93+ setPosition ( pos , event , map ) {
94+ onSelectPosition ( pos , map ) ;
95+ } ,
13296 } ) ,
13397 ]
13498 )
13599 ) ;
136100}
137101
102+ type PositionBuilder = (
103+ position : MapPosition | null ,
104+ map : mapboxgl . Map | undefined
105+ ) => void ;
106+
107+ function useMapLocationManager ( ) : [ MapPosition , PositionBuilder ] {
108+ const { routeParams } = usePageContext ( ) ;
109+ const { lng, lat } = routeParams ;
110+
111+ let initialPosition = null ;
112+ if ( lng != null && lat != null ) {
113+ try {
114+ // Try to get the zoom level from the hash
115+ const q = new URLSearchParams ( window . location . hash . slice ( 1 ) ) ;
116+ const zoom = q . has ( "z" ) ? parseInt ( q . get ( "z" ) ) : 7 ;
117+
118+ initialPosition = { lng : parseFloat ( lng ) , lat : parseFloat ( lat ) , zoom } ;
119+ } catch {
120+ console . error ( "Failed to parse initial position" ) ;
121+ }
122+ }
123+
124+ const [ inspectPosition , setInspectPosition ] =
125+ useState < mapboxgl . LngLat | null > ( initialPosition ) ;
126+
127+ const onSelectPosition = useCallback (
128+ ( position : mapboxgl . LngLat | null , map : mapboxgl . Map | undefined ) => {
129+ setInspectPosition ( position ) ;
130+ setURL ( position , map ) ;
131+ } ,
132+ [ ]
133+ ) ;
134+
135+ return [ inspectPosition , onSelectPosition ] ;
136+ }
137+
138+ function setURL ( position : mapboxgl . LngLat , map : mapboxgl . Map ) {
139+ let newPathname = "/dev/map/rockd-strabospot" ;
140+ let currentPathname = window . location . pathname ;
141+
142+ if ( map != null && position != null ) {
143+ const z = map . getZoom ( ) ?? 7 ;
144+ const lng = formatCoordForZoomLevel ( position . lng , z ) ;
145+ const lat = formatCoordForZoomLevel ( position . lat , z ) ;
146+ newPathname += `/loc/${ lng } /${ lat } ` ;
147+ }
148+ newPathname += buildHashParams ( map , position ) ;
149+ console . log ( currentPathname , newPathname ) ;
150+ if ( currentPathname !== newPathname ) {
151+ history . replaceState ( { } , "" , newPathname ) ;
152+ }
153+ }
154+
138155function buildHashParams ( map , selectedPosition ) {
139156 if ( selectedPosition == null ) return "" ;
140157 const z = map . getZoom ( ) ;
0 commit comments