in packages/layers/geojson/src/Polygon/PolygonSurfaceLayer.ts [250:413]
private async createGeom(data, projection, polaris) {
this.featIndexRangeMap = new Map()
this.featColorRangeMap = new Map()
this.featLineInfoMap = new Map()
this.featColorMap = new Map()
const getThickness = this.getProps('getThickness')
const getColor = this.getProps('getColor')
const getOpacity = this.getProps('getOpacity')
const baseAlt = this.getProps('baseAlt')
const genSelectLines = this.getProps('genSelectLines')
const lineHeight = this.getProps('selectLinesHeight')
const positions: number[] = []
const colors: number[] = []
const indices: number[] = []
const linePosArr: number[][] = []
let linePosOffset = 0
let offset = 0
let results
if (this._workerManager) {
// Triangulate geojson using workers
const geomPendings: Promise<any>[] = []
data.features.forEach((feature, index) => {
feature.index = index // Store feature index range
let promise
if (this.getProps('useTessellation') && !projection.isPlaneProjection) {
promise = this._workerManager.execute({
data: {
task: 'tessellation',
feature,
tessellation: this._tessellation,
},
transferables: undefined,
})
} else {
promise = this._workerManager.execute({
data: {
task: 'triangulate',
feature,
},
transferables: undefined,
})
}
geomPendings.push(promise)
})
results = await Promise.all(geomPendings)
} else {
// Triangulate geojson in main thread
results = []
data.features.forEach((feature, index) => {
feature.index = index // Store feature index range
let result
if (this.getProps('useTessellation') && !projection.isPlaneProjection) {
result = CDTGeojsonWithSubdivision(feature, Math.pow(2, this._tessellation))
} else {
result = triangulateGeoJSON(feature)
}
result.index = index
results.push(result)
})
}
results.forEach((result) => {
const feature = data.features[result.index]
const points = result.points
const triangles = result.triangles
const indexRange = new Uint32Array([indices.length, 0])
const colorRange = new Uint32Array([offset * 4, 0])
for (let i = 0; i < points.length; i += 2) {
const xyz = projection.project(points[i], points[i + 1], baseAlt + getThickness(feature))
positions.push(...xyz)
}
for (let i = 0; i < triangles.length; i++) {
indices.push(triangles[i] + offset)
}
const count = points.length / 2
const offset4 = offset * 4
const color = new Color(getColor(feature))
const alpha = getOpacity(feature) ?? 1.0
const colorUint = getColorUint(color, alpha)
for (let i = 0; i < count; i++) {
const i4 = i * 4
colors[i4 + 0 + offset4] = colorUint[0]
colors[i4 + 1 + offset4] = colorUint[1]
colors[i4 + 2 + offset4] = colorUint[2]
colors[i4 + 3 + offset4] = colorUint[3]
}
this.featColorMap.set(feature, colorUint)
offset += count
// Store index range for feature
indexRange[1] = indices.length - 1
// Store feature vert range
colorRange[1] = offset * 4
this.featIndexRangeMap.set(feature, indexRange)
this.featColorRangeMap.set(feature, colorRange)
// LineIndicator geom info creation
if (genSelectLines) {
const linePos = featureToLinePositions(
feature,
projection,
baseAlt + getThickness(feature) + lineHeight
)
if (linePos) {
linePos.forEach((positions) => {
linePosArr.push(positions)
// Cache offset/count info
const info = this.featLineInfoMap.get(feature)
if (info) {
info.push({
offset: linePosOffset,
count: positions.length / 3,
})
} else {
this.featLineInfoMap.set(feature, [
{
offset: linePosOffset,
count: positions.length / 3,
},
])
}
// Offset
linePosOffset += positions.length / 3
})
}
}
})
this.geom = new Geom()
this.geom.attributes.position = new Attr(new Float32Array(positions), 3)
this.geom.attributes.color = new Attr(new Uint16Array(colors), 4, false, 'DYNAMIC_DRAW')
const indicesArray = offset > 65535 ? new Uint32Array(indices) : new Uint16Array(indices)
this.geom.indices = new Attr(indicesArray, 1)
// disable auto gpu dispose
this.geom.attributes.position.disposable = false
this.geom.attributes.color.disposable = false
this.geom.indices.disposable = false
this.geom.boundingSphere = computeBSphere(this.geom)
this.geom.boundingBox = computeBBox(this.geom)
// regenerate mesh
this._generateMesh()
this.mesh.geometry = this.geom
// Create selection polyline
// Remove if existed
this._removeIndicator(this.selectIndicator)
this._removeIndicator(this.hoverIndicator)
if (genSelectLines) {
this._genLineIndicators(polaris, linePosArr)
}
}