ebike-ui/ebike-maintenance/pages/map/map-bikesite.vue
2025-05-13 16:05:03 +08:00

655 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div :style="{width:'100vw',height}">
<map id="mapRef" ref="mapRef" :style="{width:'100vw',height}" show-location :longitude="mapcenter.longitude"
:latitude="mapcenter.latitude" :markers="markers" :polygons="polygons" :circles="circles"
:polyline="polyline" :scale="scale" @tap="mapTap" @poitap="mapTap" @markertap="markerTap" />
<div class="divNav">
</div>
<div class="divLowerLeft">
<div class="divBtn">
<div class="divBtnTitle" @click="getLoalcation">
<uni-icons custom-prefix="iconfont" type="icon-ebikedingwei2" :color="iconcolor" :size="iconsize" />
<div>定位</div>
</div>
<div class="divBtnTitle" @click="refreshArea">
<uni-icons custom-prefix="iconfont" type="icon-ebikeshuaxin" :color="iconcolor" :size="iconsize" />
<div>刷新</div>
</div>
<div class="divBtnTitle" style="padding-bottom: 10px;"
@click="()=>{showRegion=!showRegion;showMapSite(showRegion)}">
<uni-icons custom-prefix="iconfont" type="icon-ebikeP" :color="!showRegion?iconcolor:showColor"
:size="iconsize" />
<div :style="{color:!showRegion?iconcolor:showColor}">站点</div>
</div>
</div>
</div>
<div v-if="showDraw" class="divBottom">
<!-- <div style="display: flex;">
<label>选择形状</label>
<div style="margin-top: -5px;">
<uni-data-checkbox v-model="selDraw" :localdata="drawType"
@change="changDrawType"></uni-data-checkbox>
</div>
</div> -->
<div v-if="selDraw=='1'" style="line-height: 35px;">
<label class="lbWorn">请点击地图绘制您想绘制的区域</label>
<div>
<label class="b-btn-blue" @click="delPoint">删除点</label>
<label class="b-btn-blue" style="margin-left: 15px;" @click="clearPoint">清空点</label>
</div>
</div>
<div v-if="selDraw=='2'">
<label class="lbWorn">
请点
<uni-icons type="plus" color="#1082FF" size="30" @click="onZoom('out')" />
击放
大圆点击<uni-icons type="minus" color="#1082FF" size="30" @click="onZoom('in')" />
缩小圆,半径为
<label style="color: #000;">{{radius}}</label>
</label>
</div>
<div style="text-align: center;display: flex;justify-content: space-evenly;margin: 10px 0px;">
<div class="b-btn-white" style="width:100%;margin-right: 10px" @click="cancelDraw">取消绘制</div>
<div class="b-btn-blue" style="width:100%;" @click="completeDraw">完成绘制</div>
</div>
</div>
<div class="divSiteInfo" v-if="showSiteInfo">
<div class="divClose" @click="closeSiteInfo">
<uni-icons custom-prefix="iconfont" type="icon-ebikeguanbi" size="25" color="#777777" />
</div>
<div class="divName">
<label style="flex: 1;">{{siteInfo.name}}</label>
<div style="margin-left: 10px;" @click="openSiteInfo">
<uni-icons custom-prefix="iconfont" type="icon-ebikebianji" color="rgb(121 116 116)"
size="20" />
</div>
</div>
<div class="divAdrress">{{siteInfo.address}}</div>
<div class="divCountRow">
<div>
<div class="divCount">
{{siteInfo.zdrl}}
</div>
<div class="divTitle">
站点容量
</div>
</div>
<div>
<div class="divCount">
{{siteInfo.sssl}}
</div>
<div class="divTitle">
实时数量
</div>
</div>
<div>
<div class="divCount" :style="{color:siteInfo.xdd<=0?'#EF4B4D':'#00BCD4'}">
{{siteInfo.xdd>0?'+'+siteInfo.xdd:siteInfo.xdd}}
</div>
<div class="divTitle">
需调度
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {
ref,
onMounted,
getCurrentInstance
} from 'vue';
import * as map from "@/utils/map.js";
import {
useSelarea
} from "@/stores/selarea.js";
import {
onLoad
} from "@dcloudio/uni-app";
import {
showModelMessage,
getScreenHeightNoTabBar
} from "@/utils/tools.js";
import {
cloneDeep,
findIndex
} from "lodash"
const title = ref("新建站点");
let isload = false;
let oMap = null;
const mapcenter = ref({
longitude: "",
latitude: ""
})
const scale = ref(18);
const polygons = ref([]);
const circles = ref([]);
const markers = ref([]);
const polyline = ref([]);
const radius = ref(20);
let drawPoint = [];
let areaData = {};
let selArea = null; //选中区域
let siteData = {};
let showRegion = ref(false);
const iconsize = 16;
const iconcolor = "#6f7777";
const showColor = "#1088FD";
//行政区划
const selAreaStore = useSelarea();
const zoneId = selAreaStore.value;
const showDraw = ref(false);
const drawType = [{
text: "多边形",
value: "1"
}, {
text: "圆形",
value: "2"
}];
const selDraw = ref("1");
const drawId = 10000000;
const drawColor = "#e58b04";
const drawFillColor = "#e58b041a";
const editColor = "#e41309";
const editFillColor = "#e4130930";
const height = ref("100vh");
const opentype = ref("add"); //打开类型
let editId = ""; //编辑ID
const showSiteInfo = ref(false);
const siteInfo = ref({
id: "",
name: "",
address: "",
zdrl: 0,
sssl: 0,
xdd:0
})
//缩放
function onZoom(type) {
const i = 10;
let r = radius.value;
if (!drawPoint || drawPoint.length == 0) {
showModelMessage("请先绘制图形!");
return;
}
switch (type) {
case "out":
r += 10;
break;
default:
if (r == 20) {
showModelMessage("已缩放至最小!");
return;
}
r = r - 10;
break;
}
radius.value = r;
const {
latitude,
longitude
} = drawPoint[0];
circles.value[circles.value.length - 1] = map.addCirle(drawColor, drawFillColor, longitude, latitude, radius
.value);
}
//切换绘制类型
function changDrawType(e) {
const {
value
} = e.detail;
selDraw.value = value;
if (!drawPoint || drawPoint.length == 0) {
return;
}
markers.value.splice(markers.value.length - 1, 1);
switch (drawPoint.length) {
case 2:
polyline.value = [];
break;
default:
polygons.value.splice(polygons.value.length - 1, 1);
break;
}
drawPoint = [];
}
function closeSiteInfo(){
showSiteInfo.value=false;
}
function markerTap(e) {
const {
markerId
} = e.detail;
const index = markerId;
const {
arrCirclesData,
arrPolygonsData
} = siteData;
const len = arrCirclesData.length;
let data = null;
if (index <= len - 1) {
data = arrCirclesData[markerId];
} else {
data = arrPolygonsData[markerId - len];
}
const {
siteName,
siteRegionId,
siteAdress,
allowedParkingNum
} = data;
const site = {
id: siteRegionId,
name: siteName,
address: siteAdress,
zdrl: allowedParkingNum,
sssl: 0,
xdd:allowedParkingNum-0
}
siteInfo.value=site;
showSiteInfo.value = true;
}
function mapTap(e) {
const {
detail: {
latitude,
longitude
}
} = e;
if (!showDraw.value) return;
let inside = false;
if (!selArea) {
const {
arrCirclesData,
arrPolygonsData
} = areaData;
for (let i = 0; i < arrPolygonsData.length; i++) {
const data = arrPolygonsData[i];
const points = data.points;
inside = map.checkPointInPolygon(longitude, latitude, points);
if (inside) {
selArea = data;
break;
}
}
if (!inside) {
showModelMessage("请绘制在运营区域内!")
return;
}
} else {
const {
shapeType,
points
} = selArea;
if (shapeType == "2") {
inside = map.checkPointInPolygon(longitude, latitude, points);
if (!inside) {
showModelMessage("请绘制在运营区域内!")
return;
}
}
}
switch (selDraw.value) {
case "1":
drawPolygons(longitude, latitude);
break;
case "2":
drawCircle(longitude, latitude);
break;
}
}
//绘制多边形
function drawPolygons(longitude, latitude) {
const len = drawPoint.length;
switch (len) {
case 0:
const marker = map.addMarker(drawId, longitude, latitude, "point.png");
markers.value.push(marker);
break;
case 1:
polyline.value.push(map.addLine(drawColor, drawPoint));
break;
case 2:
polyline.value.splice(polyline.value.length - 1, 1);
polygons.value.push(map.addPolygon(drawColor, drawFillColor, drawPoint));
break;
default:
polygons.value[polygons.value.length - 1] = map.addPolygon(drawColor, drawFillColor, drawPoint);
break;
}
drawPoint.push({
latitude,
longitude
});
}
//绘制圆形
function drawCircle(longitude, latitude) {
const circle = map.addCirle(drawColor, drawFillColor, longitude, latitude, radius.value);
const marker = map.addMarker(drawId, longitude, latitude, "point.png");
if (drawPoint.length > 0) {
circles.value[circles.value.length - 1] = circle;
markers.value[markers.value.length - 1] = markers;
} else {
markers.value.push(marker);
circles.value.push(circle);
}
drawPoint[0] = {
latitude,
longitude
};
}
//删除点
function delPoint() {
if (!drawPoint || drawPoint.length == 0) {
showModelMessage("请先绘制点!");
return;
}
drawPoint.splice(drawPoint.length - 1, 1);
if (selDraw.value == "1") {
delPolygon();
} else {
markers.value.splice(markers.value.length - 1, 1);
circles.value.splice(circles.value.length - 1, 1);
}
}
function delPolygon() {
switch (drawPoint.length) {
case 0:
markers.value.splice(markers.value.length - 1, 1);
break;
case 1:
polyline.value.splice(polyline.value.length - 1, 1);
break;
case 2:
polygons.value.splice(polygons.value.length - 1, 1);
polyline.value.push(map.addLine(drawColor, drawPoint));
break;
default:
const index = polygons.value.length - 1;
polygons.value[index] = map.addPolygon(drawColor, drawFillColor, drawPoint);
break;
}
}
//清除点
function clearPoint() {
drawPoint = [];
markers.value.splice(markers.value.length - 1, 1);
if (selDraw.value == "1") {
polygons.value.splice(polygons.value.length - 1, 1);
} else {
circles.value.splice(circles.value.length - 1, 1);
}
}
function openSiteInfo(){
const{id}=siteInfo.value;
uni.redirectTo({
url: `/pages/devops/bikesite/bikesite-info?id=${id}&&type=edit`
})
}
//完成绘制
function completeDraw() {
if (drawPoint.length == 0) {
showModelMessage("请先绘制区域!");
return;
}
const arrPoint = cloneDeep(drawPoint)
if (selDraw.value == "1" && arrPoint.length <= 3) {
showModelMessage("至少四个点进行区域绘制!");
return;
}
if (arrPoint.length > 3) {
arrPoint.push(arrPoint[0]);
}
const points = JSON.stringify(arrPoint);
const {
operationRegionId
} = selArea;
uni.redirectTo({
url: `/pages/devops/bikesite/bikesite-info?id=${editId}&points=${points}&radius=${radius.value}&&type=${opentype.value}&&regionid=${operationRegionId}`
})
}
//取消绘制
function cancelDraw() {
uni.navigateBack();
}
function loadOperation(callback) {
console.log("666666666666666666666", "行政区划", zoneId);
map.getOperation(zoneId, (res) => {
if (!res) {
if (callback) callback();
return;
}
const {
arrRegionID,
arrCircles,
arrPolygons,
arrData,
arrCirclesData,
arrPolygonsData
} = res;
if (arrRegionID.length == 0) {
if (callback) callback();
return;
}
areaData = {
arrCircles,
arrPolygons,
arrData,
arrCirclesData,
arrPolygonsData
};
map.getRegionData(arrRegionID, (res) => {
const {
arrData,
arrCircles: arrCircles_region,
arrPolygons: arrPolygons_region,
arrCirclesData: arrCirclesData_region,
arrPolygonsData: arrPolygonsData_region
} = res;
siteData = {
arrCircles: arrCircles_region,
arrPolygons: arrPolygons_region,
arrCirclesData: arrCirclesData_region,
arrPolygonsData: arrPolygonsData_region
};
const arrMarker = [];
let len = 0;
arrCircles_region.map((item, index) => {
const {
latitude: lat,
longitude: lng
} = item;
arrMarker.push(map.addMarker(len + index, lng, lat, "bikesite.png"));
});
len = arrMarker.length;
arrPolygons_region.map((item, index) => {
const {
points
} = item;
const {
latitude: lat,
longitude: lng
} = points[0];
arrMarker.push(map.addMarker(len + index, lng, lat, "bikesite.png"));
});
markers.value = arrMarker;
showMapSite(showRegion.value);
if (callback) callback();
})
})
}
//定位
function getLoalcation() {
map.getLoalcation(oMap, (res) => {
const {
latitude,
longitude
} = res;
mapcenter.value = {
latitude,
longitude
};
})
}
function refreshArea() {
loadOperation();
}
function showMapSite(showSite) {
const {
arrCircles = [],
arrPolygons = []
} = areaData;
const {
arrCircles: arrCircles_region = [],
arrPolygons: arrPolygons_region = [],
arrCirclesData,
arrPolygonsData
} = siteData;
const arrEditC = [];
const arrEditP = [];
if (showSite) {
if (editId) { //编辑
const obj = {
siteRegionId: editId
};
let index = findIndex(arrCirclesData, obj);
if (index > -1) {
const {
latitude,
longitude
} = arrCircles_region[index];
arrCirclesData.splice(index, 1);
arrCircles_region.splice(index, 1);
arrEditC.push(map.addCirle(editColor, editFillColor, longitude, latitude, radius.value));
} else {
index = findIndex(arrPolygonsData, obj);
if (index > -1) {
const {
points: arrPoint
} = arrPolygons_region[index];
arrPolygonsData.splice(index, 1);
arrPolygons_region.splice(index, 1);
arrEditP.push(map.addPolygon(editColor, editFillColor, arrPoint))
}
}
}
polygons.value = [...arrPolygons, ...arrPolygons_region, ...arrEditP];
circles.value = [...arrCircles, ...arrCircles_region, ...arrEditC];
drawPoint = [];
} else {
polygons.value = arrPolygons;
circles.value = arrCircles;
}
}
function defualtZoom() {
console.log("888888888888888888defualtZoom", polygons.value)
if (polygons.value.length == 0) {
return;
}
const arrPoint = polygons.value[0].points;
oMap.includePoints({
points: arrPoint,
padding: [50, 50, 50, 50]
});
}
//加载数据
function loadData() {
loadOperation(() => {
if (isload) {
defualtZoom();
}
});
}
onMounted(() => {
oMap = map.getMap("mapRef", getCurrentInstance());
isload = true;
defualtZoom();
});
onLoad(options => {
console.log("33333333333333333", "options,isload", options, isload)
let title = "站点地图";
const {
type,
points,
id,
radius: r
} = options;
if (id) {
editId = id;
drawPoint = JSON.parse(points);
radius.value = r;
}
opentype.value = type;
switch (type) {
case "add":
title = "新建站点";
showRegion.value = true;
showDraw.value = true;
break;
case "edit":
title = "编辑站点";
showRegion.value = true;
showDraw.value = true;
break;
}
getScreenHeightNoTabBar(res => {
height.value = res + "px";
})
uni.setNavigationBarTitle({
title
});
//加载数据
loadData();
});
</script>
<style scoped>
@import url("map-bikesite.css");
</style>