in packages/layers/geojson/src/LineString/LodLineStringLayer.ts [88:261]
constructor(props: OptionalDefault<LodLineStringProps, typeof defaultProps> = {}) {
const _props = {
...defaultProps,
...props,
}
super(_props)
this.glineGroup = new LineLodGroup()
this.addEventListener('viewChange', (e) => {
if (this.glineGroup) {
// Update resolution
const p = e.polaris
const w = p.canvasWidth
const h = p.canvasHeight
this.glineGroup.forEach((mesh) => {
const gline = mesh as GLine
const originRes = gline.material.config['resolution']
if (originRes.x !== w || originRes.y !== h) {
gline.material.config['resolution'] = {
x: p.canvasWidth,
y: p.canvasHeight,
}
}
})
// Update lods
this.glineGroup.update(e.cameraProxy)
}
})
this.addEventListener('init', (e) => {
const polaris = e.polaris
const projection = e.projection
const timeline = e.timeline
this._workerManager = new WorkerManager(createWorkers(1))
this.listenProps(
[
'level',
'lineWidth',
'pointSize',
'color',
'opacity',
'texture',
'usePerspective',
'useColors',
'dynamic',
'lods',
],
() => {
if (this.glineGroup) {
this.glineGroup.forEach((gline) => this.group.remove(gline))
this.glineGroup.clear()
}
const textureURL = this.getProp('texture')
const texture = textureURL
? specifyTexture({
image: { uri: textureURL },
sampler: undefined,
})
: undefined
const lodInfos = this.getProp('lods') as LodInfo[]
for (let i = 0; i < lodInfos.length; i++) {
const color = this._getLineColor()
const gline = new GLine({
level: this.getProp('level'),
lineWidth: this.getProp('lineWidth'),
pointSize: this.getProp('pointSize'),
color: color,
opacity: this.getProp('opacity'),
texture,
usePerspective: this.getProp('usePerspective'),
useColors: this.getProp('useColors'),
dynamic: this.getProp('dynamic'),
resolution: {
x: polaris.canvasWidth ?? polaris.width,
y: polaris.canvasHeight ?? polaris.height,
},
})
this.group.add(gline)
this.glineGroup.add(gline, lodInfos[i].zoom)
}
}
)
this.listenProps(
[
'data',
'baseAlt',
'level',
'pointSize',
'texture',
'usePerspective',
'useColors',
'dynamic',
'lods',
],
// TODO: not safe, props may change during this async calling
async () => {
const data: FeatureCollection<any> | undefined = this.getProp('data')
if (!(data && Array.isArray(data.features))) {
return
}
const baseAlt = this.getProp('baseAlt')
/**
* Building geojson lods:
* 1. Transfer to worker
* 2. Get generated geojsons back (might be arraybuffer)
* 3. Build lod meshes
*/
const lodInfos = this.getProp('lods') as LodInfo[]
const percentages = lodInfos.map((info) => info.percentage)
const res = await this._workerManager.execute({
data: {
task: 'lods',
geojson: data,
percentages: percentages,
},
transferables: undefined,
})
res.results.forEach((lod, i) => {
const content = lod
if (!content) return
let geojson
if (content.buffer !== undefined) {
geojson = JSON.parse(textDecoder.decode(content))
} else {
geojson = content
}
// Data prep
const positions: number[][] = []
// 拍平得到lineString的数组
const flattened = flatten(geojson)
// 删除空geometry
flattened.features = flattened.features.filter((i) => {
return i.geometry
})
flattened.features.forEach((feature: any) => {
let geom: any = getGeom(feature)
if (geom) {
// 如果Geojson数据是Polygon类型,需要先转换为LineString
if (geom.type === 'Polygon') {
const line: any = polygonToLine(feature)
geom = getGeom(line)
} else if (geom.type === 'MultiPolygon') {
const line: any = polygonToLine(feature)
geom = line.features[0].geometry
}
const positionsSub: number[] = []
const coords = getCoords(geom)
coords.forEach((coord) => {
const xyz = projection.project(coord[0], coord[1], baseAlt)
positionsSub.push(...xyz)
})
positions.push(positionsSub)
}
})
const gline = this.glineGroup.get(i).mesh as GLine
gline.geometry.updateData({
positions: positions,
})
})
// Update first frame
this.glineGroup.update(polaris.cameraProxy)
}
)
})
}