Jinuss's blog Jinuss's blog
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

Web、WebGIS技术博客
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 核心基类

  • Control控件篇

  • Geom几何图形篇

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

  • Renderer篇

  • Feature篇

  • style样式篇

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

SimpleGeometry类

# 概述

本文主要介绍 Openlayers 中的SimplyGeometry类,该类继承于Geometry类,也是普通几何对象如点线面的基类或父类。SimplyGeometry类一般地也不会被实例化,只会被继承,因为它不会被渲染。

# 源码分析

# SimplyGeometry类源码

SimplyGeometry类源码实现如下:

class SimplyGeometry extends Geometry {
  constructor() {}
  computedExtent(extent) {
    return createOrUpdateFromFlatCoordinates(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride,
      extent
    );
  }
  getCoordinates() {
    return abstract();
  }
  getFirstCoordinate() {
    return this.flatCoordinates.slice(0, this.stride);
  }
  getFlatCoordinates() {
    return this.flatCoordinates;
  }
  getLastCoordinate() {
    return this.flatCoordinates.slice(
      this.flatCoordinates.length - this.stride
    );
  }
  getLayout() {
    return this.layout;
  }
  getSimplifiedGeometry(squaredTolerance) {
    if (this.simplifiedGeometryRevision !== this.getRevision()) {
      this.simplifiedGeometryMaxMinSquaredTolerance = 0;
      this.simplifiedGeometryRevision = this.getRevision();
    }
    if (
      squaredTolerance < 0 ||
      (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&
        squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance)
    ) {
      return this;
    }

    const simplifiedGeometry =
      this.getSimplifiedGeometryInternal(squaredTolerance);
    const simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();
    if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {
      return simplifiedGeometry;
    }
    this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
    return this;
  }

  getSimplifiedGeometryInternal(squaredTolerance) {
    return this;
  }

  getStride() {
    return this.stride;
  }
  setFlatCoordinates(layout, flatCoordinates) {
    this.stride = getStrideForLayout(layout);
    this.layout = layout;
    this.flatCoordinates = flatCoordinates;
  }

  setCoordinates(coordinates, layout) {
    abstract();
  }
  setLayout(layout, coordinates, nesting) {
    let stride;
    if (layout) {
      stride = getStrideForLayout(layout);
    } else {
      for (let i = 0; i < nesting; ++i) {
        if (coordinates.length === 0) {
          this.layout = "XY";
          this.stride = 2;
          return;
        }
        coordinates = /** @type {Array<unknown>} */ (coordinates[0]);
      }
      stride = coordinates.length;
      layout = getLayoutForStride(stride);
    }
    this.layout = layout;
    this.stride = stride;
  }
  applyTransform(transformFn) {
    if (this.flatCoordinates) {
      transformFn(
        this.flatCoordinates,
        this.flatCoordinates,
        this.layout.startsWith("XYZ") ? 3 : 2,
        this.stride
      );
      this.changed();
    }
  }
  rotate(angle, anchor) {
    const flatCoordinates = this.getFlatCoordinates();
    if (flatCoordinates) {
      const stride = this.getStride();
      rotate(
        flatCoordinates,
        0,
        flatCoordinates.length,
        stride,
        angle,
        anchor,
        flatCoordinates
      );
      this.changed();
    }
  }
  scale(sx, sy, anchor) {
    if (sy === undefined) {
      sy = sx;
    }
    if (!anchor) {
      anchor = getCenter(this.getExtent());
    }
    const flatCoordinates = this.getFlatCoordinates();
    if (flatCoordinates) {
      const stride = this.getStride();
      scale(
        flatCoordinates,
        0,
        flatCoordinates.length,
        stride,
        sx,
        sy,
        anchor,
        flatCoordinates
      );
      this.changed();
    }
  }

  translate(deltaX, deltaY) {
    const flatCoordinates = this.getFlatCoordinates();
    if (flatCoordinates) {
      const stride = this.getStride();
      translate(
        flatCoordinates,
        0,
        flatCoordinates.length,
        stride,
        deltaX,
        deltaY,
        flatCoordinates
      );
      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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

# SimplyGeometry类的构造函数

SimplyGeometry类的构造函数就是定义了如下变量:

  • this.layout:默认值为XY,表示二维坐标,可选值还有XYZ(表示三维坐标)、XYM(表示二维坐标,M为附加属性)和XYZM(表示三维坐标,M为附加属性)。

  • this.stride:默认值为 2,步幅,可以理解为this.layout的长度。

  • this.flatCoordinates:是一个一维数组,用来存储几何图形的坐标数据。

# SimplyGeometry类主要方法

SimplyGeometry类的主要方法如下:

  • computeExtent方法:内部就是调用createOrUpdateFromFlatCoordinate方法去计算几何对象的包围盒extent

  • getCoordinates方法:未实现,实际上就是获取几何对象的坐标

  • getFirstCoordinate方法:获取几何对象的第一个坐标

  • getFlatCoordinates方法:获取几何对象的一维数组,即this.flatCoordinates

  • getLastCoordinate方法:获取几何对象的最后一个坐标

  • getLayout方法:获取变量this.layout的值

  • getSimplifiedGeometry方法:创建一个简化的几何对象,运用Douglas Peucker算法

  • getSimplifiedGeometryInternal方法:获取简化几何对象

  • getStride方法:获取步幅,即this.stride的值

  • setFlatCoordinates方法:接受两个参数layout和flatCoordinates,调用getStrideForLayout通过参数layout计算stride,赋值this.layout和this.flatCoordinates

  • setCoordinates方法:未实现

  • setLayout方法:设置this.layout和this.stride

  • applyTransform方法:应用转换函数,参数是一个函数;判断若this.flatCoordinates存在,则调用转换函数,最后调用this.changed方法

  • rotate方法:给定一个坐标,使几何对象绕着该坐标旋转一定角度;接受两个参数angle旋转角度和anchor锚点;调用this.getFlatCoordinates获取几何对象的一维坐标,若它存在,则调用this.getStride获取步幅,然后调用rotate方法进行旋转,这操作会修改flatCoordinates;最后调用this.changed方法

  • scale方法:接受三个参数,水平方向缩放因子sx、垂直方向缩放因子sy和锚点anchor;判断,sy不存在时,则sy=sx;判断,若锚点anchor不存在,则以几何对象的包围盒的中心点为锚点;调用this.getFlatCoordinates获取this.flatCoordinates,判断,若它存在,则调用scale方法对几何对象进行缩放,最后调用this.changed方法

  • translate方法:接受两个参数deltaX和deltaY,分别表示在水平方向和垂直方向的偏移量,实际上是调用translate方法对几何对象在水平垂直两个方向上进行平移变化,最后调用this.changed方法

# 总结

本文介绍了SimpleGeometry类的源码实现和主要方法介绍,SimpleGeometry类的几何变换,包括旋转、缩放和平移都是对flatCoordinates进行操作,对于点线面都是如此,这在一定程度上降低了几何变换的复杂度。

编辑 (opens new window)
上次更新: 2024/12/25, 10:29:32
GeometryCollection类
Point类

← GeometryCollection类 Point类→

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