OpenLayers实现比例尺控件(ScaleLine)的比例尺长度保持不变,只自适应改变比例尺对应的实际长度

对于OpenLayers组件,默认的比例尺控件通常是线段比例尺,样式如下:
比例尺的长度和对应的实际长度都是自适应变化的
在这里插入图片描述
在这里插入图片描述
现在根据业务需求,比例尺的宽度需要保持不变,只变化比例尺对应的实际长度,效果如下:
在这里插入图片描述
在这里插入图片描述

对于原本的ScaleLine控件好像没有控制这种样式的属性(可能我不知道),所以我就重写了源码中的ScaleLine.js文件,全部代码在文章末尾。使用方式如下:

// 引入自定义的比例尺控件 我这里放在src下的utils目录下
import CustomScaleLine from "/src/utils/CustomScaleLine";

// 按照官方的使用方式正常添加地图控件,将 ScaleLine 替换为 CustomScaleLine 
 state.map = new ol.Map({
   
    target: 'mapContainer',
    layers: offlineMapLayer,
    view: new ol.View({
   
      projection: "EPSG:4326",
      center: [1xx.xx, 3x.x],
      zoom: 5,
    })
  });
  // 添加比例尺控件
  const scaleLineControl = new CustomScaleLine({
   
      fixedWidthPx: 100, // 可以不用设置,默认 100
      units: 'metric', // 比例尺默认的单位 自定义的比例尺,当前仅支持单位 米
  });
  state.map.addControl(scaleLineControl)

主要修改代码如下:

在构造方法中增加一个属性值fixedWidthPx_ 方便使用时控制比例尺显示长度

  constructor(options) {
   
    options = options ? options : {
   };

    const element = document.createElement('div');
    element.style.pointerEvents = 'none';

    super({
   
      element: element,
      render: options.render,
      target: options.target,
    });

    /**
     * @private 比例尺宽度 默认100px 
     * @type {number}
     */
    this.fixedWidthPx_ = options.fixedWidthPx || 100; // 默认值为100像素

    // 下面源代码不变

    /***
     * @type {ScaleLineOnSignature<import("../events").EventsKey>}
     */
    this.on;
    ...
  }

修改主要实现方法updateElement_

  /**
   * 自定义的更新方法,图上比例尺长度固定,显示的实际长度根据地图缩放比例来计算
   */
  updateElement_() {
   
    const viewState = this.viewState_;

    if (!viewState) {
   
      if (this.renderedVisible_) {
   
        this.element.style.display = 'none';
        this.renderedVisible_ = false;
      }
      return;
    }


    // 假设我们设置了一个固定的宽度值
    const fixedWidthPx = this.fixedWidthPx_; // 用你期望的固定宽度替换这个值

    const center = viewState.center;
    const projection = viewState.projection;
    const units = this.getUnits();
    const pointResolutionUnits = units == 'degrees' ? 'degrees' : 'm';
    let pointResolution = getPointResolution(
        projection,
        viewState.resolution,
        center,
        pointResolutionUnits
    );

    // 不再使用 minWidth 和 maxWidth 计算宽度
    let count, suffix, showCount;
    if (units === 'metric') {
   
      // 直接根据固定宽度计算比例尺数
      count = Math.round(fixedWidthPx * pointResolution);
      if (count < 0.001) {
   
        suffix = 'μm';
        showCount = count*1000000;
      } else if (count < 1) {
   
        suffix = 'mm';
        showCount = count*1000;
      } else if (count < 1000) {
   
        suffix = 'm';
        showCount = count;
      } else {
   
        suffix = 'km'
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值