From c0e471bfb5c3edfb862809908e2c47474c1a17cf Mon Sep 17 00:00:00 2001
From: guoshilong <123456>
Date: Wed, 20 Dec 2023 16:37:23 +0800
Subject: [PATCH] 电子围栏
---
src/views/check/leave.vue | 2
src/views/check/components/OlMapBox.vue | 411 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/views/check/livePersonLocation.vue | 19 ++
public/img/map/location.png | 0
4 files changed, 431 insertions(+), 1 deletions(-)
diff --git a/public/img/map/location.png b/public/img/map/location.png
new file mode 100644
index 0000000..b998360
--- /dev/null
+++ b/public/img/map/location.png
Binary files differ
diff --git a/src/views/check/components/OlMapBox.vue b/src/views/check/components/OlMapBox.vue
new file mode 100644
index 0000000..1957c7a
--- /dev/null
+++ b/src/views/check/components/OlMapBox.vue
@@ -0,0 +1,411 @@
+<!--
+ * @Author: shuishen 1109946754@qq.com
+ * @Date: 2023-10-11 16:01:58
+ * @LastEditors: shuishen 1109946754@qq.com
+ * @LastEditTime: 2023-11-29 14:17:09
+ * @FilePath: \web\business\src\components\OlMapBox\index.vue
+ * @Description:
+ *
+ * Copyright (c) 2023 by shuishen, All Rights Reserved.
+-->
+<template>
+ <div class="w100 h100">
+ <div id="OlMapBoxElement" class="w100 h100">
+ </div>
+ </div>
+</template>
+
+<script>
+// import OLCesium from "ol-cesium"
+import "ol/ol.css"
+import OlView from "ol/View.js"
+import {
+ // eslint-disable-next-line no-unused-vars
+ defaults as OlControlDefaults,
+ defaults,
+ // 全屏控件
+ FullScreen,
+ // 比例尺控件
+ ScaleLine,
+ // 缩放滚动条控件
+ // eslint-disable-next-line no-unused-vars
+ ZoomSlider,
+ // 鼠标位置控件
+ // eslint-disable-next-line no-unused-vars
+ MousePosition,
+ // -地图属性控件
+ Attribution,
+ // 鹰眼控件
+ // eslint-disable-next-line no-unused-vars
+ OverviewMap,
+ // 缩放到范围控件
+ // eslint-disable-next-line no-unused-vars
+ ZoomToExtent,
+ Rotate,
+} from "ol/control.js"
+import OlSourceOSM from "ol/source/OSM.js"
+import OlLayerTile from "ol/layer/Tile.js"
+
+import { Image as ImageLayer } from 'ol/layer'
+import ImageStatic from 'ol/source/ImageStatic.js'
+
+import OlLayerVectorTile from "ol/layer/VectorTile.js"
+import OlMap from "ol/Map.js"
+import OlProjection from "ol/proj/Projection.js"
+import OlMVT from "ol/format/MVT.js"
+import OlUnits from "ol/proj/Units.js"
+import OlFeature from "ol/Feature"
+
+import { get as projGet } from "ol/proj.js"
+// c
+
+import XYZ from "ol/source/XYZ"
+
+import Cluster from "ol/source/Cluster"
+
+import VectorLayer from "ol/layer/Vector"
+import VectorSource from "ol/source/Vector"
+
+import TileArcGISRest from "ol/source/TileArcGISRest"
+import TilegridTileGrid from "ol/tilegrid/TileGrid"
+
+import GeoJSON from "ol/format/GeoJSON"
+
+import Feature from 'ol/Feature.js'
+import Point from 'ol/geom/Point.js'
+import { Icon, Style, Fill, Text, Stroke, Circle } from 'ol/style.js'
+
+
+let mapView = null
+let layersObjcect = {}
+
+let baseMapLayer = {
+ yx: [],
+ sl: []
+}
+let options,
+ epsgcode,
+ isMvt = false
+
+let isMapResource = true
+export default {
+ name: 'OlMapBox',
+
+ props: {
+ mapType: {
+ type: String,
+ default: 'sl'
+ },
+
+ mapContrast: {
+ type: String,
+ default: 'custom'
+ }
+ },
+
+ data () {
+ return {
+ publicPath: process.env.BASE_URL,
+ }
+ },
+
+
+ mounted () {
+ const that = this
+
+ this.$nextTick(() => {
+ mapView = new OlMap({
+ target: 'OlMapBoxElement',
+ layers: [],
+ view: new OlView({
+ // 初始化中心点坐标,经纬度一会自己换一下
+ center: [113, 24],
+ zoom: 18,
+ projection: "EPSG:4326"
+ }),
+ })
+
+ mapView.on("singleclick", function (event) {
+ mapView.forEachFeatureAtPixel(
+ event.pixel,
+ (feature) => {
+ feature.dispatchEvent && feature.dispatchEvent({ type: 'click', event: event })
+ }
+ )
+ })
+
+ that.baseInitLayer(that.mapType)
+
+
+ this.mapAddClusterLayer(
+ 'livePersonLocationLayer',
+ '/public/img/map/location',
+ [{lng: 113, lat: 24}, {lng: 115, lat:24 }],
+ (e) => { },
+ )
+ })
+ },
+
+ methods: {
+ /**
+ * @description: 底图加载
+ * @param {*} type
+ * @return {*}
+ */
+ baseInitLayer (type) {
+ if (baseMapLayer.yx.length) {
+ baseMapLayer.yx.forEach(item => {
+ mapView.removeLayer(item)
+ })
+ baseMapLayer.yx = []
+ }
+
+ if (baseMapLayer.sl.length) {
+ baseMapLayer.sl.forEach(item => {
+ mapView.removeLayer(item)
+ })
+ baseMapLayer.sl = []
+ }
+
+ if (type == 'yx') {
+ let yxImgW = new OlLayerTile({
+ zIndex: 1,
+ title: '影像',
+ source: new XYZ({
+ url: 'https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
+ })
+ })
+
+ mapView.addLayer(yxImgW)
+
+ baseMapLayer.yx.push(yxImgW)
+
+ let yxCvaW = new OlLayerTile({
+ zIndex: 2,
+ title: '影像标注',
+ source: new XYZ({
+ url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
+ })
+ })
+
+ mapView.addLayer(yxCvaW)
+
+ baseMapLayer.yx.push(yxCvaW)
+ } else if (type == 'sl') {
+ let slVecW = new OlLayerTile({
+ zIndex: 2,
+ title: '矢量',
+ source: new XYZ({
+ url: 'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
+ })
+ })
+
+ mapView.addLayer(slVecW)
+
+ baseMapLayer.sl.push(slVecW)
+
+ let slCvaW = new OlLayerTile({
+ zIndex: 2,
+ title: '矢量标注',
+ source: new XYZ({
+ url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
+ })
+ })
+
+ mapView.addLayer(slCvaW)
+
+ baseMapLayer.sl.push(slVecW)
+ }
+ },
+
+ // javascript 转换
+ lonLat2Mercator (lonlat) {
+ var mercator = {
+ x: 0,
+ y: 0
+ }
+ var earthRad = 6378137.0
+ mercator.x = lonlat.lng * Math.PI / 180 * earthRad
+ var a = lonlat.lat * Math.PI / 180
+ mercator.y = earthRad / 2 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)))
+ return mercator
+ },
+
+ getCurItemFeature (params) {
+ const iconFeature = new Feature({
+ geometry: new Point([Number(params.lng), Number(params.lat)]),
+ attributes: params.item
+ })
+
+ let styleOptions = {
+ cursor: 'pointer',
+ }
+
+ if (params.url) {
+ styleOptions.image = new Icon({
+ scale: params.scale || 1,
+ imgSize: params.imgSize || [160, 221],
+ src: params.url,
+ })
+ }
+
+ if (params.text) {
+ let textElement = document.createElement('span')
+ textElement.innerHTML = params.text
+
+ let color = '#0000FF'
+
+ styleOptions.text = new Text({
+ // 对齐方式
+ textAlign: 'center',
+ // 文本基线
+ textBaseline: 'middle',
+ text: textElement.innerHTML,
+ font: '14px Arial',
+ fill: new Fill({
+ color: 'white'
+ }),
+ // 填充背景
+ backgroundFill: new Fill({
+ color: color
+ }),
+ padding: [2, 5, 2, 5],
+ stroke: new Stroke({ color: '#00000000', width: 1 })
+ })
+ }
+
+ iconFeature.setStyle(new Style(styleOptions))
+
+ iconFeature.on('click', (e) => {
+ if (params.event) {
+ params.event(e.target.values_.attributes.attr)
+ }
+ })
+
+ return iconFeature
+ },
+
+ /**
+ * 删除图层
+ * @param {*} layerName 图层名称
+ */
+ mapRemoveLayer (layerNames) {
+ layerNames.forEach(item => {
+ if (layersObjcect[item] && layersObjcect[item] != null) {
+ mapView.removeLayer(layersObjcect[item])
+ delete layersObjcect[item]
+ }
+
+ if (layersObjcect[item + 'ONE'] && layersObjcect[item + 'ONE'] != null) {
+ mapView.removeLayer(layersObjcect[item + 'ONE'])
+ delete layersObjcect[item + 'ONE']
+ }
+
+ if (layersObjcect[item + 'TWO'] && layersObjcect[item + 'TWO'] != null) {
+ mapView.removeLayer(layersObjcect[item + 'TWO'])
+ delete layersObjcect[item + 'TWO']
+ }
+ })
+ },
+
+ // 添加聚合图层的新模式,水库点分布
+ mapAddClusterLayer (layerName, imgUrl, positionData, incident = (e) => { }, type = '') {
+ const that = this
+
+ if (!layersObjcect[layerName]) {
+ if (type == 'cluster') {
+ let source = new VectorSource()
+
+ positionData.forEach(item => {
+ source.addFeature(that.getCurItemFeature({
+ item,
+ lng: item.lng,
+ lat: item.lat,
+ url: imgUrl,
+ event: incident
+ }))
+ })
+
+ let layer = new Cluster({
+ source: source,
+ distance: 100
+ })
+
+ layersObjcect[layerName] = new VectorLayer({
+ source: layer,
+ zIndex: 24,
+ style: (feature, resolution) => {
+ let size = feature.get('features').length
+
+ let radius = 10
+
+ if (size > 900) {
+ radius = 19
+ } else if (size > 600) {
+ radius = 16
+ } else if (size > 400) {
+ radius = 13
+ }
+
+ let style = new Style({
+ image: new Circle({
+ radius: radius,
+ stroke: new Stroke({
+ color: 'blue',
+ width: 1
+ }),
+ fill: new Fill({
+ color: 'blue'
+ })
+ }),
+ text: new Text({
+ text: size.toString(),
+ fill: new Fill({
+ color: 'white'
+ })
+ })
+ })
+
+ return style
+ }
+ })
+
+ mapView.addLayer(layersObjcect[layerName])
+
+ return
+ } else {
+ layersObjcect[layerName] = new VectorLayer({
+ // 图标图层
+ zIndex: 24,
+ minZoom: 12,
+ source: new VectorSource(),
+ })
+ }
+
+ mapView.addLayer(layersObjcect[layerName])
+ }
+
+ positionData.forEach(item => {
+ layersObjcect[layerName].getSource().addFeature(that.getCurItemFeature({
+ item,
+ lng: item.lng,
+ lat: item.lat,
+ url: imgUrl,
+ event: incident
+ }))
+ })
+ },
+ },
+}
+</script>
+
+<style lang='scss' scope>
+
+.w100 {
+ width: 100%;
+}
+
+.h100 {
+ height: 100%;
+}
+</style>
diff --git a/src/views/check/leave.vue b/src/views/check/leave.vue
index d6bbe58..251d0b1 100644
--- a/src/views/check/leave.vue
+++ b/src/views/check/leave.vue
@@ -258,7 +258,7 @@
id: row.id,
auditStatus: row.auditStatus,
auditDetail: row.auditDetail,
- auditUser: this.userInfo.Id
+ auditUser: this.userInfo.user_id
};
audit(data).then(
() => {
diff --git a/src/views/check/livePersonLocation.vue b/src/views/check/livePersonLocation.vue
new file mode 100644
index 0000000..aa228ae
--- /dev/null
+++ b/src/views/check/livePersonLocation.vue
@@ -0,0 +1,19 @@
+
+<template>
+ <div style="width: 100%; height: 100%;">
+ <OlMapBox></OlMapBox>
+
+ </div>
+</template>
+
+<script>
+import OlMapBox from "./components/OlMapBox.vue";
+export default {
+ name: "livePersonLocation",
+ components: {OlMapBox}
+}
+</script>
+
+<style scoped>
+
+</style>
--
Gitblit v1.9.3