<!-- @format --> <template> <div style="display: flex"> <a-form-item-rest> <div class="rightBox"> <div class="inputArea"> <div style="margin-right: 10px">经度</div> <div class="longitude"> <ns-input v-model:value="longitude1" type="number" class="input" placeholder="请输入经度" @change="inputChange('longitude', $event)" /> </div ><div style="margin: 0 10px">纬度</div> <div class="latitude"> <ns-input v-model:value="latitude1" type="number" class="input" placeholder="请输入纬度" @change="inputChange('latitude', $event)" /> </div> </div> <div class="inputSearch" style="margin: 15px 0 15px 0"> <label style="margin-right: 10px">地址</label> <ns-input v-model:value="address" class="inputAdress" placeholder="请输入地址" /> <ns-button type="primary" @click="onSearch">查询</ns-button> </div> <div class="mapArea"> <div id="map-container"></div> <div v-if="isShowResult" id="map-result" style="overflow: auto; width: 100%"></div> </div> </div> </a-form-item-rest> </div> </template> <script lang="ts"> import { defineComponent, watch, ref, reactive } from 'vue'; import AMapLoader from '@amap/amap-jsapi-loader'; import { shallowRef } from 'vue'; export default defineComponent({ name: 'NsGMap', props: { titleName: { type: String, default: '位置信息', }, longitude: { type: String, default: '', }, latitude: { type: String, default: '', }, defaultAddress: { type: String, default: '', }, value: { type: [Object, String], }, longLat: { type: Object, }, }, emits: ['change', 'updata:longLat'], setup(props, context) { const map = shallowRef(null); return { map, }; }, data() { return { address: '', longitude1: '', latitude1: '', longLatTudeobj: { longitude: '', latitude: '', }, localSearch: '', geoc: '', initMarker: '', AMap: {}, isShowResult: false, // map: '', }; }, watch: { defaultAddress: { handler(val) { if (this.longitude && this.latitude) { this.address = val; } }, immediate: true, // deep: true, }, address(val) { if (val) { this.address = val; this.$emit('change', [ this.longLatTudeobj.latitude, this.longLatTudeobj.longitude, this.address, ]); } }, longitude1(val) { this.longLatTudeobj.longitude = val; if (val) this.$emit('change', [ this.longLatTudeobj.latitude, this.longLatTudeobj.longitude, this.address, ]); // this.$emit('updata:longLat', this.longLatTudeobj); }, latitude1(val) { this.longLatTudeobj.latitude = val; if (val) this.$emit('change', [ this.longLatTudeobj.latitude, this.longLatTudeobj.longitude, this.address, ]); }, }, created() { if (this.longitude) { this.longitude1 = this.longitude; this.latitude1 = this.latitude; } else { // this.onSearch(); } if (this.localSearch) { console.log('mapClear'); this.localSearch.render.markerList.clear(); } }, mounted() { // this.map = new AMap.Map('map-container', { // // center: [117.000923, 36.675807], // resizeEnable: true, // zoom: 12, // }); // this.geoc = new AMap.Geocoder({ // city: '021', // }); this.initMap(); }, beforeUnmount() { this.map && this.map.destroy(); this.isShowResult = false; }, // https://webapi.amap.com/maps?v=1.4.15&key=&plugin=& methods: { // clear() { // console.log('mapClear'); // // this.localSearch.render.markerList.clear(); // this.map && this.map.destroy(); // this.isShowResult = false; // }, initMap() { AMapLoader.reset(); AMapLoader.load({ key: '2694972059c3b978de5d7e073efdfc64', // 申请好的Web端开发者Key,首次调用 load 时必填 version: '1.4.15', plugins: ['AMap.Geocoder', 'AMap.PlaceSearch', 'AMap.ToolBar'], }) .then((AMap) => { // 需要传入AMap ,否则方法无法调用 this.loadMap(AMap); this.AMap = AMap; }) .catch((e) => { console.log(e); }); }, loadMap(AMap) { this.map = new AMap.Map('map-container', { // center: [117.000923, 36.675807], resizeEnable: true, zoom: 12, }); this.geoc = new AMap.Geocoder({ city: '021', }); // 初始化地图,设置城市和地图级别。 // if (this.address) { // this.map.centerAndZoom(this.address, 11); // } if (this.longitude1 && this.latitude1) { let position = [this.longitude1, this.latitude1]; const marker = new AMap.Marker({ position: [this.longitude1, this.latitude1], offset: new AMap.Pixel(-13, -30), map: this.map, }); this.initMarker = marker; //不允许默认执行逆地理编码,消耗调用次数,地址信息需要后端存储 // this.geoc.getAddress(position, (status, result) => { // if (status == 'complete' && result.info == 'OK') { // const addComp = result['regeocode']['addressComponent']; // thisObj.address = // addComp.province + // addComp.city + // addComp.district + // addComp.street + // addComp.streetNumber; // this.address = thisObj.address; // } // }); this.map.add(marker); this.map.setFitView(marker); if (AMap.event) { // 标记物点击事件 AMap.event.addListener(marker, 'click', function (e) { // console.log('点击标记物'); // console.log(e); // thisObj.resultPanelClick(e['data']); }); } } const thisObj = this; // AMap.service(['AMap.PlaceSearch'], function () { // 回调函数 // 实例化PlaceSearch thisObj.localSearch = new AMap.PlaceSearch({ pageSize: 5, // 每页显示多少行 pageIndex: 1, // 显示的下标从那个开始 type: '', // 类别,可以以|后面加其他类 city: '021', // map: thisObj.map, // 显示地图 panel: 'map-result', // 服务显示 的面板 autoFitView: true, }); // }); if (AMap.event) { // 搜索结果列表的点标记 AMap.event.addListener(thisObj.localSearch, 'listElementClick', (e) => { thisObj.resultPanelClick(e['data']); let ve = this.map.getAllOverlays('marker'); this.map.remove(ve); const location = e['data']['location']; // 当前点击marker的经纬度信息 this.longitude1 = location['lng'].toFixed(6); this.latitude1 = location['lat'].toFixed(6); let marker = new this.AMap.Marker({ position: [this.longitude1, this.latitude1], map: this.map, }); this.initMarker = marker; this.map.add(marker); this.map.setFitView(); }); // 标记物点击 AMap.event.addListener(thisObj.localSearch, 'markerClick', function (e) { // console.log('搜索结果标记物点击'); thisObj.resultPanelClick(e['data']); }); } // 地图点击事件 this.map.on('click', (e) => { thisObj.getLatitudeAndLongitude(e); }); // 如果默认地址 // if (this.data['address']) { // this.address = this.data['address']; // this.localSearch.search(this.address); // } }, resultPanelClick(data) { if (data && data['location']) { if (data['location']) { const location = data['location']; // 当前marker的经纬度信息 this.longitude1 = location['lng'].toFixed(6); this.latitude1 = location['lat'].toFixed(6); } if (data['address']) { this.address = data['address']; } } }, getLatitudeAndLongitude(event) { if (event) { // 清除搜索标记 // if (this.localSearch && this.localSearch['render']) { // this.localSearch.render.markerList.clear(); // } // 清除初始化标记 if (this.initMarker) { this.map.remove(this.initMarker); } this.map.clearMap(); // 获取当前点击点的经纬度和地址信息 this.longitude1 = event.lnglat['lng'].toFixed(6); this.latitude1 = event.lnglat['lat'].toFixed(6); const thisObj = this; this.geoc.getAddress(event.lnglat, function (status, result) { if (status == 'complete' && result.info == 'OK') { const addComp = result['regeocode']['addressComponent']; thisObj.address = result['regeocode']['formattedAddress']; } }); // 点击地图上标记物之外的点 let marker = new this.AMap.Marker({ position: [this.longitude1, this.latitude1], // offset: new AMap.Pixel(-13, -30), map: this.map, }); this.initMarker = marker; this.map.add(marker); this.map.setFitView(); // 创建信息窗口 // const infoWindow = new AMap.InfoWindow({ // // isCustom: true, //使用自定义窗体 // content: '信息的html代码字符串', // offset: new AMap.Pixel(-15, -25) // }); // infoWindow.open(this.map, marker.getPosition()); } }, onSearch() { this.isShowResult = true; // console.log(this.address); const _this = this; // 清除点击的标记物 // if (this.initMarker) { // this.map.remove(this.initMarker); // } this.map.clearMap(); // 搜索 if (!this.localSearch) return; this.localSearch.search(this.address, (status, result) => { if (status == 'complete' && result.info == 'OK') { const resultPoi = result['poiList']['pois']; if (resultPoi && resultPoi instanceof Array && resultPoi.length > 0) { const firstPo = resultPoi[0]; // 搜索后默认选中第一个点 // this.resultArr = []; const pois = result.poiList.pois; // console.log(pois[0].location.lng, pois[1].location.lat); _this.longitude1 = pois[0].location.lng; _this.latitude1 = pois[1].location.lat; for (let i = 0; i < pois.length; i++) { const poi = pois[i]; const marker = []; marker[i] = new AMap.Marker({ position: poi.location, // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9] title: poi.name, }); // 将创建的点标记添加到已有的地图实例: // this.resultArr.push(marker[i]); this.map.add(marker[i]); } this.map.setFitView(); } } else { } }); // this.$emit('change', obj); // this.$emit('updata:longLat', obj); }, inputChange(val, e) { this.$emit('change', [ this.longLatTudeobj.latitude, this.longLatTudeobj.longitude, this.address, ]); // this.$emit('updata:longLat', this.longLatTudeobj); }, }, }); </script> <style lang="less" scoped> input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; } #map-container { height: 400px; } .leftBox, .rightBox { flex: 1; } .inputArea { display: flex; line-height: 30px; } .inputSearch { .inputAdress { width: 344px; margin-right: 10px; } } </style>