局域网内PGIS地图的使用

局域网PGIS地图的使用:以天地图做打底,使用leaflet.js交互式地图 JavaScript 库做开发。

相关参考网址:https://leafletjs.cn/reference.html#map-example

区域回显:https://kklimczak.github.io/Leaflet.Pin/;

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/124026478

热力图:https://www.jb51.net/javascript/290354ppf.htm

轨迹:https://blog.51cto.com/BADAOLIUMANGQZ/6843897

PS:相关搜索可搜Leaflet.MovingMarker-master

主要功能包括点的标记,区域的展示,以及点的点击事件;点的添加展示,区域的绘制,回显,编辑,删除;热力图;PGIS轨迹回放功能。相关代码如下:

一、点的标记,区域的展示,以及点的点击事件

相关代码组件如下,此组件整合了热力图的展示,具体根据实际业务需要选择性展示:

复制代码
<template>
    <!-- 该组件是展示点的添加,区域的添加以及点击事件 和热力图的展示的整合组件 -->
  <div class="data_map" style="height: 100%; position: relative">
    <div
      class="bg_heights"
      style="position: relative; width: 100%"
      :style="{ height: height }"
    >
      <div :id="mapId" style="width: 100%" :style="{ height: height }"></div>
    </div>
    <div class="tabClickA" v-if="$route.path != '/index'">
      <div class="tabList" @click="clickGrid('1')">警务区</div>
      <div class="tabList" @click="clickGrid('2')">网格</div>
    </div>
  </div>
</template>
<style scoped lang="scss"></style>
<style>
.anchorBL {
  display: none;
}
body,
html,
#map {
  height: 100%;
  margin: auto;
  font-family: "微软雅黑";
}
.my-label-a {
  width: 100%;
  height: 20px;
}
</style>
<script type="text/ecmascript-6">
// require('echarts/extension/bmap/bmap.min');
// import * as zrender from 'zrender'  //引入zrender库

