Merge pull request '添加地图相关组件' (#1) from main_hzz into main
Reviewed-on: #1
This commit is contained in:
commit
2baa272f9d
@ -19,6 +19,7 @@
|
|||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
"axios": "^1.2.0",
|
"axios": "^1.2.0",
|
||||||
"better-scroll": "^2.4.2",
|
"better-scroll": "^2.4.2",
|
||||||
|
"dayjs": "^1.11.20",
|
||||||
"default-passive-events": "^2.0.0",
|
"default-passive-events": "^2.0.0",
|
||||||
"echarts": "^5.2.2",
|
"echarts": "^5.2.2",
|
||||||
"element-plus": "^2.2.27",
|
"element-plus": "^2.2.27",
|
||||||
|
|||||||
BIN
frontend/src/assets/images/map-dixingtu.png
Normal file
BIN
frontend/src/assets/images/map-dixingtu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
frontend/src/assets/images/map-shiliangtu.png
Normal file
BIN
frontend/src/assets/images/map-shiliangtu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
frontend/src/assets/images/map-yingxiangtu.png
Normal file
BIN
frontend/src/assets/images/map-yingxiangtu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
BIN
frontend/src/assets/images/nineSections-dixing.png
Normal file
BIN
frontend/src/assets/images/nineSections-dixing.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
BIN
frontend/src/assets/images/nineSections-shiliang.png
Normal file
BIN
frontend/src/assets/images/nineSections-shiliang.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
frontend/src/assets/images/nineSections-yingxiang.png
Normal file
BIN
frontend/src/assets/images/nineSections-yingxiang.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
107
frontend/src/components/BaseLayerSwitcher/index.vue
Normal file
107
frontend/src/components/BaseLayerSwitcher/index.vue
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<div class="baselayer-switcher">
|
||||||
|
<div
|
||||||
|
class="switcher-item"
|
||||||
|
v-for="item in data"
|
||||||
|
:key="item.name"
|
||||||
|
:class="{ active: item.name === activeLayer }"
|
||||||
|
@click="activeLayer = item.name"
|
||||||
|
>
|
||||||
|
<img :src="item.img" alt="" />
|
||||||
|
<div class="label">{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="nineSectionsImg">
|
||||||
|
<img :src="nineSectionsImg" alt="" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch, onMounted } from "vue";
|
||||||
|
import mapShiliangtu from "@/assets/images/map-shiliangtu.png";
|
||||||
|
import mapDixingtu from "@/assets/images/map-dixingtu.png";
|
||||||
|
import mapYingxiangtu from "@/assets/images/map-yingxiangtu.png";
|
||||||
|
import nineSectionsShiliang from "@/assets/images/nineSections-shiliang.png";
|
||||||
|
import nineSectionsDixing from "@/assets/images/nineSections-dixing.png";
|
||||||
|
import nineSectionsYingxiang from "@/assets/images/nineSections-yingxiang.png";
|
||||||
|
const data = ref([
|
||||||
|
{ name: "矢量", img: mapShiliangtu },
|
||||||
|
{ name: "地形", img: mapDixingtu },
|
||||||
|
{ name: "影像", img: mapYingxiangtu },
|
||||||
|
]);
|
||||||
|
const nineSectionsImg = ref(nineSectionsShiliang);
|
||||||
|
const nineSectionsData = ref([
|
||||||
|
{ name: "矢量", img: nineSectionsShiliang },
|
||||||
|
{ name: "地形", img: nineSectionsDixing },
|
||||||
|
{ name: "影像", img: nineSectionsYingxiang },
|
||||||
|
]);
|
||||||
|
const activeLayer = ref("矢量");
|
||||||
|
|
||||||
|
watch(activeLayer, (val) => {
|
||||||
|
nineSectionsImg.value =
|
||||||
|
nineSectionsData.value.find((item) => item.name === val)?.img || "";
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.baselayer-switcher {
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 480px;
|
||||||
|
z-index: 200;
|
||||||
|
.switcher-item {
|
||||||
|
background: #d8d8d8;
|
||||||
|
border-radius: 2px;
|
||||||
|
width: 85px;
|
||||||
|
height: 60px;
|
||||||
|
display: none;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 2px 3px;
|
||||||
|
background-color: #00000059;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 2px 0 0 2px / 2px 0px 0px 2px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid #3a7098;
|
||||||
|
.label {
|
||||||
|
background-color: #005293;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.switcher-item:not(:first-child) {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
display: block;
|
||||||
|
border: 1px solid #3a7098;
|
||||||
|
.label {
|
||||||
|
background-color: #005293;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.switcher-item {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nineSectionsImg {
|
||||||
|
position: absolute;
|
||||||
|
right: 56px;
|
||||||
|
bottom: 92px;
|
||||||
|
border: 1px solid grey;
|
||||||
|
pointer-events: none;
|
||||||
|
img {
|
||||||
|
max-width: 100px;
|
||||||
|
width: 100px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,23 +1,46 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="gis-view">
|
<div class="gis-view">
|
||||||
<div id="mapContainer" />
|
<div id="mapContainer" />
|
||||||
</div>
|
<!-- 地图图例 -->
|
||||||
|
<!-- tabType="{baseType[0]?.tagType}"
|
||||||
|
legendData="{legendData}"
|
||||||
|
legendDataMap="{legendDataMap}"
|
||||||
|
setLegendDataMap="{updateLegendDataMap}"
|
||||||
|
dvtpType="{dvtpType}"
|
||||||
|
mapList="{mapList}"
|
||||||
|
loading="{loading}"
|
||||||
|
pointData="{pointData}" -->
|
||||||
|
<MapLegend />
|
||||||
|
<!-- 地图筛选器 -->
|
||||||
|
<MapFilter />
|
||||||
|
<!-- 地图控制器 -->
|
||||||
|
<MapController />
|
||||||
|
<!-- 基础图层切换器 -->
|
||||||
|
<BaseLayerSwitcher />
|
||||||
|
<!-- <MapFilter inverse={true} searchList={mapSearchList} pointData={pointData} fish={fish}
|
||||||
|
wqElementsList={wqElementsList} className={'map-filter'} initialValues={{ timeRange: searchTimeRange, dvtp: dvtpType, year: yearTime }}
|
||||||
|
getFormRef={(ref: any) => (mapFilterFormRef.current = ref)}
|
||||||
|
fetchPointData={fetchPointData} /> -->
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import MapLegend from "@/components/mapLegend/index.vue";
|
||||||
|
import MapFilter from "@/components/mapFilter/index.vue";
|
||||||
|
import MapController from "@/components/mapController/index.vue";
|
||||||
|
import BaseLayerSwitcher from "@/components/baseLayerSwitcher/index.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.gis-view {
|
.gis-view {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
#mapContainer {
|
#mapContainer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: red;
|
background-color: red;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
103
frontend/src/components/mapController/index.vue
Normal file
103
frontend/src/components/mapController/index.vue
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div class="map-controller">
|
||||||
|
<div class="map-controller-group">
|
||||||
|
<div class="map-controller-item" v-for="item in controllers" :key="item.key">
|
||||||
|
<a-tooltip :title="item.name" placement="left">
|
||||||
|
<i class="icon iconfont" :class="'icon-' + item.icon"></i>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
|
const isFullScreen = ref(false);
|
||||||
|
const mapType = ref("2D");
|
||||||
|
const controllers = ref([
|
||||||
|
{
|
||||||
|
name: "全屏",
|
||||||
|
key: "fullScreen",
|
||||||
|
icon: isFullScreen.value ? "exitFullScreen" : "fullScreen",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "定位",
|
||||||
|
key: "positioning",
|
||||||
|
icon: "iconGlobal",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "放大",
|
||||||
|
key: "zoomIn",
|
||||||
|
icon: "zoomIn",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "缩小",
|
||||||
|
key: "zoomOut",
|
||||||
|
icon: "zoomOut",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "3D",
|
||||||
|
key: "dim",
|
||||||
|
icon: mapType.value === "2D" ? "a-3D" : "a-2D",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "图层",
|
||||||
|
// 树形图层组件
|
||||||
|
key: "layerController",
|
||||||
|
icon: "layer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "下载",
|
||||||
|
key: "screenShot",
|
||||||
|
icon: "downLoad",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "梯级",
|
||||||
|
key: "TJ",
|
||||||
|
icon: "tiji",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "倾斜摄影",
|
||||||
|
key: "OSBGController",
|
||||||
|
icon: "obliquePhotography",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "三维漫游",
|
||||||
|
key: "threedRoam",
|
||||||
|
icon: "roaming",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.map-controller {
|
||||||
|
position: absolute;
|
||||||
|
right: 480px;
|
||||||
|
bottom: 114px;
|
||||||
|
z-index: 10;
|
||||||
|
.map-controller-group {
|
||||||
|
box-shadow: 0 1px 2px #00000026;
|
||||||
|
background-color: #fff;
|
||||||
|
border: none;
|
||||||
|
.map-controller-item {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
color: #000;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
.iconfont {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: #005292;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map-controller-group:not(:first-child) {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
75
frontend/src/components/mapFilter/index.vue
Normal file
75
frontend/src/components/mapFilter/index.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<div class="map-filter-container">
|
||||||
|
<div class="toolbar">
|
||||||
|
<a-form :model="formModel" :rules="rules" ref="formRef">
|
||||||
|
<a-row :gutter="10">
|
||||||
|
<a-col>
|
||||||
|
<a-form-item label="" name="siteRangePicker">
|
||||||
|
<a-select
|
||||||
|
v-model:value="formModel.siteRangePicker"
|
||||||
|
placeholder="装机容量"
|
||||||
|
style="width: 120px"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="item in siteRangePicker" :key="item.value">{{
|
||||||
|
item.label
|
||||||
|
}}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col>
|
||||||
|
<a-form-item label="" name="siteRangePicker">
|
||||||
|
<a-select
|
||||||
|
v-model:value="formModel.siteRangePicker"
|
||||||
|
placeholder="请输入关键字检索"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
|
||||||
|
const siteRangePicker = [
|
||||||
|
{ label: "0-10", value: "0-10" },
|
||||||
|
{ label: "10-20", value: "10-20" },
|
||||||
|
{ label: "20-30", value: "20-30" },
|
||||||
|
{ label: "30-40", value: "30-40" },
|
||||||
|
{ label: "40-50", value: "40-50" },
|
||||||
|
{ label: "50-60", value: "50-60" },
|
||||||
|
];
|
||||||
|
const formModel = ref({
|
||||||
|
siteRangePicker: [],
|
||||||
|
});
|
||||||
|
const rules = ref({
|
||||||
|
siteRangePicker: [{ required: true, message: "请选择装机容量" }],
|
||||||
|
});
|
||||||
|
const formRef = ref<any>(null);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.map-filter-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 220px;
|
||||||
|
top: 15px;
|
||||||
|
z-index: 99;
|
||||||
|
padding: 6px 0px;
|
||||||
|
background: #e5edf3;
|
||||||
|
border: none;
|
||||||
|
:deep(.ant-form-item) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
:deep(.ant-row) {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
114
frontend/src/components/mapLegend/index.vue
Normal file
114
frontend/src/components/mapLegend/index.vue
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mapLegendView">
|
||||||
|
<div class="legendTitle">
|
||||||
|
图例
|
||||||
|
<span class="legendBtn" @click="isOpen = !isOpen">
|
||||||
|
<i class="icon iconfont" :class="isOpen ? 'icon-fold' : 'icon-unFold'"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legendContent" v-show="isOpen">
|
||||||
|
<a-spin :spinning="data === 0">
|
||||||
|
<div class="legendGroup" v-for="i in data">
|
||||||
|
<div class="groupTitle">工程</div>
|
||||||
|
<div class="groupContent">
|
||||||
|
<div class="legendItem" v-for="j in 10" :key="j">
|
||||||
|
<div class="legendIcon smallIcon"></div>
|
||||||
|
<div class="legendIconTitle">
|
||||||
|
大型水电站-已建
|
||||||
|
<!-- <span
|
||||||
|
><br />
|
||||||
|
2.、装机容量(万kW)
|
||||||
|
</span> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
const data = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
data.value = 10;
|
||||||
|
}, 1000);
|
||||||
|
console.log(data.value);
|
||||||
|
});
|
||||||
|
const isOpen = ref(true);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mapLegendView {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
min-width: 72px;
|
||||||
|
margin: 24px 0 16px 16px;
|
||||||
|
border: 1px solid #ccdae7;
|
||||||
|
padding: 6px;
|
||||||
|
z-index: 9;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
.legendTitle {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
.legendBtn {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.legendContent {
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 450px;
|
||||||
|
max-height: 392px;
|
||||||
|
overflow-x: scroll;
|
||||||
|
overflow-y: scroll;
|
||||||
|
border-top: 1px solid #eeeeee;
|
||||||
|
overflow-y: hidden;
|
||||||
|
// &::-webkit-scrollbar {
|
||||||
|
// width: 0;
|
||||||
|
// }
|
||||||
|
.legendGroup {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0 4px;
|
||||||
|
.groupTitle {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.groupContent {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 10px 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
.gray {
|
||||||
|
filter: grayscale(100%);
|
||||||
|
color: #00000073;
|
||||||
|
}
|
||||||
|
.legendItem {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding: 4px 0;
|
||||||
|
min-height: 30px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
.legendIcon {
|
||||||
|
width: 22px !important;
|
||||||
|
height: 22px !important;
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
.legendIconTitle {
|
||||||
|
cursor: pointer;
|
||||||
|
flex: 1 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -81,7 +81,7 @@ const selectedItem: any = ref(1);
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/variables.module.scss";
|
@use "@/styles/variables.module.scss" as *;
|
||||||
.jidiSelectorMod {
|
.jidiSelectorMod {
|
||||||
width: 175px;
|
width: 175px;
|
||||||
max-height: 941px;
|
max-height: 941px;
|
||||||
|
|||||||
@ -63,6 +63,9 @@ svg {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
.leftContent {
|
||||||
|
width: 188px;
|
||||||
|
}
|
||||||
.rightContent {
|
.rightContent {
|
||||||
height: 98%;
|
height: 98%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export default ({ mode }: ConfigEnv): UserConfig => {
|
|||||||
// 线上API地址
|
// 线上API地址
|
||||||
//target: 'http://192.168.1.20:8090/',
|
//target: 'http://192.168.1.20:8090/',
|
||||||
// 本地API地址
|
// 本地API地址
|
||||||
target: 'http://10.84.1.66:8093',
|
target: 'http://localhost:8093',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: path =>
|
rewrite: path =>
|
||||||
path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
|
path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user