constructor()

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)
				}
			)
		})
	}