|
@@ -1,10 +1,157 @@
|
|
|
<template>
|
|
|
- <div id="mapChart"></div>
|
|
|
+ <div class="shouye-index">
|
|
|
+ <div id="mapChart"></div>
|
|
|
+ <!-- 地图工具 -->
|
|
|
+ <div class="map-tools">
|
|
|
+ <div :class="{'map-tool-item':mapToolName!='测距','map-tool-itemActive':mapToolName=='测距'}"
|
|
|
+ @click="handleMapTools('测距')">
|
|
|
+ <img v-if="mapToolName!='测距'" src="@/assets/yujing/map/measure-deactive.png"/>
|
|
|
+ <img v-else src="@/assets/yujing/map/measure-active.png"/>
|
|
|
+ </div>
|
|
|
+ <div :class="{'map-tool-item':mapToolName!='测面','map-tool-itemActive':mapToolName=='测面'}" @click="handleMapTools('测面')">
|
|
|
+ <img v-if="mapToolName!='测面'" src="@/assets/yujing/map/area-deactive.png"/>
|
|
|
+ <img v-else src="@/assets/yujing/map/area-active.png"/>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 勾选框 -->
|
|
|
+ <div class="shouye-checkbox">
|
|
|
+ <el-checkbox v-model="mapCheckbox.wyhChecked" label="望虞河测站" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.tphChecked" label="太浦河测站" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.xmhChecked" label="新孟河测站" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.xmhChecked_js" label="新孟河测站-江苏省共享" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.wyhChecked_lh" label="望虞河-浏河区间河网" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.zdChecked" label="自动监测站" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.lzspChecked" label="蓝藻视频站" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.thsyChecked" label="太湖水源地" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.thlzChecked" label="太湖蓝藻" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.zysyChecked" label="流域片重要水源地" size="small"/>
|
|
|
+ <el-checkbox v-model="mapCheckbox.wrjzysyChecked" label="无人机数据查看" size="small"/>
|
|
|
+ </div>
|
|
|
+ <!-- 图例 -->
|
|
|
+ <div class="shouye-tuli">
|
|
|
+ <div class="tuli-title">图例</div>
|
|
|
+ <div class="tuli-content">
|
|
|
+ <div class="tuli-content-left">
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/blue-circle.png" style="width: 25px;height: 25px;margin-left: 5px;"/>
|
|
|
+ <span style="line-height: 25px;">自动监测站</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/视频监控.png" style="width: 18px;height: 20px;margin:0 5px 0 8px;"/>
|
|
|
+ <span>视频监控站</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/Ⅰ.png" class="left-item-img"/>
|
|
|
+ <span>测站(Ⅰ类水)</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/Ⅱ.png" class="left-item-img"/>
|
|
|
+ <span>测站(Ⅱ类水)</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/Ⅲ.png" class="left-item-img"/>
|
|
|
+ <span>测站(Ⅲ类水)</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/Ⅳ.png" class="left-item-img"/>
|
|
|
+ <span>测站(Ⅳ类水)</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/Ⅴ.png" class="left-item-img"/>
|
|
|
+ <span>测站(Ⅴ类水)</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-left-item">
|
|
|
+ <img src="@/assets/yujing/map/劣Ⅴ.png" class="left-item-img"/>
|
|
|
+ <span>测站(劣Ⅴ类水)</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="tuli-content-right">
|
|
|
+ <div class="content-right-item">
|
|
|
+ <img src="@/assets/yujing/map/square-black.png" class="right-item-img"/>
|
|
|
+ <span>沉水植被</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-right-item">
|
|
|
+ <img src="@/assets/yujing/map/square-brown.png" class="right-item-img"/>
|
|
|
+ <span>沉水植被</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-right-item">
|
|
|
+ <img src="@/assets/yujing/map/square-pink.png" class="right-item-img"/>
|
|
|
+ <span>圈围区</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-right-item">
|
|
|
+ <img src="@/assets/yujing/map/square-yellow.png" class="right-item-img"/>
|
|
|
+ <span>人工养殖水葫芦</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-right-item">
|
|
|
+ <img src="@/assets/yujing/map/square-green.png" class="right-item-img"/>
|
|
|
+ <span>围网养殖</span>
|
|
|
+ </div>
|
|
|
+ <div class="content-right-item">
|
|
|
+ <img src="@/assets/yujing/map/维修.png" class="right-item-img"/>
|
|
|
+ <span>维修中</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="map-select">
|
|
|
+ <el-form
|
|
|
+ ref="mapFormRef"
|
|
|
+ :model="mapForm"
|
|
|
+ label-width="auto"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ <el-form-item label="监测图标:" prop="region">
|
|
|
+ <el-select-v2
|
|
|
+ v-model="mapForm.region"
|
|
|
+ placeholder="请选择要监测的图标"
|
|
|
+ :options="maprRegionOptions"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ <!-- 地图站点信息弹框 -->
|
|
|
+ <div ref="popupRefs" class="map-popup" v-show="showPopup">
|
|
|
+ <div class="map-popup-top">
|
|
|
+ <img src="@/assets/yujing/map/取消.png" @click="closePopup"/>
|
|
|
+ </div>
|
|
|
+ <div class="map-popup-content">
|
|
|
+ <div class="popup-content-left">
|
|
|
+ <span>测站名称:</span>
|
|
|
+ <span>所在河流:</span>
|
|
|
+ <span>最新监测时间:</span>
|
|
|
+ <span>溶解氧(mg/L):</span>
|
|
|
+ <span>高锰酸盐指数(mg/L):</span>
|
|
|
+ <span>氨氮(mg/L):</span>
|
|
|
+ <span>总磷(mg/L):</span>
|
|
|
+ <span>锑(μg/L):</span>
|
|
|
+ </div>
|
|
|
+ <div class="popup-content-right">
|
|
|
+ <span
|
|
|
+ style="color: #4a93f5;cursor: pointer;"
|
|
|
+ @click="handleStnmDialog(mapPopupData,'stnm')"
|
|
|
+ >{{ mapPopupData.stnm }}</span>
|
|
|
+ <span
|
|
|
+ style="color: #4a93f5;cursor: pointer;"
|
|
|
+ @click="handleStnmDialog(mapPopupData,'river')"
|
|
|
+ >{{ mapPopupData.river }}</span>
|
|
|
+ <span>{{ mapPopupData.tm }}</span>
|
|
|
+ <span>{{ mapPopupData.cod }}</span>
|
|
|
+ <span></span>
|
|
|
+ <span></span>
|
|
|
+ <span></span>
|
|
|
+ <span></span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="popup-trangle"></div>
|
|
|
+ </div>
|
|
|
+ <StnmDialog :showStnmDialog="stnmDialogVisible" :stnmData="stnmDialogData" @closeDialog="closeStnmDialog"/>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
-<script setup name="BigscreenIndex">
|
|
|
+<script setup>
|
|
|
import {ElMessage} from 'element-plus';
|
|
|
import 'ol/css';
|
|
|
+import {ScaleLine, defaults as defaultControls} from 'ol/control';
|
|
|
import Map from 'ol/Map';
|
|
|
import View from 'ol/View';
|
|
|
import TileLayer from "ol/layer/Tile";
|
|
@@ -16,12 +163,55 @@ import Fill from "ol/style/Fill";
|
|
|
import Feature from 'ol/Feature';
|
|
|
import Stroke from "ol/style/Stroke";
|
|
|
import Overlay from 'ol/Overlay';
|
|
|
-import { LinearRing } from "ol/geom";
|
|
|
-import { fromExtent } from "ol/geom/Polygon";
|
|
|
+import StnmDialog from "./components/StnmDialog.vue"
|
|
|
+import imgⅣ from "@/assets/yujing/map/Ⅳ.png";
|
|
|
|
|
|
const mapChart = ref(null);
|
|
|
const mapCenter = ref([120.745, 31.120]);
|
|
|
const mapZoom = ref(10.6);
|
|
|
+const mapToolName = ref("");
|
|
|
+const mapCheckbox = ref({
|
|
|
+ wyhChecked: true,
|
|
|
+ tphChecked: true,
|
|
|
+ xmhChecked: false,
|
|
|
+ xmhChecked_js: false,
|
|
|
+ wyhChecked_lh: false,
|
|
|
+ zdChecked: false,
|
|
|
+ lzspChecked: false,
|
|
|
+ thsyChecked: false,
|
|
|
+ thlzChecked: false,
|
|
|
+ zysyChecked: false,
|
|
|
+ wrjzysyChecked: false,
|
|
|
+});
|
|
|
+const mapForm = ref({
|
|
|
+ region:'cod',
|
|
|
+});
|
|
|
+const maprRegionOptions = [
|
|
|
+ {label:"溶解氧(mg/L)",value:'cod'}
|
|
|
+];
|
|
|
+const mapPointData = [
|
|
|
+ {
|
|
|
+ stnm: "太浦闸下",
|
|
|
+ river: "太浦河干流",
|
|
|
+ tm: "2025-08-21 13:51",
|
|
|
+ lgtd: 120.745,
|
|
|
+ lttd: 31.120,
|
|
|
+ cod:10.87,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ stnm: "太浦闸上",
|
|
|
+ river: "太浦河干流",
|
|
|
+ tm: "2025-09-05 15:48",
|
|
|
+ lgtd: 120.545,
|
|
|
+ lttd: 31.020,
|
|
|
+ cod:8.87,
|
|
|
+ },
|
|
|
+];
|
|
|
+const popupRefs = ref(null);
|
|
|
+const showPopup = ref(false);
|
|
|
+const mapPopupData = ref({});
|
|
|
+const stnmDialogVisible = ref(false);
|
|
|
+const stnmDialogData = ref({});
|
|
|
|
|
|
onMounted(() => {
|
|
|
initMap();
|
|
@@ -52,14 +242,276 @@ const initMap = () => {
|
|
|
maxZoom: 16,
|
|
|
projection: 'EPSG:4326',
|
|
|
}),
|
|
|
- layers: [vecLayer,cvaLayer],
|
|
|
+ layers: [vecLayer, cvaLayer],
|
|
|
+ controls: defaultControls({
|
|
|
+ zoom: false,//不显示放大放小按钮
|
|
|
+ rotate: false,//不显示指北针控件
|
|
|
+ attribution: false,//不显示右下角的地图信息控件
|
|
|
+ scaleLine:false,//不显示比例尺控件
|
|
|
+ })
|
|
|
+ });
|
|
|
+ // 添加地图站点
|
|
|
+ let featuresData = [];
|
|
|
+ mapPointData.forEach((item) => {
|
|
|
+ let iconFeature = new Feature({
|
|
|
+ geometry: new Point([item.lgtd,item.lttd]),
|
|
|
+ properties: item,
|
|
|
+ });
|
|
|
+ iconFeature.setStyle(
|
|
|
+ new Style({
|
|
|
+ image: new Icon({
|
|
|
+ src: imgⅣ,
|
|
|
+ anchor: [0.5, 0.5],
|
|
|
+ scale: 0.08,
|
|
|
+ }),
|
|
|
+ })
|
|
|
+ );
|
|
|
+ featuresData.push(iconFeature);
|
|
|
+ })
|
|
|
+ var polygonLayer = new VectorLayer({
|
|
|
+ source:new VectorSource({
|
|
|
+ features: featuresData,
|
|
|
+ }),
|
|
|
+ zIndex:5,
|
|
|
+ visible:true,
|
|
|
+ })
|
|
|
+ mapChart.value.addLayer(polygonLayer);
|
|
|
+ singleclick();
|
|
|
+};
|
|
|
+// 地图点击事件
|
|
|
+const singleclick = () => {
|
|
|
+ let elpopup = popupRefs.value;
|
|
|
+ let popupOverlay = new Overlay({
|
|
|
+ element: elpopup,
|
|
|
+ positioning: "bottom-center",
|
|
|
+ stopEvent: false,
|
|
|
+ offset: [220, 110],
|
|
|
+ });
|
|
|
+ mapChart.value.on("singleclick", (e) => {
|
|
|
+ let feature = mapChart.value.forEachFeatureAtPixel(e.pixel, (feature) => feature);
|
|
|
+ if (feature) {
|
|
|
+ showPopup.value = true;
|
|
|
+ mapPopupData.value = feature.values_.properties;
|
|
|
+ let position = [mapPopupData.value.lgtd, mapPopupData.value.lttd];
|
|
|
+ popupOverlay.setPosition(position);
|
|
|
+ }
|
|
|
});
|
|
|
+ // 设置弹窗位置
|
|
|
+ mapChart.value.addOverlay(popupOverlay);
|
|
|
};
|
|
|
+// 关闭站点信息弹框
|
|
|
+const closePopup = () => {
|
|
|
+ showPopup.value = false;
|
|
|
+};
|
|
|
+const handleStnmDialog = (data,type) => {
|
|
|
+ stnmDialogData.value = {
|
|
|
+ ...data,
|
|
|
+ type
|
|
|
+ };
|
|
|
+ stnmDialogVisible.value = true;
|
|
|
+};
|
|
|
+const closeStnmDialog = (status) => {
|
|
|
+ stnmDialogVisible.value = status;
|
|
|
+};
|
|
|
+const handleMapTools = (name) => {
|
|
|
+ mapToolName.value = name;
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-#mapChart{
|
|
|
+.shouye-index{
|
|
|
height: 100%;
|
|
|
width: 100%;
|
|
|
+ position: relative;
|
|
|
+ #mapChart{
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ .map-tools{
|
|
|
+ position: absolute;
|
|
|
+ top: 8%;
|
|
|
+ left: 1%;
|
|
|
+ width: 30px;
|
|
|
+ height: 80px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .map-tool-item{
|
|
|
+ width: 100%;
|
|
|
+ height: 30px;
|
|
|
+ background: rgba(255,255,255,0.9);
|
|
|
+ border-radius: 3px;
|
|
|
+ margin: 5px 0;
|
|
|
+ display:flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ cursor: pointer;
|
|
|
+ img{
|
|
|
+ width: 18px;
|
|
|
+ height: 18px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .map-tool-itemActive{
|
|
|
+ width: 100%;
|
|
|
+ height: 30px;
|
|
|
+ background: rgba(74, 147, 245,0.9);
|
|
|
+ border-radius: 3px;
|
|
|
+ margin: 5px 0;
|
|
|
+ display:flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ cursor: pointer;
|
|
|
+ img{
|
|
|
+ width: 18px;
|
|
|
+ height: 18px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .map-tool-item:hover{
|
|
|
+ background: rgba(74, 147, 245,0.9);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .shouye-checkbox{
|
|
|
+ position: absolute;
|
|
|
+ top:2%;
|
|
|
+ left: 3%;
|
|
|
+ width: 200px;
|
|
|
+ height: 180px;
|
|
|
+ padding: 10px 0 10px 20px;
|
|
|
+ background: url("@/assets/yujing/img/left-box.png");
|
|
|
+ background-size: 100% 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center; /* 垂直居中 */
|
|
|
+ .el-checkbox {
|
|
|
+ height:18px;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .shouye-tuli{
|
|
|
+ width: 300px;
|
|
|
+ height: 230px;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #4a93f5;
|
|
|
+ border-radius: 5px;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 1%;
|
|
|
+ left:0.5%;
|
|
|
+ .tuli-title{
|
|
|
+ width: 100%;
|
|
|
+ line-height: 30px;
|
|
|
+ background: url("@/assets/images/lefttitle-bg.png");
|
|
|
+ background-size: 100% 100%;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #fff;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .tuli-content{
|
|
|
+ width: 100%;
|
|
|
+ height: 80%;
|
|
|
+ display: flex;
|
|
|
+ .tuli-content-left{
|
|
|
+ width: 50%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .content-left-item{
|
|
|
+ line-height: 20px;
|
|
|
+ margin-bottom: 3px;
|
|
|
+ display: flex;
|
|
|
+ .left-item-img{
|
|
|
+ height: 20px;
|
|
|
+ width: 20px;
|
|
|
+ margin: 0 5px;
|
|
|
+ }
|
|
|
+ span{
|
|
|
+ color: #000;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .tuli-content-right{
|
|
|
+ width: 50%;
|
|
|
+ height: 100%;
|
|
|
+ .content-right-item{
|
|
|
+ line-height: 20px;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ display: flex;
|
|
|
+ .right-item-img{
|
|
|
+ height: 20px;
|
|
|
+ width: 20px;
|
|
|
+ margin: 0 5px;
|
|
|
+ }
|
|
|
+ span{
|
|
|
+ color: #000;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .map-select{
|
|
|
+ position: absolute;
|
|
|
+ right: 1%;
|
|
|
+ top: 1%;
|
|
|
+ width: 13%;
|
|
|
+ }
|
|
|
+}
|
|
|
+.map-popup {
|
|
|
+ width:400px;
|
|
|
+ height: 220px;
|
|
|
+ background-color: rgba(255, 255, 255,0.9);
|
|
|
+ border-radius: 5px;
|
|
|
+ position: relative;
|
|
|
+ .map-popup-top{
|
|
|
+ width: 100%;
|
|
|
+ height: 20px;
|
|
|
+ background: url("@/assets/images/lefttitle-bg.png");
|
|
|
+ background-size: 100% 100%;
|
|
|
+ border-radius: 5px 5px 0 0;
|
|
|
+ img{
|
|
|
+ position: absolute;
|
|
|
+ top: 2px;
|
|
|
+ right: 2px;
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .map-popup-content{
|
|
|
+ width: 95%;
|
|
|
+ height: 82%;
|
|
|
+ margin: 2.5%;
|
|
|
+ background-color: #fff;
|
|
|
+ border: 1px solid #e9e9e9;
|
|
|
+ display: flex;
|
|
|
+ .popup-content-left{
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bolder;
|
|
|
+ color: #444444;
|
|
|
+ line-height: 22px;
|
|
|
+ margin-left: 5PX;
|
|
|
+ }
|
|
|
+ .popup-content-right{
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #444444;
|
|
|
+ line-height: 22px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .popup-trangle{
|
|
|
+ width:0;
|
|
|
+ height:0;
|
|
|
+ content:'';
|
|
|
+ border-right:10px solid rgba(255,255,255,0.9);
|
|
|
+ border-top:10px solid transparent;
|
|
|
+ border-bottom:10px solid transparent;
|
|
|
+ position:absolute;
|
|
|
+ left:-10px;
|
|
|
+ bottom:100px;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|