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类
      • 概述
      • 源码分析
        • MultiPoint类的源码
        • MultiPoint类的构造函数
        • MultiPoint类的主要方法
      • 总结
    • LinearRing类
    • Polygon类
    • MultiPolygon类
    • LineString类
    • MultiLineString类
    • Circle类
  • Layer图层篇

  • Renderer篇

  • Feature篇

  • style样式篇

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

MultiPoint类

# 概述

在 Openlayers 中,MultiPoint类的实例对象就是由一些列点组成的几何对象。MultiPoint类继承于SimpleGeometry类,关于SimpleGeometry类可以参考这篇文章

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

# 源码分析

# MultiPoint类的源码

MultiPoint类的源码实现如下:

class MultiPoint extends SimpleGeometry {
  constructor(coordinates, layout) {
    super();
    if (layout && !Array.isArray(coordinates[0])) {
      this.setFlatCoordinates(layout, coordinates);
    } else {
      this.setCoordinates(coordinates, layout);
    }
  }
  appendPoint(point) {
    extend(this.flatCoordinates, point.getFlatCoordinates());
    this.changed();
  }
  clone() {
    const multiPoint = new MultiPoint(
      this.flatCoordinates.slice(),
      this.layout
    );
    multiPoint.applyProperties(this);
    return multiPoint;
  }
  closestPointXY(x, y, closestPoint, minSquaredDistance) {
    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
      return minSquaredDistance;
    }
    const flatCoordinates = this.flatCoordinates;
    const stride = this.stride;
    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
      const squaredDistance = squaredDx(
        x,
        y,
        flatCoordinates[i],
        flatCoordinates[i + 1]
      );
      if (squaredDistance < minSquaredDistance) {
        minSquaredDistance = squaredDistance;
        for (let j = 0; j < stride; ++j) {
          closestPoint[j] = flatCoordinates[i + j];
        }
        closestPoint.length = stride;
      }
    }
    return minSquaredDistance;
  }
  getCoordinates() {
    return inflateCoordinates(
      this.flatCoordinates,
      0,
      this.flatCoordinates.length,
      this.stride
    );
  }
  getPoint(index) {
    const n = this.flatCoordinates.length / this.stride;
    if (index < 0 || n <= index) {
      return null;
    }
    return new Point(
      this.flatCoordinates.slice(
        index * this.stride,
        (index + 1) * this.stride
      ),
      this.layout
    );
  }
  getPoints() {
    const flatCoordinates = this.flatCoordinates;
    const layout = this.layout;
    const stride = this.stride;
    const points = [];
    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
      const point = new Point(flatCoordinates.slice(i, i + stride), layout);
      points.push(point);
    }
    return points;
  }
  getType() {
    return "MultiPoint";
  }
  intersectsExtent(extent) {
    const flatCoordinates = this.flatCoordinates;
    const stride = this.stride;
    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
      const x = flatCoordinates[i];
      const y = flatCoordinates[i + 1];
      if (containsXY(extent, x, y)) {
        return true;
      }
    }
    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
101
102
103
104
105

# MultiPoint类的构造函数

MultiPoint类的构造函数接受两个参数:coordinates坐标数组和layout坐标布局方式;构造函数内部会判断,若layout存在且coordinates坐标的第一项不是数组,则调用父类的setFlatCoordinates方法设置this.layout、this.stride和this.flatCoordinates等变量;否则调用this.setCoordinates方法设置这些变量。

# MultiPoint类的主要方法

MultiPoint类的主要方法如下:

  • appendPoint方法:接受一个参数point点,point是Point类的实例对象,关于Point类,可以参考;appendPoint方法会先获取参数point的坐标,调用实例的getFlatCoordinates方法;然后将其坐标添加到当前几何对象的this.flatCoordinates变量中,最后调用this.changed方法。

  • clone方法:复制当前几何对象;内部会实例化MultiPoint类,然后调用该实例对象的applyProperties方法应用属性,最后返回实例对象multiPoint

  • closestPointXY方法:接受四个参数,给定点坐标x、y、最近点坐标closestPoint和最小距离平方minSquaredDistance;closestPintXY主要用于获取给定点距离几何对象的最短距离的平方以及修改最近点坐标closestPoint;方法内部会调用closestSquaredDistanceXY获取给定点距离几何对象包围盒的最短距离的平方,并将它与minSquaredDistance比较大小;若minSquaredDistance较小,则直接返回它;否则遍历几何对象的坐标数组this.flatCoordinates获取每个点坐标,调用squaredDx方法计算给定点(x,y)与几何对象上点坐标的距离平方squaredDistance,然后比较squaredDistance与minSquaredDistance大小;若squaredDistance小于squaredDistance,则更新最近点坐标closestPoint坐标为几何对象上的点坐标,并将squaredDistance的值赋值给minSquaredDistance用于下次循环比较;最后返回minSquaredDistance。

  • getCoordinates方法:获取当前几何对象的(多维数组)坐标,内部调用的是inflateCoordinates方法并返回结果

  • getPoint方法:用于返回当前几何对象在指定位置index处的坐标;方法会先判断index的合法性,然后通过index截取this.flatCoordinates,再实例化Point类,最后返回实例对象。

  • getPoints方法:用于获取当前几何对象中的所有点坐标,通过this.layout、this.stride去遍历截取几何对象的坐标数组this.flatCoordinates,然后调用Point类进行实例化,将实例化的对象统一存放再points数组中,最后返回points。

  • getType方法:获取当前几何对象的类型,MultiPoint

  • intersectsExtent方法:用于判断矩形extent是否与当前几何对象相交;原理就是遍历this.flatCoordinates,调用containsXY方法判断每一个点的坐标是否在extent的边界或内部,若是,则返回true;若没有一个点在extent内部或边界上,则返回false。

  • setCoordinates方法:用于设置坐标数据,也就是调用deflateCoordinates方法将多维数组扁平化,设置this.layout、this.stride以及this.flatCoordinates,最后调用this.changed方法。

# 总结

本文主要介绍了MultiPoint类的源码实现以及其主要方法。

编辑 (opens new window)
上次更新: 2024/12/31, 07:05:01
Point类
LinearRing类

← Point类 LinearRing类→

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