Compare commits

..

4 Commits

Author SHA1 Message Date
zzq e65c5b693b 地图完善 2024-05-17 09:15:18 +08:00
zzq 4c6ba8d9a8 Merge branch 'main' of http://123.132.248.154:10000/HC_YFZX/CaiYuanYiTiHua 2024-05-17 08:50:19 +08:00
zzq 70cfeea7a0 Revert "地图完善"
This reverts commit d000464ce8.
2024-05-17 08:49:41 +08:00
zzq d000464ce8 地图完善 2024-05-17 08:35:50 +08:00
5 changed files with 723 additions and 659 deletions

View File

@ -1,5 +1,11 @@
<template> <template>
<a-modal class="insert-shp-modal" width="1290px" :destroyOnClose="true" v-model:open="props.openModal" @cancel="closeModal"> <a-modal
class="insert-shp-modal"
width="1290px"
:destroyOnClose="true"
v-model:open="props.openModal"
@cancel="closeModal"
>
<template #closeIcon> <template #closeIcon>
<CloseCircleOutlined /> <CloseCircleOutlined />
</template> </template>
@ -9,16 +15,12 @@
class="steps" class="steps"
:current="current" :current="current"
label-placement="vertical" label-placement="vertical"
:items="[ :items="[{ title: '选择文件' }, { title: '编辑信息' }, { title: '完成' }]"
{title: '选择文件',},
{title: '编辑信息',},
{title: '完成',},
]"
></a-steps> ></a-steps>
<div class="select-file-div" v-show="current === 0"> <div class="select-file-div" v-show="current === 0">
<div class="upload-div"> <div class="upload-div">
<a-upload-dragger <a-upload-dragger
style="height: 174px; width: 174px;" style="height: 174px; width: 174px"
class="upload-dragger" class="upload-dragger"
v-model:fileList="fileList" v-model:fileList="fileList"
name="file" name="file"
@ -29,16 +31,16 @@
<p class="ant-upload-drag-icon"> <p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined> <inbox-outlined></inbox-outlined>
</p> </p>
<div style="opacity: 0.7;"> <div style="opacity: 0.7">
<a-button :icon="h(PlusOutlined)">文件上传</a-button> <a-button :icon="h(PlusOutlined)">文件上传</a-button>
</div> </div>
</a-upload-dragger> </a-upload-dragger>
</div> </div>
<div class="upload-span"> <div class="upload-span">
<div class="upload-span-content"> <div class="upload-span-content">
<div style="opacity: 0.7;">将文件拖拽到这里或点击上传按钮</div> <div style="opacity: 0.7">将文件拖拽到这里或点击上传按钮</div>
<div style="color: #1E5EFF;">支持扩展名zip</div> <div style="color: #1e5eff">支持扩展名zip</div>
<div style="opacity: 0.7;">zip中需要包含 .shp .shx .dbf 文件 .shp文件大小小于10MB</div> <div style="opacity: 0.7">zip中需要包含 .shp .shx .dbf 文件 .shp文件大小小于10MB</div>
</div> </div>
</div> </div>
<div class="upload-form"> <div class="upload-form">
@ -47,9 +49,10 @@
:model="uploadFrom" :model="uploadFrom"
:label-col="{ style: { width: '75px' } }" :label-col="{ style: { width: '75px' } }"
labelAlign="right" labelAlign="right"
:rules="uploadFormRules"> :rules="uploadFormRules"
>
<a-form-item label="服务名称" name="serverName"> <a-form-item label="服务名称" name="serverName">
<a-input v-model:value="uploadFrom.serverName" placeholder="请输入服务名称"/> <a-input v-model:value="uploadFrom.serverName" placeholder="请输入服务名称" />
</a-form-item> </a-form-item>
<a-form-item label="空间参考" name="spaceType"> <a-form-item label="空间参考" name="spaceType">
<!-- <a-input v-model:value="uploadFrom.spaceType" /> --> <!-- <a-input v-model:value="uploadFrom.spaceType" /> -->
@ -60,7 +63,7 @@
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="表名" name="tableName"> <a-form-item label="表名" name="tableName">
<a-input v-model:value="uploadFrom.tableName" placeholder="请输入表名"/> <a-input v-model:value="uploadFrom.tableName" placeholder="请输入表名" />
</a-form-item> </a-form-item>
</a-form> </a-form>
<div class="upload-span-button"> <div class="upload-span-button">
@ -69,10 +72,16 @@
</div> </div>
</div> </div>
<div class="edit-info-div" v-show="current === 1"> <div class="edit-info-div" v-show="current === 1">
<a-table :columns="columns" :data-source="dataList" :pagination="false" :bordered="true" :scroll="{y: 260}"> <a-table
:columns="columns"
:data-source="dataList"
:pagination="false"
:bordered="true"
:scroll="{ y: 260 }"
>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'type'"> <template v-if="column.key === 'type'">
<a-select v-model:value="record.type" style="width: 120px;"> <a-select v-model:value="record.type" style="width: 120px">
<a-select-option value="geometry">geometry</a-select-option> <a-select-option value="geometry">geometry</a-select-option>
<a-select-option value="varchar">varchar</a-select-option> <a-select-option value="varchar">varchar</a-select-option>
<a-select-option value="text">text</a-select-option> <a-select-option value="text">text</a-select-option>
@ -97,13 +106,15 @@
<div class="insert-list-button" @click="insertListItem"></div> <div class="insert-list-button" @click="insertListItem"></div>
<div class="footer-button"> <div class="footer-button">
<a-button @click="current--"></a-button> <a-button @click="current--"></a-button>
<a-button style="margin-left: 25px;" type="primary" @click="submitDataList"></a-button> <a-button style="margin-left: 25px" type="primary" @click="submitDataList"
>下一步</a-button
>
</div> </div>
</div> </div>
<div class="submit-success" v-show="current === 2"> <div class="submit-success" v-show="current === 2">
<div class="success-content"> <div class="success-content">
<CheckCircleOutlined style="font-size: 100px;color: #1FD286;margin-bottom:30px"/> <CheckCircleOutlined style="font-size: 100px; color: #1fd286; margin-bottom: 30px" />
<div style="margin-bottom:19px;font-size:26px">导入成功</div> <div style="margin-bottom: 19px; font-size: 26px">导入成功</div>
<div><a-button type="primary">查看数据</a-button></div> <div><a-button type="primary">查看数据</a-button></div>
</div> </div>
</div> </div>
@ -112,209 +123,227 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineEmits, defineProps, ref, h, reactive, onUnmounted, toRaw } from "vue" import { defineEmits, defineProps, ref, h, reactive, onUnmounted, toRaw } from 'vue';
import { CloseCircleOutlined, PlusOutlined, DeleteOutlined,CheckCircleOutlined } from "@ant-design/icons-vue" import {
import './index.scss' CloseCircleOutlined,
import { InboxOutlined } from '@ant-design/icons-vue'; PlusOutlined,
import { message } from 'ant-design-vue'; DeleteOutlined,
import type { UploadChangeParam } from 'ant-design-vue'; CheckCircleOutlined,
import type { UploadProps } from 'ant-design-vue'; } from '@ant-design/icons-vue';
// import { uploadShp } from '@/api/sys/analysis.ts' import './index.scss';
import axios from 'axios' import { InboxOutlined } from '@ant-design/icons-vue';
import { v4 as uuidv4 } from 'uuid'; import { message } from 'ant-design-vue';
import type { UploadChangeParam } from 'ant-design-vue';
import type { UploadProps } from 'ant-design-vue';
// import { uploadShp } from '@/api/sys/analysis.ts'
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
const current = ref(0) const current = ref(0);
const fileList = ref<UploadProps['fileList']>([]); const fileList = ref<UploadProps['fileList']>([]);
const props = defineProps(['openModal']) const props = defineProps(['openModal']);
const emits = defineEmits(['update:openModal']) const emits = defineEmits(['update:openModal']);
const uploadFrom = reactive({ const uploadFrom = reactive({
serverName:'', serverName: '',
spaceType:null, spaceType: null,
tableName:'', tableName: '',
}) });
const formRef = ref() const formRef = ref();
const dataList = ref([]) const dataList = ref([]);
const isShp = ref(false) const isShp = ref(false);
// todo // todo
const columns = [ const columns = [
{title: 'Shp原始字段',dataIndex: 'name',key: 'name'}, { title: 'Shp原始字段', dataIndex: 'name', key: 'name' },
{title: '数据类型',dataIndex: 'type',key: 'type'}, { title: '数据类型', dataIndex: 'type', key: 'type' },
{title: '数据长度',dataIndex: 'length',key: 'length'}, { title: '数据长度', dataIndex: 'length', key: 'length' },
{title: '英文名称',dataIndex: 'refName',key: 'refName'}, { title: '英文名称', dataIndex: 'refName', key: 'refName' },
{title: '中文名称',dataIndex: 'initName',key: 'initName'}, { title: '中文名称', dataIndex: 'initName', key: 'initName' },
{title: '操作',dataIndex: 'operation',key: 'operation'}, { title: '操作', dataIndex: 'operation', key: 'operation' },
] ];
const uploadFormRules = { const uploadFormRules = {
serverName: [{ required: true, message: '请输入服务名称', trigger: 'blur' },], serverName: [{ required: true, message: '请输入服务名称', trigger: 'blur' }],
spaceType: [{ required: true, message: '请选择参考系', trigger: 'blur' },], spaceType: [{ required: true, message: '请选择参考系', trigger: 'blur' }],
tableName: [{ required: true, message: '请输入表名', trigger: 'blur' },], tableName: [{ required: true, message: '请输入表名', trigger: 'blur' }],
} };
const beforeUpload: UploadProps['beforeUpload'] = (file) => { const beforeUpload: UploadProps['beforeUpload'] = (file) => {
console.log('beforeUpload',file) console.log('beforeUpload', file);
fileList.value = [file]; fileList.value = [file];
return false; return false;
}; };
const submitShp = () => { const submitShp = () => {
formRef.value.validate().then(() => { formRef.value
if(fileList.value?.length < 1){ .validate()
message.warning('请选择shp文件') .then(() => {
return if (fileList.value?.length < 1) {
} message.warning('请选择shp文件');
let formData = new FormData(); return;
const [proxyFile] = fileList.value }
let file = proxyFile.originFileObj let formData = new FormData();
formData.append('file', file) const [proxyFile] = fileList.value;
formData.append('serverName',uploadFrom.serverName) let file = proxyFile.originFileObj;
formData.append('spaceType',uploadFrom.spaceType) formData.append('file', file);
formData.append('tableName',uploadFrom.tableName) formData.append('serverName', uploadFrom.serverName);
axios.post('http://221.2.83.254:9006/geoserver/uploadFile',formData,{headers: {'Content-Type': 'multipart/form-data'}}).then(res => { formData.append('spaceType', uploadFrom.spaceType);
console.log(res) formData.append('tableName', uploadFrom.tableName);
let data = { axios
"dataType": "线", .post('http://221.2.83.254:9006/geoserver/uploadFile', formData, {
"heads": [ headers: { 'Content-Type': 'multipart/form-data' },
{ })
"name": "geom", .then((res) => {
"length": "", console.log(res);
"type": "geometry" let data = {
}, dataType: '线',
{ heads: [
"name": "MINGCHENG", {
"length": 319, name: 'geom',
"type": "varchar" length: '',
}, type: 'geometry',
{ },
"name": "CHANGDU", {
"length": 319, name: 'MINGCHENG',
"type": "varchar" length: 319,
} type: 'varchar',
], },
"styleName": null, {
"tableName": "aa" name: 'CHANGDU',
} length: 319,
let showData = data.heads.map(item => { type: 'varchar',
return {...item,refName:item.name.toLowerCase(),initName:item.name,key:uuidv4()} },
],
styleName: null,
tableName: 'aa',
};
let showData = data.heads.map((item) => {
return {
...item,
refName: item.name.toLowerCase(),
initName: item.name,
key: uuidv4(),
};
});
dataList.value = showData;
current.value++;
})
.catch((err) => {
console.log(err);
});
}) })
dataList.value = showData .catch((err) => {
current.value++ console.log(err);
}).catch(err => { });
console.log(err) };
}) const closeModal = () => {
}).catch(err => { emits('update:openModal', false);
console.log(err) formRef.value.resetFields();
}) fileList.value = [];
} current.value = 0;
const closeModal = () => { };
emits('update:openModal', false) const deleteListItem = (record) => {
formRef.value.resetFields() dataList.value = dataList.value.filter((item) => item.key !== record.key);
fileList.value = [] };
current.value = 0 const insertListItem = () => {
} dataList.value.push({
const deleteListItem = (record) => { key: uuidv4(),
dataList.value = dataList.value.filter(item => item.key !== record.key) name: '',
} type: '',
const insertListItem = () => { length: '',
dataList.value.push({ refName: '',
key:uuidv4(), initName: '',
name:'', });
type:'', };
length:'', const submitDataList = () => {
refName:'', console.log(dataList.value);
initName:'', current.value++;
}) };
}
const submitDataList = () => {
console.log(dataList.value)
current.value++
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.insert-shp-modal{ .insert-shp-modal {
.title{ .title {
height: 77px; height: 77px;
border-bottom: 1px solid #D7DBEC; border-bottom: 1px solid #d7dbec;
display: flex;
align-items: center;
padding-left: 63px;
font-size: 28px;
}
.content{
padding: 106px;
}
.steps{
// margin-bottom: 80px;
}
.select-file-div{
padding-left: 52px;
padding-top: 80px;
display: flex;
.upload-div{
width:200px;
height:200px;
background: #FFFFFF;
box-shadow: 0px 52px 103px 0px rgba(192,199,218,0.35);
border-radius: 4px;
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
.upload-dragger{ padding-left: 63px;
height: 174px; font-size: 28px;
}
} }
.upload-span{ .content {
margin-left: 40px; padding: 106px;
}
.steps {
// margin-bottom: 80px;
}
.select-file-div {
padding-left: 52px;
padding-top: 80px;
display: flex; display: flex;
flex-direction: column; .upload-div {
justify-content: space-between; width: 200px;
.upload-span-content{ height: 200px;
font-size:16px; background: #ffffff;
margin-top: 8px; box-shadow: 0px 52px 103px 0px rgba(192, 199, 218, 0.35);
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
.upload-dragger {
height: 174px;
}
}
.upload-span {
margin-left: 40px;
display: flex;
flex-direction: column;
justify-content: space-between;
.upload-span-content {
font-size: 16px;
margin-top: 8px;
}
}
.upload-form {
flex: 1;
margin-left: 40px;
.upload-span-button {
display: flex;
justify-content: flex-end;
}
} }
} }
.upload-form{ .edit-info-div {
flex: 1; padding-top: 26px;
margin-left:40px; .footer-button {
.upload-span-button{ margin-top: 20px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
} }
.insert-list-button {
background-color: #91b0ff;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
user-select: none;
cursor: pointer;
height: 30px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
font-weight: 400;
transition: 1s;
}
.insert-list-button:hover {
font-weight: 900;
color: #000;
}
}
.submit-success {
.success-content {
width: 200px;
align-items: center;
margin: auto;
display: flex;
flex-direction: column;
}
} }
} }
.edit-info-div{
padding-top:26px;
.footer-button{
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.insert-list-button{
background-color: #91b0ff;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
user-select: none;
cursor: pointer;
height: 30px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
font-weight: 400;
transition: 1s;
}
.insert-list-button:hover{
font-weight: 900;
color:#000;
}
}
.submit-success{
.success-content{
width: 200px;
align-items: center;
margin: auto;
display: flex;
flex-direction: column;
}
}
}
</style> </style>

View File

@ -2,7 +2,13 @@
<div class="LayerComponent"> <div class="LayerComponent">
<div class="title">图层</div> <div class="title">图层</div>
<div class="insert-layer"> <div class="insert-layer">
<a-button class="add-layer-button" type="primary" :icon="h(PlusOutlined)" @click="openInsertShpModal"></a-button> <a-button
class="add-layer-button"
type="primary"
:icon="h(PlusOutlined)"
@click="openInsertShpModal"
>添加图层</a-button
>
<span class="clear-layer-button">清空</span> <span class="clear-layer-button">清空</span>
</div> </div>
<div class="show-current-layer"> <div class="show-current-layer">
@ -12,21 +18,31 @@
</div> </div>
</div> </div>
<div class="show-layers"> <div class="show-layers">
<div :class="`show-layer-item ${isSelected === item.id ? 'select-list-item': ''}`" <div
v-for="item in dataList" :key='item.id' @click="selectLayer(item.id)"> :class="`show-layer-item ${isSelected === item.id ? 'select-list-item' : ''}`"
<a-checkbox v-model:checked="item.checked"/> v-for="item in dataList"
:key="item.id"
@click="selectLayer(item.id)"
>
<a-checkbox v-model:checked="item.checked" />
<a-image <a-image
:width="119" :width="119"
:height="87" :height="87"
style="margin-left: 10px;border-radius: 5px;" style="margin-left: 10px; border-radius: 5px"
src="https://gw.alipayobjects.com/zos/antfincdn/cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp" src="https://gw.alipayobjects.com/zos/antfincdn/cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp"
:preview="false" :preview="false"
:fallback="errorImage"/> :fallback="errorImage"
/>
<div class="layer-item-text"> <div class="layer-item-text">
<div class="item-title">名称 {{ item.name }}</div> <div class="item-title">名称 {{ item.name }}</div>
<div class="item-control"> <div class="item-control">
<a-button type="primary" size="small" style="background-color:#09B66D;margin-right: 7px;">查看数据</a-button> <a-button
<a-button type="primary" size="small" style="background-color: #0081FF;">操作</a-button> type="primary"
size="small"
style="background-color: #09b66d; margin-right: 7px"
>查看数据</a-button
>
<a-button type="primary" size="small" style="background-color: #0081ff">操作</a-button>
</div> </div>
</div> </div>
</div> </div>
@ -35,158 +51,158 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PlusOutlined } from '@ant-design/icons-vue' import { PlusOutlined } from '@ant-design/icons-vue';
import { h, defineEmits, ref } from "vue" import { h, defineEmits, ref } from 'vue';
import { errorImage } from "../util.ts" import { errorImage } from '../util.ts';
const dataList = ref([ const dataList = ref([
{ {
id:1, id: 1,
name:"111", name: '111',
checked:true, checked: true,
}, },
{ {
id:2, id: 2,
name:"222", name: '222',
checked:false, checked: false,
}, },
{ {
id:3, id: 3,
name:"333", name: '333',
checked:false, checked: false,
}, },
{ {
id:4, id: 4,
name:"444", name: '444',
checked:false, checked: false,
}, },
{ {
id:5, id: 5,
name:"555", name: '555',
checked:false, checked: false,
}, },
{ {
id:6, id: 6,
name:"666", name: '666',
checked:false, checked: false,
}, },
{ {
id:7, id: 7,
name:"777", name: '777',
checked:false, checked: false,
}, },
{ {
id:8, id: 8,
name:"888", name: '888',
checked:false, checked: false,
}, },
]) ]);
const isSelected = ref() const isSelected = ref();
const emits = defineEmits(["changeOpenModal","changeOpenInsertShpModal"]) const emits = defineEmits(['changeOpenModal', 'changeOpenInsertShpModal']);
const changeClick = () => { const changeClick = () => {
emits("changeOpenModal",true) emits('changeOpenModal', true);
} };
const openInsertShpModal = () => { const openInsertShpModal = () => {
emits("changeOpenInsertShpModal",true) emits('changeOpenInsertShpModal', true);
} };
const selectLayer = (id:number) => { const selectLayer = (id: number) => {
isSelected.value = id isSelected.value = id;
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.LayerComponent{ .LayerComponent {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 356px; width: 356px;
height: 100%; height: 100%;
background-color: #E0E5ED; background-color: #e0e5ed;
.title{ .title {
height:61px; height: 61px;
font-size: 26px; font-size: 26px;
display: flex;
justify-content: center;
align-items: center;
}
.insert-layer{
height:61px;
background-color: #fff;
padding-left: 16px;
padding-right: 14px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.add-layer-button{
background-color: #0081FF;
}
.clear-layer-button{
user-select: none;
cursor: pointer;
}
}
.show-current-layer{
padding-left: 15px;
padding-right: 15px;
.current-layer-div{
height: 37px;
display: flex; display: flex;
user-select: none;; justify-content: center;
.current-layer-title{ align-items: center;
background-color: #fff; }
flex: 1; .insert-layer {
display: flex; height: 61px;
align-items: center; background-color: #fff;
border-top-left-radius: 5px; padding-left: 16px;
border-bottom-left-radius: 5px; padding-right: 14px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.add-layer-button {
background-color: #0081ff;
} }
.current-layer-title::before{ .clear-layer-button {
content: ""; user-select: none;
display: block;
width: 7px;
height: 7px;
background-color: #09B66D;
border-radius: 50%;
margin: 6px;
}
.create-new-layer-button{
width: 106px;
background-color: #0081FF;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
cursor: pointer; cursor: pointer;
} }
} }
} .show-current-layer {
.show-layers{ padding-left: 15px;
height: calc(100% - 179px); padding-right: 15px;
padding-top: 14px; .current-layer-div {
padding-left: 15px; height: 37px;
padding-right: 15px;
overflow: auto;
.show-layer-item{
background-color: #fff;
height: 133px;
border-radius: 5px;
padding: 23px 10px;
display: flex;
margin-bottom: 14px;
.layer-item-text{
margin-left: 20px;
flex: 1;
display: flex; display: flex;
flex-direction: column; user-select: none;
justify-content: space-between; .current-layer-title {
background-color: #fff;
flex: 1;
display: flex;
align-items: center;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.current-layer-title::before {
content: '';
display: block;
width: 7px;
height: 7px;
background-color: #09b66d;
border-radius: 50%;
margin: 6px;
}
.create-new-layer-button {
width: 106px;
background-color: #0081ff;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
cursor: pointer;
}
} }
} }
.show-layers {
height: calc(100% - 179px);
padding-top: 14px;
padding-left: 15px;
padding-right: 15px;
overflow: auto;
.show-layer-item {
background-color: #fff;
height: 133px;
border-radius: 5px;
padding: 23px 10px;
display: flex;
margin-bottom: 14px;
.layer-item-text {
margin-left: 20px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
}
.select-list-item {
border: 1px solid;
}
} }
.select-list-item{
border:1px solid;
}
}
</style> </style>

View File

@ -1,6 +1,8 @@
<template> <template>
<div class="LayerControl"> <div class="LayerControl">
<a-button type="primary" class="blue line-up" :icon="h(EditOutlined)">绘制</a-button> <a-button type="primary" class="blue line-up" @click="drawClick" :icon="h(EditOutlined)"
>绘制</a-button
>
<a-button type="primary" class="blue line-up" :icon="h(FormOutlined)">编辑</a-button> <a-button type="primary" class="blue line-up" :icon="h(FormOutlined)">编辑</a-button>
<a-button type="primary" class="blue last-line-up" :icon="h(BlockOutlined)">合并</a-button> <a-button type="primary" class="blue last-line-up" :icon="h(BlockOutlined)">合并</a-button>
<a-button type="primary" class="orange line-up" :icon="h(SplitCellsOutlined)">分割</a-button> <a-button type="primary" class="orange line-up" :icon="h(SplitCellsOutlined)">分割</a-button>
@ -12,35 +14,47 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { EditOutlined, FormOutlined, BlockOutlined, import {
SplitCellsOutlined, DragOutlined, DeleteOutlined, RollbackOutlined, CloseCircleOutlined, } from "@ant-design/icons-vue" EditOutlined,
import { h } from "vue" FormOutlined,
BlockOutlined,
SplitCellsOutlined,
DragOutlined,
DeleteOutlined,
RollbackOutlined,
CloseCircleOutlined,
} from '@ant-design/icons-vue';
import { h } from 'vue';
const emit = defineEmits(['draw']);
function drawClick() {
emit('draw');
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.LayerControl{ .LayerControl {
position: absolute; position: absolute;
top: 20px; top: 20px;
left: 386px; left: 386px;
background-color: #fff; background-color: #fff;
padding: 13px 13px 8px 13px; padding: 13px 13px 8px 13px;
button{ button {
margin-bottom: 5px; margin-bottom: 5px;
}
}
.blue {
background-color: #0081ff;
}
.orange {
background-color: #ff8a48;
}
.green {
background-color: #09b66d;
}
.line-up {
margin-right: 10px;
}
.last-line-up {
margin-right: 15px;
} }
}
.blue{
background-color: #0081FF;
}
.orange{
background-color: #FF8A48;
}
.green{
background-color: #09B66D;
}
.line-up{
margin-right: 10px;
}
.last-line-up{
margin-right: 15px
}
</style> </style>

View File

@ -11,285 +11,283 @@
/> />
<img v-show="nextMapControl.length > 0" @click="handlerUnDraw" src="/del.png" title="清除" /> <img v-show="nextMapControl.length > 0" @click="handlerUnDraw" src="/del.png" title="清除" />
</div> --> </div> -->
<LayerComponent @changeOpenModal="changeOpenModal" @changeOpenInsertShpModal="changeOpenInsertShpModal"/> <LayerComponent
<LayerControl /> @changeOpenModal="changeOpenModal"
<UseModal v-model:openModal="openModal" @changeOpenModal="changeOpenModal"/> @changeOpenInsertShpModal="changeOpenInsertShpModal"
/>
<LayerControl @draw="handlerDrawPolygon" />
<UseModal v-model:openModal="openModal" @changeOpenModal="changeOpenModal" />
<InsertShp v-model:openModal="insertShpModal" /> <InsertShp v-model:openModal="insertShpModal" />
<DataListComponent /> <DataListComponent />
<RightShowInfo /> <RightShowInfo v-model:openModal="openRightInfo" />
</div> </div>
</template> </template>
<script lang="ts" setup>
import { onMounted, onUnmounted, defineProps, reactive, ref } from 'vue';
import { useMessage } from '@/hooks/web/useMessage';
import mapboxgl, { Map,Popup } from 'mapbox-gl';
// <script lang="ts" setup>
import MapboxDraw from "@mapbox/mapbox-gl-draw"; import { onMounted, onUnmounted, defineProps, reactive, ref } from 'vue';
import { useMessage } from '@/hooks/web/useMessage';
import mapboxgl, { Map, Popup } from 'mapbox-gl';
import U from 'mapbox-gl-utils'; //
import 'mapbox-gl/dist/mapbox-gl.css'; import MapboxDraw from '@mapbox/mapbox-gl-draw';
import './src/index.less';
import { MapboxConfig, MapboxDefaultStyle, MapControlConfig } from './src/config';
import { MP } from './src/MP';
import { DrawingType } from '@/enums/mapEnum';
import { import U from 'mapbox-gl-utils';
SnapPolygonMode, import 'mapbox-gl/dist/mapbox-gl.css';
SnapPointMode, import './src/index.less';
SnapLineMode, import { MapboxConfig, MapboxDefaultStyle, MapControlConfig } from './src/config';
SnapModeDrawStyles, import { MP } from './src/MP';
SnapDirectSelect, import { DrawingType } from '@/enums/mapEnum';
} from "mapbox-gl-draw-snap-mode";
import LayerComponent from './LayerComponent/index.vue'
import LayerControl from './LayerControl/index.vue'
import UseModal from './Modal/index.vue'
import InsertShp from './InsertShp/index.vue'
import DataListComponent from './DataListComponent/index.vue'
import RightShowInfo from './RightShowInfo/index.vue'
const openModal = ref(false); import {
const insertShpModal = ref(false) SnapPolygonMode,
const changeOpenModal = (value) => { SnapPointMode,
openModal.value = value SnapLineMode,
} SnapModeDrawStyles,
const changeOpenInsertShpModal = (value) => { SnapDirectSelect,
insertShpModal.value = value } from 'mapbox-gl-draw-snap-mode';
} import LayerComponent from './LayerComponent/index.vue';
import LayerControl from './LayerControl/index.vue';
// map import UseModal from './Modal/index.vue';
interface MapboxOptionsInterface { import InsertShp from './InsertShp/index.vue';
mapOptions: mapboxgl.MapboxOptions; import DataListComponent from './DataListComponent/index.vue';
control: DrawingType[]; import RightShowInfo from './RightShowInfo/index.vue';
}
const props = defineProps<MapboxOptionsInterface>();
let nextMapControl: Array<any> = reactive([]);
nextMapControl = props.control
? props.control.map((item) => {
console.log('item::: ', item);
return MapControlConfig[item];
})
: [];
console.log('nextMapControl::: ', nextMapControl); const openModal = ref(false);
const insertShpModal = ref(false);
// const openRightInfo = ref(false);
let map: Map; const changeOpenModal = (value) => {
let popup:Popup; openModal.value = value;
let clickPoisition:Array<number> = []; };
let selectFeature:Object = {}; const changeOpenInsertShpModal = (value) => {
let mp: any = null; insertShpModal.value = value;
};
const { createConfirm, createMessage } = useMessage(); // map
interface MapboxOptionsInterface {
mapOptions: mapboxgl.MapboxOptions;
control: DrawingType[];
}
const props = defineProps<MapboxOptionsInterface>();
// emit let nextMapControl: Array<any> = reactive([]);
// nextMapControl = props.control
const emit = defineEmits(['mapOnLoad', 'mapDraw']); ? props.control.map((item) => {
console.log('item::: ', item);
return MapControlConfig[item];
})
: [];
onMounted(() => { console.log('nextMapControl::: ', nextMapControl);
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
map = initMap();
map.on('load', () => {
//mapbox-gl-utils
// U.init(map);
// mp = new MP(map);
// emit('mapOnLoad', map);
// //
handlerInitDrawTool(); let map: Map;
let popup: Popup;
let clickPoisition: Array<number> = [];
let selectFeature: Object = {};
let mp: any = null;
map.on("click",(e)=>{ const { createConfirm, createMessage } = useMessage();
clickPoisition = e.lngLat
})
map.on("draw.selectionchange",(e)=>{ // emit
handlerCopyToTargetLayer(e); //
}) const emit = defineEmits(['mapOnLoad', 'mapDraw']);
window.handlerCopyFeature = handlerCopyFeature; onMounted(() => {
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
map = initMap();
map.on('load', () => {
//mapbox-gl-utils
// U.init(map);
mp = new MP(map);
emit('mapOnLoad', map);
//
handlerInitDrawTool();
map.on('click', (e) => {
clickPoisition = e.lngLat;
}); });
map.on('draw.selectionchange', (e) => {
handlerCopyToTargetLayer(e);
});
window.handlerCopyFeature = handlerCopyFeature;
}); });
// });
// //
onUnmounted(() => { //
map ? map.remove() : null; onUnmounted(() => {
map ? map.remove() : null;
});
//
//
const initMap = () => {
return new mapboxgl.Map({
container: 'mapContainer',
language: 'zh-cmn',
projection: 'equirectangular', // wgs84
style: MapboxDefaultStyle,
maxZoom: 22,
minZoom: 6,
...props.mapOptions,
}); });
// };
//
const initMap = () => {
return new mapboxgl.Map({
container: 'mapContainer',
language: 'zh-cmn',
projection: 'equirectangular', // wgs84
style: MapboxDefaultStyle,
maxZoom: 22,
minZoom: 6,
...props.mapOptions,
});
};
const handlerMapControlClick = (handler: string) => {
handler === 'handlerDrawPoint' && handlerDrawPoint();
handler === 'handlerDrawLineString' && handlerDrawLineString();
handler === 'handlerDrawPolygon' && handlerDrawPolygon();
};
//
const handlerDrawPoint = () => {
mp.draw('Point');
mp.on('Point', function (e) {
emit('mapDraw', 'Point', e);
});
};
//线
const handlerDrawLineString = () => {
mp.draw('LineString');
mp.on('LineString', function (e) {
emit('mapDraw', 'LineString', e);
});
};
//
const handlerDrawPolygon = () => {
mp.draw('Polygon');
mp.on('Polygon', function (e) {
emit('mapDraw', 'Polygon', e);
});
};
//
const handlerUnDraw = () => {
mp.deleteDraw();
emit('mapDraw', 'cancel');
};
//
const handlerInitDrawTool = () => {
let drawTool = new MapboxDraw({ const handlerMapControlClick = (handler: string) => {
modes: { handler === 'handlerDrawPoint' && handlerDrawPoint();
...MapboxDraw.modes, handler === 'handlerDrawLineString' && handlerDrawLineString();
draw_point: SnapPointMode, handler === 'handlerDrawPolygon' && handlerDrawPolygon();
draw_polygon: SnapPolygonMode, };
draw_line_string: SnapLineMode, //
direct_select: SnapDirectSelect, const handlerDrawPoint = () => {
}, mp.draw('Point');
// Styling guides mp.on('Point', function (e) {
styles: SnapModeDrawStyles, emit('mapDraw', 'Point', e);
userProperties: true, });
// Config snapping features };
snap: true, //线
snapOptions: { const handlerDrawLineString = () => {
snapPx: 15, // defaults to 15 mp.draw('LineString');
snapToMidPoints: true, // defaults to false mp.on('LineString', function (e) {
snapVertexPriorityDistance: 0.0025, // defaults to 1.25 emit('mapDraw', 'LineString', e);
}, });
guides: true, };
}); //
const handlerDrawPolygon = () => {
mp.draw('Polygon');
mp.on('Polygon', function (e) {
emit('mapDraw', 'Polygon', e);
});
};
//
const handlerUnDraw = () => {
mp.deleteDraw();
emit('mapDraw', 'cancel');
};
map.addControl(drawTool, "top-right"); //
} const handlerInitDrawTool = () => {
let drawTool = new MapboxDraw({
modes: {
...MapboxDraw.modes,
draw_point: SnapPointMode,
draw_polygon: SnapPolygonMode,
draw_line_string: SnapLineMode,
direct_select: SnapDirectSelect,
},
// Styling guides
styles: SnapModeDrawStyles,
userProperties: true,
// Config snapping features
snap: true,
snapOptions: {
snapPx: 15, // defaults to 15
snapToMidPoints: true, // defaults to false
snapVertexPriorityDistance: 0.0025, // defaults to 1.25
},
guides: true,
});
// map.addControl(drawTool, 'top-right');
const handlerCopyToTargetLayer = (e) => { };
if(e.features.length>0){
if(popup){
popup.remove();
popup = null;
}
selectFeature = e.features[0]; //
const handlerCopyToTargetLayer = (e) => {
popup = new mapboxgl.Popup({ if (e.features.length > 0) {
closeButton: false, if (popup) {
closeOnClick: false,
});
// popup
popup
.setLngLat(clickPoisition)
.setHTML(`
<div style="color:#333;padding:3px 12px;cursor:pointer;" type="primary" icon="el-icon-search" onclick="handlerCopyFeature();">复制当前图斑</div>`
).addTo(map);
}else{
popup.remove();
}
}
const handlerCopyFeature = () => {
console.log(selectFeature)
popup.remove(); popup.remove();
createMessage.success("复制成功!") popup = null;
}
selectFeature = e.features[0];
popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false,
});
// popup
popup
.setLngLat(clickPoisition)
.setHTML(
`
<div style="color:#333;padding:3px 12px;cursor:pointer;" type="primary" icon="el-icon-search" onclick="handlerCopyFeature();">复制当前图斑</div>`,
)
.addTo(map);
} else {
popup.remove();
} }
</script> };
const handlerCopyFeature = () => {
console.log(selectFeature);
popup.remove();
createMessage.success('复制成功!');
};
</script>
<style> <style>
.mapboxgl-ctrl-group:not(:empty){ .mapboxgl-ctrl-group:not(:empty) {
box-shadow: none; box-shadow: none;
} }
.mapboxgl-ctrl-group{ .mapboxgl-ctrl-group {
background:none!important; background: none !important;
} }
.mapbox-gl-draw_ctrl-draw-btn{ .mapbox-gl-draw_ctrl-draw-btn {
width:40px!important; width: 40px !important;
height:40px!important; height: 40px !important;
float:left; float: left;
border-radius: 50%; border-radius: 50%;
} }
.mapboxgl-ctrl-top-right{ .mapboxgl-ctrl-top-right {
} }
.mapboxgl-ctrl-group button+button{ .mapboxgl-ctrl-group button + button {
border:0px; border: 0px;
margin:0px 3px; margin: 0px 3px;
} }
.mapbox-gl-draw_ctrl-draw-btn:hover{ .mapbox-gl-draw_ctrl-draw-btn:hover {
transform: scale(1.2); transform: scale(1.2);
} }
.mapbox-gl-draw_polygon{ .mapbox-gl-draw_polygon {
background-image:url(/polygon.png); background-image: url(/polygon.png);
background-size:100% 100%; background-size: 100% 100%;
width:100px; width: 100px;
height:100px; height: 100px;
} }
.mapbox-gl-draw_point{ .mapbox-gl-draw_point {
background-image:url(/point.png); background-image: url(/point.png);
background-size:100% 100%; background-size: 100% 100%;
width:100px; width: 100px;
height:100px; height: 100px;
} }
.mapbox-gl-draw_line{ .mapbox-gl-draw_line {
background-image:url(/line.png); background-image: url(/line.png);
background-size:100% 100%; background-size: 100% 100%;
width:100px; width: 100px;
height:100px; height: 100px;
} }
.mapbox-gl-draw_trash{ .mapbox-gl-draw_trash {
background-image:url(/del.png); background-image: url(/del.png);
background-size:100% 100%; background-size: 100% 100%;
width:100px; width: 100px;
height:100px; height: 100px;
} }
.mapbox-gl-draw_combine{ .mapbox-gl-draw_combine {
background-image:url(/combine.png); background-image: url(/combine.png);
background-size:100% 100%; background-size: 100% 100%;
width:100px; width: 100px;
height:100px; height: 100px;
} }
.mapbox-gl-draw_uncombine{
background-image:url(/uncombine.png);
background-size:100% 100%;
width:100px;
height:100px;
}
.mapbox-gl-draw_uncombine {
background-image: url(/uncombine.png);
background-size: 100% 100%;
width: 100px;
height: 100px;
}
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<a-drawer class="right-show-info" placement="right" :open="open" @close="()=>open=false"> <a-drawer class="right-show-info" placement="right" :open="open" @close="() => (open = false)">
<div class="title"> <div class="title">
<div class="tag"></div> <div class="tag"></div>
<div class="title-text">操作</div> <div class="title-text">操作</div>
@ -16,39 +16,46 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue" import { ref, defineProps, watch } from 'vue';
import './index.scss' import './index.scss';
const open = ref(true) const open = ref(true);
const props = defineProps(['openModal']);
watch(
() => props.openModal,
(newValue) => {
open.value = newValue;
},
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.right-show-info { .right-show-info {
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
width: 356px; width: 356px;
height: 100%; height: 100%;
background-color: #FFF; background-color: #fff;
.title{ .title {
height: 61px; height: 61px;
padding-left: 26px; padding-left: 26px;
display:flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid #D9E2F2; border-bottom: 1px solid #d9e2f2;
.tag{ .tag {
width: 3px; width: 3px;
height: 23px; height: 23px;
background-color:#0081FF; background-color: #0081ff;
margin-right: 19px; margin-right: 19px;
}
.title-text {
color: #141d27;
font-size: 24px;
}
} }
.title-text{ .content {
color: #141D27 ; height: calc(100% - 61px);
font-size: 24px; padding: 25px;
} }
} }
.content{
height: calc(100% - 61px);
padding: 25px;
}
}
</style> </style>