You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
409 lines
13 KiB
409 lines
13 KiB
<!-- @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>
|
|
|