OpenLayers 点位撒点

OpenLayers 百万点位撒点


提示:下面案例可供参考

一、解决方案

设置网格,把地图切分成不同网格,在zoon 视图放大到一定程度,进行视图大小获取点位撒点

二、使用步骤

1.引入库

代码如下(示例):

import 'ol/ol.css'
import { Map, View } from 'ol'
import Tile from 'ol/layer/Tile'
// import OSM from "ol/source/OSM";
import { Style, Circle, Stroke, Fill, Text, Icon } from 'ol/style'
import layerVector from 'ol/layer/Vector'
import sourceVector from 'ol/source/Vector'
import Cluster from 'ol/source/Cluster'
import XYZ from 'ol/source/XYZ'
import { get as getProjection } from 'ol/proj'
import { getWidth } from 'ol/extent'
import Point from 'ol/geom/Point'
import Feature from 'ol/Feature'
import { defaults } from 'ol/interaction'
import Overlay from 'ol/Overlay'
import { getbmapData, getsmapData, getpointData } from '@/api/api.js'

2.html代码

代码如下(示例):

<template>
  <div class="vm">
    <div id="map" class="map-x"></div>
    </div>
  </div>
</template>

3.js代码

代码如下(示例):


  data() {
    return {
      map: null,
      popup: null,
      isPopup: false,
      clusterSource: null,
      points: [],
      clusterData: [],
      list:[],
      mixzoom: true,
      maxzoom: true,
      zoomfont: true,
      ismovezoom: 0,
      ismovezoomend: 0,
      systemId: '',
      openhx: true,
      fullAddr: '',
      dycxsxmc: '',
      orgName: '',
      qu: '',
    }
  },

  mounted() {
    // 初始化 地图
    this.initMap()
    // this.addFeatures()
    this.getbmapData()
    // 初始化 新增聚合点
    this.addCluster(this.clusterData, this.points)
  },

  methods: {
    //节流
    debounce (func, delay = 1000, immediate = false) {
      //闭包
      let timer = null
      //不能用箭头函数
      return function () {
        if (timer) {
          clearTimeout(timer)
        }
        if (immediate && !timer) {
          func.apply(this,arguments)
        }
        timer = setTimeout(() => {
          func.apply(this,arguments)
        }, delay)
      }
    },
    openhxbox() {
     
      this.$emit('openhxfun', { systemId: this.systemId, openhx: this.openhx, fullAddr: this.fullAddr })
   
    },
    // 不同值,返回不同颜色
    getColor(val) {
    
      if (val < 10) return 'mix'
      else if (val >= 10 && val < 200) return 'mid'
      else if (val >= 200) return 'max'
    },
    initMap() {
      var projection = getProjection('EPSG:4326')
      var projectionExtent = projection.getExtent()
      var size = getWidth(projectionExtent) / 256
      var resolutions = []
      var matrixIds = []

      for (var z = 0; z < 21; ++z) {
        resolutions[z] = size / Math.pow(2, z)
        matrixIds[z] = z
      }
      // 地图地址
      var dzdt_xyz_Url =  window._CONFIG['bigMapURL']  // 在 index.html 文件中设置

      //电子地图图层XYZ方式
      var dzdtXYZlayer = new Tile({
        source: new XYZ({
          url: dzdt_xyz_Url,
          //crossOrigin: 'anonymous',
          projection: 'EPSG:4326',
        }),
        visible: true,
      })

      this.map = new Map({
        target: 'map',
        layers: [dzdtXYZlayer],
        view: new View({
          // center: [0, 0],
          center: [120.440239, 36.103322], // 中心点位置 全国地市
          projection: projection,
          zoom: 10, // 显示的缩放大小
          maxZoom: 20, // 最大缩放
          minZoom: 6, // 最小缩放
        }),
        interactions: defaults({
          doubleClickZoom: false, // 取消双击放大功能交互
        }),
      })
      // 监听放大缩小
      this.map.getView().on('change:resolution', this.checkZoom)

      this.map.getView().on('change:center', this.checkcenter)
      // 点击地图展示弹窗
      this.popup = new Overlay({
        element: document.getElementById('popup'),
        positioning: 'center-left', //相对于其位置属性的实际位置
        stopEvent: true, //事件冒泡
      })
      // this.map.addOverlay(this.popup) // 新增元素
      this.map.on('singleclick', (evt) => {
        // 增加点击事件
        // this.clickMap(evt)
      })
    },

    clusterlouStyle() {
      return (feature) => {
        var total = 0
        feature.get('features').forEach((value) => {
          total += value.get('value') // 获取显示的值 用来聚合
        })
        var src = ''
        var offsetY = 0

        var style = new Style({
          image: new Icon({
            anchor: [0.5, 46],
            anchorOrigin: 'top-lefttop-right',
            anchorXUnits: 'fraction',
            anchorYUnits: 'pixels',
            src: `${window.location.origin}/lou.png`,
          }),
        })

        return style
      }
    },
    //设置聚合样式
    clusterStyle() {
      return (feature) => {
        var total = 0
        feature.get('features').forEach((value) => {
          total += value.get('value') // 获取显示的值 用来聚合
        })
        var src = ''
        var offsetY = 0
        if (total < 2) {
          src = `${window.location.origin}/mix.png`
          offsetY = 23
        } else if (total >= 2 && total < 3) {
          src = `${window.location.origin}/mid.png`
          offsetY = 48
        } else if (total >= 3) {
          src = `${window.location.origin}/max.png`
          offsetY = 53
        }
        var style = new Style({
          image: new Icon({
            anchor: [0.5, 46],
            anchorOrigin: 'top-lefttop-right',
            anchorXUnits: 'fraction',
            anchorYUnits: 'pixels',
            src: src,
          }),
          text: new Text({
            text: total.toString(), // 中心点显示的内容
            offsetY: offsetY,
            fill: new Fill({
              // 文字内的颜色
              color: '#FFF',
            }),
            textAlign: 'center',
            font: '32px Calibri,sans-serif',
            stroke: new Stroke({
              // 文字得到边框的颜色
              color: 'red',
              width: 5,
            }),
          }),
        })
        return style
      }
    },
    //移除聚合标注
    removeFeatures() {
      this.clusterSource.getSource().clear() //移除聚合标注数据源中的所有要素
      this.map.removeLayer(this.layer) //移除标注图层
    },
    //添加聚合标注
    addFeatures() {
      // console.log(this.clusterSource)
      var currentFeatures = this.clusterSource.getSource().getFeatures()
      // //如果聚合标注数据源中没有要素,则重新添加要素
      if (currentFeatures.length == 0) {
        this.addCluster(this.clusterData, this.points)
      }
      // } else {
      //   alert("要素已经存在");

      // }
    },
    addCluster(clusterData, points) {
      let source = new sourceVector()
      this.clusterSource = new Cluster({
        distance: parseInt(20, 10),
        source: source,
      })
      this.layer = new layerVector({
        source: this.clusterSource,
        style: this.clusterStyle.call(this),
      })
      this.map.addLayer(this.layer)
      let count = clusterData.length // 点的数量
      let features = clusterData //存放点要素的数组
      // 初始化每个点的坐标位置
      for (let i = 0; i < count; ++i) {
        let pit = [features[i].lng, features[i].lat]
        let mm = new Feature({
          geometry: new Point(pit),
        })
        mm.set('name', features[i].orgName) // 给点位增加参数 name  名称
        mm.set('value', 1) // 给点位增加参数 value  值
        mm.set('lat', features[i].lat) // 给点位增加参数 lan  坐标
        mm.set('lon', features[i].lng) // 给点位增加经度参数 lot  坐标
        features[i] = mm
      }
      console.log(features)
      // 把点都添加到 地图中去
      source.addFeatures(features)
    },
    checkcenter(e) {
      // 监听返回的视图大小
      // var max = true;
      let zoom = Math.round(this.map.getView().getZoom() * 10000) / 10000
      // console.log(e, this.map.getView().calculateExtent(this.map.getSize())); // 视图大小
      this.points = this.map.getView().calculateExtent(this.map.getSize())
      // console.log(this.points);
      if (zoom > 14 && this.maxzoom) {
        if (this.ismovezoomend === zoom) {
          this.removeFeatures()
          this.getsmapData()
        }
        this.zoomfont = false
        setTimeout(() => {
          this.maxzoom = true
        }, 1000)
      }
    },
    getsmapData() {
      let data = {
        // mplx: '1',
        trlng: this.points[2],
        trlat: this.points[3],
        bllng: this.points[0],
        bllat: this.points[1],
      }
      this.maxzoom = false
      getsmapData(data).then((res) => {
        if (res.success) {
          this.map.removeLayer(this.layer)
          let clusterData = res.result //存放点要素的数组
          // 新增聚合点
          let source = new sourceVector()
          this.clusterSource = new Cluster({
            distance: parseInt(20, 10),
            source: source,
          })
          this.layer = new layerVector({
            source: this.clusterSource,
            style: this.clusterlouStyle.call(this),
          })

          this.map.addLayer(this.layer)
          let count = clusterData.length // 点的数量
          let features = clusterData //存放点要素的数组
          // // 初始化每个点的坐标位置
          for (let i = 0; i < count; ++i) {
            let pit = [features[i].mapy, features[i].mapx]
            let mm = new Feature({
              geometry: new Point(pit),
            })
            // 	mm.set('name', features[i].orgName); // 给点位增加参数 name  名称
            mm.set('value', 1) // 给点位增加参数 value  值
            mm.set('systemId', features[i].systemId) // 给点位增systemId
            mm.set('lat', features[i].mapx) // 给点位增加纬度参数 lat   坐标
            mm.set('lon', features[i].mapy) // 给点位增加经度参数 lon 120  坐标
            features[i] = mm
          }
          // console.log(features);
          // // 把点都添加到 地图中去
          source.addFeatures(features)
        }
      })
    },

    getbmapData() {
      console.log("getbmapData()")
      getbmapData().then((res) => {
        if (res.success) {
          sessionStorage.setItem('getbmapData',JSON.stringify(res.result[2].list));
          this.list = res.result[2].list
          this.clusterData = res.result[2].list //存放点要素的数组
          this.addCluster(res.result[2].list)
        }
      })
    },
    checkZoom(e) {
      if (this.isPopup) {
        this.isPopup = false
        this.popup.setPosition(undefined)
      }
      // 监听返回的当前地图的缩放,取值为 正整数
      let zoom = Math.round(this.map.getView().getZoom() * 10000) / 10000
      if ((zoom < 14 && !this.zoomfont) || (zoom <= 14 && !this.zoomfont)) {
        // 移除 聚合点
        this.removeFeatures()
        this.getbmapData()
        this.zoomfont = true
      }
      if (zoom > 14) {
        this.ismovezoomend = this.ismovezoom
        this.ismovezoom = zoom
        // console.log(this.ismovezoomend);
        // console.log(this.ismovezoom);
        // // 监听移动
        // this.map.getView().on('moveend', function(ent){
        // 	console.log(ent);
        // 	this.ismove = !this.ismove;
        // });
      }
    },
  },

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值