746 字
4 分钟
地图工具类:多边形
import { Vector as SourceVector } from 'ol/source';
import { Feature } from 'ol';
import { Style, Stroke, Fill, Text } from 'ol/style';
import { Vector as LayerVector } from 'ol/layer';
import { Polygon,GeometryCollection } from 'ol/geom';

export default class OlMapGrid {
  constructor(mapObj) {
    this.mapObj = mapObj;
    this.idOfGrid = {};
    this.colors = [
      {strokeColor: '#007CEE',fillColor: '#007CED1A',fillOpacity: 1,titleFillColor: '#4A91E8'},
      {strokeColor: '#0DA25A',fillColor: '#0DA25A1A',fillOpacity: 1,titleFillColor: '#0DA25A'},
      {strokeColor: '#F1A31B',fillColor: '#F1A31B1A',fillOpacity: 1,titleFillColor: '#F1A31B'},
      {strokeColor: '#ff41df',fillColor: '#ff41df1A',fillOpacity: 1,titleFillColor: '#ff41df'},
    ];
    this.selectRowId = '';
    this.prevSelectLayer = []; // 上个选中图层
  }
  /**
     * 显示网格
     * @param {*} pointsArr             [ [[经度, 纬度], [经度, 纬度]] ], 即:[网格分区1,网格分区2]
     * @param {*} id                  折线id 用于清除面
     * @param {*} isShowTitle         是否显示标题
     * @param {*} title               标题
     * @param {*} strokeColor         颜色
     * @param {*} strokeWidth         折线宽度
     * @param {*} fillColor           面填充色
     * @param {*} fillOpacity         面填充色的透明度
     * @param {*} titleFillColor      标题背景填充色
     * @param {*} zIndex              图层显示级别
     * @param {*} isSole : 是否唯一 默认false
     * @param {*} isAutoColor : 是否自动处理配色,如是则相关颜色优先级高于传参 默认false
     */
  showGrid({
    pointsArr,
    id = new Date().getTime(),
    isShowTitle = false,
    title = '',
    strokeColor,
    strokeWidth,
    fillColor,
    fillOpacity = 0.6,
    titleFillColor,
    zIndex = 100,
    isSole = false,
    isAutoColor = false,
  } = {}) {
    if (!this.mapObj) return;

    if (isSole) {
      this.clearGridById(id);
    }

    // 没有点位信息, 不做处理
    if (!pointsArr.length) return;
    
    // 创建多个特征
    const features = pointsArr.map((points, index) => {
      const coordinates = points.map((item)=>{
        // 是数组:将经纬度转为Number类型(否则标题不能正常显示)
        if(Array.isArray(item)) {
          return [+item[0], +item[1]];
        }
        // 是对象
        const longitude = item.longitude || item.long;
        const latitude = item.latitude || item.latitude;
        return [+longitude, +latitude];
      });

      return new Feature({
        name: `grid-${id}-${index}`,
        _gridId: id,
        _index: index,
        geometry: new Polygon([coordinates])
      });
    });
    // 创建一个 source图层, 把features添加到source里
    const source = new SourceVector();
    source.addFeatures(features);

    // 处理默认颜色
    if(isAutoColor) {
      const colorConfig = this.getGridColor();
      strokeColor = colorConfig.strokeColor;
      fillColor = colorConfig.fillColor;
      fillOpacity = colorConfig.fillOpacity;
      titleFillColor = colorConfig.titleFillColor;
    }
    const gridLayer = new LayerVector({
      className: 'map-grid',
      source: source,
      zIndex: zIndex,
      style: this.getGirdStyle({strokeColor,strokeWidth,fillColor,titleFillColor,isShowTitle,title}),
      opacity: fillOpacity
    });
    gridLayer.set('_colorConfig',{
      strokeColor,
      strokeWidth,
      fillColor,
      titleFillColor
    });
    gridLayer.set('_titleConfig',{
      isShowTitle,
      title,
    });
    this.idOfGrid[id] = {
      layer: gridLayer,
      features: features
    };
    this.mapObj.addLayer(gridLayer);
  }
  /**
     * 根据id修改多边形颜色
     * @param {*} id
     * @param {*} color
     * @returns
     */
  updateGridColorById(id, color, strokeColor) {
    if (!this.idOfGrid[id]) return;

    let { layer } = this.idOfGrid[id];
    layer.getStyle().setFill(
      new Fill({
        color
      })
    );
    layer.getStyle().setStroke(
      new Stroke({
        color: strokeColor,
        width: 2
      })
    );
    layer.changed();
  }
  /* 网格-根据id清除 */ 
  clearGridById(id) {
    if (!this.idOfGrid[id]) return;

    let { layer } = this.idOfGrid[id];
    layer.getSource().clear();
    this.mapObj.removeLayer(layer);
    layer = null;
    delete this.idOfGrid[id];
  }
  /* 网格-清除所有 */ 
  clearAllGrid() {
    Object.keys(this.idOfGrid).forEach((key) => {
      this.clearGridById(key);
    });

    this.idOfGrid = {};
  }
  /* 网格-获取配色信息 */ 
  getGridColor() {
    const currentGridLength = Object.keys(this.idOfGrid).length;
    const nextColorIndex = currentGridLength % (this.colors.length);
    return this.colors[nextColorIndex];
  }
  /* 网格-获取区域中心点 */ 
  getGridCenter(id) {
    let { features } = this.idOfGrid[id] || {};
    if(!features) return null;

    const geometryCollection = new GeometryCollection(features.map((feature)=>feature.getGeometry()));
    const center = geometryCollection.getClosestPoint(geometryCollection.getExtent());
    return center;
  }

  /** hover左边菜单 */
  onEnterLayer(rowId) {
    const {layer} = this.idOfGrid[rowId] || {};
    if(!layer)return;

    const titleInfo = layer.get('_titleConfig');
    layer.setStyle(this.getGirdStyle(titleInfo));
  }

  /** 离开左边菜单 */
  onLeaveLayer(rowId) {
    const {layer} = this.idOfGrid[rowId] || {};
    if(!layer)return;
    
    const titleInfo = layer.get('_titleConfig');
    const colorInfo = layer.get('_colorConfig');
    layer.setStyle(this.getGirdStyle({...colorInfo,...titleInfo}));
  }

  /** 获取网格样式配置 */
  getGirdStyle({strokeColor = '#ff0000',strokeWidth = 2,fillColor = '#ff00005C',titleFillColor = '#ff0000',isShowTitle,title}) {
    return new Style({
      // 多边形边框
      stroke: new Stroke({
        color: strokeColor,
        width: strokeWidth
      }),
      // 多边形填充样式
      fill: new Fill({
        color: fillColor
      }),
      // 文本样式
      text: isShowTitle
        ? new Text({
          text: title,
          fill: new Fill({
            color: '#fff'
          }),
          font: '14px Microsoft YaHei',
          offsetX: 0,
          offsetY: 0,
          padding: [4, 12, 4, 12],
          backgroundFill: new Fill({
            color: titleFillColor
          })
        })
        : null
    });
  }
};
地图工具类:多边形
https://ping5-1.github.io/posts/vue/map/grid/
作者
YiPing5
发布于
2024-04-30
许可协议
CC BY-NC-SA 4.0