1030 lines
28 KiB
Vue
1030 lines
28 KiB
Vue
<template>
|
||
<!-- 顶部导航栏 -->
|
||
<custom-nav-bar :left="false" leftText="" @leftClick="" :title="title">
|
||
<template v-slot:left>
|
||
<view @click="$refs.landRef.open()">地块</view>
|
||
</template>
|
||
</custom-nav-bar>
|
||
<!-- 地图 -->
|
||
<view id="map" class="map" :imgs="mapData.imgs" :change:imgs="leaflet.imgsEmitHandler" :wo="mapData.wo"
|
||
:change:wo="leaflet.woEmitHandler"></view>
|
||
|
||
<!-- 控制弹出 -->
|
||
<u-popup mode="bottom" :show="pop.show" @close="closePopup">
|
||
<view class="popup-content" v-if="pop.show">
|
||
<view class="card-grey">
|
||
<view class="card-title">
|
||
<u-row>
|
||
<u-col span="2">
|
||
<view>
|
||
<text class="font-green">●</text>{{pop.item.showName}}
|
||
</view>
|
||
</u-col>
|
||
<u-col span="5">
|
||
<view class="fixed">
|
||
<view class="iconfont icon-wendu icon" style="float: left;margin-left: 5px;">
|
||
</view>
|
||
</view>
|
||
</u-col>
|
||
<u-col span="5" style="align-items: flex-end;">
|
||
<view class="fixed">
|
||
<u-button type="success" size="mini" text="刷新" icon="reload"
|
||
:loading="dc.dataObj[pop.item.dataKey]?.refresh"
|
||
@click="dc.refreshDeviceItem(pop.item.dataKey, pop.item.device)" />
|
||
</view>
|
||
</u-col>
|
||
</u-row>
|
||
</view>
|
||
|
||
<view class="control" v-if="dc.dataObj[pop.item.dataKey]">
|
||
<u-row v-if="pop.item.device.deviceTypeKey == 'valve'">
|
||
<u-col span="3">
|
||
<u-button :disabled="pop.item.device.disable?.open1"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'open1')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.open1.work"
|
||
@click="dc.deviceControlHandle(pop.item, 1)"> ①
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open1.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
<span class="name">张三</span>
|
||
</u-button>
|
||
<u-line-progress height="8" :showText="false"
|
||
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open1.openAngle" activeColor="#74ffd4"
|
||
inactiveColor="#c7c7c7" />
|
||
</u-col>
|
||
<u-col span="6">
|
||
<view class="valve">
|
||
<view>
|
||
<u-button :disabled="pop.item.device.disable?.open"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'open')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.open.work"
|
||
@click="dc.deviceControlHandle(pop.item, 3)"> 全开
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
</u-button>
|
||
</view>
|
||
<view class="btn-img">
|
||
<view class="text">
|
||
<view class="left">
|
||
{{ dc.dataObj[pop.item.dataKey].adc.p[0] }}
|
||
</view>
|
||
<view class="top"></view>
|
||
<view class="middle" v-show="!dc.dataObj[pop.item.dataKey].online">
|
||
离线
|
||
</view>
|
||
<view class="right">
|
||
{{ dc.dataObj[pop.item.dataKey].adc.p[1] }}
|
||
</view>
|
||
<view class="bottom"></view>
|
||
</view>
|
||
<image :src="valveImg[dc.dataObj[pop.item.dataKey].valveImg]" mode="widthFix" />
|
||
</view>
|
||
<view>
|
||
<u-button :disabled="pop.item.device.disable?.close"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'close')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.close.work"
|
||
@click="dc.deviceControlHandle(pop.item, 4)"> 全关
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.close.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
</u-button>
|
||
</view>
|
||
</view>
|
||
</u-col>
|
||
<u-col span="3">
|
||
<u-button :disabled="pop.item.device.disable?.open2"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'open2')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.open2.work"
|
||
@click="dc.deviceControlHandle(pop.item, 2)"> ②
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open2.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
</u-button>
|
||
<u-line-progress height="8" :showText="false"
|
||
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open2.openAngle" activeColor="#74ffd4"
|
||
inactiveColor="#c7c7c7" />
|
||
</u-col>
|
||
</u-row>
|
||
|
||
<u-row v-else-if="pop.item.device.deviceTypeKey == 'fiveValve'">
|
||
<u-col span="3">
|
||
<u-button :disabled="pop.item.device.disable?.open1"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'open1')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.open1.work"
|
||
@click="dc.deviceControlHandle(pop.item, 1)"> ①
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open1.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
</u-button>
|
||
<u-line-progress height="8" :showText="false"
|
||
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open1.openAngle" activeColor="#74ffd4"
|
||
inactiveColor="#c7c7c7" />
|
||
</u-col>
|
||
<u-col span="6">
|
||
<view class="valve">
|
||
<view>
|
||
<u-button :disabled="pop.item.device.disable?.open2"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'open2')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.open2.work"
|
||
@click="dc.deviceControlHandle(pop.item, 2)"> ②
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open2.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
</u-button>
|
||
<u-line-progress height="8" :showText="false"
|
||
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open2.openAngle"
|
||
activeColor="#74ffd4" inactiveColor="#c7c7c7" />
|
||
</view>
|
||
<view class="btn-img">
|
||
<view class="text">
|
||
<view class="left">
|
||
{{ dc.dataObj[pop.item.dataKey].adc.p[0] }}
|
||
</view>
|
||
<view class="top">
|
||
{{ dc.dataObj[pop.item.dataKey].adc.p[1] }}
|
||
</view>
|
||
<view class="middle" v-show="!dc.dataObj[pop.item.dataKey].online">
|
||
离线
|
||
</view>
|
||
<view class="right">
|
||
{{ dc.dataObj[pop.item.dataKey].adc.p[2] }}
|
||
</view>
|
||
<view class="bottom">
|
||
{{ dc.dataObj[pop.item.dataKey].adc.p[3] }}
|
||
</view>
|
||
</view>
|
||
<image :src="valveImg[dc.dataObj[pop.item.dataKey].valveImg]" mode="widthFix" />
|
||
</view>
|
||
<view>
|
||
<u-button :disabled="pop.item.device.disable?.open4"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'open4')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.open4.work"
|
||
@click="dc.deviceControlHandle(pop.item, 4)"> ④
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open4.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout" style="color: red;">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
</u-button>
|
||
<u-line-progress height="8" :showText="false"
|
||
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open4.openAngle"
|
||
activeColor="#74ffd4" inactiveColor="#c7c7c7" />
|
||
</view>
|
||
</view>
|
||
</u-col>
|
||
<u-col span="3">
|
||
<u-button :disabled="pop.item.device.disable?.open3"
|
||
:type="dc.getBtnType(pop.item.dataKey, 'open3')"
|
||
:plain="dc.dataObj[pop.item.dataKey].btnObj.open3.work"
|
||
@click="dc.deviceControlHandle(pop.item, 3)"> ③
|
||
<span v-if="dc.dataObj[pop.item.dataKey].btnObj.open3.work">
|
||
<span v-if="dc.countdownObj[pop.item.dataKey]">
|
||
({{ dc.countdownObj[pop.item.dataKey] }})
|
||
</span>
|
||
<span v-else class="timeout">
|
||
{{ dc.timeoutObj[pop.item.dataKey] }}
|
||
</span>
|
||
</span>
|
||
</u-button>
|
||
<u-line-progress height="8" :showText="false"
|
||
:percentage="dc.dataObj[pop.item.dataKey].btnObj.open3.openAngle" activeColor="#74ffd4"
|
||
inactiveColor="#c7c7c7" />
|
||
</u-col>
|
||
</u-row>
|
||
|
||
<u-row v-else>
|
||
未知的设备
|
||
</u-row>
|
||
<view class="tips font-red"
|
||
v-if="dc.dataObj[pop.item.dataKey].warning && dc.dataObj[pop.item.dataKey].warning.length">
|
||
<view class="iconfont icon-guzhang icon">
|
||
{{ dc.dataObj[pop.item.dataKey].warning.toString() }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 无数据上报 -->
|
||
<view class="control" v-else>
|
||
<u-row
|
||
v-if="pop.item.device.deviceTypeKey == 'valve' || pop.item.device.deviceTypeKey == 'fiveValve'">
|
||
<u-col span="3"></u-col>
|
||
<u-col span="6">
|
||
<view class="valve">
|
||
<view class="btn-img">
|
||
<view class="text">
|
||
<view class="middle" style="width: 100%;">
|
||
无数据上报
|
||
</view>
|
||
</view>
|
||
<image mode="widthFix" v-if="pop.item.device.deviceTypeKey == 'valve'"
|
||
:src="valveImg['valve3_close']" />
|
||
<image mode="widthFix" v-if="pop.item.device.deviceTypeKey == 'fiveValve'"
|
||
:src="valveImg['valve5_0000']" />
|
||
</view>
|
||
</view>
|
||
</u-col>
|
||
<u-col span="3"></u-col>
|
||
</u-row>
|
||
<u-row v-else>
|
||
未知的设备
|
||
</u-row>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
|
||
<!-- 地块选择 -->
|
||
<custom-select-land ref="landRef" :data="ijs.companys" :defaultSelect="ijs.land" @getLand="getLand"
|
||
@select="landChange" />
|
||
<!-- 角度 -->
|
||
<custom-angle-slider ref="refAngleSlider" mode="bottom" @close="swiperClose" @confirm="swiperConfirm" />
|
||
<!-- ADC -->
|
||
<custom-index-adc ref="adcRef" />
|
||
|
||
<!-- <custom-index-mp ref="mpRef" /> -->
|
||
</template>
|
||
<script>
|
||
import store from "@/store"
|
||
import * as imageAssets from '@/utils/indexUtil/imageAssets.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
user: store.state.user.user,
|
||
title: "",
|
||
ijs: getApp().ijs, // 首页公共js
|
||
dc: getApp().dc, // 设备控制公共代码
|
||
valveImg: imageAssets, //阀门图片
|
||
mqttshow: false, // h5端手动链接mqtt按钮显示
|
||
mqttConnected: false, // mqtt链接状态
|
||
screenValue: "", // 关键字搜索
|
||
isSticky: false, //吸顶状态
|
||
stateScreen: { // 吸顶筛选选中的项 值为 click
|
||
all: null,
|
||
online: null,
|
||
error: null
|
||
},
|
||
mapData: {
|
||
imgs: null, //地图所用到的图片
|
||
wo: null,
|
||
},
|
||
pop: {
|
||
show: false,
|
||
showA: false,
|
||
item: {}
|
||
},
|
||
selectItem: null,
|
||
}
|
||
},
|
||
onLoad() {
|
||
console.error("onLoad")
|
||
// 监听mqtt链接状态
|
||
// uni.$off("mqtt-connected");
|
||
uni.$on("mqtt-connected", (e) => {
|
||
this.mqttConnected = e;
|
||
});
|
||
// 监听地块改变
|
||
uni.$on("update-land-indexMap", (e) => {
|
||
console.error("update-land-indexMap:", e);
|
||
this.initMapData();
|
||
});
|
||
|
||
// this.ijs.initData(this.user.userId, (land, wo) => {
|
||
// getApp().getWoList(land, wo);
|
||
// });
|
||
},
|
||
onShow() {
|
||
this.title = this.ijs?.land?.landName || "田间";
|
||
|
||
// // 监听当前页面的加载状态
|
||
// uni.$off("index-showLoading");
|
||
// uni.$on("index-showLoading", (flg) => {
|
||
// if (flg) {
|
||
// uni.showLoading();
|
||
// } else {
|
||
// uni.hideLoading();
|
||
// }
|
||
// });
|
||
// 监听控制角度弹窗通知
|
||
uni.$off("open-angle-slider");
|
||
uni.$on("open-angle-slider", (e) => {
|
||
console.error("打开角度选择:", e)
|
||
this.$refs.refAngleSlider.show(e.title, e.extra, e.value, e.other);
|
||
this.pop.showA = true;
|
||
this.pop.show = false;
|
||
});
|
||
},
|
||
mounted() {
|
||
//初始化基础数据
|
||
this.mapData.imgs = {
|
||
key: import.meta.env.VITE_APP_TIAN_DI_TU_KEY,
|
||
centerPoint: [87.624947, 43.791789], //默认乌鲁木齐
|
||
imgs: imageAssets,
|
||
};
|
||
},
|
||
onHide() {
|
||
uni.$off("index-showLoading");
|
||
uni.$off("open-angle-slider");
|
||
},
|
||
methods: {
|
||
mapEventHandler(e) {
|
||
if (!e) {
|
||
return;
|
||
}
|
||
switch (e.type) {
|
||
case "msg":
|
||
this.$toast(e.data);
|
||
break;
|
||
case "showPopup":
|
||
this.showPopup(e.data);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
},
|
||
initMapData() {
|
||
//初始化地块数据
|
||
this.mapData.wo = this.ijs.wo;
|
||
},
|
||
// 地块选择回调
|
||
landChange(e) {
|
||
this.title = e.landName;
|
||
},
|
||
// 获取地块信息
|
||
getLand(e) {
|
||
this.ijs.getLand(e.node).then(res => {
|
||
this.$refs.landRef.addLand(e, res.data);
|
||
});
|
||
},
|
||
showPopup(e) {
|
||
this.pop.item = e;
|
||
console.error("item:", this.pop.item);
|
||
console.error("dataObj:", this.dc.dataObj);
|
||
this.pop.show = true;
|
||
this.pop.showA = false;
|
||
},
|
||
closePopup() {
|
||
this.pop.show = false;
|
||
},
|
||
// 角度控制回调
|
||
swiperConfirm(e) {
|
||
this.dc.buildCommand(e.item, e.index, e.value, e.other);
|
||
this.swiperClose();
|
||
},
|
||
swiperClose() {
|
||
this.pop.show = true;
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
<script module="leaflet" lang="renderjs">
|
||
// #ifdef H5
|
||
import "leaflet/dist/leaflet.css"
|
||
// #endif
|
||
import L from "leaflet"
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
map: null,
|
||
key: null,
|
||
centerPoint: null, //默认乌鲁木齐
|
||
mapType: null,
|
||
selectMapType: "img_w",
|
||
dom: {
|
||
landMap: null,
|
||
dataObj: {},
|
||
imgs: null,
|
||
cp: null,
|
||
label: {},
|
||
marker: {}
|
||
},
|
||
};
|
||
},
|
||
mounted() {},
|
||
methods: {
|
||
// 接受图片传递
|
||
imgsEmitHandler(e) {
|
||
if (!e) {
|
||
return;
|
||
}
|
||
this.key = e.key;
|
||
this.centerPoint = {
|
||
lat: e.centerPoint[0],
|
||
lng: e.centerPoint[1],
|
||
};
|
||
this.dom.imgs = e.imgs;
|
||
this.initMap();
|
||
},
|
||
woEmitHandler(e) {
|
||
if (!e) {
|
||
return;
|
||
}
|
||
console.error("woEmitHandler:", e);
|
||
const that = this;
|
||
if (this.map) {
|
||
var layers = that.map._layers;
|
||
var markersToRemove = [];
|
||
// 遍历所有图层并移除
|
||
for (var id in layers) {
|
||
if (layers[id] instanceof L.Marker) { // 确保我们处理的是一个Leaflet图层
|
||
markersToRemove.push(layers[id]);
|
||
}
|
||
}
|
||
// 移除所有的 Marker
|
||
markersToRemove.forEach(function(marker) {
|
||
that.map.removeLayer(marker);
|
||
});
|
||
} else {
|
||
this.initMap();
|
||
}
|
||
this.dom.dataObj = e.deviceData;
|
||
this.drawMap(e.landMap);
|
||
this.setWaterOutlet(e.wo);
|
||
},
|
||
//初始化地图
|
||
initMap() {
|
||
if (this.map) {
|
||
return;
|
||
}
|
||
const that = this;
|
||
that.mapType = {
|
||
vec_w: new L.tileLayer(
|
||
`http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${that.key}`, {
|
||
attribution: '矢量地图'
|
||
}),
|
||
img_w: new L.tileLayer(
|
||
`http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${that.key}`, {
|
||
attribution: '影像地图'
|
||
}),
|
||
ter_w: new L.tileLayer(
|
||
`http://t0.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=${that.key}`, {
|
||
attribution: '地形图'
|
||
}),
|
||
labelLayer: new L.tileLayer(
|
||
`http://t0.tianditu.gov.cn/cva_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cva&tileMatrixSet=w&TileMatrix={z}&TileRow={y}&TileCol={x}&style=default&format=tiles&tk=${that.key}`, {
|
||
attribution: '矢量地名标注'
|
||
}),
|
||
};
|
||
var normal = L.layerGroup([that.mapType[that.selectMapType], that.mapType.labelLayer])
|
||
|
||
const map = L.map('map', {
|
||
// crs: L.CRS.EPSG3857,
|
||
// center: [34.07148, 108.84076], //中心点
|
||
center: [that.centerPoint.lng, that.centerPoint.lat], //中心点
|
||
layers: normal,
|
||
zoom: 5, //默认层级
|
||
minZoom: 2, //最小层级
|
||
maxZoom: 18, //最大层级
|
||
zoomControl: true, //是否将 zoom 缩放控件添加到地图中。
|
||
doubleClickZoom: false, //图是否可以通过双击来放大
|
||
dragging: true, //地图是否可以通过 mouse/touch 进行拖动。
|
||
attributionControl: false, //是否将 attribution 版权控件添加到地图中。
|
||
tap: true // 确保此选项为 true 或者不指定,因为默认值是 true
|
||
});
|
||
|
||
// 如果需要监听缩放过程中的变化,可以使用 'zoom' 事件
|
||
map.on('zoom', function() {
|
||
that.onZoomend();
|
||
});
|
||
|
||
that.map = map;
|
||
that.$ownerInstance.callMethod('initMapData', "map初始化回调");
|
||
},
|
||
onZoomend() { //缩放监听
|
||
const that = this;
|
||
var currentZoomLevel = this.map.getZoom();
|
||
console.log("正在缩放,当前缩放级别: " + currentZoomLevel);
|
||
var layers = that.map._layers;
|
||
var markersToRemove = [];
|
||
// 遍历所有图层并移除
|
||
for (var id in layers) {
|
||
if (layers[id] instanceof L.Marker) { // 确保我们处理的是一个Leaflet图层
|
||
markersToRemove.push(layers[id]);
|
||
}
|
||
}
|
||
// 移除所有的 Marker
|
||
markersToRemove.forEach(function(marker) {
|
||
that.map.removeLayer(marker);
|
||
});
|
||
if (currentZoomLevel > 16) {
|
||
for (let key in that.dom.label) {
|
||
that.map.addLayer(that.dom.label[key])
|
||
}
|
||
for (let key in that.dom.marker) {
|
||
that.map.addLayer(that.dom.marker[key].marker);
|
||
}
|
||
} else if (currentZoomLevel == 16) {
|
||
for (let key in that.dom.marker) {
|
||
that.map.addLayer(that.dom.marker[key].marker);
|
||
}
|
||
} else {
|
||
// 定义图标属性
|
||
let markerIcon = L.icon({
|
||
iconUrl: "./static/images/map/zhongxindian.png",
|
||
//图标图像的尺寸,单位是像素。
|
||
iconSize: [20, 30],
|
||
});
|
||
L.marker([that.centerPoint.lng, that.centerPoint.lat], {
|
||
icon: markerIcon,
|
||
}).addTo(that.map);
|
||
}
|
||
},
|
||
// 绘制地图
|
||
drawMap(landMap) {
|
||
if (!landMap) {
|
||
return
|
||
}
|
||
const {
|
||
centerPoint, //中心点
|
||
boundary, //边界(支持多个)
|
||
mainLine, //主干管
|
||
secondaryLine //支干管
|
||
} = landMap;
|
||
// 重新设置中心点
|
||
const cp = JSON.parse(centerPoint)
|
||
// this.map.setZoomAround([cp[1], cp[0]], 16)
|
||
// this.map.flyTo([cp[1], cp[0]], 16)
|
||
this.map.setView([cp[1], cp[0]], 18)
|
||
this.setCenterPoint(centerPoint)
|
||
this.setBoundary(boundary)
|
||
this.setMainLine(mainLine)
|
||
this.setSecondaryLine(secondaryLine)
|
||
this.dom.landMap = landMap;
|
||
},
|
||
// 设置中心点
|
||
setCenterPoint(centerPoint) {
|
||
if (!centerPoint) {
|
||
return
|
||
}
|
||
// 重新设置中心点
|
||
centerPoint = JSON.parse(centerPoint)
|
||
// 重新设置中心点
|
||
this.centerPoint = {
|
||
lat: centerPoint[0],
|
||
lng: centerPoint[1],
|
||
};
|
||
},
|
||
// 设置边界
|
||
setBoundary(boundary) {
|
||
if (!boundary) {
|
||
return
|
||
}
|
||
// 重新设置中心点
|
||
boundary = JSON.parse(boundary)
|
||
if (boundary.length) {
|
||
let points = []
|
||
boundary.forEach((item) => {
|
||
points.push([item[1], item[0]])
|
||
})
|
||
//创建面对象
|
||
var polygon = L.polygon(points, {
|
||
color: "blue"
|
||
});
|
||
this.map.addLayer(polygon);
|
||
}
|
||
},
|
||
// 设置主干管
|
||
setMainLine(mainLine) {
|
||
if (!mainLine) {
|
||
return
|
||
}
|
||
// 重新设置中心点
|
||
mainLine = JSON.parse(mainLine)
|
||
if (mainLine.length) {
|
||
mainLine.forEach((item1) => {
|
||
let points = []
|
||
item1.forEach((item2) => {
|
||
points.push([item2[1], item2[0]])
|
||
})
|
||
//创建线对象
|
||
var line = L.polyline(points, {
|
||
color: '#ff0000',
|
||
});
|
||
//向地图上添加线
|
||
this.map.addLayer(line)
|
||
})
|
||
}
|
||
},
|
||
// 设置主干管
|
||
setSecondaryLine(secondaryLine) {
|
||
if (!secondaryLine) {
|
||
return
|
||
}
|
||
// 重新设置中心点
|
||
secondaryLine = JSON.parse(secondaryLine)
|
||
secondaryLine = [
|
||
[
|
||
[108.83999, 34.07187],
|
||
[108.8438, 34.07187]
|
||
]
|
||
]
|
||
if (secondaryLine.length) {
|
||
secondaryLine.forEach((item1) => {
|
||
let points = []
|
||
item1.forEach((item2) => {
|
||
points.push([item2[1], item2[0]])
|
||
})
|
||
//创建线对象
|
||
var line = L.polyline(points, {
|
||
color: '#00ff00',
|
||
});
|
||
//向地图上添加线
|
||
this.map.addLayer(line)
|
||
})
|
||
}
|
||
},
|
||
// 设置阀门
|
||
setWaterOutlet(wo) {
|
||
if (!wo && !wo.length) {
|
||
return
|
||
}
|
||
const that = this
|
||
wo.forEach((item) => {
|
||
if (item.longitude && item.latitude) {
|
||
item.latitude = 34.07187
|
||
// 创建标注
|
||
let marker = L.marker([item.latitude, item.longitude], {
|
||
title: "312",
|
||
alt: "123",
|
||
icon: that.creatMapIcon(item?.device?.deviceTypeKey)
|
||
})
|
||
marker.on('click', function(e) {
|
||
that.mapDeviceClick(e);
|
||
});
|
||
that.map.addLayer(marker) // 将标注添加到地图中
|
||
that.addMarker(marker, item);
|
||
|
||
// 创建文字
|
||
let label = that.creatLabel(item, marker);
|
||
that.map.addLayer(label) // 将标注添加到地图中
|
||
that.addLabel(item, label);
|
||
}
|
||
if (item.children && item.children.length) {
|
||
item.children.forEach((child) => {
|
||
if (child.longitude && child.latitude) {
|
||
child.latitude = 34.07187
|
||
// 创建标注
|
||
let marker = L.marker([child.latitude, child.longitude], {
|
||
icon: that.creatMapIcon(child?.device?.deviceTypeKey)
|
||
})
|
||
marker.addEventListener("click", (e) => {
|
||
that.mapDeviceClick(e);
|
||
});
|
||
that.map.addLayer(marker) // 将标注添加到地图中
|
||
that.addMarker(marker, child);
|
||
|
||
// 创建文字
|
||
let label = that.creatLabel(child, marker);
|
||
that.map.addLayer(label) // 将标注文字添加到地图中
|
||
that.addLabel(child, label);
|
||
}
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 生成阀门图标
|
||
creatMapIcon(type, select = false) {
|
||
// 获取当前地图的缩放级别
|
||
const zoom = this.map.getZoom();
|
||
var icon = null;
|
||
switch (type) {
|
||
case 'valve':
|
||
icon = L.icon({
|
||
iconUrl: `.${select ? this.dom.imgs.valve3_select : this.dom.imgs.valve3}`,
|
||
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
|
||
});
|
||
break;
|
||
case 'fiveValve':
|
||
icon = L.icon({
|
||
iconUrl: `.${select ? this.dom.imgs.valve5_select : this.dom.imgs.valve5}`,
|
||
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
|
||
});
|
||
break;
|
||
case 'butterflyValve':
|
||
icon = L.icon({
|
||
iconUrl: `.${select ? this.dom.imgs.df_select : this.dom.imgs.df}`,
|
||
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
|
||
});
|
||
break;
|
||
default:
|
||
icon = L.icon({
|
||
iconUrl: `.${this.dom.imgs.csk}`,
|
||
iconSize: [20, 30], //图标图像的尺寸,单位是像素。
|
||
// //图标 "tip" 的坐标(相对于其左上角)。图标将被对齐,使该点位于标记的地理位置。如果指定了尺寸,默认为居中,也可以在CSS中设置负的边距。
|
||
// iconAnchor: [7, 9],
|
||
// //弹出窗口(popup)的坐标,相对于图标锚点而言,将从该点打开。
|
||
// popupAnchor: [-3, -3],
|
||
});
|
||
break;
|
||
}
|
||
return icon;
|
||
},
|
||
// 生成阀门文字
|
||
creatLabel(item, marker) {
|
||
let name = item.showName;
|
||
let divIcon = L.divIcon({
|
||
html: `<span>${name}</span>`,
|
||
className: `my-device-icon ${this.getLableColor(item.dataKey)}`,
|
||
iconAnchor: [15, -10],
|
||
});
|
||
if (name.length <= 3) {
|
||
divIcon.options.iconAnchor = [15, -10]
|
||
} else if (name.length == 4 || name.length == 5) {
|
||
divIcon.options.iconAnchor = [20, -10]
|
||
} else {
|
||
divIcon.options.iconAnchor = [25, -10]
|
||
}
|
||
return L.marker(marker._latlng, {
|
||
icon: divIcon
|
||
});
|
||
},
|
||
// 获取文字的颜色
|
||
getLableColor(dataKey) {
|
||
let color = 'device-white'; //"#fff";
|
||
if (this.dom.dataObj[dataKey] && this.dom.dataObj[dataKey]?.online) {
|
||
if (this.dom.dataObj[dataKey].warning.length) {
|
||
color = 'device-orange'; //"#fbc902"; //橙黄(警告)
|
||
} else {
|
||
color = 'device-green'; //"#0bff3a"; //绿色(在线)
|
||
}
|
||
} else {
|
||
color = 'device-white'; //"#fff"; //白色(默认/离线)
|
||
}
|
||
return color;
|
||
},
|
||
// 缓存页面marker
|
||
addMarker(marker, item) {
|
||
this.dom.marker[marker._leaflet_id] = {
|
||
item: item,
|
||
select: false,
|
||
marker: marker,
|
||
};
|
||
},
|
||
// 缓存页面Label
|
||
addLabel(item, label) {
|
||
if (item.device) {
|
||
this.dom.label[item.device.deviceCode] = label;
|
||
} else {
|
||
this.dom.label[item.showName] = label;
|
||
}
|
||
},
|
||
// 设备点击
|
||
mapDeviceClick(e) {
|
||
const that = this;
|
||
const key = e.sourceTarget._leaflet_id;
|
||
const clickItem = that.dom.marker[key];
|
||
if (clickItem.item?.device) {
|
||
for (var rkey in that.dom.marker) {
|
||
if (that.dom.marker[rkey].select) {
|
||
const clickedIcon = that.creatMapIcon(that.dom.marker[rkey].item.device?.deviceTypeKey, false);
|
||
that.dom.marker[rkey].marker.setIcon(clickedIcon);
|
||
that.dom.marker[rkey].select = false;
|
||
}
|
||
if (key == rkey) {
|
||
const clickedIcon = that.creatMapIcon(that.dom.marker[rkey].item?.device?.deviceTypeKey, true);
|
||
that.dom.marker[rkey].marker.setIcon(clickedIcon);
|
||
that.dom.marker[rkey].select = true;
|
||
}
|
||
}
|
||
// that.$ownerInstance.callMethod('showPopup', that.dom.marker[rkey].item);
|
||
that.$ownerInstance.callMethod('mapEventHandler', {
|
||
type: "showPopup",
|
||
data: clickItem.item
|
||
});
|
||
} else {
|
||
that.$ownerInstance.callMethod('mapEventHandler', {
|
||
type: "msg",
|
||
data: "未绑定设备!"
|
||
});
|
||
}
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="scss">
|
||
/* #ifdef APP-PLUS */
|
||
@import url("leaflet/dist/leaflet.css");
|
||
/* #endif */
|
||
|
||
.map {
|
||
width: 100%;
|
||
top: 0;
|
||
bottom: 0;
|
||
position: absolute;
|
||
z-index: 0;
|
||
|
||
/* 地图放大缩小 */
|
||
::v-deep .leaflet-control-container {
|
||
position: absolute !important;
|
||
right: 55px !important;
|
||
top: 20% !important;
|
||
}
|
||
|
||
/* 文字 */
|
||
:deep() {
|
||
.my-device-icon {
|
||
background-color: transparent;
|
||
}
|
||
|
||
.my-device-icon span {
|
||
font-size: 14px;
|
||
white-space: nowrap;
|
||
display: block;
|
||
border-radius: 4px;
|
||
background-color: transparent;
|
||
width: fit-content;
|
||
padding: 2px 5px;
|
||
}
|
||
|
||
.device-white span {
|
||
color: #fff;
|
||
}
|
||
|
||
.device-green span {
|
||
color: #0bff3a;
|
||
}
|
||
|
||
.device-orange span {
|
||
color: #fbc902;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
</style>
|
||
<style lang="scss" scoped>
|
||
.uni-popup {
|
||
z-index: 1000;
|
||
}
|
||
|
||
// 水阀列表title
|
||
.card-grey {
|
||
border-radius: 10px 10px 0 0;
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.sf-title {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
padding: 10px 0;
|
||
|
||
.text {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.icon {
|
||
vertical-align: top;
|
||
margin-right: 5px;
|
||
font-size: 44rpx;
|
||
color: #39ac4f;
|
||
}
|
||
}
|
||
|
||
.font-green {
|
||
color: #39ac4f !important;
|
||
}
|
||
|
||
.font-red {
|
||
color: #e60012 !important;
|
||
}
|
||
|
||
/* 首页阀门列表 */
|
||
.control {
|
||
padding: 20px 10px;
|
||
|
||
.u-button {
|
||
width: 100% !important;
|
||
min-width: 77px;
|
||
}
|
||
|
||
.u-line-progress {
|
||
min-width: 77px;
|
||
margin-top: 5px;
|
||
}
|
||
}
|
||
|
||
.tips {
|
||
font-size: 12rpx;
|
||
margin: 10px;
|
||
}
|
||
|
||
|
||
.valve {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-direction: column;
|
||
|
||
.timeout {
|
||
color: red !important;
|
||
font-size: 10px;
|
||
}
|
||
|
||
.btn-img {
|
||
width: 160px;
|
||
margin: 15px;
|
||
position: relative;
|
||
|
||
img {
|
||
width: 100%;
|
||
}
|
||
|
||
.text,
|
||
.text5 {
|
||
&>view {
|
||
position: absolute;
|
||
z-index: 2;
|
||
font-weight: bold;
|
||
font-size: 16px;
|
||
color: #333;
|
||
}
|
||
|
||
.left {
|
||
left: 0;
|
||
top: calc(50% - 17px);
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.top {
|
||
top: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
}
|
||
|
||
.middle {
|
||
font-size: 24px;
|
||
top: calc(50% - 18px);
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
color: #e60012;
|
||
text-align: center;
|
||
}
|
||
|
||
.right {
|
||
right: 0;
|
||
top: calc(50% - 17px);
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.bottom {
|
||
bottom: 0;
|
||
right: 50%;
|
||
transform: translateX(50%);
|
||
}
|
||
}
|
||
|
||
.text5 {
|
||
.left {
|
||
left: 0;
|
||
top: calc(50% - 4px);
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.middle {
|
||
top: calc(50% - 5px);
|
||
}
|
||
|
||
.right {
|
||
right: 0;
|
||
top: calc(50% - 4px);
|
||
transform: translateY(-50%);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
</style> |