@@ -3,7 +3,9 @@ import { fillLayerId, lineLayerId } from "@geolibre/map";
33import type { FeatureCollection , Geometry } from "geojson" ;
44import type { GeoJSONSource , MapMouseEvent , Map as MapLibreMap } from "maplibre-gl" ;
55import type { GeoLibreAppAPI , GeoLibreCogLayerOptions , GeoLibrePlugin } from "../types" ;
6+ import { addPMTilesLayerFromUrl } from "./maplibre-components" ;
67import {
8+ assetFormat ,
79 connectStac ,
810 horizontalBbox ,
911 isVisualizableAsset ,
@@ -209,7 +211,7 @@ let labels: StacLabels = {
209211 zoom : "Zoom" ,
210212 add : "Add" ,
211213 download : "Download" ,
212- addUnsupported : "Only GeoTIFF/COG and GeoJSON assets can be added to the map" ,
214+ addUnsupported : "Only GeoTIFF/COG, GeoJSON, and PMTiles assets can be added to the map" ,
213215 addFailed : "Could not add asset" ,
214216 cogUnsupported : "This GeoLibre host cannot visualize remote GeoTIFF assets" ,
215217 showing : ( count ) => `Showing ${ count } items.` ,
@@ -505,19 +507,36 @@ async function visualizeAsset(
505507 signal ?: AbortSignal ,
506508) : Promise < void > {
507509 const name = `${ item . id } — ${ assetLabel ( key , asset ) } ` ;
508- const value = `${ asset . type ?? "" } ${ asset . href } ` . toLowerCase ( ) ;
509- if ( value . includes ( "geo+json" ) || / \. g e o j s o n ( $ | \? ) / i. test ( asset . href ) ) {
510- const response = await fetch ( asset . href , {
511- headers : { Accept : "application/geo+json, application/json" } ,
512- signal,
513- } ) ;
514- if ( ! response . ok ) throw new Error ( `${ response . status } ${ response . statusText } ` ) ;
515- const data = ( await response . json ( ) ) as FeatureCollection ;
516- appRef ?. addGeoJsonLayer ( name , data , asset . href ) ;
517- } else if ( appRef ?. addCogLayer ) {
518- await appRef . addCogLayer ( name , asset . href , cogOptions ) ;
519- } else {
520- throw new Error ( labels . cogUnsupported ) ;
510+ const format = assetFormat ( asset ) ;
511+ switch ( format ) {
512+ case "pmtiles" : {
513+ // The same door the Source Cooperative browser uses, so an archive reaches the map one way.
514+ if ( appRef ) await addPMTilesLayerFromUrl ( appRef , asset . href , { fit : false , name } ) ;
515+ return ;
516+ }
517+ case "geojson" : {
518+ const response = await fetch ( asset . href , {
519+ headers : { Accept : "application/geo+json, application/json" } ,
520+ signal,
521+ } ) ;
522+ if ( ! response . ok ) throw new Error ( `${ response . status } ${ response . statusText } ` ) ;
523+ const data = ( await response . json ( ) ) as FeatureCollection ;
524+ appRef ?. addGeoJsonLayer ( name , data , asset . href ) ;
525+ return ;
526+ }
527+ case "cog" : {
528+ if ( ! appRef ?. addCogLayer ) throw new Error ( labels . cogUnsupported ) ;
529+ await appRef . addCogLayer ( name , asset . href , cogOptions ) ;
530+ return ;
531+ }
532+ case null :
533+ throw new Error ( labels . addUnsupported ) ;
534+ default : {
535+ // A format added to VISUALIZABLE_FORMATS with no branch here fails to compile, rather than
536+ // falling through to a renderer that cannot read it.
537+ const unhandled : never = format ;
538+ throw new Error ( `Unhandled asset format: ${ String ( unhandled ) } ` ) ;
539+ }
521540 }
522541}
523542
0 commit comments