@@ -64,6 +64,8 @@ const clusterOptions = {
6464 },
6565};
6666
67+ const locationAddresses = ref (new Map ());
68+
6769const closeTooltipCard = () => {
6870 tooltipCard .value = null ;
6971 document .getElementById (' dataset-map' )? .focus ();
@@ -285,100 +287,140 @@ const initializeMap = (datasets) => {
285287
286288const emit = defineEmits ([' toggleView' , ' datasetChange' ]);
287289
290+ onMounted (async () => {
291+ if (document .getElementById (' dataset-map' )) {
292+ initializeMap (props .datasets );
293+ }
294+ });
295+
288296const filteredLocations = computed (() => {
289- if (! searchQuery .value ) return [];
290-
291- const query = searchQuery .value .toLowerCase ();
292- return props .datasets
293- .filter (dataset => props .selectedDatasets .includes (dataset .id ))
294- .flatMap (dataset => dataset .features .map (feature => {
295- const tooltipData = feature .properties ? .tooltip || [];
296- const address = tooltipData .find (t => t .layout === ' meta' )? .meta || ' ' ;
297-
298- return {
299- ... feature,
300- datasetId: dataset .id ,
301- address,
302- matches: address .toLowerCase ().includes (query)
303- };
304- }))
305- .filter (location => location .matches );
297+ if (! searchQuery .value ) return [];
298+
299+ const query = searchQuery .value .toLowerCase ();
300+ return props .datasets
301+ .filter (dataset => props .selectedDatasets .includes (dataset .id ))
302+ .flatMap (dataset => dataset .features .map (feature => {
303+ const tooltipData = feature .properties ? .tooltip || [];
304+ const coords = feature .geometry .coordinates ;
305+
306+ // Collect all searchable text
307+ const searchableText = [
308+ // Tooltip data
309+ tooltipData .find (t => t .layout === ' meta' )? .meta ,
310+ tooltipData .find (t => t .layout === ' title' )? .title ,
311+ tooltipData .find (t => t .layout === ' text' )? .text ,
312+ // Location data
313+ feature .properties ? .name ,
314+ feature .properties ? .description ,
315+ // Coordinates (formatted for search)
316+ coords ? ` ${ coords[1 ]} ,${ coords[0 ]} ` : null
317+ ]
318+ .filter (Boolean ) // Remove null/undefined values
319+ .join (' ' )
320+ .toLowerCase ();
321+
322+ return {
323+ ... feature,
324+ datasetId: dataset .id ,
325+ matches: searchableText .includes (query)
326+ };
327+ }))
328+ .filter (location => location .matches );
306329});
307330
308331// Add search handler
309332const handleSearch = (query ) => {
310- searchQuery .value = query;
311- const map = mapRef .value ;
312-
313- // Clear existing search markers
314- searchMarkers .value .forEach (marker => {
315- map .removeLayer (marker);
316- });
317- searchMarkers .value = [];
318-
319- if (! query) {
320- // Show all markers again when search is cleared
321- clusters .value .forEach (({ cluster }) => {
322- map .addLayer (cluster);
323- });
324- return ;
325- }
333+ searchQuery .value = query;
334+ const map = mapRef .value ;
335+
336+ if (! map) return ;
337+
338+ // Clear existing search markers
339+ searchMarkers .value .forEach (marker => {
340+ if (marker && map .hasLayer (marker)) {
341+ map .removeLayer (marker);
342+ }
343+ });
344+ searchMarkers .value = [];
326345
327- // Hide all regular markers
328- clusters .value .forEach (({ cluster }) => {
329- map .removeLayer (cluster);
330- });
346+ if (! query) {
347+ // Show all markers again when search is cleared
348+ clusters .value .forEach (({ cluster }) => {
349+ if (cluster && ! map .hasLayer (cluster)) {
350+ map .addLayer (cluster);
351+ }
352+ });
353+ return ;
354+ }
331355
332- // Create markers for search results and zoom to bounds
333- const searchBounds = L .latLngBounds ();
334-
335- filteredLocations .value .forEach (location => {
336- if (location .geometry .type === ' MultiPoint' ) {
337- location .geometry .coordinates .forEach (coord => {
338- const latlng = L .latLng (coord[1 ], coord[0 ]);
339- addSearchMarker (latlng, location);
340- searchBounds .extend (latlng);
341- });
342- } else {
343- const coords = location .geometry .coordinates ;
344- const latlng = L .latLng (coords[1 ], coords[0 ]);
345- addSearchMarker (latlng, location);
346- searchBounds .extend (latlng);
347- }
348- });
356+ // Hide all regular markers
357+ clusters .value .forEach (({ cluster }) => {
358+ if (cluster && map .hasLayer (cluster)) {
359+ map .removeLayer (cluster);
360+ }
361+ });
349362
350- if (! searchBounds .isValid ()) return ;
363+ // Create markers for search results and zoom to bounds
364+ const searchBounds = L .latLngBounds ();
365+ let hasValidResults = false ;
366+
367+ filteredLocations .value .forEach (location => {
368+ if (location? .geometry ? .coordinates ) {
369+ if (location .geometry .type === ' MultiPoint' ) {
370+ location .geometry .coordinates .forEach (coord => {
371+ if (Array .isArray (coord) && coord .length >= 2 ) {
372+ const latlng = L .latLng (coord[1 ], coord[0 ]);
373+ addSearchMarker (latlng, location);
374+ searchBounds .extend (latlng);
375+ hasValidResults = true ;
376+ }
377+ });
378+ } else {
379+ const coords = location .geometry .coordinates ;
380+ if (Array .isArray (coords) && coords .length >= 2 ) {
381+ const latlng = L .latLng (coords[1 ], coords[0 ]);
382+ addSearchMarker (latlng, location);
383+ searchBounds .extend (latlng);
384+ hasValidResults = true ;
385+ }
386+ }
387+ }
388+ });
351389
352- // Zoom to results with padding
353- map .fitBounds (searchBounds, {
354- padding: [50 , 50 ],
355- maxZoom: 15
356- });
390+ if (hasValidResults) {
391+ // Zoom to results with padding
392+ map .fitBounds (searchBounds, {
393+ padding: [50 , 50 ],
394+ maxZoom: 15
395+ });
396+ }
357397};
358398
359399// Helper function to add search result markers
360400const addSearchMarker = (latlng , location ) => {
361- const map = mapRef .value ;
362- const icon = makeMarkerIcon (L , {
363- marker: location .properties ? .marker ,
364- defaultColor: props .primaryColor ,
365- });
401+ const map = mapRef .value ;
402+ if (! map || ! latlng || ! location) return ;
366403
367- const marker = new L.Marker (latlng, {
368- icon,
369- zIndexOffset: 1000 // Ensure search results appear above other markers
370- });
371-
372- attachEvents (marker, location, { id: location .datasetId });
373- marker .addTo (map);
374- searchMarkers .value .push (marker);
375- };
404+ try {
405+ const icon = makeMarkerIcon (L , {
406+ marker: location .properties ? .marker ,
407+ defaultColor: props .primaryColor ,
408+ });
376409
377- onMounted (() => {
378- if (document .getElementById (' dataset-map' )) {
379- initializeMap (props .datasets );
410+ const marker = new L.Marker (latlng, {
411+ icon,
412+ zIndexOffset: 1000 // Ensure search results appear above other markers
413+ });
414+
415+ if (marker) {
416+ attachEvents (marker, location, { id: location .datasetId });
417+ marker .addTo (map);
418+ searchMarkers .value .push (marker);
419+ }
420+ } catch (error) {
421+ console .error (' Error adding search marker:' , error);
380422 }
381- }) ;
423+ };
382424< / script>
383425
384426< template v- cloak>
0 commit comments