CaiYuanYiTiHua/src/components/MapboxMaps/Modal/ServeResource/index.vue

392 lines
9.8 KiB
Vue

<template>
<div class="serve-resource">
<div class="list">
<div class="header">
<a-select
v-model:value="data"
style="width: 142px;margin-right: 20px">
<a-select-option value="vector-data">矢量数据</a-select-option>
</a-select>
<a-input-search
style="width: 362px;margin-right: 20px"
v-model:value="key"
placeholder="请输入服务关键词"
enter-button
/>
<a-select
v-model:value="sort"
style="width: 142px">
<a-select-option value="default">默认排序</a-select-option>
</a-select>
</div>
<div class="content">
<div class="show-item" v-for="item in dataList" :key="item.id">
<div class="info">
<a-image
:width="119"
:height="87"
style="border-radius:4px"
src="https://gw.alipayobjects.com/zos/antfincdn/cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp"
:preview="false"
:fallback="errorImage"
/>
<div class="show-text">
<div class="title">服务名称: {{ item.name }}</div>
<div class="sub-title">服务描述: {{ item.description }}</div>
<div class="sub-title">创建时间: {{ item.createTime }}</div>
</div>
</div>
<div class="button">
<a-button type="error" @click="handlerDeleteLayer(item)">
<template #icon>
<DeleteOutlined />
</template>
</a-button>
&nbsp;
<a-button type="primary" @click="handlerEditLayer(item)">
<template #icon>
<EditOutlined />
</template>
</a-button>
&nbsp;
<a-button type="primary" @click="handlerAddToLayerList(item)">
<template #icon>
<PlusOutlined />
</template>
</a-button>
</div>
</div>
</div>
<div class="footer">
<a-pagination
v-model:current="queryList.page"
v-model:page-size="queryList.limit"
:total="total"
@change="onPageChange"
:show-total="total => `共 ${total} 条`"/>
</div>
</div>
<div class="information">
<div style="margin-bottom: 16px">
<div style="width: 100%;height:266px;">
<MapboxMap
ref="RenderStyleMapbox"
:mapOptions="mapOptions"
:control="mapDrawControl"
@map-on-load="mapOnLoad"
@map-draw="handlerMapDraw"
/>
</div>
</div>
<div class="show-info">
<div class="title">
<div class="first"></div>
<div class="last"></div>
</div>
<div style="position:absolute;height:32px;top:24px;display:flex;align-items:center;margin-left:14px">图层样式渲染</div>
<div class="serve-text">
<a-textarea v-model:value="jsonData" style="height: 240px;"/>
</div>
<p class="operate-box">
<a-button type="primary" @click="handlerRenderLayer">应 用</a-button>
&nbsp;
<a-button type="primary" @click="handlerSaveStyle">保 存</a-button>
</p>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { DeleteOutlined,PlusOutlined,EditOutlined } from '@ant-design/icons-vue'
import { errorImage } from '../../util.js'
import { ref,defineEmits,reactive,onBeforeMount } from "vue"
import MapboxMap from '@/components/MapboxMaps/index.vue'
import { DrawingType } from '@/enums/mapEnum';
import { useMessage } from '@/hooks/web/useMessage';
import {getLayerList,updateLayer} from '@/api/sys/layerManagement'
const { createMessage } = useMessage();
const emits = defineEmits(["handlerAddToLayerList"])
const data = ref('vector-data')
const sort = ref('default')
const key = ref('')
const current = ref()
const pageSize = ref()
const jsonData = ref('')
const dataList = ref([])
const queryList = reactive({
key:null,
limit:5,
page:1,
name:null,
})
const total = ref(0);
const handlerGetLayerList = ()=>{
getLayerList(queryList).then(res=>{
dataList.value = res.items;
total.value = res.total
})
}
onBeforeMount(()=>{
handlerGetLayerList();
})
const onPageChange = (e)=>{
queryList.page = e;
handlerGetLayerList();
}
const mapOptions = {
center: [117.963550,35.288580],
zoom: 10,
};
const mapDrawControl: DrawingType[] = [DrawingType.Polygon, DrawingType.Line];
const useMap = ref()
const mapOnLoad = (map) => {
useMap.value = map
// map 对象
console.log('map::: ', map);
// mapU封装对象
console.log('map.U::: ', map.U);
// 测试地址
const testSource =
'http://123.132.248.154:9205/geoserver/gwc/service/tms/1.0.0/TEST_WORK_SPACE%3Alindi@EPSG:900913@pbf/{z}/{x}/{y}.pbf';
// 添加矢量瓦片图层
map.U.addVector('sourceId', testSource).addLineLayer('layerId', {
source: 'sourceId',
'source-layer': 'lindi', // source-layer对应数据库的表名
});
};
//地图绘制的回调
const handlerMapDraw = (type: string, data: any) => {
console.log('data::: ', data);
console.log('type::: ', type);
};
const currentLayer = ref()
const handlerEditLayer = (item) => {
currentLayer.value = item;
let layerJson = JSON.parse(currentLayer.value?.style);
// 处理id、tiles、source-layer、state信息
console.log("currentLayer",currentLayer.value);
if(layerJson){
layerJson.id = currentLayer.value?.id;
switch(currentLayer.value?.vectorType){
case '面': layerJson.type = 'fill';
break;
case '线': layerJson.type = 'line';
break;
case '点': layerJson.type = 'symbol';
break;
}
layerJson.source.tiles = [
`http://192.168.10.102:9023/api/DroneCaseinfo/QueryVectorTileByTable?z={z}&x={x}&y={y}&table=${currentLayer.value?.relationTable}&field=\"gid\",`
]
layerJson.state = {
attributeField:currentLayer.value?.attributeField,
attributeTable:currentLayer.value?.attributeTable
}
}
jsonData.value = JSON.stringify(layerJson, null, 4);
handlerRenderLayer();
}
// 添加到图层
const handlerAddToLayerList = (item) => {
createMessage.success("图层已添加到工作区!")
item.checked = false;
emits("handlerAddToLayerList",item);
}
const handlerSaveStyle = () => {
currentLayer.value.style = jsonData.value;
delete currentLayer.value.createId
delete currentLayer.value.image
delete currentLayer.value.shpPath
delete currentLayer.value.status
delete currentLayer.value.type
updateLayer(currentLayer.value).then(res=>{
if(res){
createMessage.success("操作成功!")
}
})
}
const RenderStyleMapbox = ref();
const handlerRenderLayer = () => {
if(currentLayer.value){
let styleJson = handlerAnalysisStyle(jsonData.value);
RenderStyleMapbox.value.handlerRenderLayer(styleJson)
}else{
createMessage.error("请选择选择需要修改的图层!");
}
}
// 解析样式数据
const handlerAnalysisStyle = (jsonStr) => {
let jsonObj = null;
try {
jsonObj = JSON.parse(jsonStr);
}catch(e){
console.log(e);
createMessage.error("样式信息解析过程出现错误!");
}finally{
return jsonObj;
}
}
const handlerDeleteLayer = (item) => {
}
const handlerAddLayerToMap = (item) => {
}
</script>
<style lang="scss" scoped>
.serve-resource{
display: flex;
justify-content: space-between;
padding: 28px 46px;
background-color: #E0E5ED;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
.list{
width: calc(50% - 19px)
}
.header{
display: flex;
margin-bottom: 14px;
}
.content{
max-height: 565px;
overflow: auto;
margin-bottom: 8px;
height: 565px;
.show-item{
background-color: #fff;
height: 119px;
border-radius: 4px;
padding: 16px 30px 16px 16px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 3px;
.info{
display: flex;
.show-text{
margin-left: 15px;
display: flex;
flex-direction: column;
justify-content: center;
.title{
color: #191919;
font-size: 14px;
font-weight: 600;
margin-bottom: 3px;
}
.sub-title{
color: #191919;
font-size: 12px;
}
}
}
}
}
.footer{
display: flex;
justify-content: flex-end;
}
.information{
width: calc(50% - 19px);
.show-info{
background-color:#fff;
height: 369px;
border-radius: 10px;
padding: 24px 29px;
position:relative;
.title{
display: flex;
height:32px;
margin-bottom: 16px;
.first{
width: 3px;
height: 100%;
background-color: #0081FF;
}
.last{
background: linear-gradient(270deg, rgba(0, 183, 255, 0) 0%, #0081FF 100%);
opacity: 0.14;
flex: 1;
}
}
.serve-text{
display: flex;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 12px;
color: #303030;
.serve-info{
width: 60%;
padding-left: 12px;
.info-title{
display: inline-block;
opacity: 0.41;
width: 60px;
min-width: 60px;
}
.info-content{
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
& > div{
margin-bottom: 7px;
display: flex;
}
}
.serve-image{
width: 40%;
}
}
.operate-box{
margin:12px 0px 0px 0px;
text-align:right;
}
}
}
}
</style>