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