Jinuss's blog Jinuss's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

前端可视化
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 核心基类

  • Control控件篇

  • Geom几何图形篇

  • Layer图层篇

  • Renderer篇

  • Feature篇

    • Feature特征
      • 概述
      • 源码分析
        • Feature类的源码
        • Feature类的构造函数
        • Feature类的主要方法
      • 总结
    • RenderFeature类
  • style样式篇

  • 《Openlayers源码》笔记
  • Feature篇
东流
2025-01-04
目录

Feature特征

# 概述

在 Openlayers 中,Feature类是一个用于地理特征的矢量对象,具有几何形状和其他属性,类似于 GeoJSON 等矢量文件格式中的特征。它主要包含两个重要属性geometry几何对象和style样式,提供getGeometry和setGeometry方法用于获取和设置几何对象,以及getStyle和setStyle处理和样式相关的。

Feature类继承于BaseObject类,关于BaseObject类,可以参考这篇文章

# 源码分析

# Feature类的源码

Feature类的源码实现如下:

class Feature extends BaseObject {
  constructor(geometryOrProperties) {
    super();
    this.on;
    this.once;
    this.un;
    this.id_ = undefined;
    this.geometryName_ = "geometry";
    this.style_ = null;
    this.styleFunction_ = undefined;
    this.geometryChangeKey_ = null;
    this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
    if (geometryOrProperties) {
      if (typeof geometryOrProperties.getSimplifiedGeometry === "function") {
        const geometry = geometryOrProperties;
        this.setGeometry(geometry);
      } else {
        const properties = geometryOrProperties;
        this.setProperties(properties);
      }
    }
  }

  clone() {
    const clone = new Feature(
      this.hasProperties() ? this.getProperties() : null
    );
    clone.setGeometryName(this.getGeometryName());
    const geometry = this.getGeometry();
    if (geometry) {
      clone.setGeometry(geometry.clone());
    }
    const style = this.getStyle();
    if (style) {
      clone.setStyle(style);
    }
    return clone;
  }

  getGeometry() {
    return this.get(this.geometryName_);
  }

  getId() {
    return this.id_;
  }

  getGeometryName() {
    return this.geometryName_;
  }

  getStyle() {
    return this.style_;
  }

  getStyleFunction() {
    return this.styleFunction_;
  }

  handleGeometryChange_() {
    this.changed();
  }

  handleGeometryChanged_() {
    if (this.geometryChangeKey_) {
      unlistenByKey(this.geometryChangeKey_);
      this.geometryChangeKey_ = null;
    }
    const geometry = this.getGeometry();
    if (geometry) {
      this.geometryChangeKey_ = listen(
        geometry,
        EventType.CHANGE,
        this.handleGeometryChange_,
        this
      );
    }
    this.changed();
  }

  setGeometry(geometry) {
    this.set(this.geometryName_, geometry);
  }

  setStyle(style) {
    this.style_ = style;
    this.styleFunction_ = !style ? undefined : createStyleFunction(style);
    this.changed();
  }

  setId(id) {
    this.id_ = id;
    this.changed();
  }

  setGeometryName(name) {
    this.removeChangeListener(this.geometryName_, this.handleGeometryChanged_);
    this.geometryName_ = name;
    this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
    this.handleGeometryChanged_();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

# Feature类的构造函数

Feature类构造函数接受一个参数,参数可以是直接传递的一个几何对象,或者是一个包含属性的对象字面量。如果传递的是对象字面量,可以包含一个与 geometry 键关联的几何对象。构造函数内部初始化了this.id_为undefined,this.geometryName_为geometry以及this.style_、this.styleFunction_和this.geometryChangeKey_为null,然后调用this.addChangeListener方法监听this.geometryName_,当它发生改变时,会触发this.handleGeometryChanged_事件。判断,若参数geometryProperties上存在getSimplifiedGeometry方法,这说明参数是一个几何对象,然后会调用this.setGeometry方法设置几何对象;否则说明参数是一个包含几何对象的对象字面量,则调用this.setProperties方法设置属性。

# Feature类的主要方法

Feature类的主要方法如下:

  • clone方法:该方法用于复制当前feature,首先会实例化Feature类,调用this.hasProperties方法判断当前对象是否有属性,若存在,则调用getProperties方法获取对象上的属性,否则取值是null;hasProperties和getProperties方法都是在Observable类中定义的,关于Observable类可以参考这篇文章;然后调用this.getGeometryName获取几何对象名称,然后通过setGeometryName方法设置实例对象的几何对象名称;然后调用this.getGeometry方法获取几何对象,若它存在,则设置实例对象clone的几何对象;调用this.getStyle方法获取feature的样式,若它存在,则设置实例对象clone的样式,最后返回实例对象。

  • getGeometry方法:通过this.get方法和this.geometryName_属性,获取几何对象

  • getId方法:获取当前feature的this.id_

  • getGeometryName方法:获取当前feature的this.geometryName_

  • getStyle方法:获取当前feature的this.style_

  • getStyleFunction方法:获取当前feature的this.styleFunction_

  • handleGeometryChange_方法:本质上就是调用this.changed方法

  • handleGeometryChanged_方法:该方法就是用于监听几何对象名称的改变,会先判断,若this.geometryChanged_存在,则先调用unlisten方法移除监听,并将其置为null;调用this.getGeometry方法获取几何对象,若其存在,则调用listen方法注册几何对象的监听事件this.handleGeometryChange_;最后调用this.changed方法。

  • setGeometry方法:设置几何对象,本质上是调用的this.set方法

  • setStyle方法:设置feature的样式,参数style会赋值给this.style_,若参数style不存在,则this.styleFunction_为undefined;否则调用createStyleFunction创建一个样式函数,其返回值也是一个函数,最后会调用this.changed方法。

  • setId方法:设置this.id_,最后会调用this.changed方法。

  • setGeometryName方法:设置几何对象的名称,会先移除监听,然后设置this.geometryName_为参数name;然后注册几何对象名称的监听,最后调用this.handleGeometryChanged_方法。

# 总结

Feature类是一个很重要的知识,在矢量图层中绘制、编辑几何对象时都会用到,可以将其理解为几何对象在矢量图层上展示的一个载体,用于将几何对象和样式结合起来在地图上显示。

编辑 (opens new window)
上次更新: 2025/01/07, 09:45:13
LayerRender类
RenderFeature类

← LayerRender类 RenderFeature类→

最近更新
01
GeoJSON
05-08
02
Circle
04-15
03
CircleMarker
04-15
更多文章>
Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式