Browse Source

feat: 图层查询

feature-v1.0.0
邱伟洋 1 month ago
parent
commit
8cce3a75f0
  1. 65
      src/api/map/index.ts
  2. BIN
      src/assets/card/no-data.png
  3. 3
      src/components.d.ts
  4. 20
      src/theme/popover.scss
  5. 136
      src/views/Main/MapSearch/index.vue

65
src/api/map/index.ts

@ -1,27 +1,26 @@
import { request } from '../axios'; import { request } from "../axios";
import axios from 'axios'; import axios from "axios";
// 获取场景列表 // 获取场景列表
export const getSceneListData = async (data: any) => { export const getSceneListData = async (data: any) => {
return request({ return request({
url: `/map/scene/sceneList`, url: `/map/scene/sceneList`,
method: 'post', method: "post",
data: { data: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
data: { data: {
id: '', id: "",
name: data.name name: data.name,
}, },
params: { params: {
order: 'asc', order: "asc",
orderBy: 'pub_date' orderBy: "pub_date",
} },
} },
}); });
}; };
export const getLayerLegend = async (url: string) => { export const getLayerLegend = async (url: string) => {
return axios.get(url); return axios.get(url);
}; };
@ -30,10 +29,48 @@ export const getLayerLegend = async (url: string) => {
export const getLayerData = async (url: string, params: any) => { export const getLayerData = async (url: string, params: any) => {
return request({ return request({
url, url,
method: 'post', method: "post",
data: params, data: params,
headers: { headers: {
'Content-Type': 'multipart/form-data' "Content-Type": "multipart/form-data",
} },
}); });
}; };
//从水库-水库点图层中,根据水库名称/水平编码,从geojson中查询水库列表
export const getReservoirList = async (layerData: any, searchName: string) => {
const attributeFilter = searchName
? `RES_NAME LIKE '%${searchName}%' OR RES_CODE LIKE '%${searchName}%'`
: "1=1";
//
const { url } = layerData;
let newUrl = decodeURI(url).split("maps/")[0].replace("map-", "data-");
const reg2 = /([^/]+)$/;
const decodeUrl: any = decodeURI(url);
const newLayerName: any = decodeUrl?.match?.(reg2)?.[1];
const l = newLayerName?.split("%40");
const datasourceName = `${l?.[1]}:${l?.[0]}`;
let queryUrl = `${newUrl}data/featureResults.geojson?returnContent=true`;
const result = await axios.post(
queryUrl,
JSON.stringify({
getFeatureMode: "SQL",
datasetNames: [datasourceName],
maxFeatures: 100,
queryParameter: {
attributeFilter: attributeFilter,
},
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
},
}
);
if (result?.data?.features?.length > 0) {
return result.data;
}
return {
type: "FeatureCollection",
features: [],
};
};

BIN
src/assets/card/no-data.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

3
src/components.d.ts

@ -28,4 +28,7 @@ declare module 'vue' {
UploadImage: typeof import('./components/Upload/UploadImage.vue')['default'] UploadImage: typeof import('./components/Upload/UploadImage.vue')['default']
Video: typeof import('./components/Video/index.vue')['default'] Video: typeof import('./components/Video/index.vue')['default']
} }
export interface ComponentCustomProperties {
vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll']
}
} }

20
src/theme/popover.scss

@ -47,6 +47,7 @@
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
padding-bottom: 16px; padding-bottom: 16px;
cursor: pointer;
.title { .title {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -70,7 +71,6 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 1px 12px; padding: 1px 12px;
width: 48px;
height: 20px; height: 20px;
border-radius: 2px; border-radius: 2px;
@ -106,6 +106,10 @@
font-feature-settings: "kern" on; font-feature-settings: "kern" on;
/* 文字&图标/Font Gy2 */ /* 文字&图标/Font Gy2 */
color: rgba(0, 0, 0, 0.6); color: rgba(0, 0, 0, 0.6);
max-width: 240px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
i { i {
background: #36b29e; background: #36b29e;
width: 8px; width: 8px;
@ -117,6 +121,20 @@
border-bottom: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.1);
} }
} }
&.no-data {
align-items: center;
justify-content: center;
font-family: Source Han Sans;
font-size: 12px;
font-weight: 350;
line-height: 18px;
letter-spacing: 0em;
font-variation-settings: "opsz" auto;
/* 文字&图标/Font Gy2 */
color: rgba(0, 0, 0, 0.6);
}
} }
} }
} }

