entity/geometry/GeometryHandler.tstypescript
import * as mercator from "../../mercator";
import * as quadTree from "../../quadTree/quadTree";
import { Extent } from "../../Extent";
import { Handler } from "../../webgl/Handler";
import type { WebGLBufferExt } from "../../webgl/Handler";
import { doubleToTwoFloatsV2 } from "../../math/coder";
import { Vector } from "../../layer/Vector";
import { Vec2 } from "../../math/Vec2";
import type { NumberArray2 } from "../../math/Vec2";
import { Node } from "../../quadTree/Node";
import { Vec3 } from "../../math/Vec3";
import { Vec4 } from "../../math/Vec4";
import type {
CoordinatesType,
Geometry,
ILineStringCoordinates,
IMultiLineStringCoordinates,
IMultiPolygonCoordinates,
IPolygonCoordinates
} from "./Geometry";
import { GeometryTypeEnum } from "./Geometry";
import { earcut, flatten } from "../../utils/earcut";
const POLYVERTICES_BUFFER = 0;
const POLYINDEXES_BUFFER = 1;
const POLYCOLORS_BUFFER = 2;
const LINEVERTICES_BUFFER = 3;
const LINEINDEXES_BUFFER = 4;
const LINEORDERS_BUFFER = 5;
const LINECOLORS_BUFFER = 6;
const LINETHICKNESS_BUFFER = 7;
const LINESTROKES_BUFFER = 8;
const LINESTROKECOLORS_BUFFER = 9;
const POLYPICKINGCOLORS_BUFFER = 10;
const LINEPICKINGCOLORS_BUFFER = 11;
function doubleToTwoFloats(v: NumberArray2, high: Vec2, low: Vec2) {
let x = v[0],
y = v[1];
if (x >= 0.0) {
let doubleHigh = Math.floor(x / 65536.0) * 65536.0;
high.x = Math.fround(doubleHigh);
low.x = Math.fround(x - doubleHigh);
} else {
let doubleHigh = Math.floor(-x / 65536.0) * 65536.0;
high.x = Math.fround(-doubleHigh);
low.x = Math.fround(x + doubleHigh);
}
if (y >= 0.0) {
let doubleHigh = Math.floor(y / 65536.0) * 65536.0;
high.y = Math.fround(doubleHigh);
low.y = Math.fround(y - doubleHigh);
} else {
let doubleHigh = Math.floor(-y / 65536.0) * 65536.0;
high.y = Math.fround(-doubleHigh);
low.y = Math.fround(y + doubleHigh);
}
}
let tempHigh = new Vec2(),
tempLow = new Vec2(),
tempHighLow = new Vec2();
class GeometryHandler {
static __counter__: number = 0;
protected __id: number;
protected _layer: Vector;
protected _handler: Handler | null;
protected _geometries: Geometry[];
protected _updatedGeometryArr: Geometry[];
protected _updatedGeometry: Record<number, boolean>;
protected _removeGeometryExtentArr: Extent[];
protected _removeGeometryExtents: Record<number, boolean>;
// Polygon arrays
protected _polyVerticesHighMerc: number[];
protected _polyVerticesLowMerc: number[];
protected _polyColors: number[];
protected _polyPickingColors: number[];
protected _polyIndexes: number[];
// Line arrays
protected _lineVerticesHighMerc: number[];
protected _lineVerticesLowMerc: number[];
protected _lineOrders: number[];
protected _lineIndexes: number[];
protected _lineColors: number[];
protected _linePickingColors: number[];
protected _lineThickness: number[];
protected _lineStrokes: number[];
protected _lineStrokeColors: number[];
// Buffers
public _polyVerticesHighBufferMerc: WebGLBufferExt | null;
public _polyVerticesLowBufferMerc: WebGLBufferExt | null;
public _polyColorsBuffer: WebGLBufferExt | null;
public _polyPickingColorsBuffer: WebGLBufferExt | null;
public _polyIndexesBuffer: WebGLBufferExt | null;
public _lineVerticesHighBufferMerc: WebGLBufferExt | null;
public _lineVerticesLowBufferMerc: WebGLBufferExt | null;
public _lineColorsBuffer: WebGLBufferExt | null;
public _linePickingColorsBuffer: WebGLBufferExt | null;
public _lineThicknessBuffer: WebGLBufferExt | null;
public _lineStrokesBuffer: WebGLBufferExt | null;
public _lineStrokeColorsBuffer: WebGLBufferExt | null;
public _lineOrdersBuffer: WebGLBufferExt | null;
public _lineIndexesBuffer: WebGLBufferExt | null;
protected _buffersUpdateCallbacks: Function[];
protected _changedBuffers: boolean[];
constructor(layer: Vector) {
this.__id = GeometryHandler.__counter__++;
this._layer = layer;
this._handler = null;
this._geometries = [];
this._updatedGeometryArr = [];
this._updatedGeometry = {};
this._removeGeometryExtentArr = [];
this._removeGeometryExtents = {};
// Polygon arrays
this._polyVerticesHighMerc = [];
this._polyVerticesLowMerc = [];
this._polyColors = [];
this._polyPickingColors = [];
this._polyIndexes = [];
// Line arrays
this._lineVerticesHighMerc = [];
this._lineVerticesLowMerc = [];
this._lineOrders = [];
this._lineIndexes = [];
this._lineColors = [];
this._linePickingColors = [];
this._lineThickness = [];
this._lineStrokes = [];
this._lineStrokeColors = [];
// Buffers
this._polyVerticesHighBufferMerc = null;
this._polyVerticesLowBufferMerc = null;
this._polyColorsBuffer = null;
this._polyPickingColorsBuffer = null;
this._polyIndexesBuffer = null;
this._lineVerticesHighBufferMerc = null;
this._lineVerticesLowBufferMerc = null;
this._lineColorsBuffer = null;
this._linePickingColorsBuffer = null;
this._lineThicknessBuffer = null;
this._lineStrokesBuffer = null;
this._lineStrokeColorsBuffer = null;
this._lineOrdersBuffer = null;
this._lineIndexesBuffer = null;
this._buffersUpdateCallbacks = [];
this._buffersUpdateCallbacks[POLYVERTICES_BUFFER] = this.createPolyVerticesBuffer;
this._buffersUpdateCallbacks[POLYINDEXES_BUFFER] = this.createPolyIndexesBuffer;
this._buffersUpdateCallbacks[POLYCOLORS_BUFFER] = this.createPolyColorsBuffer;
this._buffersUpdateCallbacks[LINEVERTICES_BUFFER] = this.createLineVerticesBuffer;
this._buffersUpdateCallbacks[LINEINDEXES_BUFFER] = this.createLineIndexesBuffer;
this._buffersUpdateCallbacks[LINEORDERS_BUFFER] = this.createLineOrdersBuffer;
this._buffersUpdateCallbacks[LINECOLORS_BUFFER] = this.createLineColorsBuffer;
this._buffersUpdateCallbacks[LINETHICKNESS_BUFFER] = this.createLineThicknessBuffer;
this._buffersUpdateCallbacks[LINESTROKES_BUFFER] = this.createLineStrokesBuffer;
this._buffersUpdateCallbacks[LINESTROKECOLORS_BUFFER] = this.createLineStrokeColorsBuffer;
this._buffersUpdateCallbacks[POLYPICKINGCOLORS_BUFFER] = this.createPolyPickingColorsBuffer;
this._buffersUpdateCallbacks[LINEPICKINGCOLORS_BUFFER] = this.createLinePickingColorsBuffer;
this._changedBuffers = new Array(this._buffersUpdateCallbacks.length);
}
static appendLineData(
pathArr: CoordinatesType[][],
isClosed: boolean,
color: Vec4,
pickingColor: Vec3,
thickness: number,
strokeColor: Vec4,
strokeSize: number,
outVerticesHigh: number[],
outVerticesLow: number[],
outOrders: number[],
outIndexes: number[],
outColors: number[],
outPickingColors: number[],
outThickness: number[],
outStrokeColors: number[],
outStrokes: number[],
outVerticesHigh2: number[],
outVerticesLow2: number[]
) {
var index = 0;
if (outIndexes.length > 0) {
index = outIndexes[outIndexes.length - 5] + 9;
outIndexes.push(index, index);
} else {
outIndexes.push(0, 0);
}
var t = thickness,
c = [color.x, color.y, color.z, color.w],
s = strokeSize,
sc = [strokeColor.x, strokeColor.y, strokeColor.z, strokeColor.w],
p = [pickingColor.x, pickingColor.y, pickingColor.z, 1.0];
for (let j = 0; j < pathArr.length; j++) {
var path = pathArr[j];
if (path.length === 0) {
continue;
}
let startIndex = index;
let last: CoordinatesType;
if (isClosed) {
last = path[path.length - 1];
} else {
let p0 = path[0],
p1 = path[1];
if (!p1) {
p1 = p0;
}
last = [p0[0] + p0[0] - p1[0], p0[1] + p0[1] - p1[1]];
}
doubleToTwoFloats(last as NumberArray2, tempHigh, tempLow);
outVerticesHigh.push(
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y
);
outVerticesLow.push(tempLow.x, tempLow.y, tempLow.x, tempLow.y, tempLow.x, tempLow.y, tempLow.x, tempLow.y);
outVerticesHigh2.push(
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y
);
outVerticesLow2.push(
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y
);
outOrders.push(1, -1, 2, -2);
outThickness.push(t, t, t, t);
outStrokes.push(s, s, s, s);
outColors.push(
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3]
);
outStrokeColors.push(
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3]
);
outPickingColors.push(
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3]
);
for (let i = 0; i < path.length; i++) {
let cur = path[i];
doubleToTwoFloats(cur as NumberArray2, tempHigh, tempLow);
outVerticesHigh.push(
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y
);
outVerticesLow.push(
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y
);
outVerticesHigh2.push(
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y
);
outVerticesLow2.push(
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y
);
outOrders.push(1, -1, 2, -2);
outThickness.push(t, t, t, t);
outStrokes.push(s, s, s, s);
outColors.push(
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3]
);
outStrokeColors.push(
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3]
);
outPickingColors.push(
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3]
);
outIndexes.push(index++, index++, index++, index++);
}
let first: CoordinatesType;
if (isClosed) {
first = path[0];
outIndexes.push(startIndex, startIndex + 1, startIndex + 1, startIndex + 1);
} else {
let p0 = path[path.length - 1],
p1 = path[path.length - 2];
if (!p1) {
p1 = p0;
}
first = [p0[0] + p0[0] - p1[0], p0[1] + p0[1] - p1[1]];
outIndexes.push(index - 1, index - 1, index - 1, index - 1);
}
doubleToTwoFloats(first as NumberArray2, tempHigh, tempLow);
outVerticesHigh.push(
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y
);
outVerticesLow.push(tempLow.x, tempLow.y, tempLow.x, tempLow.y, tempLow.x, tempLow.y, tempLow.x, tempLow.y);
outVerticesHigh2.push(
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y,
tempHigh.x,
tempHigh.y
);
outVerticesLow2.push(
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y,
tempLow.x,
tempLow.y
);
outOrders.push(1, -1, 2, -2);
outThickness.push(t, t, t, t);
outStrokes.push(s, s, s, s);
outColors.push(
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3],
c[0],
c[1],
c[2],
c[3]
);
outStrokeColors.push(
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3],
sc[0],
sc[1],
sc[2],
sc[3]
);
outPickingColors.push(
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3],
p[0],
p[1],
p[2],
p[3]
);
if (j < pathArr.length - 1) {
index += 8;
outIndexes.push(index, index);
}
}
}
public assignHandler(handler: Handler) {
this._handler = handler;
this.refresh();
if (handler.isInitialized()) {
this.update();
}
}
/**
* @public
* @param {Geometry} geometry - Geometry object.
*/
public add(geometry: Geometry) {
//
// Triangulates polygon and sets geometry data.
if (geometry._handlerIndex === -1) {
geometry._handler = this;
geometry._handlerIndex = this._geometries.length;
this._geometries.push(geometry);
let pickingColor = geometry._entity!._pickingColor.scaleTo(1 / 255);
geometry._polyVerticesHighMerc = [];
geometry._polyVerticesLowMerc = [];
geometry._lineVerticesHighMerc = [];
geometry._lineVerticesLowMerc = [];
if ((geometry._coordinates as IPolygonCoordinates)[0].length) {
if (geometry.type === GeometryTypeEnum.POLYGON) {
let coordinates = geometry._coordinates as IPolygonCoordinates;
let ci: IPolygonCoordinates = [];
for (let j = 0; j < coordinates.length; j++) {
ci[j] = [];
for (let k = 0; k < coordinates[j].length; k++) {
ci[j][k] = [
mercator.forward_lon(coordinates[j][k][0]),
mercator.forward_lat(coordinates[j][k][1])
];
}
}
let data = flatten(ci);
let indexes: number[] = earcut(data.vertices, data.holes, 2);
geometry._polyVerticesHandlerIndex = this._polyVerticesHighMerc.length;
geometry._polyIndexesHandlerIndex = this._polyIndexes.length;
for (let i = 0; i < indexes.length; i++) {
this._polyIndexes.push(indexes[i] + geometry._polyVerticesHandlerIndex * 0.5);
}
let color = geometry._style.fillColor;
let verticesHigh = [],
verticesLow = [];
for (let i = 0; i < data.vertices.length * 0.5; i++) {
this._polyColors.push(color.x, color.y, color.z, color.w);
this._polyPickingColors.push(pickingColor.x, pickingColor.y, pickingColor.z, 1.0);
}
for (let i = 0; i < data.vertices.length; i++) {
doubleToTwoFloatsV2(data.vertices[i], tempHighLow);
verticesHigh[i] = tempHighLow.x;
verticesLow[i] = tempHighLow.y;
}
geometry._polyVerticesHighMerc = verticesHigh;
geometry._polyVerticesLowMerc = verticesLow;
this._polyVerticesHighMerc.push.apply(this._polyVerticesHighMerc, verticesHigh);
this._polyVerticesLowMerc.push.apply(this._polyVerticesLowMerc, verticesLow);
geometry._polyVerticesLength = data.vertices.length;
geometry._polyIndexesLength = indexes.length;
// Creates polygon stroke data
geometry._lineVerticesHandlerIndex = this._lineVerticesHighMerc.length;
geometry._lineOrdersHandlerIndex = this._lineOrders.length;
geometry._lineIndexesHandlerIndex = this._lineIndexes.length;
geometry._lineColorsHandlerIndex = this._lineColors.length;
geometry._lineThicknessHandlerIndex = this._lineThickness.length;
GeometryHandler.appendLineData(
ci,
true,
geometry._style.lineColor,
pickingColor,
geometry._style.lineWidth,
geometry._style.strokeColor,
geometry._style.strokeWidth,
this._lineVerticesHighMerc,
this._lineVerticesLowMerc,
this._lineOrders,
this._lineIndexes,
this._lineColors,
this._linePickingColors,
this._lineThickness,
this._lineStrokeColors,
this._lineStrokes,
geometry._lineVerticesHighMerc,
geometry._lineVerticesLowMerc
);
geometry._lineVerticesLength =
this._lineVerticesHighMerc.length - geometry._lineVerticesHandlerIndex;
geometry._lineOrdersLength = this._lineOrders.length - geometry._lineOrdersHandlerIndex;
geometry._lineIndexesLength = this._lineIndexes.length - geometry._lineIndexesHandlerIndex;
geometry._lineColorsLength = this._lineColors.length - geometry._lineColorsHandlerIndex;
geometry._lineThicknessLength = this._lineThickness.length - geometry._lineThicknessHandlerIndex;
} else if (geometry.type === GeometryTypeEnum.MULTIPOLYGON) {
let coordinates = geometry._coordinates as IMultiPolygonCoordinates;
let vertices: number[] = [],
indexes: number[] = [];
// Creates polygon stroke data
geometry._lineVerticesHandlerIndex = this._lineVerticesHighMerc.length;
geometry._lineOrdersHandlerIndex = this._lineOrders.length;
geometry._lineIndexesHandlerIndex = this._lineIndexes.length;
geometry._lineColorsHandlerIndex = this._lineColors.length;
geometry._lineThicknessHandlerIndex = this._lineThickness.length;
for (let i = 0; i < coordinates.length; i++) {
let cci: CoordinatesType[][] = coordinates[i];
let ci: CoordinatesType[][] = [];
for (let j = 0; j < cci.length; j++) {
ci[j] = [];
for (let k = 0; k < coordinates[i][j].length; k++) {
ci[j][k] = [mercator.forward_lon(cci[j][k][0]), mercator.forward_lat(cci[j][k][1])];
}
}
let data = flatten(ci);
let dataIndexes: number[] = earcut(data.vertices, data.holes, 2);
for (let j = 0; j < dataIndexes.length; j++) {
indexes.push(dataIndexes[j] + vertices.length * 0.5);
}
vertices.push.apply(vertices, data.vertices);
GeometryHandler.appendLineData(
ci,
true,
geometry._style.lineColor,
pickingColor,
geometry._style.lineWidth,
geometry._style.strokeColor,
geometry._style.strokeWidth,
this._lineVerticesHighMerc,
this._lineVerticesLowMerc,
this._lineOrders,
this._lineIndexes,
this._lineColors,
this._linePickingColors,
this._lineThickness,
this._lineStrokeColors,
this._lineStrokes,
geometry._lineVerticesHighMerc,
geometry._lineVerticesLowMerc
);
}
geometry._polyVerticesHandlerIndex = this._polyVerticesHighMerc.length;
geometry._polyIndexesHandlerIndex = this._polyIndexes.length;
for (let i = 0; i < indexes.length; i++) {
this._polyIndexes.push(indexes[i] + geometry._polyVerticesHandlerIndex * 0.5);
}
let color = geometry._style.fillColor;
let verticesHigh = [],
verticesLow = [];
for (let i = 0; i < vertices.length * 0.5; i++) {
this._polyColors.push(color.x, color.y, color.z, color.w);
this._polyPickingColors.push(pickingColor.x, pickingColor.y, pickingColor.z, 1.0);
}
for (let i = 0; i < vertices.length; i++) {
doubleToTwoFloatsV2(vertices[i], tempHighLow);
verticesHigh[i] = tempHighLow.x;
verticesLow[i] = tempHighLow.y;
}
geometry._polyVerticesHighMerc = verticesHigh;
geometry._polyVerticesLowMerc = verticesLow;
this._polyVerticesHighMerc.push.apply(this._polyVerticesHighMerc, verticesHigh);
this._polyVerticesLowMerc.push.apply(this._polyVerticesLowMerc, verticesLow);
geometry._polyVerticesLength = vertices.length;
geometry._polyIndexesLength = indexes.length;
geometry._lineVerticesLength =
this._lineVerticesHighMerc.length - geometry._lineVerticesHandlerIndex;
geometry._lineOrdersLength = this._lineOrders.length - geometry._lineOrdersHandlerIndex;
geometry._lineIndexesLength = this._lineIndexes.length - geometry._lineIndexesHandlerIndex;
geometry._lineColorsLength = this._lineColors.length - geometry._lineColorsHandlerIndex;
geometry._lineThicknessLength = this._lineThickness.length - geometry._lineThicknessHandlerIndex;
} else if (geometry.type === GeometryTypeEnum.LINESTRING) {
let coordinates: ILineStringCoordinates = geometry._coordinates as ILineStringCoordinates;
let ci = new Array(coordinates.length);
for (let j = 0; j < coordinates.length; j++) {
ci[j] = [mercator.forward_lon(coordinates[j][0]), mercator.forward_lat(coordinates[j][1])];
}
// Creates polygon stroke data
geometry._lineVerticesHandlerIndex = this._lineVerticesHighMerc.length;
geometry._lineOrdersHandlerIndex = this._lineOrders.length;
geometry._lineIndexesHandlerIndex = this._lineIndexes.length;
geometry._lineColorsHandlerIndex = this._lineColors.length;
geometry._lineThicknessHandlerIndex = this._lineThickness.length;
GeometryHandler.appendLineData(
[ci],
false,
geometry._style.lineColor,
pickingColor,
geometry._style.lineWidth,
geometry._style.strokeColor,
geometry._style.strokeWidth,
this._lineVerticesHighMerc,
this._lineVerticesLowMerc,
this._lineOrders,
this._lineIndexes,
this._lineColors,
this._linePickingColors,
this._lineThickness,
this._lineStrokeColors,
this._lineStrokes,
geometry._lineVerticesHighMerc,
geometry._lineVerticesLowMerc
);
geometry._lineVerticesLength =
this._lineVerticesHighMerc.length - geometry._lineVerticesHandlerIndex;
geometry._lineOrdersLength = this._lineOrders.length - geometry._lineOrdersHandlerIndex;
geometry._lineIndexesLength = this._lineIndexes.length - geometry._lineIndexesHandlerIndex;
geometry._lineColorsLength = this._lineColors.length - geometry._lineColorsHandlerIndex;
geometry._lineThicknessLength = this._lineThickness.length - geometry._lineThicknessHandlerIndex;
} else if (geometry.type === GeometryTypeEnum.MULTILINESTRING) {
let coordinates = geometry._coordinates as IMultiLineStringCoordinates;
let ci: IMultiLineStringCoordinates = [];
for (let j = 0; j < coordinates.length; j++) {
ci[j] = [];
for (let k = 0; k < coordinates[j].length; k++) {
ci[j][k] = [
mercator.forward_lon(coordinates[j][k][0]),
mercator.forward_lat(coordinates[j][k][1])
];
}
}
// Creates polygon stroke data
geometry._lineVerticesHandlerIndex = this._lineVerticesHighMerc.length;
geometry._lineOrdersHandlerIndex = this._lineOrders.length;
geometry._lineIndexesHandlerIndex = this._lineIndexes.length;
geometry._lineColorsHandlerIndex = this._lineColors.length;
geometry._lineThicknessHandlerIndex = this._lineThickness.length;
GeometryHandler.appendLineData(
ci,
false,
geometry._style.lineColor,
pickingColor,
geometry._style.lineWidth,
geometry._style.strokeColor,
geometry._style.strokeWidth,
this._lineVerticesHighMerc,
this._lineVerticesLowMerc,
this._lineOrders,
this._lineIndexes,
this._lineColors,
this._linePickingColors,
this._lineThickness,
this._lineStrokeColors,
this._lineStrokes,
geometry._lineVerticesHighMerc,
geometry._lineVerticesLowMerc
);
geometry._lineVerticesLength =
this._lineVerticesHighMerc.length - geometry._lineVerticesHandlerIndex;
geometry._lineOrdersLength = this._lineOrders.length - geometry._lineOrdersHandlerIndex;
geometry._lineIndexesLength = this._lineIndexes.length - geometry._lineIndexesHandlerIndex;
geometry._lineColorsLength = this._lineColors.length - geometry._lineColorsHandlerIndex;
geometry._lineThicknessLength = this._lineThickness.length - geometry._lineThicknessHandlerIndex;
}
}
// Refresh visibility
this.setGeometryVisibility(geometry);
!this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
this._updatedGeometry[geometry.__id] = true;
this.refresh();
}
}
public remove(geometry: Geometry) {
const index = geometry._handlerIndex;
if (index !== -1) {
this._geometries.splice(index, 1);
// polygon
// this._polyVerticesLonLat.splice(geometry._polyVerticesHandlerIndex, geometry._polyVerticesLength);
this._polyVerticesHighMerc.splice(geometry._polyVerticesHandlerIndex, geometry._polyVerticesLength);
this._polyVerticesLowMerc.splice(geometry._polyVerticesHandlerIndex, geometry._polyVerticesLength);
this._polyColors.splice(geometry._polyVerticesHandlerIndex * 2, geometry._polyVerticesLength * 2);
this._polyPickingColors.splice(geometry._polyVerticesHandlerIndex * 2, geometry._polyVerticesLength * 2);
this._polyIndexes.splice(geometry._polyIndexesHandlerIndex, geometry._polyIndexesLength);
let di = geometry._polyVerticesLength * 0.5;
for (let i = geometry._polyIndexesHandlerIndex; i < this._polyIndexes.length; i++) {
this._polyIndexes[i] -= di;
}
// line
// this._lineVerticesLonLat.splice(geometry._lineVerticesHandlerIndex, geometry._lineVerticesLength);
this._lineVerticesHighMerc.splice(geometry._lineVerticesHandlerIndex, geometry._lineVerticesLength);
this._lineVerticesLowMerc.splice(geometry._lineVerticesHandlerIndex, geometry._lineVerticesLength);
this._lineOrders.splice(geometry._lineOrdersHandlerIndex, geometry._lineOrdersLength);
this._lineColors.splice(geometry._lineColorsHandlerIndex, geometry._lineColorsLength);
this._linePickingColors.splice(geometry._lineColorsHandlerIndex, geometry._lineColorsLength);
this._lineStrokeColors.splice(geometry._lineColorsHandlerIndex, geometry._lineColorsLength);
this._lineThickness.splice(geometry._lineThicknessHandlerIndex, geometry._lineThicknessLength);
this._lineStrokes.splice(geometry._lineThicknessHandlerIndex, geometry._lineThicknessLength);
this._lineIndexes.splice(geometry._lineIndexesHandlerIndex, geometry._lineIndexesLength);
di = geometry._lineVerticesLength * 0.5;
for (let i = geometry._lineIndexesHandlerIndex; i < this._lineIndexes.length; i++) {
this._lineIndexes[i] -= di;
}
// reindex
let g = this._geometries;
for (let i = index; i < g.length; i++) {
let gi = g[i];
gi._handlerIndex = i;
gi._polyVerticesHandlerIndex -= geometry._polyVerticesLength;
gi._polyIndexesHandlerIndex -= geometry._polyIndexesLength;
gi._lineVerticesHandlerIndex -= geometry._lineVerticesLength;
gi._lineOrdersHandlerIndex -= geometry._lineOrdersLength;
gi._lineColorsHandlerIndex -= geometry._lineColorsLength;
gi._lineThicknessHandlerIndex -= geometry._lineThicknessLength;
gi._lineIndexesHandlerIndex -= geometry._lineIndexesLength;
}
geometry._pickingReady = false;
geometry._handler = null;
geometry._handlerIndex = -1;
geometry._polyVerticesHighMerc = [];
geometry._polyVerticesLowMerc = [];
geometry._polyVerticesLength = -1;
geometry._polyIndexesLength = -1;
geometry._polyVerticesHandlerIndex = -1;
geometry._polyIndexesHandlerIndex = -1;
geometry._lineVerticesHighMerc = [];
geometry._lineVerticesLowMerc = [];
geometry._lineVerticesLength = -1;
geometry._lineOrdersLength = -1;
geometry._lineIndexesLength = -1;
geometry._lineColorsLength = -1;
geometry._lineThicknessLength = -1;
geometry._lineVerticesHandlerIndex = -1;
geometry._lineOrdersHandlerIndex = -1;
geometry._lineIndexesHandlerIndex = -1;
geometry._lineThicknessHandlerIndex = -1;
geometry._lineColorsHandlerIndex = -1;
!this._removeGeometryExtents[geometry.__id] && this._removeGeometryExtentArr.push(geometry.getExtent());
this._removeGeometryExtents[geometry.__id] = true;
this.refresh();
}
}
protected _refreshRecursevely(geometry: Geometry, treeNode: Node) {
if (treeNode.ready) {
let lid = this._layer._id;
for (let i = 0; i < treeNode.nodes.length; i++) {
let ni = treeNode.nodes[i];
if (geometry.overlaps(ni.segment.getExtentLonLat())) {
this._refreshRecursevely(geometry, ni);
let m = ni.segment.materials[lid];
if (m && m.isReady) {
if (m.segment.node.getState() !== quadTree.RENDERING) {
m.layer.clearMaterial(m);
} else {
m.pickingReady = m.pickingReady && geometry._pickingReady;
m.isReady = false;
m._updateTexture = m.texture;
m._updatePickingMask = m.pickingMask;
}
geometry._pickingReady = true;
}
}
}
}
}
protected _refreshRecursevelyExt(extent: Extent, treeNode: Node) {
if (treeNode.ready) {
let lid = this._layer.__id;
for (let i = 0; i < treeNode.nodes.length; i++) {
let ni = treeNode.nodes[i];
if (extent.overlaps(ni.segment.getExtentLonLat())) {
this._refreshRecursevelyExt(extent, ni);
let m = ni.segment.materials[lid];
if (m && m.isReady) {
m.layer.clearMaterial(m);
// m.pickingReady = false;
// m.isReady = false;
// m._updateTexture = m.texture;
// m._updatePickingMask = m.pickingMask;
}
}
}
}
}
protected _refreshPlanetNode(treeNode: Node) {
let i;
let e = this._removeGeometryExtentArr;
for (i = 0; i < e.length; i++) {
this._refreshRecursevelyExt(e[i], treeNode);
}
let g = this._updatedGeometryArr;
for (i = 0; i < g.length; i++) {
this._refreshRecursevely(g[i], treeNode);
}
}
protected _updatePlanet() {
let p = this._layer._planet;
if (p) {
let ql = p.quadTreeStrategy.quadTreeList;
for (let i = 0; i < ql.length; i++) {
this._refreshPlanetNode(ql[i]);
}
// p.quadTreeStrategy.quadTreeList.forEach((quadTree: Node) => {
// this._refreshPlanetNode(quadTree);
// });
}
this._updatedGeometryArr.length = 0;
this._updatedGeometryArr = [];
this._updatedGeometry = {};
this._removeGeometryExtentArr.length = 0;
this._removeGeometryExtentArr = [];
this._removeGeometryExtents = {};
}
protected refresh() {
let i = this._changedBuffers.length;
while (i--) {
this._setChangedBuffer(i);
}
}
protected _setChangedBuffer(index: number) {
this._changedBuffers[index] = true;
this._handler && (this._handler.needRedraw = true);
}
public update() {
if (this._handler) {
let needUpdate = false;
let i = this._changedBuffers.length;
while (i--) {
if (this._changedBuffers[i]) {
needUpdate = true;
this._buffersUpdateCallbacks[i].call(this);
this._changedBuffers[i] = false;
}
}
needUpdate && this._updatePlanet();
}
}
public setGeometryVisibility(geometry: Geometry) {
let v = geometry.getVisibility() ? 1.0 : 0.0;
let a = this._polyVerticesHighMerc,
b = this._polyVerticesLowMerc;
let l = geometry._polyVerticesLength;
let ind = geometry._polyVerticesHandlerIndex;
for (let i = 0; i < l; i++) {
a[ind + i] = geometry._polyVerticesHighMerc[i] * v;
b[ind + i] = geometry._polyVerticesLowMerc[i] * v;
}
a = this._lineVerticesHighMerc;
b = this._lineVerticesLowMerc;
l = geometry._lineVerticesLength;
ind = geometry._lineVerticesHandlerIndex;
for (let i = 0; i < l; i++) {
a[ind + i] = geometry._lineVerticesHighMerc[i] * v;
b[ind + i] = geometry._lineVerticesLowMerc[i] * v;
}
this._setChangedBuffer(POLYVERTICES_BUFFER);
this._setChangedBuffer(LINEVERTICES_BUFFER);
!this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
this._updatedGeometry[geometry.__id] = true;
}
public setPolyColorArr(geometry: Geometry, color: Vec4) {
let index = geometry._polyVerticesHandlerIndex * 2, // ... / 2 * 4
size = index + geometry._polyVerticesLength * 2; // ... / 2 * 4
let a = this._polyColors;
for (let i = index; i < size; i += 4) {
a[i] = color.x;
a[i + 1] = color.y;
a[i + 2] = color.z;
a[i + 3] = color.w;
}
this._setChangedBuffer(POLYCOLORS_BUFFER);
!this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
this._updatedGeometry[geometry.__id] = true;
}
public setLineStrokeColorArr(geometry: Geometry, color: Vec4) {
let index = geometry._lineColorsHandlerIndex,
size = index + geometry._lineColorsLength;
let a = this._lineStrokeColors;
for (let i = index; i < size; i += 4) {
a[i] = color.x;
a[i + 1] = color.y;
a[i + 2] = color.z;
a[i + 3] = color.w;
}
this._setChangedBuffer(LINESTROKECOLORS_BUFFER);
!this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
this._updatedGeometry[geometry.__id] = true;
}
public setLineColorArr(geometry: Geometry, color: Vec4) {
let index = geometry._lineColorsHandlerIndex,
size = index + geometry._lineColorsLength;
let a = this._lineColors;
for (let i = index; i < size; i += 4) {
a[i] = color.x;
a[i + 1] = color.y;
a[i + 2] = color.z;
a[i + 3] = color.w;
}
this._setChangedBuffer(LINECOLORS_BUFFER);
!this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
this._updatedGeometry[geometry.__id] = true;
}
public setLineStrokeArr(geometry: Geometry, width: number) {
// let index = geometry._lineStrokesHandlerIndex,
// size = index + geometry._lineStrokesLength;
// let a = this._lineStrokes;
// for (let i = index; i < size; i++) {
// a[i] = width;
// }
// this._changedBuffers[LINESTROKES_BUFFER] = true;
// !this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
// this._updatedGeometry[geometry.__id] = true;
}
public setLineThicknessArr(geometry: Geometry, width: number) {
let index = geometry._lineThicknessHandlerIndex,
size = index + geometry._lineThicknessLength;
let a = this._lineThickness;
for (let i = index; i < size; i++) {
a[i] = width;
}
this._setChangedBuffer(LINETHICKNESS_BUFFER);
!this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
this._updatedGeometry[geometry.__id] = true;
}
public bringToFront(geometry: Geometry) {
let polyIndexes = this._polyIndexes.splice(geometry._polyIndexesHandlerIndex, geometry._polyIndexesLength);
let lineIndexes = this._lineIndexes.splice(geometry._lineIndexesHandlerIndex, geometry._lineIndexesLength);
this._geometries.splice(geometry._handlerIndex, 1);
let g = this._geometries;
for (let i = geometry._handlerIndex; i < g.length; i++) {
let gi = g[i];
gi._handlerIndex = i;
gi._polyIndexesHandlerIndex -= geometry._polyIndexesLength;
gi._lineIndexesHandlerIndex -= geometry._lineIndexesLength;
}
geometry._polyIndexesHandlerIndex = this._polyIndexes.length;
geometry._lineIndexesHandlerIndex = this._lineIndexes.length;
geometry._handlerIndex = this._geometries.length;
this._geometries.push(geometry);
this._polyIndexes.push.apply(this._polyIndexes, polyIndexes);
this._lineIndexes.push.apply(this._lineIndexes, lineIndexes);
this._setChangedBuffer(POLYINDEXES_BUFFER);
this._setChangedBuffer(LINEINDEXES_BUFFER);
!this._updatedGeometry[geometry.__id] && this._updatedGeometryArr.push(geometry);
this._updatedGeometry[geometry.__id] = true;
}
public createPolyVerticesBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._polyVerticesHighBufferMerc!);
this._polyVerticesHighBufferMerc = h.createArrayBuffer(
new Float32Array(this._polyVerticesHighMerc),
2,
this._polyVerticesHighMerc.length / 2
);
h.gl!.deleteBuffer(this._polyVerticesLowBufferMerc!);
this._polyVerticesLowBufferMerc = h.createArrayBuffer(
new Float32Array(this._polyVerticesLowMerc),
2,
this._polyVerticesLowMerc.length / 2
);
}
public createPolyIndexesBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._polyIndexesBuffer!);
this._polyIndexesBuffer = h.createElementArrayBuffer(
new Uint32Array(this._polyIndexes),
1,
this._polyIndexes.length
);
}
public createPolyColorsBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._polyColorsBuffer!);
this._polyColorsBuffer = h.createArrayBuffer(
new Float32Array(this._polyColors),
4,
this._polyColors.length / 4
);
}
public createPolyPickingColorsBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._polyPickingColorsBuffer!);
this._polyPickingColorsBuffer = h.createArrayBuffer(
new Float32Array(this._polyPickingColors),
4,
this._polyPickingColors.length / 4
);
}
public createLineVerticesBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._lineVerticesHighBufferMerc!);
this._lineVerticesHighBufferMerc = h.createArrayBuffer(
new Float32Array(this._lineVerticesHighMerc),
2,
this._lineVerticesHighMerc.length / 2
);
h.gl!.deleteBuffer(this._lineVerticesLowBufferMerc!);
this._lineVerticesLowBufferMerc = h.createArrayBuffer(
new Float32Array(this._lineVerticesLowMerc),
2,
this._lineVerticesLowMerc.length / 2
);
}
public createLineIndexesBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._lineIndexesBuffer!);
this._lineIndexesBuffer = h.createElementArrayBuffer(
new Uint32Array(this._lineIndexes),
1,
this._lineIndexes.length
);
}
public createLineOrdersBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._lineOrdersBuffer!);
this._lineOrdersBuffer = h.createArrayBuffer(
new Float32Array(this._lineOrders),
1,
this._lineOrders.length / 2
);
}
public createLineColorsBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._lineColorsBuffer!);
this._lineColorsBuffer = h.createArrayBuffer(
new Float32Array(this._lineColors),
4,
this._lineColors.length / 4
);
}
public createLinePickingColorsBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._linePickingColorsBuffer!);
this._linePickingColorsBuffer = h.createArrayBuffer(
new Float32Array(this._linePickingColors),
4,
this._linePickingColors.length / 4
);
}
public createLineThicknessBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._lineThicknessBuffer!);
this._lineThicknessBuffer = h.createArrayBuffer(
new Float32Array(this._lineThickness),
1,
this._lineThickness.length
);
}
public createLineStrokesBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._lineStrokesBuffer!);
this._lineStrokesBuffer = h.createArrayBuffer(new Float32Array(this._lineStrokes), 1, this._lineStrokes.length);
}
public createLineStrokeColorsBuffer() {
let h = this._handler!;
h.gl!.deleteBuffer(this._lineStrokeColorsBuffer!);
this._lineStrokeColorsBuffer = h.createArrayBuffer(
new Float32Array(this._lineStrokeColors),
4,
this._lineStrokeColors.length / 4
);
}
public clear() {
this._geometries = [];
this._polyVerticesHighMerc = [];
this._polyVerticesLowMerc = [];
this._polyIndexes = [];
this._polyColors = [];
this._polyPickingColors = [];
this._lineVerticesHighMerc = [];
this._lineVerticesLowMerc = [];
this._lineOrders = [];
this._lineIndexes = [];
this._lineColors = [];
this._linePickingColors = [];
this._lineThickness = [];
this._lineStrokeColors = [];
this._lineStrokes = [];
this._deleteBuffers();
this._polyVerticesHighBufferMerc = null;
this._polyVerticesLowBufferMerc = null;
this._polyIndexesBuffer = null;
this._polyColorsBuffer = null;
this._polyPickingColorsBuffer = null;
this._lineVerticesHighBufferMerc = null;
this._lineVerticesLowBufferMerc = null;
this._lineIndexesBuffer = null;
this._lineOrdersBuffer = null;
this._lineColorsBuffer = null;
this._linePickingColorsBuffer = null;
this._lineThicknessBuffer = null;
this._lineStrokeColorsBuffer = null;
this._lineStrokesBuffer = null;
this._updatedGeometryArr = [];
this._updatedGeometry = {};
this._removeGeometryExtentArr = [];
this._removeGeometryExtents = {};
this.refresh();
}
public _deleteBuffers() {
if (this._layer._planet && this._layer._planet.renderer) {
let h = this._layer._planet.renderer.handler,
gl = h.gl!;
if (gl) {
gl.deleteBuffer(this._polyVerticesHighBufferMerc!);
gl.deleteBuffer(this._polyVerticesLowBufferMerc!);
gl.deleteBuffer(this._polyIndexesBuffer!);
gl.deleteBuffer(this._polyColorsBuffer!);
gl.deleteBuffer(this._polyPickingColorsBuffer!);
gl.deleteBuffer(this._lineVerticesHighBufferMerc);
gl.deleteBuffer(this._lineVerticesLowBufferMerc);
gl.deleteBuffer(this._lineIndexesBuffer);
gl.deleteBuffer(this._lineOrdersBuffer);
gl.deleteBuffer(this._lineColorsBuffer);
gl.deleteBuffer(this._linePickingColorsBuffer);
gl.deleteBuffer(this._lineThicknessBuffer);
gl.deleteBuffer(this._lineStrokeColorsBuffer);
gl.deleteBuffer(this._lineStrokesBuffer);
}
}
}
}
export { GeometryHandler };