import { GeoJson , isFeatureGeometry , ITiler } from "@here/harp-datasource-protocol" ; import { TileKey } from "@here/harp-geoutils" ; import * as geojsonvtExport from "geojson-vt" ; const geojsonvt = geojsonvtExport . default ?? geojsonvtExport ; const EXTENT = 4096 ; const BUFFER_FACTOR = 0.05 ; const BUFFER = - ( - Math . ceil ( EXTENT * BUFFER_FACTOR ) & - 2 ) ; interface GeoJsonVtIndex { geojson : GeoJson ; getTile ( level , column , row ) : any ; } export class GeoJsonTiler implements ITiler { indexes : Map < string , GeoJsonVtIndex > ; constructor ( ) { this . indexes = new Map ( ) ; } dispose ( ) { } async connect ( ) { return await Promise . resolve ( ) ; } async registerIndex ( indexId , input ) { if ( this . indexes . has ( indexId ) ) { return ; } return await this . updateIndex ( indexId , input ) ; } async updateIndex ( indexId , input ) { if ( input instanceof URL ) { const response = await fetch ( input . href ) ; if ( ! response . ok ) { throw new Error ( `GeoJsonTiler: Unable to fetch ${ input . href }: ${ response . statusText }` ) ; } input = ( await response . json ( ) ) as GeoJson ; } else { input = input as GeoJson ; } const generateId = isFeatureGeometry ( input ) || input . type === "GeometryCollection" || ( input . type === "Feature" && input . id === undefined ) || ( input . type === "FeatureCollection" && input . features . length > 0 && input . features [ 0 ] . id === undefined ) ; const index = geojsonvt ( input , { maxZoom : 20 , indexMaxZoom : 5 , indexMaxPoints : 100000 , tolerance : 3 , extent : EXTENT , buffer : BUFFER , lineMetrics : false , promoteId : null , generateId , debug : 0 } ) ; index . geojson = input ; this . indexes . set ( indexId , index ) ; } async getTile ( indexId , tileKey ) { const index = this . indexes . get ( indexId ) ; if ( index === undefined ) { throw new Error ( "Tile not found" ) ; } const tile = index . getTile ( tileKey . level , tileKey . column , tileKey . row ) ; if ( tile !== null ) { tile . layer = indexId ; } return tile || { } ; } }