152 lines
4.5 KiB
Vue
152 lines
4.5 KiB
Vue
<template>
|
||
<el-dialog
|
||
class="map-dialog"
|
||
:style="{ width: '80%' }"
|
||
:modelValue="modelValue"
|
||
:show-close="true"
|
||
@update:model-value="emit('update:modelValue', $event)"
|
||
@open="open"
|
||
@close="close"
|
||
>
|
||
<template #header="{ titleId, titleClass }">
|
||
<div class="header">
|
||
<h4 :id="titleId" :class="titleClass">坐标拾取</h4>
|
||
<div class="search-container">
|
||
<div class="search-item">
|
||
<label class="search"
|
||
><span>请输入地址:</span>
|
||
<el-input id="map-input" v-model="address" />
|
||
<!-- <input id="input" type="text" /> -->
|
||
</label>
|
||
<!-- <el-button class="btn-search" type="primary">搜索</el-button> -->
|
||
</div>
|
||
<div class="search-item">
|
||
<label class="address"><span>地址:</span><el-input disabled :model-value="coordinateInfo.address" /></label>
|
||
<label class="lon"><span>经度:</span><el-input disabled :model-value="coordinateInfo.lng" /></label>
|
||
<label class="lat"><span>纬度:</span><el-input disabled :model-value="coordinateInfo.lat" /></label>
|
||
<el-button class="btn-submit" type="primary" @click="submit">提交</el-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<div id="map-container" class="map"></div>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ElMessage } from "element-plus";
|
||
import { ref, shallowRef, reactive, watch, onUnmounted } from "vue";
|
||
import initAMap from "./AMap";
|
||
|
||
const props = defineProps<{
|
||
modelValue: boolean;
|
||
defaultAddress?: {
|
||
lng: string;
|
||
lat: string;
|
||
address?: string;
|
||
};
|
||
}>();
|
||
|
||
const setCenter = val => {
|
||
coordinateInfo.address = val?.address || "";
|
||
coordinateInfo.lat = val?.lat || null;
|
||
coordinateInfo.lng = val?.lng || null;
|
||
|
||
if (coordinateInfo.lat) {
|
||
// console.log("eeeeeee", coordinateInfo);
|
||
map.value?.setCenter([+coordinateInfo.lng, +coordinateInfo.lat]);
|
||
map.value?.add(new AMap.Marker({ position: new AMap.LngLat(+val.lng, +val.lat) }));
|
||
}
|
||
};
|
||
|
||
watch(() => props.defaultAddress, setCenter);
|
||
|
||
const emit = defineEmits<{
|
||
(e: "update:modelValue", data: boolean): void;
|
||
(e: "getAddress", data: typeof coordinateInfo): void;
|
||
}>();
|
||
|
||
const address = ref("");
|
||
const coordinateInfo = reactive({ address: "", lng: "", lat: "" });
|
||
const map = shallowRef<AMap.Map>();
|
||
const search = shallowRef<any>();
|
||
const autocomplete = shallowRef<any>();
|
||
|
||
const open = async () => {
|
||
const AMap = await initAMap();
|
||
|
||
// 地图加载与点击
|
||
map.value = new AMap.Map("map-container", { zoom: 8, resizeEnable: true });
|
||
|
||
map.value?.on("complete", e => {
|
||
setCenter(props.defaultAddress);
|
||
});
|
||
|
||
// map.value?.on('')
|
||
|
||
map.value?.on("click", e => {
|
||
map.value?.clearMap();
|
||
map.value?.add(new AMap.Marker({ position: e.lnglat }));
|
||
|
||
map.value?.setCenter(e.lnglat);
|
||
coordinateInfo.lng = e.lnglat.getLng();
|
||
coordinateInfo.lat = e.lnglat.getLat();
|
||
const geocoder = new AMap.Geocoder();
|
||
geocoder.getAddress(e.lnglat, (status: string, result: any) => {
|
||
if (status === "complete" && result.info === "OK") {
|
||
const regeocode = result.regeocode;
|
||
coordinateInfo.address = regeocode.formattedAddress;
|
||
}
|
||
});
|
||
});
|
||
|
||
// 联想输入与 POI 搜索
|
||
autocomplete.value = new AMap.AutoComplete({ input: "map-input" });
|
||
search.value = new AMap.PlaceSearch({ map: map.value, extensions: "base" });
|
||
autocomplete.value?.on("select", (e: any) => {
|
||
map.value?.clearMap();
|
||
if (e.poi.location) {
|
||
coordinateInfo.lng = e.poi.location.lng;
|
||
coordinateInfo.lat = e.poi.location.lat;
|
||
map.value?.add(new AMap.Marker({ position: e.poi.location }));
|
||
} else {
|
||
const geocoder = new AMap.Geocoder({ city: e.adcode });
|
||
geocoder.getLocation(e.poi.name, (status: string, result: any) => {
|
||
if (status === "complete" && result.info === "OK") {
|
||
const data = result.geocodes;
|
||
if (data.length > 1) ElMessage.success("检索到多个结果,已为您定位到第一个地址");
|
||
coordinateInfo.lng = data[0].location.lng;
|
||
coordinateInfo.lat = data[0].location.lat;
|
||
map.value?.add(new AMap.Marker({ position: data[0].location }));
|
||
}
|
||
});
|
||
}
|
||
coordinateInfo.address = e.poi.district;
|
||
search.value.setCity(e.poi.adcode);
|
||
search.value.search(e.poi.name);
|
||
});
|
||
};
|
||
|
||
const submit = () => {
|
||
if (coordinateInfo.address && coordinateInfo.lng && coordinateInfo.lat) {
|
||
emit("getAddress", coordinateInfo);
|
||
}
|
||
};
|
||
|
||
const close = () => {
|
||
address.value = "";
|
||
coordinateInfo.address = "";
|
||
coordinateInfo.lng = "";
|
||
coordinateInfo.lat = "";
|
||
};
|
||
|
||
onUnmounted(() => {
|
||
map.value?.destroy();
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import "./AMap.scss";
|
||
</style>
|