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几何图形篇

    • Geom几何图形篇介绍
    • Geometry基类
    • GeometryCollection类
    • SimpleGeometry类
    • Point类
    • MultiPoint类
    • LinearRing类
      • 概述
      • 源码分析
        • LinearRing类源码实现
        • LinearRing类的构造函数
        • LinearRing类的主要方法
      • 总结
    • Polygon类
    • MultiPolygon类
    • LineString类
    • MultiLineString类
    • Circle类
  • Layer图层篇

  • Renderer篇

  • Feature篇

  • style样式篇

  • 《Openlayers源码》笔记
  • Geom几何图形篇
东流
2024-12-26
目录

LinearRing类

# 概述

在 OpenLayers 中,LinearRing 类用于表示封闭的线段集合(即多段线)形成的环状路径。LinearRing 是 SimpleGeometry 的子类,继承自几何图形类。它通常用于描述多边形的外边界或孔洞边界,本质上它就是一个封闭的线段路径,首尾点必须是重合的,形成一个封闭环。

本文主要介绍LinearRing类的源码实现和原理。

# 源码分析

# LinearRing类源码实现

class LinearRing extends SimpleGeometry {
  constructor(coordinates, layout) {
    super();
    this.maxDelta_ = -1;
    this.maxDeltaRevision_ = -1;
    if (layout !== undefined && !Array.isArray(coordinates[0])) {
      this.setFlatCoordinates(layout, coordinates);
    } else {
      this.setCoordinates(coordinates, layout);
    }
  }

  clone() {
    return new LinearRing(this.flatCoordinates.slice(), this.layout);
  }

  closestPointXY(x, y, closestPoint, minSquaredDistance) {
    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
      return minSquaredDistance;
    }
    if (this.maxDeltaRevision_ != this.getRevision()) {
      this.maxDelta_ = Math.sqrt(
        maxSquaredDelta(
          this.flatCoordinates,
          0,
          this.flatCoordinates.length,
          this.stride,
          0
        )
      );
      this.maxDeltaRevision_ = this.getRevision();
    }
    return assignClosestPoint(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride,
      this.maxDelta_,
      true,
      x,
      y,
      closestPoint,
      minSquaredDistance
    );
  }

  getArea() {
    return linearRingArea(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride
    );
  }

  getCoordinates() {
    return inflateCoordinates(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride
    );
  }

  getSimplifiedGeometryInternal(squaredTolerance) {
    const simplifiedFlatCoordinates = [];
    simplifiedFlatCoordinates.length = douglasPeucker(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride,
      squaredTolerance,
      simplifiedFlatCoordinates,
      0
    );
    return new LinearRing(simplifiedFlatCoordinates, "XY");
  }

  getType() {
    return "LinearRing";
  }

  intersectsExtent(extent) {
    return false;
  }

  setCoordinates(coordinates, layout) {
    this.setLayout(layout, coordinates, 1);
    if (!this.flatCoordinates) {
      this.flatCoordinates = [];
    }
    this.flatCoordinates.length = deflateCoordinates(
      this.flatCoordinates,
      0,
      coordinates,
      this.stride
    );
    this.changed();
  }
}
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

# LinearRing类的构造函数

LinearRing类的构造函数中定义了两个变量this.maxDelta_和this.maxDeltaRevision_,这两个变量都与优化和性能相关,在LinearRing类的管理和更新时,可以避免不必要的计算,具体如下

  • this.maxDelta_:该变量通常用于控制几何形状的精度或处理几何更新时的变化阈值。初始值为-1,表示初始、未定义的状态,还没有设置具体的最大变化量;实际的值通常是在更新几何图形时进行设定;当几何图形的顶点发生变化时,this.maxDelta_会用来判断这些变化是否超出阈值,若没有,这不会触发重新渲染或计算的操作;
  • this.maxDeltaRevision_:初始值也是-1,该变量是用于跟踪几何图形修订版本的变量。它存储了上次更新时的修订版本号,用于判断当前几何形状是否发生了变化。每当几何形状的顶点或属性更新时,this.maxDeltaRevision_ 会被更新。如果当前版本与上次的版本不一致,可能会触发一些操作,比如重新计算、重新渲染或者优化缓存等。该变量有助于优化性能,因为在很多情况下,OpenLayers 需要检查对象是否发生了变化。如果当前修订版本与上次的修订版本一致,那么可以跳过一些不必要的操作。

除了定义上述两个变量外,LinearRing类还会判断构造函数的第二个参数layout是否存在,若不存在,且参数coordinates的第一个值不是数组,则调用父类SimpleGeometry类中的this.setFlatCoordinates方法;否则调用this.setCoordinates方法,二者都是会设置this.layout、this.stride和this.flatCoordinates的值。

# LinearRing类的主要方法

LinearRing类的主要方法如下:

  • clone方法:用于克隆一个LinearRing几何对象,内部就是实例化LinearRing类并返回实例。

  • closestPointXY方法:接受四个参数,目标点坐标x、y、最近点坐标closestPoint和最短距离平方minSquaredDistance;首先会判断,若minSquaredDistance小于目标点离包围盒的距离(该距离是调用closetSquaredDistanceXY方法计算),则返回minSquaredDistance;然后调用this.getRevision()方法获取几何对象的修改次数,若该次数不等于this.maxDeltaRevision_,则调用maxSquaredDelta方法计算几何对象相邻点之间的最大平方距离并将其平方根赋值给this.maxDelta_,并调用this.getRevision()将返回值赋值给this.maxDeltaRevision_;最后调用assignClosePoint方法并返回,assignClosePoint方法就是寻找一组坐标点中离给定点 (x, y) 最近的点,并返回该点的平方距离。该方法是计算几何中点之间最近距离的一种实现,特别适用于路径、线段、或者多边形边界等几何结构,常用于计算点到线的最近距离,或者优化几何数据结构。所以closestPointXY同Point类的同名方法作用一样,修改最近点坐标并返回最短距离

  • getArea方法:获取几何对象的面积,内部是调用linearRingArea方法,该方法的原理是使用**Shoelace定理**(或高斯面积公式)计算多边形的面积。

  • getCoordinates方法:获取几何对象的坐标,内部是调用inflateCoordinates方法

  • getSimplifiedGeometryInternal方法:内部方法,获取简化的几何对象,接受一个参数squaredTolerance,该参数表示一个距离阈值的平方,用于控制在多大程度上可以去除多余的点,即控制简化的精度,值越大,去除的点更多;内部利用了Douglas-Peucker算法来对多边形进行简化。

  • getType方法:获取几何对象的类型,返回LinearRing类

  • intersectsExtent方法:返回false

  • setCoordinates方法:设置坐标,主要还是赋值,内部会调用deflateCoordinates方法修改三个变量this.stride、this.layout和this.flatCoordinates,最后会调用this.changed方法

# 总结

本文介绍了LinearRing类的源码实现,LinearRing类通常情况下实例化后不会直接被渲染,而是在Polygon类中用于构建多边形。

编辑 (opens new window)
上次更新: 2024/12/26, 10:36:02
MultiPoint类
Polygon类

← MultiPoint类 Polygon类→

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