142 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Vue
		
	
	
		
		
			
		
	
	
			142 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Vue
		
	
	
|  | <template> | ||
|  |   <el-dialog v-model="visible" title="坐标"> | ||
|  |     <el-form label-position="right" label-width="100px"> | ||
|  |       <el-row> | ||
|  |         <el-col :span="12"> | ||
|  |           <el-form-item label="关键字搜索"> | ||
|  |             <el-input v-model="localSearch" clearable /> | ||
|  |           </el-form-item> | ||
|  |         </el-col> | ||
|  |         <el-col :span="12"> | ||
|  |           <el-form-item label-width="10px"> | ||
|  |             <el-button type="primary" @click="fnLocalSearch">搜索</el-button> | ||
|  |           </el-form-item> | ||
|  |         </el-col> | ||
|  |       </el-row> | ||
|  |       <el-row> | ||
|  |         <el-col :span="12"> | ||
|  |           <el-form-item label="坐标:"> | ||
|  |             <el-input disabled :model-value="currentLongitude || longitude" /> | ||
|  |           </el-form-item> | ||
|  |         </el-col> | ||
|  |         <el-col :span="12"> | ||
|  |           <el-form-item label-width="10px"> | ||
|  |             <el-input disabled :model-value="currentLatitude || latitude" /> | ||
|  |           </el-form-item> | ||
|  |         </el-col> | ||
|  |       </el-row> | ||
|  |     </el-form> | ||
|  |     <div | ||
|  |       v-loading="loading" | ||
|  |       element-loading-text="地图正在加载中..." | ||
|  |       element-loading-background="rgba(0, 0, 0, 0.5)" | ||
|  |     > | ||
|  |       <div id="map_container" style="width: 100%; height: 500px" /> | ||
|  |     </div> | ||
|  |     <template #footer> | ||
|  |       <el-button @click="fnClose">关闭</el-button> | ||
|  |       <el-button type="primary" @click="fnConfirm"> 确定 </el-button> | ||
|  |     </template> | ||
|  |   </el-dialog> | ||
|  | </template> | ||
|  | 
 | ||
|  | <script setup> | ||
|  | import { nextTick, ref, watch } from "vue"; | ||
|  | import { ElDialog, ElForm, ElRow, ElCol, ElFormItem, ElInput, ElButton } from "element-plus"; | ||
|  | import "element-plus/es/components/dialog/style/css"; | ||
|  | import "element-plus/es/components/form/style/css"; | ||
|  | import "element-plus/es/components/row/style/css"; | ||
|  | import "element-plus/es/components/col/style/css"; | ||
|  | import "element-plus/es/components/form-item/style/css"; | ||
|  | import "element-plus/es/components/input/style/css"; | ||
|  | import "element-plus/es/components/button/style/css"; | ||
|  | 
 | ||
|  | defineOptions({ | ||
|  |   name: "AppMapSelector", | ||
|  | }); | ||
|  | let mapInstance; | ||
|  | const visible = defineModel("visible", { type: Boolean, required: true }); | ||
|  | const longitude = defineModel("longitude", { | ||
|  |   type: [Number, String], | ||
|  |   required: true, | ||
|  |   default: "", | ||
|  | }); | ||
|  | const latitude = defineModel("latitude", { | ||
|  |   type: [Number, String], | ||
|  |   required: true, | ||
|  |   default: "", | ||
|  | }); | ||
|  | const loading = ref(false); | ||
|  | const currentLongitude = ref(""); | ||
|  | const currentLatitude = ref(""); | ||
|  | const localSearch = ref(""); | ||
|  | const emits = defineEmits(["submit"]); | ||
|  | const fnMapInit = async () => { | ||
|  |   loading.value = true; | ||
|  |   await nextTick(); | ||
|  |   mapInstance = new window.BMapGL.Map("map_container"); | ||
|  |   mapInstance.centerAndZoom( | ||
|  |     new window.BMapGL.Point( | ||
|  |       longitude.value || "119.69457721306945", | ||
|  |       latitude.value || "39.940504336846665" | ||
|  |     ), | ||
|  |     16 | ||
|  |   ); | ||
|  |   mapInstance.enableScrollWheelZoom(true); | ||
|  |   loading.value = false; | ||
|  |   if (longitude.value && latitude.value) { | ||
|  |     const point = new window.BMapGL.Point(longitude.value, latitude.value); | ||
|  |     const marker = new window.BMapGL.Marker(point); | ||
|  |     mapInstance.addOverlay(marker); | ||
|  |   } | ||
|  |   mapInstance.addEventListener("click", function (event) { | ||
|  |     mapInstance.clearOverlays(); | ||
|  |     const point = new window.BMapGL.Point(event.latlng.lng, event.latlng.lat); | ||
|  |     const marker = new window.BMapGL.Marker(point); | ||
|  |     mapInstance.addOverlay(marker); | ||
|  |     currentLatitude.value = event.latlng.lat; | ||
|  |     currentLongitude.value = event.latlng.lng; | ||
|  |   }); | ||
|  | }; | ||
|  | const fnLocalSearch = () => { | ||
|  |   if (localSearch.value) { | ||
|  |     const local = new window.BMapGL.LocalSearch(mapInstance, { | ||
|  |       renderOptions: { map: mapInstance }, | ||
|  |     }); | ||
|  |     local.search(localSearch.value); | ||
|  |   } | ||
|  | }; | ||
|  | const fnClose = () => { | ||
|  |   if (mapInstance) { | ||
|  |     mapInstance.destroy(); | ||
|  |     mapInstance = null; | ||
|  |   } | ||
|  |   currentLatitude.value = ""; | ||
|  |   currentLongitude.value = ""; | ||
|  |   localSearch.value = ""; | ||
|  |   visible.value = false; | ||
|  | }; | ||
|  | const fnConfirm = () => { | ||
|  |   latitude.value = currentLatitude.value; | ||
|  |   longitude.value = currentLongitude.value; | ||
|  |   emits("submit", { | ||
|  |     latitude: latitude.value, | ||
|  |     longitude: longitude.value, | ||
|  |   }); | ||
|  |   fnClose(); | ||
|  | }; | ||
|  | watch( | ||
|  |   () => visible.value, | ||
|  |   (val) => { | ||
|  |     if (val && !mapInstance) { | ||
|  |       fnMapInit(); | ||
|  |     } | ||
|  |   }, | ||
|  |   { | ||
|  |     immediate: true, | ||
|  |   } | ||
|  | ); | ||
|  | </script> | ||
|  | 
 | ||
|  | <style scoped lang="scss"></style> |