美文网首页
Openlayers 添加 单点marks 和 聚合Marks,

Openlayers 添加 单点marks 和 聚合Marks,

作者: 冰落寞成 | 来源:发表于2023-01-08 14:19 被阅读0次

    组件引入openlayer

    import * as ol from '../openLayer'
    

    openLayer.js 内容如下:

      
    export { Map, View, Feature } from 'ol'
    export { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
    export { Select } from 'ol/interaction'
    export { Point } from 'ol/geom'
    
    export { XYZ, Vector as VectorSource, ImageStatic, ImageWMS, Cluster } from 'ol/source'
    export {
      Icon, Style, Circle as CircleStyle,
      Fill,
      Stroke,
      Text
    } from 'ol/style'
    

    使用Cluster 添加坐标点

     /**
       * 添加坐标点
       */
      addMarks () {
        let features = []
        for (let point of this.points) {
          // 点的坐标信息
          let coordinates = [point.lng, point.lat]
          let feature = new ol.Feature({
            geometry: new ol.Point(coordinates),
            name: point.name,
            id: point.id,
            properties: point
          })
          features.push(feature)
        }
        // 创建聚合对象并设置数据源和距离
        const source = new ol.VectorSource({
          features: features
        })
        let clusterSource = new ol.Cluster({
          distance: parseInt(10, 10),
          source: source
        })
        let clusters = new ol.VectorLayer({
          source: clusterSource,
          style: (feature) => this.setSelectStyle(feature)
        })
        this.map.addLayer(clusters)
        this.attachActionListener(clusters)
      }
    

    使用Select 添加 hover(pointerMove ) 和click(click)事件

    Select 配置项condition 可以设置事件类型

     /**
       * 添加监听,
      * actions为配置项
       */
      attachActionListener () { 
        if (this.actions.length > 0) {
          for (let action of this.actions) { //  绑定事件
            let condition = action.type === 'hover' ? pointerMove : click // 默认有点击事件
            let marksEvents = new ol.Select({
              condition: condition,
              hitTolerance: action.hitTolerance || 5, // 命中容差默认是5
              style: (feature) => this.setSelectStyle(feature)
    
            })
            this.map.addInteraction(marksEvents)
            marksEvents.on('select', (e) => {
              let selectedfeature = e.selected
              if (selectedfeature.length > 0) {
                let featuresArr = selectedfeature[0].get('features')
                let pointsList = []
                for (let feature of featuresArr) {
                  pointsList.push(feature.get('properties'))
                }
                // console.log('pointsList=', pointsList)
                if (pointsList.length > 0) {
                  action.handle(pointsList)
                }
              }
            })
          }
        }
      }
    

    设置marks 样式

      /**
       * 设置marks 样式
       * @param {*} feature
       * @returns
       */
      setSelectStyle (feature, type = 'unaction') {
        const size = feature.get('features').length
        let styleObj = type === 'action' ? this.markSelectStyle : this.markStyle // 默认未选中
        let style = this.styleCache[size]
        if (size > 1) {
          if (!style) {
            let customStyle = styleObj.filter(item => item.type === 'clusterMark')[0] || { pointType: 'CircleStyle', style: {} }
            customStyle.style.text = size.toString()
            style = createMarksStyle(customStyle, 'clusterMark')
            this.styleCache[size] = style
          }
          return style
        } else {
          let status = feature.get('features')[0].get('properties').status
          let legendArr = styleObj.filter(item => item.legend === status) //  使用图例
          let customStyle
          if (legendArr.length > 0) { // 有图例
            customStyle = legendArr[0]
          } else { // 无图例,找type类型为singleMark 点配置
            customStyle = styleObj.filter(item => item.type === 'singleMark')[0] || { pointType: 'CircleStyle', style: {} }
          }
          let markerStyle = createMarksStyle(customStyle)
          this.styleCache[size] = markerStyle
          return markerStyle
        }
      }
    
    

    marks 类封装

    
    import * as ol from '../openLayer'
    import { createMarksStyle } from './style'
    import { click, pointerMove } from 'ol/events/condition.js'
    export default class OlMarks {
      constructor (_map, _config) {
        this.map = _map
        this.points = _config.points
        this.markStyle = _config.style
        this.markSelectStyle = _config.selectStyle
        this.actions = _config.action || []
        this.clusters = null
        this.addMarks()
      }
    
      /**
       * 添加坐标点
       */
      addMarks () {
        let features = []
        for (let point of this.points) {
          // 点的坐标信息
          let coordinates = [point.lng, point.lat]
          let feature = new ol.Feature({
            geometry: new ol.Point(coordinates),
            name: point.name,
            id: point.id,
            properties: point
          })
          features.push(feature)
        }
        // 创建聚合对象并设置数据源和距离
        const source = new ol.VectorSource({
          features: features
        })
        let clusterSource = new ol.Cluster({
          distance: parseInt(10, 10),
          source: source
        })
        let clusters = new ol.VectorLayer({
          source: clusterSource,
          style: (feature) => this.setSelectStyle(feature)
        })
        this.map.addLayer(clusters)
        this.attachActionListener(clusters)
      }
    
      /**
       * 添加监听
       */
      attachActionListener () {
        if (this.actions.length > 0) {
          for (let action of this.actions) { //  绑定事件
            let condition = action.type === 'hover' ? pointerMove : click // 默认有点击事件
            let marksEvents = new ol.Select({
              condition: condition,
              hitTolerance: action.hitTolerance || 5, // 命中容差默认是5
              style: (feature) => this.setSelectStyle(feature)
    
            })
            this.map.addInteraction(marksEvents)
            marksEvents.on('select', (e) => {
              let selectedfeature = e.selected
              if (selectedfeature.length > 0) {
                let featuresArr = selectedfeature[0].get('features')
                let pointsList = []
                for (let feature of featuresArr) {
                  pointsList.push(feature.get('properties'))
                }
                // console.log('pointsList=', pointsList)
                if (pointsList.length > 0) {
                  action.handle(pointsList)
                }
              }
            })
          }
        }
      }
    
      /**
       * 设置marks 样式
       * @param {*} feature
       * @returns
       */
      setSelectStyle (feature, type = 'unaction') {
        const size = feature.get('features').length
        let styleObj = type === 'action' ? this.markSelectStyle : this.markStyle // 默认未选中
        let styleCache = {}
        let style = styleCache[size]
        if (size > 1) {
          if (!style) {
            let customStyle = styleObj.filter(item => item.type === 'clusterMark')[0] || { pointType: 'CircleStyle', style: {} }
            customStyle.style.text = size.toString()
            style = createMarksStyle(customStyle, 'clusterMark')
            styleCache[size] = style
          }
          return style
        } else {
          let status = feature.get('features')[0].get('properties').status
          let legendArr = styleObj.filter(item => item.legend === status) //  使用图例
          let customStyle
          if (legendArr.length > 0) { // 有图例
            customStyle = legendArr[0]
          } else { // 无图例,找type类型为singleMark 点配置
            customStyle = styleObj.filter(item => item.type === 'singleMark')[0] || { pointType: 'CircleStyle', style: {} }
          }
          let markerStyle = createMarksStyle(customStyle)
          styleCache[size] = markerStyle
          return markerStyle
        }
      }
    }
    
    

    marks 样式封装

    import * as ol from '../openLayer'
    import { markStypeDefaultConfig } from '../../config'
    /**
     * mark 样式
     * @param {*} config
     * @param {*} type
     * @returns
     */
    export function createMarksStyle (config = { pointType: 'CircleStyle', style: {} }, type = 'singleMark') {
      let style = {}
      if (type === 'singleMark') { //  单点
        Object.assign(style, markStypeDefaultConfig.singleMark.markConfig, config.style)
      } else if (type === 'clusterMark') { //  聚合
        Object.assign(style, markStypeDefaultConfig.clusterMark.markConfig, config.style)
      }
      if (config.pointType === 'CircleStyle') { // 圆点
        return markCircleStyle(style, type)
      } else if (config.pointType === 'image') { // 使用图片
        return markImageStyle(style)
      }
    }
    
    /**
     * 圆点
     * @param {*} config
     * @returns
     */
    export function markCircleStyle (config, type = 'singleMark') {
      if (type === 'singleMark') {
        return new ol.Style({
          image: new ol.CircleStyle({
            radius: config.radius,
            fill: new ol.Fill({ color: config.fillColor }),
            stroke: new ol.Stroke({ color: config.strokeColor, width: config.strokeWidth }),
            size: [config.size, config.size]
          })
    
        })
      } else if (type === 'clusterMark') {
        // 内圆
        const innerCircle = new ol.CircleStyle({
          radius: config.innerRadius,
          fill: new ol.Fill({
            color: config.innerFillColor
          })
        })
        // 外圆
        const outerCircle = new ol.CircleStyle({
          radius: config.outerRadius,
          fill: new ol.Fill({
            color: config.outerFillColor
          })
        })
        return [
          new ol.Style({
            image: outerCircle
          }),
          new ol.Style({
            image: innerCircle,
            text: new ol.Text({
              text: config.text,
              scale: config.textScale,
              fill: new ol.Fill({
                color: config.textFillColor
              }),
              stroke: new ol.Stroke({
                color: config.textStrokeColor,
                width: config.textStrokeStrokeWidth
              })
            })
          })
        ]
      }
    }
    /**
     * 图片
     * @param {*} config
     * @returns
     */
    export function markImageStyle (config) {
      return new ol.Style({
        image: new ol.Icon({
          src: config.url,
          scale: config.scale
        })
      })
    }
    
    

    marks 类使用

    new OlMarks(map, config)
    

    相关文章

      网友评论

          本文标题:Openlayers 添加 单点marks 和 聚合Marks,

          本文链接:https://www.haomeiwen.com/subject/dqjucdtx.html