16 changed files with 622 additions and 129 deletions
@ -0,0 +1,27 @@ |
|||
import { request } from '../axios'; |
|||
import axios from 'axios'; |
|||
|
|||
// 获取场景列表
|
|||
export const getSceneListData = async (data: any) => { |
|||
return request({ |
|||
url: `/map/scene/sceneList`, |
|||
method: 'post', |
|||
data: { |
|||
pageNum: 1, |
|||
pageSize: 10, |
|||
data: { |
|||
id: '', |
|||
name: data.name |
|||
}, |
|||
params: { |
|||
order: 'asc', |
|||
orderBy: 'pub_date' |
|||
} |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
|
|||
export const getLayerLegend = async (url: string) => { |
|||
return axios.get(url); |
|||
}; |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 373 B |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,245 @@ |
|||
|
|||
import { getLayerLegend } from "@/api/map"; |
|||
import axios from "axios"; |
|||
|
|||
const identifyLayerActions: any = { |
|||
"021102": async (params: any) => { |
|||
return new Promise(async (resolve, reject) => { |
|||
const { url, input_geometry, geometry_type, layers = "all", returnGeometry = false, tolerance = 1 } = params; |
|||
const result = await axios.get(`${url}.json`); |
|||
if (result.status === 200 && result.data) { |
|||
const { xmin, ymin, xmax, ymax } = result.data.fullExtent; |
|||
const mapExtent = `${xmin},${ymin},${xmax},${ymax}`; |
|||
const data = await axios.get( |
|||
`${url}/identify?geometry=${input_geometry}&geometryType=${geometry_type}&layers=${layers}&returnGeometry=${returnGeometry}&mapExtent=${mapExtent}&imageDisplay=600,550,96&tolerance=${tolerance}&out_fields=*&f=json`, |
|||
); |
|||
if (data.status === 200 && data.data) { |
|||
resolve(data.data); |
|||
} else { |
|||
resolve(null); |
|||
} |
|||
} |
|||
}); |
|||
}, |
|||
"030300": async (params: any) => { |
|||
console.log(params); |
|||
}, |
|||
"081100": async (params: any) => { |
|||
return new Promise(async (resolve, reject) => { |
|||
let { queryMode, bufferDistance, geometry, url, layerTable, layerName, k } = params; |
|||
// const queryUrl = url.split('maps/')[0].replace('map-', 'data-');
|
|||
let queryUrl = ""; |
|||
if (layerName.split(";").length == 1 && layerName.includes(":")) { |
|||
queryUrl = url.split("maps/")[0].replace("map-", "data-"); |
|||
} else if (layerName.split(";").length == 2 && layerName.includes(":")) { |
|||
let dataServiceLayerInfo = layerName.split(";"); |
|||
queryUrl = dataServiceLayerInfo[0] + "/"; |
|||
layerName = dataServiceLayerInfo[1]; |
|||
} |
|||
let requestUrl = `${queryUrl}data/featureResults.rjson?returnContent=true`; |
|||
if (k) { |
|||
requestUrl += `&k=${k}`; |
|||
} |
|||
const result = await axios.post( |
|||
requestUrl, |
|||
JSON.stringify({ |
|||
datasetNames: [layerTable || layerName], |
|||
getFeatureMode: queryMode, |
|||
bufferDistance, |
|||
geometry, |
|||
}), |
|||
{ |
|||
headers: { |
|||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", |
|||
}, |
|||
}, |
|||
); |
|||
resolve(result); |
|||
}); |
|||
}, |
|||
}; |
|||
|
|||
export const queryLayersByPos = (position: any, layerList = [], cb: any) => { |
|||
const { lng, lat } = position; |
|||
const layers = layerList; |
|||
layers.forEach(async (layer: any) => { |
|||
const action = identifyLayerActions[layer.layerType]; |
|||
switch (layer.layerType) { |
|||
case "021102": { |
|||
const input_geometry = `${lng},${lat}`; |
|||
const geometry_type = "esriGeometryPoint"; |
|||
const result = await action({ |
|||
input_geometry, |
|||
geometry_type, |
|||
url: layer.url, |
|||
}); |
|||
let res; |
|||
if (result?.results?.length > 0) { |
|||
res = result.results[0]; |
|||
} |
|||
if (cb) cb(res); |
|||
break; |
|||
} |
|||
case "030300": |
|||
break; |
|||
case "081100": { |
|||
const queryMode = "BUFFER"; |
|||
const bufferDistance = 0.005; // 缓冲距离大概是50米
|
|||
// const bufferDistance = 0.5; // 缓冲距离大概是??米
|
|||
const spatialQueryMode = "INTERSECT"; |
|||
const geometry = { |
|||
id: 0, |
|||
style: null, |
|||
parts: [1], |
|||
points: [ |
|||
{ |
|||
x: lng, |
|||
y: lat, |
|||
}, |
|||
], |
|||
type: "POINT", |
|||
}; |
|||
let type = ""; |
|||
let isSite = false; |
|||
let layerTable = ""; |
|||
if (layer.extendData) { |
|||
const extendData = JSON.parse(layer.extendData); |
|||
} |
|||
const result = await action({ |
|||
queryMode, |
|||
spatialQueryMode, |
|||
bufferDistance, |
|||
geometry, |
|||
layerName: layer.text, |
|||
layerTable, |
|||
url: layer.url, |
|||
k: layer.serviceToken, |
|||
}); |
|||
let resData; |
|||
if ([200, 201].includes(result.status) && result?.data?.datasetInfos?.length > 0) { |
|||
console.log("处理业务数据 >>>>>> ", result?.data); |
|||
const fieldInfos = result.data.datasetInfos?.[0]?.fieldInfos; |
|||
console.log("fieldInfos >>>>> ", fieldInfos); |
|||
const currentFeature = result.data.features?.[0]; |
|||
console.log("currentFeature >>>>> ", currentFeature); |
|||
const nameIndex = fieldInfos.findIndex((f: any) => ["res_name", "dike_name", "waga_name"].includes(f.name)); |
|||
const codeIndex = fieldInfos.findIndex((f: any) => ["res_code", "dike_code", "waga_code"].includes(f.name)); |
|||
// if (layer?.fields?.length > 0) {
|
|||
// const fieldIndex = fieldInfos.findIndex((f) => f.name === layer?.fields[0]?.field);
|
|||
// code = currentFeature?.fieldValues[fieldIndex];
|
|||
// }
|
|||
resData = { |
|||
attributes: { |
|||
showCode: "" + currentFeature?.fieldValues[codeIndex], |
|||
showName: "" + currentFeature?.fieldValues[nameIndex], |
|||
}, |
|||
}; |
|||
console.log("resData >>>>> ", resData); |
|||
} |
|||
if (cb) cb(resData); |
|||
break; |
|||
} |
|||
default: |
|||
break; |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
// 获取图层图例
|
|||
export const getSelectedLayersLegend = (selectedLayersList: any) => { |
|||
let legendList: any = []; |
|||
selectedLayersList.forEach(async (layer: any) => { |
|||
switch (layer.layerType) { |
|||
case "021102": { |
|||
const res = await getLayerLegend(layer.url); |
|||
let mapName = ""; |
|||
if (res.status === 200) { |
|||
mapName = res.data.mapName; |
|||
} |
|||
let queryUrl = `${layer.url}/legend.json`; |
|||
if (layer.serviceToken) { |
|||
queryUrl = `${layer.url}/legend.json?k=${layer.serviceToken}`; |
|||
} |
|||
const result = await getLayerLegend(queryUrl); |
|||
// 超图的arcgisrest服务 - 021102
|
|||
let currentLayer = []; |
|||
if (mapName) { |
|||
currentLayer = result.data.layers.filter((item: any) => item.layerName === mapName); |
|||
} |
|||
const legends: any = []; |
|||
currentLayer.forEach((item: any) => { |
|||
legends.push(item); |
|||
}); |
|||
legendList.push({ |
|||
layerName: mapName, |
|||
legends, |
|||
}); |
|||
break; |
|||
} |
|||
case "081100": { |
|||
let queryUrl = `${layer.url}.json`; |
|||
if (layer.serviceToken) { |
|||
queryUrl = `${layer.url}.json?k=${layer.serviceToken}`; |
|||
} |
|||
const res = await getLayerLegend(queryUrl); |
|||
// let mapName = '';
|
|||
// if (res?.status === 200) {
|
|||
// mapName = res.data.name;
|
|||
// }
|
|||
let mapName = layer.nameCn; |
|||
// 用逗号分隔的图层范围
|
|||
let bbox = |
|||
res?.data?.viewBounds?.left + |
|||
"," + |
|||
res?.data?.viewBounds?.bottom + |
|||
"," + |
|||
res?.data?.viewBounds?.right + |
|||
"," + |
|||
res?.data?.viewBounds?.top; |
|||
let result = null; |
|||
if (layer.serviceToken) { |
|||
result = await getLayerLegend(`${layer.url}/legend.json?bbox=${bbox}&k=${layer.serviceToken}`); |
|||
} else { |
|||
result = await getLayerLegend(`${layer.url}/legend.json?bbox=${bbox}`); |
|||
} |
|||
console.log(result); |
|||
if (result.status === 200 && result.data) { |
|||
let currentLayer = []; |
|||
// if (mapName) {
|
|||
// currentLayer = result.data.layerLegends.filter((item) => item.layerCaption === mapName);
|
|||
// }
|
|||
// if (currentLayer.length > 0) {
|
|||
// currentLayer = currentLayer[0];
|
|||
// legendList.push({
|
|||
// ...currentLayer,
|
|||
// layerName: mapName
|
|||
// });
|
|||
// }
|
|||
if (result.data.layerLegends && result.data.layerLegends.length > 0) { |
|||
let layerLegends = result.data.layerLegends[0]; |
|||
if (layerLegends.subLayerLegends && layerLegends.subLayerLegends.length > 0) { |
|||
let subLayerLegends = layerLegends.subLayerLegends; |
|||
let legends = []; |
|||
for (let item of subLayerLegends) { |
|||
legends.push(...item.legends); |
|||
} |
|||
legendList.push({ |
|||
legends, |
|||
layerName: mapName, |
|||
}); |
|||
} else { |
|||
currentLayer = result.data.layerLegends[0]; |
|||
legendList.push({ |
|||
...currentLayer, |
|||
layerName: mapName, |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
}); |
|||
|
|||
return legendList; |
|||
}; |
@ -0,0 +1,65 @@ |
|||
<template> |
|||
<div class="layer-switch"> |
|||
<div class="btn"> |
|||
<img class="icon" src="@/assets/map/layer.svg" alt="" @click="layerTreeChange" /> |
|||
</div> |
|||
<div class="slider-line"></div> |
|||
<div class="btn"> |
|||
<el-tooltip effect="dark" :content="is3DScene ? '三维模式' : '二维模式'" placement="right"> |
|||
<img class="icon" src="@/assets/map/changeScene.svg" alt="" @click="handleChangeMode" /> |
|||
</el-tooltip> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref } from "vue"; |
|||
import * as SyCim from "sy-cesium-sdk"; |
|||
|
|||
defineOptions({ |
|||
name: "MapLayerSwitch", |
|||
}); |
|||
let is3DScene = ref(true); |
|||
let showTreeBox = ref(false); |
|||
const emits = defineEmits(["layerTreeChange"]); |
|||
function handleChangeMode() { |
|||
is3DScene.value = !is3DScene.value; |
|||
const mapSceneType = !is3DScene.value ? 2 : 3; |
|||
viewer?.changeSceneMode(mapSceneType); |
|||
let position = new SyCim.Position(113.27, 23.13, 600000, 0, -90, 0); |
|||
viewer?.flyToPosition( |
|||
position, |
|||
() => { |
|||
console.log("移动结束 >>>>> "); |
|||
}, |
|||
1, |
|||
); |
|||
} |
|||
|
|||
function layerTreeChange() { |
|||
showTreeBox.value = !showTreeBox.value; |
|||
emits("showChange", showTreeBox.value); |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.layer-switch { |
|||
display: flex; |
|||
width: 100%; |
|||
height: 37px; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.btn { |
|||
padding: 8px 12px; |
|||
.icon { |
|||
width: 17px; |
|||
height: 17px; |
|||
} |
|||
} |
|||
.slider-line { |
|||
width: 1px; |
|||
height: 50%; |
|||
background-color: rgba(0, 0, 0, 0.2); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,138 @@ |
|||
<template> |
|||
<SyDialog dialog-class="layer-tree-dialog" :dialog-show="showDialog" :style="style"> |
|||
<template #body> |
|||
<Tree |
|||
ref="layerTreeRef" |
|||
class="layer-tree" |
|||
node-key="id" |
|||
showNodeLabelTips |
|||
:data="layerData" |
|||
:defaultProps="defaultProps" |
|||
:default-expanded-keys="expandedLayerKeys" |
|||
:default-checked-keys="selectedLayerKeys" |
|||
:default-expand-all="true" |
|||
:show-input="false" |
|||
:show-checkbox="true" |
|||
@check="handleCheck" |
|||
> |
|||
<template v-slot:default="{ data, onMouseoverTip }"> |
|||
<div class="item-name"> |
|||
<div class="icon"> |
|||
<img v-if="data && !data.iconCls" src="@/assets/map/icon-layer.png" alt="" /> |
|||
<img v-else src="@/assets/map/icon-folder.png" alt="" /> |
|||
</div> |
|||
<span class="name" @mouseover="onMouseoverTip($event)"> |
|||
{{ data.nameCn || data.text }} |
|||
</span> |
|||
</div> |
|||
</template> |
|||
<template v-slot:right="{ node, data }"> |
|||
<span class="btn-item" v-if="data && !data.iconCls" @click.stop="flyTo(data)"> |
|||
<iconpark-icon size="16" name="location"></iconpark-icon> |
|||
</span> |
|||
</template> |
|||
</Tree> |
|||
</template> |
|||
</SyDialog> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref, watch, computed, nextTick } from "vue"; |
|||
import SyDialog from "@/components/Dialog/index.vue"; |
|||
import { useProjectStore } from "@/store/modules/project"; |
|||
import { useLayer } from "@/hooks/web/useProject"; |
|||
import { flattenTree } from "@/utils/index"; |
|||
import Tree from "@/components/Tree/index.vue"; |
|||
const { addLayer, removeLayer, zoomToLayer } = useLayer(); |
|||
|
|||
const projectStore = useProjectStore(); |
|||
defineOptions({ |
|||
name: "MapLayerTree", |
|||
}); |
|||
|
|||
defineProps({ |
|||
showDialog: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
type: { |
|||
type: String, |
|||
default: "normal", |
|||
}, |
|||
style: { |
|||
type: String, |
|||
default: "", |
|||
}, |
|||
}); |
|||
const defaultProps: any = { |
|||
children: "children", |
|||
label: "text", |
|||
}; |
|||
const layerTreeRef = ref(); |
|||
const layerData = computed(() => projectStore.layerData); |
|||
const expandedLayerKeys = computed(() => projectStore.expandedLayerKeys); |
|||
const selectedLayerKeys = computed(() => projectStore.selectedLayerKeys); |
|||
const sceneConfig = computed(() => projectStore.sceneConfig); |
|||
|
|||
const flyTo = (data: any) => { |
|||
zoomToLayer(data); |
|||
}; |
|||
|
|||
const handleCheck = (data: any, checked: boolean) => { |
|||
if (data.pid === "root" || data.layers) return; |
|||
if (checked) { |
|||
// const list = layerTreeRef.value?.getCheckedNodes(); |
|||
addLayer(data); |
|||
// this.legendList = getSelectedLayersLegend(list); |
|||
// this.layerList.push(data); |
|||
} else { |
|||
// this.checkList = this.checkList.filter((v) => v != data.id); |
|||
// this.layerList = this.layerList.filter((v) => v.id != data.id); |
|||
removeLayer(data); |
|||
} |
|||
}; |
|||
const toggleShow = (data: any, checked: boolean) => { |
|||
if (data.pid === "root" || data.layers) return; |
|||
layerTreeRef.value?.setChecked(data.id, checked, true); |
|||
onCheck(data); |
|||
}; |
|||
|
|||
const handleCheckChange = (data: any, checkedData: any) => { |
|||
const { id } = data; |
|||
const { checkedKeys } = checkedData; |
|||
const nodes = [data]; |
|||
if (data.children?.length > 0) { |
|||
flattenTree(data.children, nodes); |
|||
} |
|||
if (checkedKeys.includes(id)) { |
|||
// 加载 |
|||
projectStore.setLayerSelectedNodes(nodes); |
|||
} else { |
|||
// 删除 |
|||
projectStore.removeLayerSelectedNodes(nodes); |
|||
} |
|||
}; |
|||
const onCheck = (data: any) => { |
|||
// 获取树的勾选值,不一定是默认勾选的值 |
|||
const checkedKeys = layerTreeRef.value?.getCheckedKeys(); |
|||
handleCheckChange(data, { checkedKeys }); |
|||
}; |
|||
|
|||
watch( |
|||
() => sceneConfig.value, |
|||
(val) => { |
|||
if (val?.layerId) { |
|||
const layerIds = JSON.parse(val.layerId); |
|||
layerTreeRef.value?.setCheckedKeys(layerIds, true); |
|||
nextTick(() => { |
|||
setTimeout(() => { |
|||
const checkedNodes = layerTreeRef.value?.getCheckedNodes(true, false); |
|||
checkedNodes.forEach((data: any) => { |
|||
handleCheckChange(data, { checkedKeys: layerIds }); |
|||
}); |
|||
}, 500); |
|||
}); |
|||
} |
|||
}, |
|||
); |
|||
</script> |
Loading…
Reference in new issue