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.

434 lines
13 KiB

7 months ago
<!-- @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" style="width: 600px"></div>
<div v-if="isShowResult" id="map-result" style="width: 600px; overflow: auto"></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/reactivity';
export default defineComponent({
name: 'NsMap',
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: {
// value(val) {
// if (val.latitude) {
// this.longitude1 = val.longitude;
// this.latitude1 = val.latitude;
// this.longLatTudeobj.latitude = val.latitude;
// this.longLatTudeobj.longitude = val.longitude;
// this.initMap();
// }
// // if (val) {
// // console.log('value', val);
// // // this.$emit('change', [
// // // this.longLatTudeobj.latitude,
// // // this.longLatTudeobj.longitude,
// // // this.address,
// // // ]);
// // this.initMap();
// // }
// // this.$emit('change', [
// // this.longLatTudeobj.latitude,
// // this.longLatTudeobj.longitude,
// // this.address,
// // ]);
// },
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,
]);
},
defaultAddress: {
handler(val) {
if (this.longitude && this.latitude) {
this.address = val;
}
},
immediate: true,
// deep: true,
},
},
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();
}
// this.onSearch();
// this.longitude1 = this.longLat.longitude;
// this.latitude1 = this.longLat.latitude;
// console.log(this.longitude1);
},
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']);
});
// 标记物点击
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 =
addComp.province +
addComp.city +
addComp.district +
addComp.street +
addComp.streetNumber;
}
});
// 点击地图上标记物之外的点
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) {
let value = e.target.value;
console.log(this.longitude1, this.latitude1, this.address);
console.log(value);
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 {
width: 600px;
height: 400px;
}
.leftBox,
.rightBox {
flex: 1;
}
.inputArea {
display: flex;
line-height: 30px;
}
.inputSearch {
.inputAdress {
width: 344px;
margin-right: 10px;
}
}
</style>