import 'leaflet.heat'
import { loadBMap } from './map'
var map;
var T = window.T;
export default {
    props:{
        height:{
            type:String,
            default:'100%'
        },
        mapId:{
            type:String,
            default:'mapId'
        },
        //商圈区域
        businessList:{
            type:Array,
            default:()=>[]
        },
        //绘制商铺点
        shopList:{
            type:Array,
            default:()=>[]
        },
        //绘制设备点
        equList:{
            type:Array,
            default:()=>[]
        },
        //警务区网格
        policeArea:{
            type:Array,
            default:()=>[]
        },
        //综治网格
        gridArea:{
            type:Array,
            default:()=>[]
        },
        //警务区展示与否
        isShowPolice:{
            type:Boolean,
            default:false
        },
        //网格展示与否
        isShowGrid:{
            type:Boolean,
            default:false
        },
        //热力地图数据
        houtData:{
            type:Array,
            default:()=>[
            //     {coor:[118.711996,37.440117], count: 45},
            // {coor:[118.714751,37.439935], count: 56},
            // {coor:[118.709006,37.442001], count: 127},
            // {coor:[118.707861,37.438914],  count: 89},
            // {coor:[118.712757,37.434551],  count: 13},
            // {coor:[118.649018, 37.453269], count: 234},
            // {coor:[118.718937,37.434179],  count: 46},
            // {coor:[118.718398,37.443677],  count: 339},
            // {coor:[118.713907,37.448061],  count: 95},
            // {coor:[118.713907,37.448061],  count: 354},
            ]
        },
        //点击设备展示设备信息还是video
        isShowVideo:{
            type:Boolean,
            default:false
        },
        //是否展示商圈边界
        isBusiness:{
            type:Boolean,
            default:false
        },
        //这是商圈地图的点击商圈的展示与否的
    isMapEvery: {
      type: Boolean,
      default:false
    }

    },
    data(){
        return {
            mapLoading:false,
            bgHeight:'668px',
            map:'',
            currentLat:118.70034983319356,
            currentLon : 37.45030118084613,
            getZoom:16,   //地图当前的等级
            previousBusinessPolygons: [], // 存储之前绘制的业务描边图形
            previousPolicePolygons: [],   // 存储之前绘制的警察描边图形
            previousGridPolygons: []     // 存储之前绘制的网格描边图形
        }
    },
    watch: {
        businessList: {
        handler: function (newObj, oldObj) {
            let that = this;
                that.addMarker(this.businessList,'business')
            },
            deep: true, // 深度监听
            immediate: true // 会在监测开始时调用一次该处理函数
        },
        shopList: {
            handler: function(newObj, oldObj) {
                let that=this;
                that.drawPoint(that.shopList,'shop')
            },
            deep: true, // 深度监听
            // immediate: true // 会在监测开始时调用一次该处理函数
        },
        equList: {
            handler: function(newObj, oldObj) {
                let that=this;
                that.drawPoint(that.equList,'camera')
            },
            deep: true, // 深度监听
            immediate: true // 会在监测开始时调用一次该处理函数
        },
        policeArea: {
            handler: function(newObj, oldObj) {
                let that=this;
                that.addMarker(that.policeArea,'police')
            },
            deep: true, // 深度监听
            immediate: true // 会在监测开始时调用一次该处理函数
        },
        gridArea: {
            handler: function(newObj, oldObj) {
                let that=this;
                that.addMarker(that.gridArea,'grid')
            },
            deep: true, // 深度监听
            immediate: true // 会在监测开始时调用一次该处理函数
        },
        houtData: {
            handler: function(newObj, oldObj) {
                let that=this;
                setTimeout(function(){
                    that.initHotMap()
                },100)
            },
            deep: true, // 深度监听
            immediate: true // 会在监测开始时调用一次该处理函数
        },

    },
    methods:{
         //初始化百度地图
        initBdMap() {
            var that = this
            var cenPoint = [118.688,37.443]
            var map = L.map(this.mapId, {
                attributionControl:false,
                crs:L.CRS.EPSG4326,  //要使用的坐标系  WGS84 是目前最流行的地理坐标系统
                center:[cenPoint[1],cenPoint[0]],
                zoom: 16
            });
            //这里是加载的内网的瓦片地址
            L.tileLayer('这是url', {
            // L.tileLayer(imageURL, {
                minZoom:0,
                maxZoom:19,
                zoomOffset:0,
                tms:false
            }).addTo(map);
            this.map = map
        },

        //绘制点
      drawPoint(data, type) {
            var that = this
            //获取所有的图层
            let all = this.map._layers
            let arr = Object.values(all)
            arr.map(item=>{
                if (item.class === "shopPointA") {
                    //如果是点图层就删除相关的点图层
                    that.map.removeLayer(item);
                }
            })
            //图标大小
            var LeafIcon = L.Icon.extend({
                options: {
                    iconSize: [36, 47],
                }
            });
            document.body.addEventListener('click', function(event) {
                //查看更多的跳转
                if (event.target.innerText == '查看更多>>') {
                    that.$router.push("/business/shopDetail?id="+event.target.id );
                }
            });
            var data_info = data,content,newPoint,mapUrl,shopName;
            for(var i = 0;i<data_info.length;i++){
                //根据不同的类型展示不同的点的图片以及点击点的弹框的内容
                if(type=='shop'){
                    mapUrl = require("../../assets/base/shop.png")
                    shopName = data_info[i].shopName
                    content = "<div class='skyDiv'>"+
                            "<div class='skyTitle'>"+shopName+"</div>"+
                            "<p class='skyP'>联系人:"+data_info[i].userName +'  ('+data_info[i].phone+')'+"</p>"+
                            "<p class='skyP'>地址:"+data_info[i].addressName+"</p>"+
                            "<p class='skyP' style='color:#50b3ff;cursor: pointer' id='"+data_info[i].id+"'>查看更多>></p>"+
                            "</div>"
                }else{
                    mapUrl = require("../../assets/base/equ.png")
                    shopName = data_info[i].name
                    content = "<div class='skyDiv'>"+
                            "<div class='skyTitle'>"+shopName+"</div>"+
                            "</div>"
                }
                //申明点
                var icon = new LeafIcon({iconUrl: mapUrl});
                L.icon = function (options) {
                    return new L.Icon(options);
                };
                newPoint = [data_info[i].longitude, data_info[i].latitude]
                var shopPoint = L.marker([Number(newPoint[1]), Number(newPoint[0])], { icon: icon })
                shopPoint.class='shopPointA'   //确立点的标识,方便后期做相关的操作应用,具体看实际的业务逻辑
                shopPoint.addTo(that.map).bindPopup(content);   //bindPopup  在点上添加点击事件
            }
        },
        //绘制区域描边
        addMarker(data, type) {
            let that = this
                //添加警务网格
                var business = data;
                for(var i = 0;i<business.length;i++){
                    if(business[i].border!=''&&business[i].border!=null){
                        //整理绘制区域需要的数据格式
                        var policeGrid = business[i].border.split(';'),newArr = [],newArrNow = [],oneArr = []
                        if(policeGrid.length>0){
                            policeGrid.forEach(item=>{
                                var aa = [Number(item.split(',')[1]), Number(item.split(',')[0])]
                            newArr.push(aa)
                            })
                            //获取相关图层
                            let all = this.map._layers
                            let arr = Object.values(all)
                            var bus
                            //此处是商圈的区域添加  --》》mxj 20231214
                            if (type == 'business') {
                                bus = L.polygon(newArr, {
                                    color: "#FF5663", weight: 2, opacity: 1, fillColor: "#FF5663", fillOpacity: 0.5,lineStyle:'dashed',
                                })
                                bus.class = 'businessA'   //添加唯一标识
                                //isBusiness是在搜索的时候判断是否在次添加  --》》mxj 20231214
                                if (this.isBusiness == true) {
                                    bus.bindTooltip(business[i].name, {
                                        permanent: true,
                                        direction: 'top'
                                    }).openTooltip()
                                    bus.addTo(that.map)   //添加区域展示
                                } else {
                                    if (that.isMapEvery == true) {
                                        //此处的业务逻辑是先删除,在添加区域展示,具体的根据实际业务逻辑来
                                        arr.map(item=>{
                                            if (item.class === "businessA") {
                                                //删除相关图层
                                                that.map.removeLayer(item);
                                            }
                                        })
                                        bus.bindTooltip(business[i].name, {
                                            permanent: true,
                                            direction: 'top'
                                        }).openTooltip()
                                        bus.addTo(that.map)
                                    }
                                }
                            } else if (type == 'police') {
                                //此处是警务区的区域添加  --》》mxj 20231214
                                var police = L.polygon(newArr, {
                                    color: "#FF5663", weight: 2, opacity: 1, fillColor: "#FF5663", fillOpacity: 0.5,lineStyle:'dashed',
                                })
                                police.class='policeA'
                                //isShowPolice判断是添加还是隐藏  --》》mxj 20231214
                                if(this.isShowPolice){
                                    police.bindTooltip(business[i].policeDistrictName,{
                                        permanent:true,
                                        direction:'top'
                                    }).openTooltip()
                                    police.addTo(this.map)   //添加
                                }else{
                                    arr.map(item=>{
                                        if (item.class === "policeA") {   //删除
                                            that.map.removeLayer(item);
                                        }
                                    })
                                }
                            }else if(type=='grid'){
                                //此处是网格的区域添加  --》》mxj 20231214
                                var grid = L.polygon(newArr, {
                                    // color: "#FF642E", weight: 2, opacity: 1, fillColor: "#FF642E", fillOpacity: 0.5,lineStyle:'dashed',
                                    color: "#FF5663", weight: 2, opacity: 1, fillColor: "#FF5663", fillOpacity: 0.5,lineStyle:'dashed',
                                })
                                grid.class='gridA'
                                //isShowGrid判断是添加还是隐藏  --》》mxj 20231214
                                if(this.isShowGrid){
                                    grid.bindTooltip(business[i].gridName,{
                                        permanent:true,
                                        direction:'top'
                                    }).openTooltip()
                                    grid.addTo(this.map)   //添加
                                }else{
                                    arr.map(item=>{
                                        if (item.class === "gridA") {
                                            //删除
                                            that.map.removeLayer(item);
                                        }
                                    })
                                }
                            }
                        }
                    }
                }
        },
        clickGrid(data){
            this.$emit('clickGrid',data)
        },
        //热力图
        initHotMap(){
            var that = this
            //热力图添加之前先把之前的热力图层去掉,以防止多次重复添加
            let all = this.map._layers
            let arr = Object.values(all)
            arr.map(item=>{
                if (item.class === "heatA") {
                    that.map.removeLayer(item);
                }
            })
            let heatDataList = [
                // { lat: 39.6408, lng: 116.7728, count: 1 },
                // { lat: 39.75, lng: 116.55, count: 1 },
                // { lat: 39.55, lng: 116.55, count: 100 },
                // { lat: 39.65, lng: 116.45, count: 1 },
                // { lat: 39.45, lng: 116.35, count: 1 },
                // { lat: 39.35, lng: 116.25, count: 1 },
                // { lat: 39.25, lng: 116.15, count: 1 }
            ]
            // 构造热力图数据
            this.houtData.forEach((v) => {
                // 纬度、经度、阈值
                var aa = v.coor
                let group = [aa[0], aa[1], v.count]
                heatDataList.push(group)
            })

            // 生成热力图图层,并添加到地图中
            let heat = L.heatLayer(heatDataList, {
                radius: 12,
                minOpacity: 0.2,
                gradient: { // 自定义渐变颜色,区间为 0~1 之间(也可以不指定颜色,使用默认颜色)
                    '0.25': 'rgba(0, 0, 255, 1)',
                    '0.55': 'rgba(0, 255, 0, 1)',
                    '0.85': 'rgba(255, 255, 0, 1)',
                    '1': 'rgba(255, 0, 0, 1)'
                }
            });
            heat.class='heatA'
            heat.addTo(this.map)
        },
    },
    //调用方法
    mounted() {
        var that = this
        that.$nextTick(() => {
            that.initBdMap();
        })
    }
}
</script>
<style lang="scss">
.tabClickA {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  z-index: 1000;
  cursor: pointer;
  .tabList {
    width: 93px;
    height: 38px;
    background: #53c9fc;
    color: #ffffff;
    font-size: 14px;
    text-align: center;
    line-height: 38px;
    margin-left: 10px;
  }
}
.divOutMap {
  width: 290px;
  height: 185px;
  background: url("http://218.56.180.213:8035/shopping/static/file/pic/202307/picrXBtW1uh1689581712300.png");
  margin-top: -50px;
  margin-left: -145px;
  .topDiv {
    display: flex;
    padding: 25px 10px 0px 20px;
    justify-content: space-between;
    .closeDiv {
      margin-left: 10px;
      font-size: 14px;
      color: #53c9fc;
      text-decoration: underline;
    }
    opLeft {
      font-size: 16px;
      color: rgba(235, 251, 255, 0.8);
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .topRight {
      font-size: 14px;
      color: #53c9fc;
      text-decoration: underline;
      width: 56px;
    }
  }
  .shopBoxMap {
    padding: 0px 10px 0px 20px;
    .shopOne {
      background: rgba(58, 129, 200, 0.26);
      border-radius: 5px;
      height: 40px;
      margin-top: 15px;
      box-shadow: 0px 0px 15px rgba(50, 121, 198, 1) inset;
      line-height: 40px;
      color: #ffffff;
      font-size: 14px;
      padding: 0px 10px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
  .mapShowImgA {
    width: 250px;
    height: 106px;
    margin-top: 10px;
    margin-left: 25px;
  }
}
</style>
复制代码

 

二、点的添加展示,区域的绘制,回显,编辑,删除功能

在public页面引入如下代码:

复制代码
<!-- 局域网 -->
<link rel="stylesheet" href="leaflet.css"/>
<script type="text/javascript" src="leaflet.js"></script>
<script type="text/javascript" src="leaflet-hash.js"></script>
<script type="text/javascript" src="MovingMarker.js"></script>
<!-- 这是绘制区域 -->
<script type="text/javascript" src="Leaflet.draw.js"></script>
<link rel="stylesheet" href="leaflet.draw.css"/>
<script src="leaflet.pin.js"></script>
<!-- 天地图 -->
<script type="text/javascript" src="https://api.tianditu.gov.cn/api?v=4.0&tk=d98028206b9637c8e3e21a7041c01b7a"></script>
复制代码

组件代码:

复制代码
<!--
 * @Author: menxiaojin
 * @Date: 2023-07-14 10:24:08
 * @LastEditors: menxiaojin
 * @LastEditTime: 2023-08-24 13:36:24
-->
<template>
  <div class="appInner">
      <form-back></form-back>
      <base-cont height="100%" :isScrollbar="false">
          <template #head>
              <hy-header :importe="false" :exporte="false" :add="false" :deleted="false">绘制地图</hy-header>
          </template>
          <template #cont>
              <div >
                  <titleTwo title="基础信息"></titleTwo>
                  <disPlay>
                      <listOne paddingLeft="0px" name="商铺名称" :content="detailObj.name"></listOne>
                      <listOne name="是否绘制" :content="detailObj.border==''?'无':'是'"></listOne>
                      <listOne  paddingRight="0px" name="中心点坐标" :content="centerPoint.toString()"></listOne>
                      <div class="newDrawEwar">
                        <el-form >
                          <el-form-item label="拾取中心点坐标" class="labelItem" style="z-index: 30 !important;margin-bottom: 0 !important;padding-top:10px;padding-left:10px">
                            <el-switch v-model="getCenPoint" active-text="开始" inactive-text="关闭"></el-switch>
                          </el-form-item>
                        </el-form>
                      </div>
                  </disPlay>
              </div>
              <div id="adjustMap" class="adjustStyle" ></div>
          </template>
      </base-cont>
      <increasePop
        :centerDialogVisible.sync="tipsAlert"
        title="绘制数据"
        :ruleForm="ruleFormH"
        @resertClick="resertDetailH"
        @sureClick="sureClickH"
      >
        <form-textarea :value.sync="ruleFormH.areaStr" label="边界数据" preFixIcon="" placeholder="请输入边界数据"></form-textarea>
      </increasePop>
  </div>
</template>

<script>
import { businessEdit,businessDetail } from "@/api/shop/business";
import titleTwo from '@/components/shopNew/title.vue';
import listOne from '@/components/shopNew/list.vue';
import disPlay from '@/components/shopNew/disPlay.vue';
// import twoMap from "@/components/map/twoMap.vue";  //百度地图绘制
import twoMap from "@/components/map/twoMapNei.vue";  //天地图
import increasePop from '@/components/form/increasePop.vue';
export default {
  components: {titleTwo,listOne,disPlay,twoMap,increasePop},
  name: "Drawarea",
  data() {
      return {
        detailId:'',
        detailObj:{},
        map:null,
        centerPoint:[],
        getCenPoint:false,  //是否拾取中心点坐标
        //绘制完成的弹框
        tipsAlert:false,
        ruleFormH:{
          areaStr:'',
        },
        //地图
        nowArrBorder:[],
        newBorder:'',  //新绘制的边界数据
      }
  },
  mounted() {
      this.initDetail()
  },
  created(){
      this.detailId = this.$route.query.id;
  },
  methods: {
      resertDetailH(){
        this.tipsAlert = false
        this.ruleFormH.areaStr = ''
      },
      //获取详情
      initDetail(){
          let that=this;
          businessDetail({id:this.detailId}).then((res) => {
              if (res.code == 0) {
                  this.detailObj = res.data
                  if(res.data.border!=''&&res.data.border!=null){
                    var aa = res.data.border.split(';'),newArrBOrder = []
                    aa.forEach(item=>{
                      var singArr = [Number(item.split(',')[0]),Number(item.split(',')[1])]

                      newArrBOrder.push(singArr)
                    })
                    that.nowArrBorder = newArrBOrder
                    var bb = res.data.border.split(';')[0].split(',')
                    that.centerPoint = res.data.centerPoint.split(',');
                  }else{
                    that.centerPoint = [118.7241,37.45292]
                  }

                  that.$nextTick(() => {
                    that.initBdMap();
                  })
                  } else {
                  that.$global.tipMsg("error", res.msg);
              }
          });
      },
      cenPoint(data){
          this.centerPoint = data
          var that = this
          businessEdit({id:this.detailId,centerPoint:data.toString()}).then(res=>{
              if(res.code==0){
                  // this.$router.go(-1)
                  this.$global.tipMsg("success", '中心点设置成功');
              }else{
                  this.$global.tipMsg("error", res.msg);
              }
          }).catch()
      },
      //展示地图
      loadJson () {
        var data = this.nowArrBorder,newData = []
        data.forEach(item=>{
          var aa = JSON.stringify(item)
          newData.push(JSON.parse(aa))
        })
          return {
              "type": "FeatureCollection",
              "features": [{
                  "type": "Feature",
                  "properties": {},
                  "geometry": {
                      "type": "Polygon",
                      "coordinates": [
                        // [
                          // [118.69159877773762,37.481140660363366],
                          // [118.69102386221124,37.47756100936721],
                          // [118.70011471397221,37.47747509561818],
                          // [118.7004021717354,37.48016701241549],
                          // [118.69838996739306,37.48185656980892],
                          // [118.69159877773762,37.481140660363366]
                          // this.nowArrBorder
                          // [118.69159877773762, 37.481140660363366],
                          // [118.69102386221124, 37.47756100936721],
                          // [118.70011471397221, 37.47747509561818],
                          // [118.7004021717354, 37.48016701241549],
                          // [118.69838996739306, 37.48185656980892],
                          // [118.69159877773762, 37.481140660363366],
                          newData
                        // ]
                      ]
                  }
              },
            ]
          }
      },
      //添加点
      addPoint(data){
        var that = this
        var center = JSON.parse(data)   // 经度,维度的排序
        var LeafIcon = L.Icon.extend({
          options: {
              iconSize: [29, 25],
          }
        });
        let mapUrl = 'http://218.56.180.213:8035/shopping/static/file/pic/202307/piclCI6umdv1689299533795.png'
        var icon = new LeafIcon({iconUrl: mapUrl});
        L.icon = function (options) {
          return new L.Icon(options);
        };
        L.marker([center[1],center[0]],{icon: icon}).addTo(that.map);
      },
      //初始化百度地图
      initBdMap() {
           //声明地图
           var that = this
          var cenPoint = [Number(this.centerPoint[0]),Number(this.centerPoint[1])]
          var map = L.map('adjustMap', {
              attributionControl:false,
              crs:L.CRS.EPSG4326,  //要使用的坐标系  WGS84 是目前最流行的地理坐标系统
              center:[cenPoint[1],cenPoint[0]],
              zoom: 15,
          });
          // L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
          // L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
          L.tileLayer('这是url', {
          // L.tileLayer(imageURL, {
              minZoom:0,
              maxZoom:19,
              zoomOffset:0,
              tms:false
          }).addTo(map);
          this.map = map

          //添加绘制图层
          var drawnItems = new L.FeatureGroup();
          map.addLayer(drawnItems);
          //添加绘制控件
          var drawControl = new L.Control.Draw({
              draw:{
                  // //绘制线
                  polyline:false,
                  //绘制多边形
                  polygon:true,
                  //绘制矩形
                  rectangle:false,
                  //绘制圆
                  circle:false,
                  //绘制标注
                  marker:false,
                  //绘制圆形标注
                  circlemarker:false
              },
              edit:{
                  //绘制图层
                  featureGroup:drawnItems,
                  //图形编辑控件
                  edit:true,
                  //图形删除控件
                  remove:true,
              }
          });

      //添加绘制控件
      map.addControl(drawControl);
      //这里时将已绘制的区域进行回显展示
      if(this.nowArrBorder.length!=0){
        L.geoJson(this.loadJson(), {
          onEachFeature: function (feature, layer) {
            //设置颜色,目前没有到,暂时留存,不影响功能
            if(feature.geometry.type == "LineString") {
              layer.setStyle({
                color: 'purple',
                weight: 5
              });
            }
            drawnItems.addLayer(layer);
          }
        });

        map.addGuideLayer(drawnItems);
        map.removeGuideLayer(drawnItems);
      }
      //对中心点进行回显
      this.addPoint(JSON.stringify(this.centerPoint))

      // //绘制事件
      map.on(L.Draw.Event.CREATED, function(e){
         //获取绘制图形类型
         var type = e.layerType,
         //获取绘制图层
         drawlayer = e.layer;
         if (type === 'marker') {
             //显示Popup
             drawlayer.bindPopup('A popup!');
         }
         //显示图层
         drawnItems.addLayer(drawlayer);
         //几何信息字符串
         var latlngsStr = "";
          //获取多边形几何信息
         if (type == 'polygon') {
             if (drawlayer._latlngs[0].length > 0) {
                 for (var latlngslength = 0; latlngslength < drawlayer._latlngs[0].length; latlngslength++) {
                     //获取几何信息
                     latlngsStr +=  drawlayer._latlngs[0][latlngslength].lng + "," + drawlayer._latlngs[0][latlngslength].lat + ";"
                 }
                 var bb = [latlngsStr.slice(0,latlngsStr.length-1)];
                 that.newBorder = bb.toString();
                 that.ruleFormH.areaStr = bb.toString();
                 that.tipsAlert = true
             }
         }
         //显示信息
        });
        this.map.addLayer(drawnItems);
        // 删除事件
        this.map.on(L.Draw.Event.DELETED, this.handleDelete)
        // 编辑事件
        this.map.on(L.Draw.Event.EDITED, this.handleEdited)

        //监听鼠标点击事件,点击拾取坐标,设置中心店
        function onMapClick(e) {
          // console.log(e)
          if(that.getCenPoint == true){
            that.centerPoint = [e.latlng.lng,e.latlng.lat]
            //清空之前全部的标记点,然后重新添加
            $(".leaflet-marker-pane").empty()
            //点击的时候顺便加点
            that.addPoint(JSON.stringify(that.centerPoint))
            //设置中心点接口
            that.cenPoint(that.centerPoint)
          }
        };
        map.on('click',onMapClick);
      },
      //删除
      handleDelete(e){
        this.nowArrBorder = []
      },
      //编辑
      handleEdited(e){
        var that = this
        if(e.layers._layer!=undefined){
          var obj = e.layers._layers,newArr = [],arrSub=[],strSub = ''
          for(var i in obj) {
            newArr = obj[i]._latlngs[0]
          }
          for(var i = 0;i<newArr.length;i++){
            strSub+=newArr[i].lng+','+newArr[i].lat+';'   //strSu是上传所需要的数据
          }
          var bb = [strSub.slice(0,strSub.length-1)];
          businessEdit({id:this.detailId,border:bb.toString()}).then(res=>{
            if(res.code==0){
                this.$global.tipMsg("success", '保存成功');
            }else{
                this.$global.tipMsg("error", res.msg);
            }
          }).catch()
        }

      },
      //提交绘制
      sureClickH(){
        var that = this
        businessEdit({id:this.detailId,border:this.ruleFormH.areaStr}).then(res=>{
            if(res.code==0){
                this.tipsAlert = false
            }else{
                this.$global.tipMsg("error", res.msg);
            }
        }).catch()
      },
  },
};
</script>

<style  lang="scss">
.appInner {
  min-width: 1055px;
  height: 100%;
  position: relative;
}
.adjustStyle{
  width: 100%;
  height: calc(100% - 125px);
  margin-top: 20px;
}
.backBtnDraw{
  position: absolute;
  top:200px;
  right: 40px;
}
.showSearch{
  background: rgba(23, 114, 153, 1);
  padding: 10px;
  display: flex;
  border-radius: 5px;
}
.newDrawEwar{
  .el-form-item__label{
    width:100%;
    text-align: left;
    color: rgba(225, 225, 225, 0.5);
  }
  .el-form-item__content{
    // widows: 100%;
    background:rgba(75, 173, 248, 0.33);
    height: 32px;
    margin-top:35px;
    .el-radio{
      margin-left: 10px;
    }
    .el-switch{
      margin-left: 10px;
      margin-top: -10px;
      .el-switch__label{
        color: rgba(255,255,255,0.5);
      }
      .is-active{
        color: #47d0f1;
      }
    }
  }
}
</style>
复制代码

三、热力图的关键代码

在index.html页面引入js

<!-- 热力图 -->
    <script type="text/javascript" src="HeatmapOverlay.js"></script>

热力图相关主要代码:

复制代码
//热力图
initHotMap(){
    var that = this
    //热力图添加之前先把之前的热力图层去掉,以防止多次重复添加
    let all = this.map._layers
    let arr = Object.values(all)
    arr.map(item=>{
        if (item.class === "heatA") {
            that.map.removeLayer(item);
        }
    })
    let heatDataList = [
        // { lat: 39.6408, lng: 116.7728, count: 1 },
        // { lat: 39.75, lng: 116.55, count: 1 },
        // { lat: 39.55, lng: 116.55, count: 100 },
        // { lat: 39.65, lng: 116.45, count: 1 },
        // { lat: 39.45, lng: 116.35, count: 1 },
        // { lat: 39.35, lng: 116.25, count: 1 },
        // { lat: 39.25, lng: 116.15, count: 1 }
    ]
    // 构造热力图数据
    this.houtData.forEach((v) => {
        // 纬度、经度、阈值
        var aa = v.coor
        let group = [aa[0], aa[1], v.count]
        heatDataList.push(group)
    })

    // 生成热力图图层,并添加到地图中
    let heat = L.heatLayer(heatDataList, {
        radius: 12,
        minOpacity: 0.2,
        gradient: { // 自定义渐变颜色,区间为 0~1 之间(也可以不指定颜色,使用默认颜色)
            '0.25': 'rgba(0, 0, 255, 1)',
            '0.55': 'rgba(0, 255, 0, 1)',
            '0.85': 'rgba(255, 255, 0, 1)',
            '1': 'rgba(255, 0, 0, 1)'
        }
    });
    heat.class='heatA'
    heat.addTo(this.map)
},
复制代码

四、PGIS局域网地图的轨迹回放

主要代码:

复制代码
<!--首页地图组件-->
<template>
    <!-- 该页面的逻辑是一开始展示轨迹,点击轨迹按钮出现播放轨迹动效的相关操作,点击返回重新返回轨迹静态展示页面 -->
  <div class="data_map" style="height: 100%">
    <div class="bg_heights" style="position: relative; height: 100%">
      <div :id="mapId" style="width: 100%; height: 100%"></div>
      <div class="bofang" v-if="markerArr.length != 0">
        <el-button
          type="primary"
          size="mine"
          @click="plackBack"
          v-if="condition"
          >轨迹</el-button
        >
        <el-button type="primary" size="mine" @click="continueMap"
          >返回</el-button
        >
      </div>
    </div>
  </div>
</template>
<style lang="scss">
.bofang {
  position: absolute;
  top: 20px;
  left: 30px;
  z-index: 1000;
}
</style>
<style lang="scss">
.anchorBL {
  display: none;
}
body,
html,
#map {
  height: 100%;
  margin: auto;
  font-family: "微软雅黑";
}
.divLabelMApText {
  width: 36px;
  height: 36px;
  text-align: center;
  line-height: 16px;
  font-size: 14px;
  color: #ffffff;
}
.divOutMapA {
  width: 320px;
  height: 185px;
  background: url("http://218.56.180.213:8035/shopping/static/file/pic/202307/picrXBtW1uh1689581712300.png")
    no-repeat;
  background-size: 100% 100%;
  margin-top: -50px;
  margin-left: -145px;
}
.pointClassNum {
  color: #ffffff;
  font-size: 14px;
  line-height: 12px;
  width: 12px;
  text-align: center;
}
.mapFlexDivGis {
  display: flex;
  .flexLeftImg {
    width: 80px;
    height: 90px;
  }
  .flexRight {
    flex: 1;
    padding-left: 10px;
    .flexRightListOne {
      width: 100%;
      line-height: 20px;
      color: #333333;
      font-size: 13px;
      padding: 3px 10px;
    }
    .flexRightListTwo {
      background: rgba(41, 147, 207, 0.4);
      line-height: 20px;
      color: #ffffff;
      font-size: 13px;
      padding: 5px 10px;
      margin-top: 15px;
    }
  }
}
</style>
<script type="text/ecmascript-6">
export default {
    props:{
        mapId:{
            type:String,
            default:'mapId'
        },
        zoom:{
            type:Number,
            default:17
        },
        markerArr:{
            type:Array,
            default:()=>[
                // {
                //     imgurl: "http://218.56.180.213:8137/policeNewFormalFile/subFace/snapFace/202211/20221128/snapFace1ec55445-4abf-4a8d-a59d-17ada05b02b3-0.png",
                //     visitTime: "2022-11-28 17:03:21",
                //     longitude: 118.712444,
                //     uptownName: "中国广饶今田小商品批发市场西门",
                //     latitude: 37.43991,
                //     cameraName: "花苑路交叉口朝东500m人脸",
                //     type:'start'
                // },
                // {
                //     imgurl: "http://218.56.180.213:8137/policeNewFormalFile/subFace/snapFace/202211/20221128/snapFace1ec55445-4abf-4a8d-a59d-17ada05b02b3-0.png",
                //     visitTime: "2022-11-28 17:03:21",
                //     longitude: 118.713192,
                //     uptownName: "中国广饶今田小商品批发市场西门",
                //     latitude: 37.441471,
                //     cameraName: "花苑路交叉口朝东500m人脸",
                //     type:''
                // },
                // {
                //     imgurl: "http://218.56.180.213:8137/policeNewFormalFile/subFace/snapFace/202211/20221128/snapFace1ec55445-4abf-4a8d-a59d-17ada05b02b3-0.png",
                //     visitTime: "2022-11-28 17:03:21",
                //     longitude: 118.710435,
                //     uptownName: "中国广饶今田小商品批发市场西门",
                //     latitude: 37.441478,
                //     cameraName: "花苑路交叉口朝东500m人脸",
                //     type:''
                // },
                // {
                //     imgurl: "http://218.56.180.213:8137/policeNewFormalFile/subFace/snapFace/202211/20221128/snapFace1ec55445-4abf-4a8d-a59d-17ada05b02b3-0.png",
                //     visitTime: "2022-11-28 17:03:21",
                //     longitude: 118.710929,
                //     uptownName: "中国广饶今田小商品批发市场西门",
                //     latitude: 37.439616,
                //     cameraName: "花苑路交叉口朝东500m人脸",
                //     type:''
                // },
                // {
                //     imgurl: "http://218.56.180.213:8137/policeNewFormalFile/subFace/snapFace/202211/20221128/snapFace1ec55445-4abf-4a8d-a59d-17ada05b02b3-0.png",
                //     visitTime: "2022-11-28 17:03:21",
                //     longitude: 118.709608,
                //     uptownName: "中国广饶今田小商品批发市场西门",
                //     latitude:37.4404,
                //     cameraName: "花苑路交叉口朝东500m人脸",
                //     type:'end'
                // },
            ]
        },
        //经纬度
        currentLat:{
            type:Number,
            default:0
        },
        currentLon:{
            type:Number,
            default:0
        }
    },
    data(){
        return {
            mapLoading:false,
            bgHeight:'668px',
            map:'',
            getZoom:15,   //地图当前的等级
            peopleLocus:'',
            trackAni:null,
            iconPeople:require('../../assets/base/flow_people.png'),
            condition:true,
            suspedContinueShow:true,
            playGis:null,
        }
    },
    //关键
    created(){
        let that=this;
        window.bigImg=that.bigImg;
    },
    watch: {
        currentLat: {
            handler: function (val) {
                let that=this;
                if(that.currentLat!=''&&that.map==''){
                    that.initAMap();
                }
                //设置地图中心点
                that.map.setView([this.currentLon,this.currentLat], 15)
            },
            // immediate: true
        },
        markerArr: {
            handler: function(newObj, oldObj) {
                let that=this;
                that.$nextTick(() => {
                    that.peopleMap()
                })
            },
            deep: true, // 深度监听
            immediate: true // 会在监测开始时调用一次该处理函数
        }
    },
    methods:{
        initAMap(){
            //声明地图
            var that = this
            var cenPoint = [this.currentLat,this.currentLon]
            var map = L.map(this.mapId, {
                attributionControl:false,
                crs:L.CRS.EPSG4326,  //要使用的坐标系  WGS84 是目前最流行的地理坐标系统
                center:[cenPoint[1],cenPoint[0]],
                zoom: 15
            });
            map.setView([cenPoint[1],cenPoint[0]], 15) //设置中心点以及zoom
            L.tileLayer('这是URL', {   //内网瓦片地址
                minZoom:0,
                maxZoom:19,
                zoomOffset:0,
                tms:false
            }).addTo(map);
            this.map = map
        },
        //清楚轨迹划线
        clearMap() {
            const that = this; // 保存Vue组件的上下文
            if (that.map) {
                that.map.eachLayer(function (layer) {
                    if (layer instanceof L.Marker || layer instanceof L.Polyline) {
                        that.map.removeLayer(layer);
                    }
                });
            }
        },
        peopleMap(id){
            var that = this
            this.clearMap();
            this.peopleLocus = this.map
            //图标大小
            var LeafIcon = L.Icon.extend({
                options: {
                    iconSize: [36, 47],
                }
            });
            var data_info = this.markerArr,content,newPoint,mapUrl,shopName,num;
            for(var i = 0;i<data_info.length;i++){
                if(data_info[i].type=='start'){
                    mapUrl=require('../../assets/base/start.png');
                }
                else if(data_info[i].type=='end'){
                    mapUrl=require('../../assets/base/end.png');
                }
                else{
                    mapUrl=require('../../assets/base/ing.png');
                }
                content = "<div class='mapFlexDivGis'>"+
                        "<img class='flexLeftImg' src='"+ that.$global.imgPross(data_info[i].photo) +"' width='100%'/>"+
                            "<div class='flexRight'>"+
                                "<p class='flexRightListOne'>时间:"+data_info[i].snapTime +"</p>"+
                                "<p class='flexRightListOne'>设备名称:"+data_info[i].deviceName+"</p>"+
                            "</div>"+
                        "</div>"
                var icon = new LeafIcon({iconUrl: mapUrl});
                L.icon = function (options) {
                    return new L.Icon(options);
                };
                newPoint = [data_info[i].longitude, data_info[i].latitude]
                num = i+1
                L.marker([newPoint[1],newPoint[0]],{icon: icon}).addTo(that.map)
                    .bindPopup(content);   //添加点以及点的点击事件

                // 写在初始化地图的方法里,必须放在mounted钩子中
                var customLabel = L.divIcon({
                    html: '<div class="my-label">'+num+'</div>',
                    className: 'pointClassNum'
                });
                // 添加自定义文本标注到地图上
                var labelMarker = L.marker([newPoint[1],newPoint[0]], {
                    icon: customLabel,
                    zIndexOffset: 0 // 防止标签与图标相互遮挡
                }).addTo(this.map);
            }
            //绘制线
            var points = new Array();
            for (var i = 0; i < data_info.length; i++) {
                var p0 = data_info[i].longitude;
                var p1 = data_info[i].latitude;
                var newPoint = [p0, p1]
                var thePoint1 = [newPoint[1],newPoint[0]]
                points.push(thePoint1);
            }
            var polyline = L.polyline(points, {
                color: 'RGBA(255, 0, 0, 0.7)',//线的颜色
                weight: 3 //线的粗细
            }).addTo(this.map);
      },

        // 回放按钮
        plackBack(){
            let that=this;
            that.suspedContinueShow = true;
            that.backShow = true;
            let mapData=that.markerArr,newArr = [];
            var newArrTime = []
            for(var i = 0;i<mapData.length;i++){
                var newPoint = [mapData[i].longitude, mapData[i].latitude]
                let item = [newPoint[1],newPoint[0]]
                newArr.push(item)
                newArrTime.push(5000)
            }
            that.map.fitBounds(newArr);


            var LeafIcon = L.Icon.extend({
                options: {
                    iconSize: [31, 36],
                }
            });
            var mapUrl = this.iconPeople

            var icon = new LeafIcon({iconUrl: mapUrl});
            L.icon = function (options) {
                return new L.Icon(options);
            };

            var marker1 = L.Marker.movingMarker(newArr, newArrTime,{icon: icon}).addTo(that.map);

            L.polyline(newArr,{color:'RGBA(255, 0, 0, 0.7)'}).addTo(that.map);
            marker1.once('click', function () {
                marker1.start();
                marker1.closePopup();
                marker1.unbindPopup();
                marker1.on('click', function() {
                    if (marker1.isRunning()) {
                        marker1.pause();
                    } else {
                        marker1.start();
                    }
                });
                setTimeout(function() {
                    marker1.bindPopup('<b>点我暂停!</b>').openPopup();
                }, 1000);
            });

            marker1.bindPopup('<b>点我播放 !</b>', {closeOnClick: true});
            marker1.openPopup();
            that.playGis = marker1

        },
        //返回  清空播放轨迹的图层
        continueMap(){
            this.suspedContinueShow = !this.suspedContinueShow
            this.map.removeLayer(this.playGis)
        },
    },
    //调用方法
    mounted() {

    }
}
</script>
复制代码

 

posted @   星宝攸宁  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示