392 lines
9.8 KiB
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>
|
|
|
|
<a-button type="primary" @click="handlerEditLayer(item)">
|
|
<template #icon>
|
|
<EditOutlined />
|
|
</template>
|
|
</a-button>
|
|
|
|
<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>
|
|
|
|
<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>
|