成果bug改修

dianlixunjian
滕嵩 2024-09-27 17:29:10 +08:00
parent 4a5c66342a
commit b84b4e2ed6
14 changed files with 667 additions and 206 deletions

BIN
public/display/cate-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/display/position.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
public/display/title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/display/uav-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -11,8 +11,11 @@
<a-row ::gutter="0">
<a-col :span="tableSpan">
<BasicTable @register="registerTable" @row-click="handRowClick">
<!-- <template #expandedRowRender="{ record }">
<span>{{ record.id }} </span>
</template> -->
<template #toolbar>
<!-- <PermissionBtn @btn-event="onBtnClicked" /> -->
<PermissionBtn @btn-event="onBtnClicked" />
</template>
</BasicTable>
</a-col>
@ -29,7 +32,7 @@
left: '0px',
zIndex: '0',
}"
@handleOpen="handleOpen"
@handleOpenImage="handleOpenImage"
/>
<div class="full-screen-button" :style="{ zIndex: 1 }">
<a-tooltip placement="top">
@ -154,7 +157,10 @@
ellipsis: false,
bordered: true,
showTableSetting: false,
autoCreateKey: false,
autoCreateKey: true,
canResize: false,
expandRowByClick: true,
accordion: true,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
@ -415,7 +421,7 @@
const modalImage = ref('');
const visible = ref<boolean>(false);
//
const handleOpen = (properties) => {
const handleOpenImage = (properties) => {
// modalOpen.value = true;
setVisible(true);
modalTitle.value = '';

View File

@ -0,0 +1,120 @@
<template>
<div class="window-container">
<div class="info">
<div class="item-header">
<!-- {{ datainfo.dwmc }} -->
</div>
<div
class="item"
v-for="(item, index) in detailDataArr"
:key="index"
v-show="item.name && item.value"
>
<div class="item-title">
{{
item.name != '' && item.name != null && item.name != 'nulll' ? item.name : '暂无属性'
}}
</div>
<div class="item-value">
{{
item.value != '' && item.value != null && item.value != 'nulll'
? item.value
: '暂无数据'
}}
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
const emits = defineEmits(['closeAttributeWindow']);
const props = defineProps({
showAttributeFeature: { type: Object },
});
const detailDataArr: any = ref([]);
watch(
() => props.showAttributeFeature,
() => {
console.log(39, props.showAttributeFeature);
let detailData = props.showAttributeFeature;
detailDataArr.value = [];
for (let key in detailData) {
if (!['id'].includes(key)) {
let detail: any = {};
// let enObj = dictionaries.find((item)=>{
// return item.en_name == key
// })
// if(enObj){
// detail.name = enObj.cn_name ? enObj.cn_name : null;
// }else{
// detail.name = ""
// }
detail.name = key;
// detail.name = '';
detail.value = detailData[key];
detailDataArr.value.push(detail);
}
}
// console.log(54, detailDataArr.value);
},
{
deep: true,
immediate: true,
},
);
</script>
<style lang="less" scoped>
.window-container {
width: 100%;
height: 100%;
}
.info {
width: 100%;
padding: 12px;
box-sizing: border-box;
height: 500px;
overflow: auto;
// background: rgba(6, 16, 64, 0.7);
}
.item-header {
width: 100%;
// height: 30px;
// background: rgba(0, 157, 255, 0.4);
// line-height: 30px;
// color: #fff;
// text-indent: 8px;
border-bottom: 1px solid #088eda;
}
.item {
width: calc(100% - 2px);
height: 30px;
line-height: 30px;
// color: #fff;
border-bottom: 1px solid #088eda;
border-left: 1px solid #088eda;
text-indent: 6px;
}
.item .item-title {
width: 40%;
float: left;
font-size: 12px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.item .item-value {
width: calc(60%);
float: left;
font-size: 12px;
border-left: 1px solid #088eda;
border-right: 1px solid #088eda;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
</style>

View File

@ -0,0 +1,255 @@
<template>
<div @keydown="handleKeydown">
<div class="toper" :style="{ zIndex: 1082 }" v-if="visible">
<span class="info-item solo">任务名称{{ modalImage.taskName }}</span>
<div class="info-row">
<span class="info-item">飞手名{{ modalImage.flyer }}</span>
<span class="info-item">飞行时间{{ modalImage.flyTime }}</span>
<span class="info-item">任务位置{{ modalImage.workPosition }}</span>
</div>
</div>
<div class="leftOutlined" :style="{ zIndex: 1082 }" v-if="visible && beforeImageVif">
<LeftOutlined :style="{ fontSize: '30px' }" @click="beforeImage" />
</div>
<div class="rightOutlined" :style="{ zIndex: 1082 }" v-if="visible && afterImageVif">
<RightOutlined :style="{ fontSize: '30px' }" @click="afterImage" />
</div>
<a-image
:width="200"
:style="{ display: 'none', zIndex: 1001 }"
:preview="{
visible,
onVisibleChange: setVisible,
}"
:src="modalImage.path"
/>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, onMounted } from 'vue';
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
//
import { getAppEnvConfig } from '@/utils/env';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const VITE_GLOB_API_URL_VAR = ref<String>(VITE_GLOB_API_URL + '/');
const emits = defineEmits(['closeImageModal']);
const props = defineProps({
modalImage: { type: Object },
tableData3_tupian: { type: Object },
});
watch(
() => props.modalImage,
() => {
setTimeout(() => {
handleOpenImage(props.modalImage);
}, 1);
},
{
deep: true,
immediate: true,
},
);
// ------------------------------------------------------------
//
const modalImage: any = ref({});
const visible = ref<boolean>(false);
//
const handleOpenImage = (properties) => {
//
modalImage.value = properties;
if (isValidUrl(properties.path)) {
modalImage.value.path = properties.path;
} else {
modalImage.value.path = VITE_GLOB_API_URL_VAR.value + properties.path;
}
nowImgs = props.tableData3_tupian?.filter((f) => {
return f.taskId == modalImage.value.taskId;
});
nowImgs?.forEach((item, index) => {
if (item.id == modalImage.value.id) {
if (index != 0) {
beforeImageVif.value = true;
} else {
beforeImageVif.value = false;
}
if (index != nowImgs.length - 1) {
afterImageVif.value = true;
} else {
afterImageVif.value = false;
}
}
});
setVisible(true);
};
const beforeImageVif = ref(false);
const afterImageVif = ref(false);
let nowImgs: any = [];
//
function beforeImage() {
for (let index = 0; index < nowImgs.length; index++) {
const item = nowImgs[index];
if (item.id == modalImage.value.id) {
modalImage.value = nowImgs[index - 1];
if (isValidUrl(modalImage.value.path)) {
modalImage.value.path = modalImage.value.path;
} else {
modalImage.value.path = VITE_GLOB_API_URL_VAR.value + modalImage.value.path;
}
if (index == 1) {
beforeImageVif.value = false;
}
afterImageVif.value = true;
return;
}
}
}
//
function afterImage() {
for (let index = 0; index < nowImgs.length; index++) {
const item = nowImgs[index];
if (item.id == modalImage.value.id) {
modalImage.value = nowImgs[index + 1];
if (isValidUrl(modalImage.value.path)) {
modalImage.value.path = modalImage.value.path;
} else {
modalImage.value.path = VITE_GLOB_API_URL_VAR.value + modalImage.value.path;
}
if (index == nowImgs.length - 2) {
afterImageVif.value = false;
}
beforeImageVif.value = true;
return;
}
}
}
const setVisible = (value): void => {
visible.value = value;
if (!value) {
emits('closeImageModal');
// removeGlobalListener();
}
};
//
function isValidUrl(url: string): boolean {
const regex =
/^(?:http|ftp)s?:\/\/(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[?[A-F0-9]*:[A-F0-9:]+\]?)(?::\d+)?(?:\/?|[\/?]\S+)$/i;
return regex.test(url);
}
// let cleanupFunction: (() => void) | undefined;
// const handleKeydown = (event: KeyboardEvent) => {
// if (event.key === 'ArrowLeft') {
// console.log('Left arrow key pressed');
// // ...
// } else if (event.key === 'ArrowRight') {
// console.log('Right arrow key pressed');
// // ...
// }
// };
// const addGlobalListener = () => {
// cleanupFunction = addEventListener(document, 'keydown', handleKeydown);
// };
// const removeGlobalListener = () => {
// if (cleanupFunction) {
// cleanupFunction();
// cleanupFunction = undefined;
// }
// };
// //
// onMounted(() => {
// addGlobalListener();
// });
</script>
<style type="less" scoped>
.toper {
position: absolute;
display: flex;
flex-direction: column;
justify-content: flex-start;
z-index: 1082;
width: 100%;
font-size: 40px;
top: 0px;
height: auto; /* 自动高度,适应内容 */
background: rgba(0, 0, 0, 0.4);
padding: 10px; /* 内边距,使文本不紧贴边框 */
opacity: 1;
}
.info-item {
color: #ffffff;
font-size: 30px; /* 后面三个项的字体大小 */
margin-right: 30px; /* 每个 span 之间的间距 */
opacity: 1;
}
.info-item.solo {
font-size: 40px; /* 第一个 span 的字体大小 */
margin-bottom: 10px; /* 第一个 span 的底部间距 */
opacity: 1;
}
.info-row {
display: flex; /* 使用 flex 布局使三个 span 排成一行 */
flex-wrap: nowrap; /* 不允许换行 */
opacity: 1;
}
.info-row .info-item:last-child {
margin-right: 0; /* 最后一个 span 不需要右边距 */
opacity: 1;
}
.leftOutlined {
position: absolute;
top: 40%;
z-index: 1082;
left: 0px;
color: #ffffff;
background-color: gray; /* 默认灰色背景 */
border-radius: 50%; /* 圆形 */
padding: 10px; /* 内边距 */
margin: 5px; /* 外边距 */
transition: background-color 0.3s ease; /* 平滑过渡 */
cursor: pointer; /* 鼠标指针变为手型 */
overflow: visible;
opacity: 1;
}
.rightOutlined {
position: absolute;
z-index: 1082;
top: 40%;
right: 0px;
color: #ffffff;
background-color: gray; /* 默认灰色背景 */
border-radius: 50%; /* 圆形 */
padding: 10px; /* 内边距 */
margin: 5px; /* 外边距 */
transition: background-color 0.3s ease; /* 平滑过渡 */
cursor: pointer; /* 鼠标指针变为手型 */
opacity: 1;
}
.leftOutlined:hover {
background-color: black; /* 鼠标悬停时背景颜色变为黑色 */
opacity: 1;
}
.rightOutlined:hover {
background-color: black; /* 鼠标悬停时背景颜色变为黑色 */
opacity: 1;
}
</style>

View File

@ -76,12 +76,13 @@
<span
:style="{
position: 'relative',
bottom: `${10 + 25 * countLines(label, point)}px`,
bottom: `${10 + 35 + 0 * countLines(label, point)}px`,
}"
>
<a-popover>
<template #content> {{ getNameByJxnanme(label) }} </template>
<a-tag closable color="#2db7f5">{{ label }}</a-tag>
<!-- <a-tag closable color="#2db7f5">{{ label }}</a-tag> -->
<img src="/display/position.png" />
</a-popover>
</span>
</template>

View File

@ -1,10 +1,10 @@
<template>
<div>
<div class="switch-button-open" @click="handlerOpen" v-if="!isOpen">
<img src="/statistical/switch-button.png" />
<img src="/display/switch-button.png" />
</div>
<div class="switch-button-close" @click="handlerOpen" v-if="isOpen">
<img src="/statistical/switch-button-active.png" />
<img src="/display/switch-button-active.png" />
</div>
<div class="case-tree-container" v-if="!isOpen">
<div class="title"> 图层列表 </div>
@ -36,32 +36,32 @@
left: '0px',
zIndex: '0',
}"
@handleOpen="handleOpen"
@handleOpenImage="handleOpenImage"
@getDetailByFeature="getDetailByFeature"
/>
</div>
<!-- <a-modal :open="modalOpen" :title="modalTitle" :footer="null" @cancel="handleCancel">
<a-image style="height: 100%; width: 100%" :src="modalImage" />
<!-- <a-modal
:open="modalOpen"
width="100%"
wrap-class-name="full-modal"
:footer="null"
@cancel="handleCancelImage"
>
</a-modal> -->
<a-image
:width="200"
:style="{ display: 'none', zIndex: 1082 }"
:preview="{
visible,
onVisibleChange: setVisible,
}"
:src="modalImage.path"
<div v-if="modalOpen" style="width=100%">
<ImageModal
:tableData3_tupian="tableData3_tupian"
:modalImage="modalImage"
@closeImageModal="closeImageModal"
/>
<div class="leftOutlined" :style="{ zIndex: 1082000000 }" v-if="visible && beforeImageVif">
<LeftOutlined :style="{ fontSize: '30px' }" @click="beforeImage" />
</div>
<div class="rightOutlined" :style="{ zIndex: 1082 }" v-if="visible && afterImageVif">
<RightOutlined :style="{ fontSize: '30px' }" @click="afterImage" />
</div>
<div class="footer" :style="{ zIndex: 1082 }" v-if="visible">
<span class="info-item">飞手名{{ modalImage.flyer }}</span>
<span class="info-item">飞行时间{{ modalImage.flyTime }}</span>
<span class="info-item">任务名称{{ modalImage.taskName }}</span>
<span class="info-item">任务位置{{ modalImage.workPosition }}</span>
<div class="attribute" v-if="showAttributeWindow">
<span class="span-title">详细信息</span>
<a-button class="span-button" type="link" @click="closeAttributeWindow">
<CloseOutlined style="color: black" />
</a-button>
<AttributeWindow :showAttributeFeature="showAttributeFeature" />
</div>
</div>
</template>
@ -69,14 +69,15 @@
<script lang="ts" setup>
import { ref, watch, onMounted } from 'vue';
import { BasicTree, TreeItem, TreeActionType } from '@/components/Tree';
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
import { CloseOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
import type { TreeProps } from 'ant-design-vue';
// vben
import { useMessage } from '@/hooks/web/useMessage';
//
import MapComponent from '@/views/demo/system/geoservermanagement/clound/mapComponent.vue';
import TimeLine from './TimeLine.vue';
import AttributeWindow from './AttributeWindow.vue';
import ImageModal from './ImageModal.vue';
import {
AchievementManageListTask,
AchievementManageListDroneShpImageexif,
@ -108,11 +109,11 @@
let tableData2: any = [];
let uniqueKeysArray: any = [];
let tableData3: any = [];
let tableData3_tupian: any = [];
const tableData3_tupian: any = ref([]);
let tableData1_id_list: any = [];
let tableData2_id_list: any = [];
let tableData3_id_list: any = [];
let isTimeMove = false;
// let isTimeMove = false;
let moveKey = null;
let startTime = dayjs().startOf('year').format('YYYY-MM-DD HH:mm:ss');
@ -160,7 +161,7 @@
pageSize: 10000,
}).then((res) => {
//
tableData3_tupian = [];
tableData3_tupian.value = [];
treeData.value[2].children = [];
// -
let taskDateArray: any = [];
@ -194,7 +195,7 @@
res.items.forEach((item) => {
tableData3_id_list.push(item.id);
});
tableData3_tupian = [];
tableData3_tupian.value = [];
res.items.forEach((item1) => {
if (item1.imageCount > 0) {
// -
@ -204,7 +205,7 @@
taskId: item1.id,
}).then((res2) => {
res2.items.forEach((item2) => {
tableData3_tupian.push(item2);
tableData3_tupian.value.push(item2);
});
});
}
@ -249,10 +250,13 @@
let filter_hangfei: any = [];
moveKey = null;
console.log(243, checkedKeys_now);
console.log(243, checkedKeys);
if (!checkedKeys_now || checkedKeys_now.length == 0) {
mapboxComponentRef.value.clearTaskLayer('GeoserverManagementRaster');
tableData1.forEach((data) => {
mapboxComponentRef.value.clearTaskLayer(data.dataTable);
});
mapboxComponentRef.value.clearTaskLayer('GeoTiffManagerRaster');
mapboxComponentRef.value.clearTaskLayer('AchievementManageRaster');
} else {
@ -300,7 +304,7 @@
tableData3.forEach((data) => {
if (checkedKey == data.id) {
if (data.imageCount > 0) {
tableData3_tupian.forEach((tupian) => {
tableData3_tupian.value.forEach((tupian) => {
if (tupian.taskId == data.id) {
//
// if (
@ -322,7 +326,7 @@
}
// -
// else {
// let filter = tableData3_tupian.filter((item) => item.id == checkedKey);
// let filter = tableData3_tupian.value.filter((item) => item.id == checkedKey);
// filter?.forEach((f) => {
// if (!filter_hangfei.includes(f)) {
// if (dayjs(startTime).isBefore(f.uploadTime) && dayjs(endTime).isAfter(f.uploadTime)) {
@ -334,6 +338,9 @@
});
//
if (filter_tuceng.length > 0) {
tableData1.forEach((data) => {
mapboxComponentRef.value.clearTaskLayer(data.dataTable);
});
mapboxComponentRef.value.GeoserverManagementRaster(
filter_tuceng,
// [118.30207505530701, 35.30123435040745],
@ -344,6 +351,9 @@
);
} else {
mapboxComponentRef.value.clearTaskLayer('GeoserverManagementRaster');
tableData1.forEach((data) => {
mapboxComponentRef.value.clearTaskLayer(data.dataTable);
});
}
//
if (filter_yingxiang.length > 0) {
@ -364,33 +374,33 @@
} else {
mapboxComponentRef.value.clearTaskLayer('AchievementManageRaster');
}
//
if (moveKey != null && !isTimeMove) {
// console.log(358, moveKey);
if (moveKey.geometry) {
let lngLat: any = moveKey.geometry.slice(6, -1);
lngLat = lngLat.split(' ');
//
const result = isProjectedCoordinates(parseFloat(lngLat[0]), parseFloat(lngLat[1]));
if (result) {
lngLat[0] = result[0];
lngLat[1] = result[1];
}
mapboxComponentRef.value.handlerLocation([lngLat[0], lngLat[1]], 10);
}
if (moveKey.accessUrl) {
let bbox = getBboxFromUrl(moveKey.accessUrl);
let lngLat = getCenterPoint(bbox);
//
const result = isProjectedCoordinates(parseFloat(lngLat[0]), parseFloat(lngLat[1]));
if (result) {
lngLat[0] = result[0];
lngLat[1] = result[1];
}
mapboxComponentRef.value.handlerLocation([lngLat[0], lngLat[1]], 10);
}
}
isTimeMove = false;
// //
// if (moveKey != null && !isTimeMove) {
// // console.log(358, moveKey);
// if (moveKey.geometry) {
// let lngLat: any = moveKey.geometry.slice(6, -1);
// lngLat = lngLat.split(' ');
// //
// const result = isProjectedCoordinates(parseFloat(lngLat[0]), parseFloat(lngLat[1]));
// if (result) {
// lngLat[0] = result[0];
// lngLat[1] = result[1];
// }
// mapboxComponentRef.value.handlerLocation([lngLat[0], lngLat[1]], 10);
// }
// if (moveKey.accessUrl) {
// let bbox = getBboxFromUrl(moveKey.accessUrl);
// let lngLat = getCenterPoint(bbox);
// //
// const result = isProjectedCoordinates(parseFloat(lngLat[0]), parseFloat(lngLat[1]));
// if (result) {
// lngLat[0] = result[0];
// lngLat[1] = result[1];
// }
// mapboxComponentRef.value.handlerLocation([lngLat[0], lngLat[1]], 10);
// }
// }
// isTimeMove = false;
}
};
@ -502,7 +512,7 @@
// console.log(421, value);
startTime = dayjs(value[0]).startOf('year').format('YYYY-MM-DD HH:mm:ss');
endTime = dayjs(value[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss');
isTimeMove = true;
// isTimeMove = true;
onCheck(checkedKeys_now);
}
@ -516,97 +526,35 @@
fetch();
});
// ------------------------------------------------------------
const showAttributeWindow = ref(false);
const showAttributeFeature: any = ref();
const getDetailByFeature = (feature) => {
showAttributeFeature.value = feature.properties;
showAttributeWindow.value = true;
};
const closeAttributeWindow = () => {
showAttributeWindow.value = false;
};
// ------------------------------------------------------------
//
// const modalOpen = ref(false);
const modalTitle = ref('');
const modalOpen = ref(false);
const modalImage: any = ref({});
const visible = ref<boolean>(false);
const closeImageModal = () => {
modalOpen.value = false;
};
//
const handleOpen = (properties) => {
console.log(444, properties);
// modalOpen.value = true;
setVisible(true);
modalTitle.value = '';
const handleOpenImage = (properties) => {
modalOpen.value = true;
//
modalImage.value = properties;
if (isValidUrl(properties.path)) {
modalImage.value.path = properties.path;
} else {
modalImage.value.path = VITE_GLOB_API_URL_VAR.value + properties.path;
}
};
const beforeImageVif = ref(false);
const afterImageVif = ref(false);
let nowImgs: any = [];
//
function beforeImage() {
for (let index = 0; index < nowImgs.length; index++) {
const item = nowImgs[index];
if (item.id == modalImage.value.id) {
modalImage.value = nowImgs[index - 1];
if (isValidUrl(modalImage.value.path)) {
modalImage.value.path = modalImage.value.path;
} else {
modalImage.value.path = VITE_GLOB_API_URL_VAR.value + modalImage.value.path;
}
if (index == 1) {
beforeImageVif.value = false;
}
afterImageVif.value = true;
return;
}
}
}
//
function afterImage() {
for (let index = 0; index < nowImgs.length; index++) {
const item = nowImgs[index];
if (item.id == modalImage.value.id) {
modalImage.value = nowImgs[index + 1];
if (isValidUrl(modalImage.value.path)) {
modalImage.value.path = modalImage.value.path;
} else {
modalImage.value.path = VITE_GLOB_API_URL_VAR.value + modalImage.value.path;
}
if (index == nowImgs.length - 2) {
afterImageVif.value = false;
}
beforeImageVif.value = true;
return;
}
}
// setVisible(true);
}
const setVisible = (value): void => {
visible.value = value;
setTimeout(() => {
nowImgs = tableData3_tupian.filter((f) => {
return f.taskId == modalImage.value.taskId;
});
nowImgs?.forEach((item, index) => {
if (item.id == modalImage.value.id) {
if (index != 0) {
beforeImageVif.value = true;
} else {
beforeImageVif.value = false;
}
if (index != nowImgs.length - 1) {
afterImageVif.value = true;
} else {
afterImageVif.value = false;
}
}
});
}, 500);
const handleCancelImage = () => {
modalOpen.value = false;
};
//
function isValidUrl(url: string): boolean {
const regex =
/^(?:http|ftp)s?:\/\/(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[?[A-F0-9]*:[A-F0-9:]+\]?)(?::\d+)?(?:\/?|[\/?]\S+)$/i;
return regex.test(url);
}
</script>
<style type="less" scoped>
::v-deep .ant-tree-list {
@ -629,7 +577,7 @@
justify-content: center;
width: 100%;
height: 40px;
background-image: url('/videosupervision/title.png');
background-image: url('/display/title.png');
background-size: 100% 100%;
line-height: 40px;
text-indent: 18px;
@ -687,22 +635,38 @@
}
}
.footer {
.toper {
position: absolute;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
flex-direction: column;
justify-content: flex-start;
z-index: 1082;
width: 100%;
font-size: 40px;
bottom: 0px;
height: 100px;
top: 0px;
height: auto; /* 自动高度,适应内容 */
background: rgba(0, 0, 0, 0.4);
padding: 10px; /* 内边距,使文本不紧贴边框 */
}
.info-item {
color: #ffffff;
flex-basis: calc(50% - 10px); /* 每个 span 占据一半的宽度减去一定的间隔 */
font-size: 30px; /* 后面三个项的字体大小 */
margin-right: 30px; /* 每个 span 之间的间距 */
}
.info-item.solo {
font-size: 40px; /* 第一个 span 的字体大小 */
margin-bottom: 10px; /* 第一个 span 的底部间距 */
}
.info-row {
display: flex; /* 使用 flex 布局使三个 span 排成一行 */
flex-wrap: nowrap; /* 不允许换行 */
}
.info-row .info-item:last-child {
margin-right: 0; /* 最后一个 span 不需要右边距 */
}
.leftOutlined {
@ -717,6 +681,7 @@
margin: 5px; /* 外边距 */
transition: background-color 0.3s ease; /* 平滑过渡 */
cursor: pointer; /* 鼠标指针变为手型 */
overflow: visible;
}
.rightOutlined {
@ -739,4 +704,29 @@
.rightOutlined:hover {
background-color: black; /* 鼠标悬停时背景颜色变为黑色 */
}
.attribute {
position: absolute;
background-color: white;
right: 10px;
z-index: 1;
top: 80px;
width: 400px;
height: 540px;
border-radius: 10px;
}
.span-title {
margin-left: 10px;
color: rgba(0, 0, 0, 0.88);
font-weight: 600;
font-size: 20px;
line-height: 1.5;
word-wrap: break-word;
}
.span-button {
position: absolute;
right: 10px;
}
</style>

View File

@ -9,7 +9,7 @@ export const indexColumns: BasicColumn[] = [
{
title: '服务名称',
dataIndex: 'serverName',
width: 140,
width: 100,
},
{
title: '服务地址',
@ -20,7 +20,7 @@ export const indexColumns: BasicColumn[] = [
{
title: '空间参考',
dataIndex: 'spatialRef',
width: 100,
width: 80,
},
{
title: '数据源类型',
@ -31,12 +31,12 @@ export const indexColumns: BasicColumn[] = [
{
title: '数据类型',
dataIndex: 'dataType',
width: 100,
width: 40,
},
{
title: '数据表名',
dataIndex: 'dataTable',
width: 150,
width: 100,
},
{
title: 'shp或者xls地址',
@ -53,12 +53,12 @@ export const indexColumns: BasicColumn[] = [
{
title: '创建时间',
dataIndex: 'createTime',
width: 150,
width: 100,
},
{
title: '修改时间',
dataIndex: 'updateTime',
width: 150,
width: 100,
},
];

View File

@ -17,7 +17,7 @@
const mapContainerName = ref<String>();
mapContainerName.value = 'mapContainer-' + generateUUID();
const emits = defineEmits(['handleOpen']);
const emits = defineEmits(['handleOpenImage', 'getDetailByFeature']);
let map: Map;
@ -215,38 +215,79 @@
// -
function GeoserverManagementRaster(chooseRows, lngLat, zoom, isMove) {
//
clearTaskLayer('GeoserverManagementRaster');
// clearTaskLayer('GeoserverManagementRaster');
// if (isMove) {
// handlerLocation(lngLat, zoom);
// }
// let tiles: any = [];
// chooseRows.forEach((chooseRow) => {
// let tile =
// 'http://192.168.10.131:8080/geoserver/my_workspace/wms?service=WMS&version=1.1.0&request=GetMap&layers=my_workspace:' +
// chooseRow.dataTable +
// '&styles=&bbox={bbox-epsg-3857}&width=256&height=256&srs=EPSG:3857' +
// '&format=image/png&TRANSPARENT=TRUE';
// tiles.push(tile);
// });
// map.addSource('GeoserverManagementRaster' , {
// type: 'raster',
// tiles: tiles,
// tileSize: 256,
// });
// map.addLayer({
// id: 'GeoserverManagementRaster',
// type: 'raster',
// source: 'GeoserverManagementRaster' ,
// layout: {
// visibility: 'visible',
// },
// });
// map.on('click', 'GeoserverManagementRaster', (e) => {
// console.log(e);
// });
// if (map.getLayer('streetLayer')) {
// map.moveLayer('GeoserverManagementRaster', 'streetLayer');
// }
console.log(chooseRows);
if (isMove) {
handlerLocation(lngLat, zoom);
}
let tiles: any = [];
chooseRows.forEach((chooseRow) => {
let tile =
'http://192.168.10.131:8080/geoserver/my_workspace/wms?service=WMS&version=1.1.0&request=GetMap&layers=my_workspace:' +
chooseRow.dataTable +
'&styles=&bbox={bbox-epsg-3857}&width=256&height=256&srs=EPSG:3857' +
'&format=image/png&TRANSPARENT=TRUE';
tiles.push(tile);
});
map.addSource('GeoserverManagementRaster' + 'wmsSource', {
type: 'raster',
tiles: tiles,
tileSize: 256,
chooseRows?.forEach((chooseRow) => {
// chooseRow.dataTable = 'pingyi304086660120221229';
map.addSource(chooseRow.dataTable, {
type: 'vector',
tiles: [
'http://192.168.10.131:8989/api/ShpGeoLayer/QueryVectorTileByTable?z={z}&x={x}&y={y}&table=' +
chooseRow.dataTable,
// '&field=id,',
],
minzoom: parseInt(1),
maxzoom: parseInt(18),
});
map.addLayer({
id: 'GeoserverManagementRaster',
type: 'raster',
source: 'GeoserverManagementRaster' + 'wmsSource',
layout: {
visibility: 'visible',
id: chooseRow.dataTable,
type: 'fill',
source: chooseRow.dataTable,
'source-layer': chooseRow.dataTable,
paint: {
'fill-opacity': 1,
'fill-color': 'red',
'fill-outline-color': 'green',
},
});
if (map.getLayer('streetLayer')) {
map.moveLayer('GeoserverManagementRaster', 'streetLayer');
map.on('click', chooseRow.dataTable, function (e) {
//
if (e.features.length > 0) {
//
const feature = e.features[0];
// console.log(400, feature);
emits('getDetailByFeature', feature);
}
});
if (map.getLayer('streetLayer')) {
map.moveLayer(chooseRow.dataTable, 'streetLayer');
}
});
}
// -
@ -268,7 +309,7 @@
tiles.push(tile);
});
map.addSource('GeoTiffManagerRaster' + 'wmsSource', {
map.addSource('GeoTiffManagerRaster', {
type: 'raster',
tiles: tiles,
tileSize: 256,
@ -276,7 +317,7 @@
map.addLayer({
id: 'GeoTiffManagerRaster',
type: 'raster',
source: 'GeoTiffManagerRaster' + 'wmsSource',
source: 'GeoTiffManagerRaster',
layout: {
visibility: 'visible',
},
@ -302,11 +343,11 @@
handlerLocation(lngLat, zoom);
}
if (map.getSource('AchievementManageRaster' + 'wmsSource')) {
map.getSource('AchievementManageRaster' + 'wmsSource').setData(taskLayerGeoJson);
if (map.getSource('AchievementManageRaster')) {
map.getSource('AchievementManageRaster').setData(taskLayerGeoJson);
} else {
//
map.addSource('AchievementManageRaster' + 'wmsSource', {
map.addSource('AchievementManageRaster', {
type: 'geojson',
data: taskLayerGeoJson,
cluster: true,
@ -316,7 +357,7 @@
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'AchievementManageRaster' + 'wmsSource',
source: 'AchievementManageRaster',
filter: ['all', ['has', 'point_count'], ['!=', 'point_count', 1]], // 1
paint: {
'circle-color': [
@ -334,7 +375,7 @@
map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'AchievementManageRaster' + 'wmsSource',
source: 'AchievementManageRaster',
filter: ['all', ['has', 'point_count'], ['!=', 'point_count', 1]], // 1
layout: {
'text-field': ['get', 'point_count_abbreviated'],
@ -345,7 +386,7 @@
// map.addLayer({
// id: 'unclustered-point',
// type: 'circle',
// source: 'AchievementManageRaster' + 'wmsSource',
// source: 'AchievementManageRaster' ,
// filter: ['any', ['!', ['has', 'point_count']], ['==', 'point_count', 1]],
// paint: {
// 'circle-color': '#11b4da',
@ -355,7 +396,7 @@
// },
// });
//
map.loadImage('/map/AchievementManage.png', function (error, image) {
map.loadImage('/videosupervision/uav-1.png', function (error, image) {
if (error) throw error;
if (!map.hasImage('taskIcon')) {
map.addImage('taskIcon', image);
@ -364,7 +405,7 @@
map.addLayer({
id: 'AchievementManageRaster',
type: 'symbol',
source: 'AchievementManageRaster' + 'wmsSource',
source: 'AchievementManageRaster',
layout: {
'icon-image': 'taskIcon',
'icon-size': 0.8,
@ -392,7 +433,7 @@
// 'path'
// const path = feature.properties.path;
// console.log(400, feature.properties);
emits('handleOpen', feature.properties);
emits('handleOpenImage', feature.properties);
}
});
@ -429,9 +470,9 @@
}
}
//
if (map.getSource(layerName + 'wmsSource')) {
if (map.getSource(layerName)) {
//
map.removeSource(layerName + 'wmsSource');
map.removeSource(layerName);
}
}

View File

@ -23,6 +23,7 @@
width: calc(85vh);
z-index: 0;
"
@getDetailByFeature="getDetailByFeature"
/>
</div>
</a-tab-pane>
@ -138,6 +139,14 @@
<a-button type="primary" @click="handleEditSubmit"> </a-button>
</template>
</a-modal>
<div class="attribute" v-if="showAttributeWindow">
<span class="span-title">详细信息</span>
<a-button class="span-button" type="link" @click="closeAttributeWindow">
<CloseOutlined style="color: black" />
</a-button>
<AttributeWindow :showAttributeFeature="showAttributeFeature" />
</div>
</div>
</template>
<script lang="ts" setup>
@ -146,11 +155,13 @@
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { useMessage } from '@/hooks/web/useMessage';
import { CloseOutlined } from '@ant-design/icons-vue';
//
import UploadFrom from './clound/uploadFrom.vue';
import HeadersTable from './clound/headersTable.vue';
import ServiceTable from './clound/serviceTable.vue';
import MapComponent from './clound/mapComponent.vue';
import AttributeWindow from '@/views/demo/system/achievement/Display/AttributeWindow.vue';
import {
indexColumns,
@ -479,6 +490,18 @@
reload();
}
// ------------------------------------------------------------
const showAttributeWindow = ref(false);
const showAttributeFeature: any = ref();
const getDetailByFeature = (feature) => {
showAttributeFeature.value = feature.properties;
showAttributeWindow.value = true;
};
const closeAttributeWindow = () => {
showAttributeWindow.value = false;
};
onMounted(() => {
reload();
});
@ -493,4 +516,29 @@
display: flex;
width: 800px;
}
.attribute {
position: absolute;
background-color: white;
right: 10px;
z-index: 1;
top: 10px;
width: 400px;
height: 540px;
border-radius: 10px;
}
.span-title {
margin-left: 10px;
color: rgba(0, 0, 0, 0.88);
font-weight: 600;
font-size: 20px;
line-height: 1.5;
word-wrap: break-word;
}
.span-button {
position: absolute;
right: 10px;
}
</style>