|
@@ -2,19 +2,33 @@
|
|
|
<div class="menu-content">
|
|
|
<div class="gradient-text title">定点分析</div>
|
|
|
<div class="scroll-box">
|
|
|
- <div v-if="!tempState.address" class="search-box">
|
|
|
- <div class="text-box">
|
|
|
+ <div class="search-box">
|
|
|
+ <di class="text-box">
|
|
|
<i class="icon-position2" />
|
|
|
- <div class="text1" :title="selectData.event_title">{{ selectData.event_title }}</div>
|
|
|
- </div>
|
|
|
- <div class="common-btn-primary3" @click="toSelect">定点选取</div>
|
|
|
+ <div class="text1" :title="tempState.address ? tempState.address : selectData.event_title">
|
|
|
+ {{ tempState.address ? tempState.address : selectData.event_title }}
|
|
|
+ </div>
|
|
|
+ </di>
|
|
|
+ <div v-if="tempState.address" class="common-btn-primary4" @click="confirmSelect">确定定位</div>
|
|
|
</div>
|
|
|
- <div v-else class="search-box">
|
|
|
- <div class="text-box">
|
|
|
- <i class="icon-position2" />
|
|
|
- <div class="text1" :title="tempState.address">{{ tempState.address }}</div>
|
|
|
+ <div ref="inputRef" class="search-item" style="position: relative">
|
|
|
+ <el-input v-model="inputText" class="custom-input2" placeholder="请输入地址或经纬度后回车搜索" @keyup.enter="handleSearch" />
|
|
|
+ <div v-if="searchPop" class="scroll_box" style="width: 1350px; height: 700px">
|
|
|
+ <div style="height: 60px; line-height: 60px">
|
|
|
+ <span style="font-weight: bold">搜索结果列表</span>
|
|
|
+ <i class="el-icon-close" style="float: right; font-size: 20px; cursor: pointer" @click="closeSearchList()" />
|
|
|
+ </div>
|
|
|
+ <el-scrollbar class="scroll" style="height: 600px">
|
|
|
+ <div v-for="(item, index) in searchList" v-show="searchList.length" :key="index" class="item" @click="handleSearchSelect(item)">
|
|
|
+ <div>
|
|
|
+ <div class="text">{{ item.name }}</div>
|
|
|
+ <div>{{ item.address }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-show="!searchList.length" class="empty" style="text-align: center">没有搜索到内容</div>
|
|
|
+ </el-scrollbar>
|
|
|
</div>
|
|
|
- <div class="common-btn-primary4" @click="confirmSelect">确定定位</div>
|
|
|
+ <div class="common-btn-primary4" @click="toSelect">地图选取</div>
|
|
|
</div>
|
|
|
<div class="search-item">
|
|
|
<div class="text1">选择救灾资源:</div>
|
|
@@ -111,6 +125,8 @@ import useMapStore from '@/store/modules/map';
|
|
|
import markImg from '@/assets/images/map/mark.png';
|
|
|
import startImg from '@/assets/images/map/start.png';
|
|
|
import endImg from '@/assets/images/map/end.png';
|
|
|
+import { showErrorMsg } from '@/utils/notification';
|
|
|
+import { onClickOutside } from '@vueuse/core';
|
|
|
|
|
|
interface Props {
|
|
|
location?: string | number[];
|
|
@@ -122,6 +138,7 @@ const getMap = inject('getMap');
|
|
|
const getMapUtils = inject('getMapUtils');
|
|
|
const mapStore = useMapStore();
|
|
|
const amapKey = 'e45d4caa2bef3c84714a2ed9b1e27d98';
|
|
|
+let inputRef = ref();
|
|
|
let showAddress = ref(true);
|
|
|
let routeData = ref([]);
|
|
|
let routeLine, startMarker, endMarker;
|
|
@@ -145,8 +162,11 @@ let queryParams = reactive({
|
|
|
keyword: '',
|
|
|
dataType: '2'
|
|
|
});
|
|
|
+let inputText = ref('');
|
|
|
let total = ref(0);
|
|
|
let dataList = ref([]);
|
|
|
+let searchList = ref([]);
|
|
|
+let searchPop = ref(false);
|
|
|
watch(
|
|
|
() => mapStore.mapLoaded,
|
|
|
(loaded) => {
|
|
@@ -159,6 +179,10 @@ watch(
|
|
|
immediate: true
|
|
|
}
|
|
|
);
|
|
|
+onClickOutside(inputRef, (event) => {
|
|
|
+ searchPop.value = false;
|
|
|
+ searchList.value = [];
|
|
|
+});
|
|
|
const toSelect = () => {
|
|
|
map.on('click', handleClickMap);
|
|
|
mapStore.setIsMapSelect(true);
|
|
@@ -463,6 +487,61 @@ const clearLine = () => {
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
+// 搜索地址或者经纬度
|
|
|
+const handleSearch = () => {
|
|
|
+ const value = inputText.value.trim();
|
|
|
+ // 1. 检测是否为经纬度格式
|
|
|
+ const isCoordinate = /^\s*[-+]?\d{1,3}(\.\d+)?\s*[,,]\s*[-+]?\d{1,3}(\.\d+)?\s*$/.test(value);
|
|
|
+
|
|
|
+ if (isCoordinate) {
|
|
|
+ // 2. 分割并验证经纬度范围
|
|
|
+ const parts = value.split(/[,,]/);
|
|
|
+ if (parts.length !== 2) {
|
|
|
+ handleAddress(value);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const lng = parseFloat(parts[0]);
|
|
|
+ const lat = parseFloat(parts[1]);
|
|
|
+
|
|
|
+ if (lng < -180 || lng > 180 || lat < -90 || lat > 90) {
|
|
|
+ showErrorMsg('请输入合法的坐标');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ handleCoordinate([lng, lat]); // 处理经纬度逻辑
|
|
|
+ } else {
|
|
|
+ handleAddress(value); // 处理地址逻辑
|
|
|
+ }
|
|
|
+};
|
|
|
+const handleCoordinate = (lnglat) => {
|
|
|
+ const newMap = mapStore.isAMap ? map : map.getView();
|
|
|
+ newMap.setCenter(lnglat);
|
|
|
+ getAddress(lnglat);
|
|
|
+};
|
|
|
+
|
|
|
+const handleAddress = async (value) => {
|
|
|
+ const url = `https://restapi.amap.com/v5/place/text?key=${amapKey}&keywords=${value}`;
|
|
|
+ const response = await fetch(url);
|
|
|
+ const result = await response.json();
|
|
|
+ searchList.value = result.pois;
|
|
|
+ searchPop.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+const handleSearchSelect = (item) => {
|
|
|
+ const newMap = mapStore.isAMap ? map : map.getView();
|
|
|
+ const location = item.location.split(',');
|
|
|
+ newMap.setCenter(location);
|
|
|
+ const gcj02Coord = gcoord.transform(location, gcoord.WGS84, gcoord.GCJ02);
|
|
|
+ createMarks({ longitude: gcj02Coord[0], latitude: gcj02Coord[1] }, true);
|
|
|
+ tempState.address = item.address;
|
|
|
+};
|
|
|
+
|
|
|
+const closeSearchList = () => {
|
|
|
+ searchPop.value = false;
|
|
|
+ searchList.value = [];
|
|
|
+};
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
if (mapStore.isAMap) {
|
|
|
AMap = mapUtils.getAMap();
|
|
@@ -758,4 +837,40 @@ onMounted(() => {
|
|
|
top: 30px;
|
|
|
left: 140px;
|
|
|
}
|
|
|
+.scroll_box {
|
|
|
+ width: calc(100% - 165px);
|
|
|
+ background: #0a2c5c;
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 120px;
|
|
|
+ z-index: 9;
|
|
|
+ padding: 20px;
|
|
|
+ border-radius: 3px;
|
|
|
+ .close {
|
|
|
+ position: absolute;
|
|
|
+ right: 10px;
|
|
|
+ top: 10px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 40px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.scroll {
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ .item {
|
|
|
+ display: flex;
|
|
|
+ font-size: 32px;
|
|
|
+ cursor: pointer;
|
|
|
+ padding: 8px;
|
|
|
+ border-bottom: 1px solid #4574d5;
|
|
|
+ &:hover {
|
|
|
+ background-color: #102e76;
|
|
|
+ }
|
|
|
+
|
|
|
+ .text {
|
|
|
+ font-size: 36px;
|
|
|
+ margin-bottom: 6px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|