@@ -14,17 +14,18 @@ const Map = (props: NakshaMaplibreViewProps) => {
1414 const [ map , setMap ] = useState < maplibregl . Map > ( ) ;
1515 const [ mode , setMode ] = useState ( "static" ) ;
1616 const [ draw , setDraw ] = useState < TerraDraw > ( ) ;
17- const { isMultiple = true , features = [ ] , onFeaturesChange } = props ;
17+ const drawRef = useRef < TerraDraw > ( ) ;
18+ const { isMultiple, features = [ ] , onFeaturesChange } = props ;
1819
1920 const [ selectedMapStyleIdx , setSelectedMapStyleIdx ] = useState (
2021 props ?. mapStyle || 0
2122 ) ;
22-
23- const mapTile = props . mapStyles ? props . mapStyles : defaultMapStyles ;
24-
23+ const mapTile = props . mapStyles ?? defaultMapStyles ;
2524 const mapStyle = mapTile [ selectedMapStyleIdx ] ?. style ;
25+ const mapStyleConfig = mapTile [ selectedMapStyleIdx ] ;
26+
27+ const storedFeaturesRef = useRef < GeoJSONStoreFeatures [ ] > ( [ ] ) ;
2628
27- // Autofocus utility
2829 const autoFocus = useCallback (
2930 ( features : GeoJSONStoreFeatures [ ] ) => {
3031 if ( ! features ?. length || ! map ) return ;
@@ -38,9 +39,11 @@ const Map = (props: NakshaMaplibreViewProps) => {
3839 [ map ]
3940 ) ;
4041
41- const mapStyleConfig = mapTile [ selectedMapStyleIdx ] ;
42-
4342 useEffect ( ( ) => {
43+ if ( features . length > 0 ) {
44+ storedFeaturesRef . current = ensureModeProperty ( features ) ;
45+ }
46+
4447 const maplibreMap = setupMaplibreMap ( {
4548 containerId : "maplibre-map" ,
4649 latitude : props . defaultViewState ?. latitude ?? 0 ,
@@ -64,11 +67,30 @@ const Map = (props: NakshaMaplibreViewProps) => {
6467 maplibreMap . addControl ( navControl , "bottom-right" ) ;
6568 maplibreMap . addControl ( fullscreen , "bottom-right" ) ;
6669
67- maplibreMap . once ( "style.load" , ( ) => setMap ( maplibreMap ) ) ;
70+ maplibreMap . once ( "style.load" , ( ) => {
71+ setMap ( maplibreMap ) ;
72+ } ) ;
73+
6874 return ( ) => {
69- maplibreMap . removeControl ( navControl ) ;
75+ if ( drawRef . current ) {
76+ storedFeaturesRef . current = drawRef . current . getSnapshot ( ) ;
77+ }
78+ if ( drawRef . current ) {
79+ try {
80+ drawRef . current . stop ( ) ;
81+ } catch {
82+ // ignore stop errors
83+ }
84+ drawRef . current = undefined ;
85+ setDraw ( undefined ) ;
86+ }
87+ if ( maplibreMap ) {
88+ maplibreMap . removeControl ( navControl ) ;
89+ maplibreMap . removeControl ( fullscreen ) ;
90+ maplibreMap . remove ( ) ;
91+ }
7092 } ;
71- } , [ mapStyle , props . defaultViewState ] ) ;
93+ } , [ mapStyle ] ) ;
7294
7395 const filterUserFeatures = ( features : GeoJSONStoreFeatures [ ] ) =>
7496 features . filter (
@@ -81,6 +103,7 @@ const Map = (props: NakshaMaplibreViewProps) => {
81103 if ( ! map ) return ;
82104 const terraDraw = setupDraw ( map ) ;
83105 terraDraw . start ( ) ;
106+ drawRef . current = terraDraw ;
84107 setDraw ( terraDraw ) ;
85108
86109 const handleChange = ( ) => {
@@ -89,7 +112,6 @@ const Map = (props: NakshaMaplibreViewProps) => {
89112
90113 if ( ! isMultiple && userFeatures . length > 1 ) {
91114 const lastFeature = userFeatures . at ( - 1 ) ! ;
92-
93115 const toRemove = userFeatures
94116 . slice ( 0 , - 1 )
95117 . map ( ( f ) => f . id )
@@ -98,37 +120,37 @@ const Map = (props: NakshaMaplibreViewProps) => {
98120 if ( toRemove . length > 0 ) {
99121 try {
100122 terraDraw . removeFeatures ( toRemove ) ;
101- } catch ( e ) {
102- console . warn ( "removeFeatures failed" , e ) ;
103- }
123+ } catch { }
104124 }
105-
106125 userFeatures = [ lastFeature ] ;
107126 }
108127 onFeaturesChange ?.( userFeatures ) ;
109128 autoFocus ( userFeatures ) ;
110- setMode ( "static" ) ;
111129 } ;
112130 terraDraw . on ( "finish" , handleChange ) ;
113131
114- // Add initial features
115- if ( features . length ) {
116- setTimeout ( ( ) => {
117- if ( terraDraw . getSnapshot ( ) . length === 0 ) {
118- let withMode = ensureModeProperty ( features ) ;
119- let initial =
120- ! isMultiple && withMode . length > 1 ? [ withMode . at ( - 1 ) ! ] : withMode ;
121- terraDraw . addFeatures ( initial ) ;
122- autoFocus ( initial ) ;
132+ setTimeout ( ( ) => {
133+ if ( terraDraw . getSnapshot ( ) . length === 0 ) {
134+ let featuresToAdd : GeoJSONStoreFeatures [ ] = [ ] ;
135+ if ( storedFeaturesRef . current . length > 0 ) {
136+ featuresToAdd = storedFeaturesRef . current ;
137+ } else if ( features . length > 0 ) {
138+ featuresToAdd = ensureModeProperty ( features ) ;
123139 }
124- } ) ;
125- }
140+ if ( ! isMultiple && featuresToAdd . length > 1 ) {
141+ featuresToAdd = [ featuresToAdd . at ( - 1 ) ! ] ;
142+ }
143+ if ( featuresToAdd . length > 0 ) {
144+ terraDraw . addFeatures ( featuresToAdd ) ;
145+ autoFocus ( featuresToAdd ) ;
146+ }
147+ }
148+ } , 100 ) ;
126149
127150 return ( ) => {
128151 terraDraw . off ( "finish" , handleChange ) ;
129- terraDraw . stop ( ) ;
130152 } ;
131- } , [ map , isMultiple , autoFocus , features , onFeaturesChange ] ) ;
153+ } , [ map ] ) ;
132154
133155 const changeMode = useCallback (
134156 ( newMode : string ) => {
@@ -138,8 +160,12 @@ const Map = (props: NakshaMaplibreViewProps) => {
138160 [ draw ]
139161 ) ;
140162
141- const handleStyleChange = ( idx ) => {
163+ const handleStyleChange = ( idx : number ) => {
164+ if ( drawRef . current ) {
165+ storedFeaturesRef . current = drawRef . current . getSnapshot ( ) ;
166+ }
142167 setSelectedMapStyleIdx ( idx ) ;
168+ setMode ( "static" ) ;
143169 } ;
144170
145171 return (
@@ -167,4 +193,5 @@ const Map = (props: NakshaMaplibreViewProps) => {
167193 </ div >
168194 ) ;
169195} ;
196+
170197export default Map ;
0 commit comments