当前位置: 首页 > article >正文

源码分析之Openlayers中MousePosition鼠标位置控件

概述

本文主要介绍 Openlayers 中的MousePosition鼠标位置控件,该控件会创建一个元素在页面的右上方用来实时显示鼠标光标的位置坐标。该控件在实际应用很有效,可以实时获取鼠标位置,但是一般控件元素都会自定义。

源码分析

MousePosition类是继承于Control类,关于Control类,可以参考这篇文章源码分析之Openlayers中的控件篇Control基类介绍。

MousePosition类实现如下:

class MousePosition extends Control {
  constructor(options) {
    options = options ? options : {};
    const element = document.createElement("div");
    element.className =
      options.className !== undefined ? options.className : "ol-mouse-position";

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

    this.on;
    this.once;
    this.un;

    this.addChangeListener(PROJECTION, this.handleProjectionChanged_);

    if (options.coordinateFormat) {
      this.setCoordinateFormat(options.coordinateFormat);
    }
    if (options.projection) {
      this.setProjection(options.projection);
    }
    this.renderOnMouseOut_ = options.placeholder !== undefined;
    this.placeholder_ = this.renderOnMouseOut_ ? options.placeholder : " ";
    this.renderedHTML_ = element.innerHTML;
    this.mapProjection_ = null;
    this.transform_ = null;
    this.wrapX_ = options.wrapX === false ? false : true;
  }

  handleProjectionChanged_() {
    this.transform_ = null;
  }

  getCoordinateFormat() {
    return this.get(COORDINATE_FORMAT);
  }
  handleMouseOut(event) {
    this.updateHTML_(null);
  }

  getProjection() {
    return this.get(PROJECTION);
  }

  handleMouseMove(event) {
    const map = this.getMap();
    this.updateHTML_(map.getEventPixel(event));
  }

  setMap(map) {
    super.setMap(map);
    if (map) {
      const viewport = map.getViewport();
      this.listenerKeys.push(
        listen(viewport, EventType.POINTERMOVE, this.handleMouseMove, this)
      );
      if (this.renderOnMouseOut_) {
        this.listenerKeys.push(
          listen(viewport, EventType.POINTEROUT, this.handleMouseOut, this)
        );
      }
      this.updateHTML_(null);
    }
  }

  setCoordinateFormat(format) {
    this.set(COORDINATE_FORMAT, format);
  }

  setProjection(projection) {
    this.set(PROJECTION, getProjection(projection));
  }

  updateHTML_(pixel) {
    let html = this.placeholder_;
    if (pixel && this.mapProjection_) {
      if (!this.transform_) {
        const projection = this.getProjection();
        if (projection) {
          this.transform_ = getTransformFromProjections(
            this.mapProjection_,
            projection
          );
        } else {
          this.transform_ = identityTransform;
        }
      }
      const map = this.getMap();
      const coordinate = map.getCoordinateFromPixelInternal(pixel);
      if (coordinate) {
        const userProjection = getUserProjection();
        if (userProjection) {
          this.transform_ = getTransformFromProjections(
            this.mapProjection_,
            userProjection
          );
        }
        this.transform_(coordinate, coordinate);
        if (this.wrapX_) {
          const projection =
            userProjection || this.getProjection() || this.mapProjection_;
          wrapX(coordinate, projection);
        }
        const coordinateFormat = this.getCoordinateFormat();
        if (coordinateFormat) {
          html = coordinateFormat(coordinate);
        } else {
          html = coordinate.toString();
        }
      }
    }
    if (!this.renderedHTML_ || html !== this.renderedHTML_) {
      this.element.innerHTML = html;
      this.renderedHTML_ = html;
    }
  }

  render(mapEvent) {
    const frameState = mapEvent.frameState;
    if (!frameState) {
      this.mapProjection_ = null;
    } else {
      if (this.mapProjection_ != frameState.viewState.projection) {
        this.mapProjection_ = frameState.viewState.projection;
        this.transform_ = null;
      }
    }
  }
}

MousePosition类构造函数

MousePosition类构造函数接受一个参数对象options,该参数可以包含如下属性:

  • className:控件类名,默认为ol-mouse-position
  • render:自定义render方法,默认undefined
  • target:控件容器,默认undefined
  • coordinateFormat:坐标格式化,默认undefined
  • projection:分辨率,默认undefined
  • placeholder:提示填充字符
  • wrapX:是否水平方向重复延申

构造函数首先会先注册projection的监听事件this.handleProjectionChanged_,若该值发生变化,则将this.transform_null;然后判断,若options.coordinateFormat存在,则调用this.setCoordinateFormat方法;若options.projection存在,则调用this.setProjection方法;

MousePosition类中的方法

  • getCoordinateFormat方法:获取坐标格式化
  • getProjection方法:获取投影
  • handleMouseMove方法:接受一个参数event,该方法是鼠标在地图上移动时调用,会更新控件的内容坐标的值,getEventPixel就是根据参数event获取鼠标的位置以及viewport的某些属性,然后计算屏幕坐标
  • handleMouseOut方法:鼠标移除地图时调用
  • setCoordinateFormat方法:设置坐标格式化
  • setProjection方法:设置投影
  • updateHTML_方法:根据屏幕坐标获取地理坐标
  • render方法:在调用父类的setMap方法时会调用,主要用于设置this.mapProject_
  • setMap方法:sepMap方法会在Map类中调用,内部首先会调用父类的setMap方法,然后判断参数map是否存在,若存在,则注册viewport视口对象pointermove类型的监听,事件为this.handleMouseMove;若构造函数参数options.placeholder设置了,还会注册viewportpointeroutthis.handleMouseOut事件。

总结

本文主要介绍了 Openlayers 中MousePosition鼠标位置控件的源码实现,核心就是注册viewport对象上pointermove类型的监听事件获取屏幕坐标,然后调用内部方法map.getCoordinateFromPixelInternal将屏幕坐标转化为实际的地理位置坐标。


http://www.kler.cn/a/443337.html

相关文章:

  • 基于springboot的网上商城购物系统
  • 【生物信息】h5py.File
  • 【漏洞工具】小米路由器任意文件读取漏洞python图形化框架利用工具(poc|exp)
  • Solidity合约编写(五)
  • PHP语言的数据库编程
  • 【Unity笔记】资源包导入后是洋红色(粉色)怎么办?
  • Redis Sentinel(哨兵) 和 Redis Cluster(集群)
  • 单元测试-Unittest框架实践
  • android RadioButton + ViewPager+fragment
  • 【Web】PolarCTF2024秋季个人挑战赛wp
  • KMP算法基础
  • 【Lua热更新】下篇 -- 更新中
  • Webpack常见的Plugin有哪些?
  • Java 初学者的第一个 SpringBoot3.4.0 登录系统
  • 【安当产品应用案例100集】032-重塑企业SaaS平台的PostgreSQL凭据管理体系
  • Running CMake (运行 CMake)
  • C语言学习day24:DLL给程序打上窗口破解补丁
  • 借助腾讯云质检平台的新范式,做工业制造企业质检的“AI慧眼”
  • ofd转pdf ofd转图片 python脚本(非ai生成,实测可转换)
  • arduino继电器与电机水泵的使用
  • IDEA能够从mapper跳转到xml的插件
  • 微信小程序TTS解决方案
  • 告别数据查询瓶颈!PostgreSQL 多表连接与复杂条件解析
  • 大连理工大学经济管理学院冠名讲席教授捐赠与聘任仪式圆满举行,乐凡信息成为“冠名讲席教授项目”首捐企业!
  • simpleperf生成火焰图的步骤
  • Python如何正确解决reCaptcha验证码(9)