概述
本文主要介绍 Openlayers 中的SimplyGeometry
类,该类继承于Geometry
类,可以参考源码分析之Openlayers中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();
}
}
}
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
进行操作,对于点线面都是如此,这在一定程度上降低了几何变换的复杂度。