<template> <div style="display: flex"> <a-form-item-rest> <div class="rightBox"> <div class="inputArea"> <div style="margin-right: 10px">经度</div> <div class="lng"> <ns-input v-model:value="lng" type="number" class="input" placeholder="请输入经度" @change="inputChange('lng', $event)" /> </div ><div style="margin: 0 10px">纬度</div> <div class="lat"> <ns-input v-model:value="lat" type="number" class="input" placeholder="请输入纬度" @change="inputChange('lat', $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" style="width: 100%"></div> </div> <div id="resultDiv" class="result" v-if="resultList.length"> <div class="title">搜索结果:</div> <ul class="resultList"> <li v-for="(item, index) in resultList" :key="item['hotPointID']" @click="clickItem(item)"> <a-row> <a-col style="width: 40px; display: flex; align-items: center"> <EnvironmentTwoTone :twoToneColor="item['hotPointID'] === checkedItem ? 'red' : ''" :style="{ fontSize: '22px', }" /></a-col> <a-col :span="20"> <p>{{ item.name }}</p> <p>地址: {{ item.address }}</p ><p v-if="item.phone">电话: {{ item.phone }}</p></a-col > </a-row> <a-divider /> </li> </ul> <!-- <ul> <li v-for="(item, index) in resultList" :key="index"> <a @click="clickItem(item)">{{ index + 1 + '-' + item.name }}</a> </li> </ul> --> <a-pagination size="small" :total="total" @change="changeHandle" :show-total="(total) => ` 共 ${total} 个搜索结果`" /> </div> </div> </a-form-item-rest> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { Pagination } from 'ant-design-vue'; import pointTransfer from './transfer'; import { EnvironmentTwoTone } from '@ant-design/icons-vue'; export default defineComponent({ name: 'NsTMap', components: { 'a-pagination': Pagination, EnvironmentTwoTone, }, props: { // 中心点坐标 centerPoint: { type: Array, }, // 纬度 longitude: { type: String, default: '', }, // 经度 latitude: { type: String, default: '', }, defaultAddress: { type: String, default: '', }, toPoint: { type: String, default: 'WGS84', }, fromPoint: { type: String, default: 'GCJ02', }, }, emits: ['change'], data() { return { T: '', zoom: 12, lng: '', lat: '', address: '', resultList: [], total: 0, page: 1, checkedItem: '', }; }, watch: { longitude: { handler(val) { if (this.longitude && this.latitude) { let point = pointTransfer( [this.longitude, this.latitude], this.fromPoint, this.toPoint, ); this.lng = point[0].toFixed(8); this.lat = point[1].toFixed(8); this.$nextTick(() => { // this.address = this.getAddress(this.T.LngLat(this.lng, this.lat)); let marker = new this.T.Marker(new this.T.LngLat(this.lng, this.lat)); this.map.addOverLay(marker); this.map.centerAndZoom(new this.T.LngLat(this.lng, this.lat), 16); this.$emit('change', [this.latitude, this.longitude, this.address]); }); } }, immediate: true, deep: true, }, latitude: { handler(val) { if (this.longitude && this.latitude) { let point = pointTransfer( [this.longitude, this.latitude], this.fromPoint, this.toPoint, ); this.lng = point[0].toFixed(8); this.lat = point[1].toFixed(8); this.$nextTick(() => { // this.address = this.getAddress(this.T.LngLat(this.lng, this.lat)); let marker = new this.T.Marker(new this.T.LngLat(this.lng, this.lat)); this.map.addOverLay(marker); this.map.centerAndZoom(new this.T.LngLat(this.lng, this.lat), 16); this.$emit('change', [this.latitude, this.longitude, this.address]); }); } }, immediate: true, deep: true, }, address(val) { if (val) { this.address = val; this.$emit('change', [this.lat, this.lng, this.address]); } }, defaultAddress: { handler(val) { if (this.longitude && this.latitude) { this.address = val; // let point = pointTransfer( // [this.longitude, this.latitude], // this.fromPoint, // this.toPoint, // ); // this.lng = point[0].toFixed(8); // this.lat = point[1].toFixed(8); // this.$nextTick(() => { // this.address = this.getAddress(this.T.LngLat(this.lng, this.lat)); // let marker = new this.T.Marker(new this.T.LngLat(this.lng, this.lat)); // this.map.addOverLay(marker); // this.map.centerAndZoom(new this.T.LngLat(this.lng, this.lat), 16); // this.$emit('change', [this.latitude, this.longitude, this.address]); // }); } }, immediate: true, // deep: true, }, }, mounted() { this.init(); this.map = new this.T.Map('map-container'); if (this.centerPoint) { this.map.centerAndZoom(new this.T.LngLat(this.centerPoint.join()), this.zoom); } else { this.map.centerAndZoom(new this.T.LngLat(118.433065, 31.352625), this.zoom); } // let cp = new this.T.CoordinatePickup(this.map, { callback: this.getLngLat }); let geocode: any = new this.T.Geocoder(); this.map.addEventListener('click', (e) => { geocode.getLocation(e.lnglat, (result: Recordable) => { this.address = result.getAddress(); this.getLngLat(e.lnglat); }); }); // cp.addEvent(); }, methods: { init() { // const script = document.createElement('script'); // script.type = 'text/javascript'; // script.src = 'http://api.tianditu.gov.cn/api?v=4.0&tk=b5311fc44ebe2d76a7738ae3b351fe28'; // document.body.appendChild(script); if (typeof window.T !== 'undefined') { console.log('初始化资源成功'); this.T = window.T; } else { console.log('初始化资源失败,查看项目index.html是否引用天地图'); } }, async getLngLat(lnglat) { let that = this; // await this.getAddress(lnglat); this.map.clearOverLays(); let marker = new this.T.Marker(new this.T.LngLat(lnglat.lng, lnglat.lat)); this.map.addOverLay(marker); this.map.centerAndZoom(new this.T.LngLat(lnglat.lng, lnglat.lat), 16); let point = pointTransfer([lnglat.lng, lnglat.lat], this.toPoint, this.fromPoint); this.lng = point[0].toFixed(8); this.lat = point[1].toFixed(8); this.$emit('change', [point[1].toFixed(8), point[0].toFixed(8), this.address]); }, async getAddress(lnglat) { let that = this; this.geocode = new this.T.Geocoder(); return await this.geocode.getLocation(lnglat, function (result) { that.address = result.getAddress(); }); }, onSearch() { console.log(this.address); this.map.clearOverLays(); let config = { // pageCapacity: 10, onSearchComplete: this.loaclSearchResult, }; this.localsearch = new this.T.LocalSearch(this.map, config); this.localsearch.search(this.address); }, loaclSearchResult(result) { // let that = this; this.resultList = result.getPois(); this.total = result.getCount(); if (this.resultList.length > 0) { let first = this.resultList[0]; let lonlat = first.lonlat.split(','); this.map.centerAndZoom(new this.T.LngLat(lonlat[0], lonlat[1]), 16); for (let i = 0; i < this.resultList.length; i++) { const item = this.resultList[i]; let lonlat = item.lonlat.split(','); let marker = new this.T.Marker(new this.T.LngLat(lonlat[0], lonlat[1])); marker['otherData'] = item; marker.addEventListener('click', (e) => { this.lng = e.lnglat.lng; this.lat = e.lnglat.lat; if (e.target['otherData']) { this.checkedItem = e.target['otherData']['hotPointID']; } this.getAddress(e.lnglat); this.map.centerAndZoom(new this.T.LngLat(e.lnglat.lng, e.lnglat.lat), 16); let point = pointTransfer([this.lng, this.lat], this.toPoint, this.fromPoint); this.$emit('change', [point[1].toFixed(8), point[0].toFixed(8), this.address]); }); this.map.addOverLay(marker); } } }, changeHandle(page) { this.map.clearOverLays(); if (this.page < page) { this.localsearch.nextPage(); } else { this.localsearch.previousPage(); } this.page = page; }, clickItem(item) { let lonlat = item.lonlat.split(','); this.checkedItem = item['hotPointID']; this.lng = lonlat[0]; this.lat = lonlat[1]; this.address = item.address + item.name; this.map.centerAndZoom(new this.T.LngLat(lonlat[0], lonlat[1]), 16); let point = pointTransfer([this.lng, this.lat], this.toPoint, this.fromPoint); this.$emit('change', [point[1].toFixed(8), point[0].toFixed(8), this.address]); }, }, }); </script> <style lang="less" scoped> input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; } #map-container { width: 100%; height: 400px; } .leftBox, .rightBox { flex: 1; } .inputArea { display: flex; line-height: 30px; } .inputSearch { .inputAdress { width: 344px; margin-right: 10px; } } .resultList { p { margin-bottom: 0; } } #resultDiv { width: 100%; ul { list-style: none; padding-left: 0; li { cursor: pointer; } } } :deep(.ant-divider) { display: block !important; margin: 4px 0; } </style>