2024-02-21 16:35:49 +01:00
|
|
|
import { FeatureSourceForTile, UpdatableFeatureSource } from "../FeatureSource"
|
2024-02-02 20:04:39 +01:00
|
|
|
import { Store } from "../../UIEventSource"
|
|
|
|
import { BBox } from "../../BBox"
|
|
|
|
import { Utils } from "../../../Utils"
|
2024-02-21 16:35:49 +01:00
|
|
|
import { Feature, MultiLineString, Position } from "geojson"
|
2024-02-02 20:04:39 +01:00
|
|
|
import { GeoOperations } from "../../GeoOperations"
|
2024-02-21 16:35:49 +01:00
|
|
|
import { UpdatableDynamicTileSource } from "./DynamicTileSource"
|
2024-02-02 20:04:39 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The PolygonSourceMerger receives various small pieces of bigger polygons and stitches them together.
|
|
|
|
* This is used to reconstruct polygons of vector tiles
|
|
|
|
*/
|
2024-02-21 16:35:49 +01:00
|
|
|
export class LineSourceMerger extends UpdatableDynamicTileSource<
|
|
|
|
FeatureSourceForTile & UpdatableFeatureSource
|
|
|
|
> {
|
2024-02-02 20:04:39 +01:00
|
|
|
private readonly _zoomlevel: Store<number>
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
zoomlevel: Store<number>,
|
|
|
|
minzoom: number,
|
2024-02-21 16:35:49 +01:00
|
|
|
constructSource: (tileIndex: number) => FeatureSourceForTile & UpdatableFeatureSource,
|
2024-02-02 20:04:39 +01:00
|
|
|
mapProperties: {
|
|
|
|
bounds: Store<BBox>
|
|
|
|
zoom: Store<number>
|
|
|
|
},
|
|
|
|
options?: {
|
|
|
|
isActive?: Store<boolean>
|
2024-02-21 16:35:49 +01:00
|
|
|
}
|
2024-02-02 20:04:39 +01:00
|
|
|
) {
|
|
|
|
super(zoomlevel, minzoom, constructSource, mapProperties, options)
|
|
|
|
this._zoomlevel = zoomlevel
|
|
|
|
}
|
|
|
|
|
|
|
|
protected addDataFromSources(sources: FeatureSourceForTile[]) {
|
|
|
|
sources = Utils.NoNull(sources)
|
|
|
|
const all: Map<string, Feature<MultiLineString>> = new Map()
|
|
|
|
const currentZoom = this._zoomlevel?.data ?? 0
|
|
|
|
for (const source of sources) {
|
2024-02-21 16:35:49 +01:00
|
|
|
if (source.z != currentZoom) {
|
2024-02-02 20:04:39 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
for (const f of source.features.data) {
|
|
|
|
const id = f.properties.id
|
2024-02-21 16:35:49 +01:00
|
|
|
const coordinates: Position[][] = []
|
|
|
|
if (f.geometry.type === "LineString") {
|
2024-02-02 20:04:39 +01:00
|
|
|
coordinates.push(f.geometry.coordinates)
|
2024-02-21 16:35:49 +01:00
|
|
|
} else if (f.geometry.type === "MultiLineString") {
|
2024-02-02 20:04:39 +01:00
|
|
|
coordinates.push(...f.geometry.coordinates)
|
2024-02-21 16:35:49 +01:00
|
|
|
} else {
|
2024-02-02 20:04:39 +01:00
|
|
|
console.error("Invalid geometry type:", f.geometry.type)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
const oldV = all.get(id)
|
2024-02-21 16:35:49 +01:00
|
|
|
if (!oldV) {
|
|
|
|
all.set(id, {
|
|
|
|
type: "Feature",
|
|
|
|
properties: f.properties,
|
|
|
|
geometry: {
|
|
|
|
type: "MultiLineString",
|
|
|
|
coordinates,
|
|
|
|
},
|
|
|
|
})
|
2024-02-02 20:04:39 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
oldV.geometry.coordinates.push(...coordinates)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const keys = Array.from(all.keys())
|
|
|
|
for (const key of keys) {
|
2024-02-21 16:35:49 +01:00
|
|
|
all.set(
|
|
|
|
key,
|
|
|
|
<any>GeoOperations.attemptLinearize(<Feature<MultiLineString>>all.get(key))
|
|
|
|
)
|
2024-02-02 20:04:39 +01:00
|
|
|
}
|
|
|
|
const newList = Array.from(all.values())
|
|
|
|
this.features.setData(newList)
|
|
|
|
this._featuresById.setData(all)
|
|
|
|
}
|
|
|
|
}
|