2023-09-06 19:08:55 +08:00

152 lines
4.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>