forked from MapComplete/MapComplete
91 lines
2.9 KiB
TypeScript
91 lines
2.9 KiB
TypeScript
import { Feature as GeojsonFeature, Geometry } from "geojson"
|
|
|
|
import { Store, UIEventSource } from "../../UIEventSource"
|
|
import { FeatureSourceForTile, UpdatableFeatureSource } from "../FeatureSource"
|
|
import { MvtToGeojson } from "mvt-to-geojson"
|
|
|
|
export default class MvtSource implements FeatureSourceForTile, UpdatableFeatureSource {
|
|
public readonly features: Store<GeojsonFeature<Geometry, { [name: string]: any }>[]>
|
|
public readonly x: number
|
|
public readonly y: number
|
|
public readonly z: number
|
|
private readonly _url: string
|
|
private readonly _layerName: string
|
|
private readonly _features: UIEventSource<
|
|
GeojsonFeature<
|
|
Geometry,
|
|
{
|
|
[name: string]: any
|
|
}
|
|
>[]
|
|
> = new UIEventSource<GeojsonFeature<Geometry, { [p: string]: any }>[]>([])
|
|
private currentlyRunning: Promise<any>
|
|
|
|
constructor(
|
|
url: string,
|
|
x: number,
|
|
y: number,
|
|
z: number,
|
|
layerName?: string,
|
|
isActive?: Store<boolean>
|
|
) {
|
|
this._url = url
|
|
this._layerName = layerName
|
|
this.x = x
|
|
this.y = y
|
|
this.z = z
|
|
this.updateAsync()
|
|
this.features = this._features.map(
|
|
(fs) => {
|
|
if (fs === undefined || isActive?.data === false) {
|
|
return []
|
|
}
|
|
return fs
|
|
},
|
|
[isActive]
|
|
)
|
|
}
|
|
|
|
async updateAsync() {
|
|
if (!this.currentlyRunning) {
|
|
this.currentlyRunning = this.download()
|
|
}
|
|
await this.currentlyRunning
|
|
}
|
|
|
|
private async download(): Promise<void> {
|
|
try {
|
|
const result = await fetch(this._url)
|
|
if (result.status !== 200) {
|
|
console.error("Could not download tile " + this._url)
|
|
return
|
|
}
|
|
const buffer = await result.arrayBuffer()
|
|
const features = MvtToGeojson.fromBuffer(buffer, this.x, this.y, this.z)
|
|
for (const feature of features) {
|
|
const properties = feature.properties
|
|
if (!properties["osm_type"]) {
|
|
continue
|
|
}
|
|
let type: string = "node"
|
|
switch (properties["osm_type"]) {
|
|
case "N":
|
|
type = "node"
|
|
break
|
|
case "W":
|
|
type = "way"
|
|
break
|
|
case "R":
|
|
type = "relation"
|
|
break
|
|
}
|
|
properties["id"] = type + "/" + properties["osm_id"]
|
|
delete properties["osm_id"]
|
|
delete properties["osm_type"]
|
|
}
|
|
this._features.setData(features)
|
|
} catch (e) {
|
|
console.error("Could not download MVT " + this._url + " tile due to", e)
|
|
}
|
|
}
|
|
}
|