@@ -36,12 +36,11 @@ const props = defineProps({
3636
3737const tooltipCard = ref (null );
3838const showFiltersCard = ref (false );
39- const datasetLocations = ref ([]);
4039const mapRef = ref (null );
4140const clusters = ref ([]);
42- const showListView = ref (false );
4341const searchQuery = ref (' ' );
44- const searchMarkers = ref ([]);
42+ const resultsCount = ref (0 );
43+ const lastSearchMarker = ref (null );
4544const clusterOptions = {
4645 spiderfyOnMaxZoom: true ,
4746 showCoverageOnHover: false ,
@@ -64,8 +63,6 @@ const clusterOptions = {
6463 },
6564};
6665
67- const locationAddresses = ref (new Map ());
68-
6966const closeTooltipCard = () => {
7067 tooltipCard .value = null ;
7168 document .getElementById (' dataset-map' )? .focus ();
@@ -104,12 +101,6 @@ const attachEvents = (marker, location, set) => {
104101 });
105102};
106103
107- // Helper function to get coordinates from feature
108- const getLatLng = (feature ) => {
109- const coords = feature .geometry .coordinates ;
110- return L .latLng (coords[1 ], coords[0 ]);
111- };
112-
113104// Helper function to get color from marker config
114105const getColorFromMarker = (markerConfig ) => {
115106 if (! markerConfig) return props .primaryColor ;
@@ -174,8 +165,8 @@ const initializeMap = (datasets) => {
174165 centerX: lat,
175166 centerY: long,
176167 minimumZoom: 4 ,
177- maximumZoom: 16 ,
178- defaultZoom: 13 ,
168+ maximumZoom: 18 ,
169+ defaultZoom: 10 ,
179170 enableHomeControl: true ,
180171 enableZoomControl: true ,
181172 enableBoxZoomControl: true ,
@@ -293,133 +284,46 @@ onMounted(async () => {
293284 }
294285});
295286
296- const filteredLocations = computed (() => {
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 );
329- });
330-
331287// Add search handler
332- const handleSearch = (query ) => {
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 = [];
345-
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- }
355-
356- // Hide all regular markers
357- clusters .value .forEach (({ cluster }) => {
358- if (cluster && map .hasLayer (cluster)) {
359- map .removeLayer (cluster);
360- }
361- });
362-
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- });
389-
390- if (hasValidResults) {
391- // Zoom to results with padding
392- map .fitBounds (searchBounds, {
393- padding: [50 , 50 ],
394- maxZoom: 15
395- });
396- }
397- };
398-
399- // Helper function to add search result markers
400- const addSearchMarker = (latlng , location ) => {
401- const map = mapRef .value ;
402- if (! map || ! latlng || ! location) return ;
403-
404- try {
405- const icon = makeMarkerIcon (L , {
406- marker: location .properties ? .marker ,
407- defaultColor: props .primaryColor ,
408- });
288+ const handleSearch = async (query ) => {
289+ searchQuery .value = query;
290+ const map = mapRef .value ;
291+
292+ if (! map || ! query) return ;
293+
294+ try {
295+ const response = await fetch (
296+ ` https://nominatim.openstreetmap.org/search?format=json&q=${ encodeURIComponent (query)} `
297+ );
298+ const results = await response .json ();
299+
300+ if (results .length > 0 ) {
301+ const { lat , lon } = results[0 ]; // Take the first (most relevant) match.
302+ const latLng = L .latLng (parseFloat (lat), parseFloat (lon));
303+ const targetIcon = L .icon ({
304+ iconUrl: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=',
305+ iconSize: [15 , 24 ],
306+ iconAnchor: [0 , 24 ],
307+ popupAnchor: [8 , - 7 ]
308+ });
409309
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);
422- }
310+ if (map && map ._loaded ) {
311+ map .once (' zoomend' , () => {
312+ if (lastSearchMarker .value ) {
313+ map .removeLayer (lastSearchMarker .value );
314+ }
315+ const targetMarker = L .marker (latLng, { icon: targetIcon });
316+ targetMarker .addTo (map);
317+ targetMarker .bindPopup (" Gevonden locatie" );
318+ lastSearchMarker .value = targetMarker;
319+ });
320+ map .flyTo (latLng, 15 , { animate: true , duration: 1 });
321+ }
322+ resultsCount .value = results .length ? 1 : 0
323+ }
324+ } catch (error) {
325+ console .error (" Error in retrieving location:" , error);
326+ }
423327};
424328< / script>
425329
@@ -432,10 +336,11 @@ const addSearchMarker = (latlng, location) => {
432336 }"
433337 >
434338 < div class = " owc-openkaarten-streetmap__controls" >
435- < BaseSearchInput
339+ < BaseSearchInput
340+ : placeholder= " 'Zoek op straat en/of plaats of postcode'"
436341 : primary- color= " primaryColor"
342+ : results- count= " resultsCount"
437343 @search= " handleSearch"
438- : results- count= " filteredLocations.length"
439344 / >
440345 < / div>
441346 < div id= " dataset-map" >< / div>
0 commit comments