<template> <div class="geocoder"> <Multiselect v-model="selection" :options="addresses" :options-limit="5" :allow-empty="true" track-by="label" label="label" :show-labels="false" :reset-after="true" select-label="" selected-label="" deselect-label="" :searchable="true" :placeholder="placeholder" :show-no-results="true" :loading="loading" :clear-on-select="false" :preserve-search="true" @search-change="search" @select="select" @close="close" > <template slot="option" slot-scope="props" > <div class="option__desc"> <span class="option__title">{{ props.option.label }}</span> </div> </template> <template slot="clear"> <div v-if="selection" class="multiselect__clear" @click.prevent.stop="selection = null" > <i class="close icon" /> </div> </template> <span slot="noResult"> Aucun résultat. </span> <span slot="noOptions"> Saisissez les premiers caractères ... </span> </Multiselect> <div style="display: none;"> <div id="marker" title="Marker" /> </div> </div> </template> <script> import Multiselect from 'vue-multiselect'; import { Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import axios from 'axios'; import mapService from '@/services/map-service'; const apiAdressAxios = axios.create({ baseURL: 'https://api-adresse.data.gouv.fr', withCredentials: false, }); export default { name: 'Geocoder', components: { Multiselect }, data() { return { loading: false, selection: null, text: null, selectedAddress: null, addresses: [], resultats: [], placeholder: 'Rechercher une adresse ...' }; }, mounted() { this.addressTextChange = new Subject(); this.addressTextChange.pipe(debounceTime(200)).subscribe((res) => this.getAddresses(res)); }, methods: { getAddresses(query){ console.log(query); let self = this; console.log('get addresses'); const limit = 5; apiAdressAxios.get(`https://api-adresse.data.gouv.fr/search/?q=${query}&limit=${limit}`) .then((retour) => { self.resultats = retour.data.features; self.addresses = retour.data.features.map(x=>x.properties); }); }, selectAddresse(event) { console.log(event); this.selectedAddress = event; if (this.selectedAddress !== null && this.selectedAddress.geometry) { let zoomlevel = 14; let { type } = this.selectedAddress.properties; if (type === 'housenumber') { zoomlevel = 19; } else if (type === 'street') { zoomlevel = 16; } else if (type === 'locality') { zoomlevel = 16; } else if (type === 'municipality') { zoomlevel = 14; } // On fait le zoom mapService.zoomTo(this.selectedAddress.geometry.coordinates, zoomlevel); // On ajoute un point pour localiser la ville mapService.addOverlay(this.selectedAddress.geometry.coordinates); } }, search(text) { this.text = text; this.addressTextChange.next(this.text); //console.log(text); }, select(e) { this.selectAddresse(this.resultats.find(x=>x.properties.label==e.label)); this.$emit('select', e); }, close() { this.$emit('close', this.selection); } } }; </script> <style scoped> .geocoder{ max-width: 400px; right: 500px; position: absolute; top: 20px; pointer-events: auto; z-index: 50000; } #marker { width: 20px; height: 20px; border: 1px solid rgb(136, 66, 0); border-radius: 10px; background-color: rgb(201, 114, 15); opacity: 0.7; } </style>