136
src/views/Main/MapSearch/index.vue

@ -3,63 +3,113 @@
<span class="map-search-icon"> <span class="map-search-icon">
<iconpark-icon name="search" size="16" fill="#fff"></iconpark-icon> <iconpark-icon name="search" size="16" fill="#fff"></iconpark-icon>
</span> </span>
<el-popover <div v-click-outside="onClickOutside">
placement="bottom" <el-popover
:width="280" placement="bottom"
trigger="click" :width="280"
popper-class="map-search-popper" :visible="popoverVisible"
> popper-class="map-search-popper"
<template #reference> >
<el-input <template #reference>
class="map-search-input" <el-input
placeholder="输入水库名称、水库编码" class="map-search-input"
v-model="searchValue" placeholder="输入水库名称、水库编码"
@change="changeInputValue" v-model="searchValue"
></el-input> @input="changeInputValue"
</template> ></el-input>
<template #default> </template>
<div class="map-search-result"> <template #default>
<div class="map-search-result-title"> <div class="map-search-result">
共搜索到<span>{{ searchResultList.length }}</span <div class="map-search-result-title">
>条结果 共搜索到<span>{{ searchResultList.length }}</span
</div> >条结果
<div class="map-search-result-list"> </div>
<div <div
class="map-search-result-list-item" v-if="searchResultList.length > 0"
v-for="(item, index) in searchResultList" class="map-search-result-list"
:key="index"
> >
<div class="title"> <div
<span class="name">{{ item.name }}</span> class="map-search-result-list-item"
<span class="tag">{{ item.level }}</span> v-for="(item, index) in searchResultList"
:key="index"
@click.stop="flyTo(item)"
>
<div class="title">
<span class="name">{{ item?.properties?.RES_NAME }}</span>
<span class="tag">{{ item?.properties?.ENG_SCAL }}</span>
</div>
<div class="item">
<i></i>工程代码{{ item?.properties?.RES_CODE }}
</div>
<div class="item">
<i></i>工程类型{{ item?.properties?.RES_TYPE }}
</div>
<div class="item">
<i></i>工程地址{{ item?.properties?.RES_LOC }}
</div>
</div> </div>
<div class="item"><i></i>工程代码{{ item.code }}</div> </div>
<div class="item"><i></i>工程类型{{ item.type }}</div> <div v-else class="map-search-result-list no-data">
<div class="item"><i></i>工程地址{{ item.address }}</div> <img src="@/assets/card/no-data.png" />
<span>暂无结果</span>
</div> </div>
</div> </div>
</div> </template>
</template> </el-popover>
</el-popover> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref, computed } from "vue";
import { getReservoirList } from "@/api/map";
import { useProjectStore } from "@/store/modules/project";
import { ClickOutside as vClickOutside } from "element-plus";
import * as SyCim from "sy-cesium-sdk";
defineOptions({ defineOptions({
name: "MapSearch", name: "MapSearch",
}); });
const Cesium = SyCim.Cesium;
const projectStore = useProjectStore();
const popoverVisible = ref(false);
const showPopover = () => {
popoverVisible.value = true;
};
const onClickOutside = () => {
popoverVisible.value = false;
};
const searchValue = ref(""); const searchValue = ref("");
const searchResultList = ref( const searchResultList = ref<any[]>([]);
new Array(10).fill({ const layerData = computed(() =>
name: "白头岗水库", projectStore.selectedLayers.find((f: any) => f.nameCn === "水库点")
level: 1,
code: "12300000000000",
address: "广州市增城区新塘县",
type: "xxx",
})
); );
const changeInputValue = (value: string) => {}; const changeInputValue = async (value: string) => {
const searchStr = (value ?? "").trim();
if (!layerData.value) return;
if (!searchStr) {
searchResultList.value = [];
return;
}
showPopover();
const data = await getReservoirList(layerData.value, searchStr);
searchResultList.value = data?.features ?? [];
};
const flyTo = (item: any) => {
const coordinates = item?.geometry?.coordinates;
if (!coordinates) return;
const center = SyCim.Parse.parsePosition(
`${coordinates[0]},${coordinates[1]},10`
).toCartesian3();
const boundingSphere = new Cesium.BoundingSphere(center, 100);
viewer.camera.flyToBoundingSphere(boundingSphere, {
offset: new Cesium.HeadingPitchRange(
viewer.camera.heading,
viewer.camera.pitch,
500
),
duration: 2,
});
};
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

Loading…
Cancel
Save