2022-11-02 14:44:06 +01:00
import { Store , UIEventSource } from "../../Logic/UIEventSource"
import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"
2023-03-28 05:13:48 +02:00
import { SpecialVisualization , SpecialVisualizationState } from "../SpecialVisualization"
import { Feature } from "geojson"
import { MapLibreAdaptor } from "../Map/MapLibreAdaptor"
import SvelteUIElement from "../Base/SvelteUIElement"
import MaplibreMap from "../Map/MaplibreMap.svelte"
import ShowDataLayer from "../Map/ShowDataLayer"
2023-04-16 04:13:09 +02:00
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { GeoOperations } from "../../Logic/GeoOperations"
import { BBox } from "../../Logic/BBox"
2022-10-28 04:33:05 +02:00
export class MinimapViz implements SpecialVisualization {
funcName = "minimap"
docs = "A small map showing the selected feature."
args = [
{
doc : "The (maximum) zoomlevel: the target zoomlevel after fitting the entire feature. The minimap will fit the entire feature, then zoom out to this zoom level. The higher, the more zoomed in with 1 being the entire world and 19 being really close" ,
name : "zoomlevel" ,
defaultValue : "18" ,
} ,
{
doc : "(Matches all resting arguments) This argument should be the key of a property of the feature. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. (Note: if the key is 'id', list interpration is disabled)" ,
name : "idKey" ,
defaultValue : "id" ,
} ,
]
2022-11-02 14:44:06 +01:00
example : "`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`"
2022-10-28 04:33:05 +02:00
2023-03-28 05:13:48 +02:00
constr (
state : SpecialVisualizationState ,
tagSource : UIEventSource < Record < string , string > > ,
2023-04-16 04:13:09 +02:00
args : string [ ] ,
feature : Feature ,
layer : LayerConfig
2023-03-28 05:13:48 +02:00
) {
2023-04-16 04:26:50 +02:00
if ( state === undefined || feature === undefined || layer . source === undefined ) {
2022-10-28 04:33:05 +02:00
return undefined
}
const keys = [ . . . args ]
keys . splice ( 0 , 1 )
2023-03-28 05:13:48 +02:00
const featuresToShow : Store < Feature [ ] > = state . indexedFeatures . featuresById . map (
( featuresById ) = > {
2023-04-06 01:33:08 +02:00
if ( featuresById === undefined ) {
return [ ]
}
2023-03-28 05:13:48 +02:00
const properties = tagSource . data
const features : Feature [ ] = [ ]
2022-10-28 04:33:05 +02:00
for ( const key of keys ) {
const value = properties [ key ]
if ( value === undefined || value === null ) {
continue
}
let idList = [ value ]
if ( key !== "id" && value . startsWith ( "[" ) ) {
// This is a list of values
idList = JSON . parse ( value )
}
for ( const id of idList ) {
2023-03-28 05:13:48 +02:00
const feature = featuresById . get ( id )
2022-10-28 04:33:05 +02:00
if ( feature === undefined ) {
console . warn ( "No feature found for id " , id )
continue
}
2023-03-28 05:13:48 +02:00
features . push ( feature )
2022-10-28 04:33:05 +02:00
}
}
return features
2023-03-28 05:13:48 +02:00
} ,
[ tagSource ]
2022-11-02 14:44:06 +01:00
)
2023-03-28 05:13:48 +02:00
const mlmap = new UIEventSource ( undefined )
const mla = new MapLibreAdaptor ( mlmap )
2023-04-21 01:53:24 +02:00
mla . maxzoom . setData ( 17 )
2022-10-28 04:33:05 +02:00
let zoom = 18
if ( args [ 0 ] ) {
const parsed = Number ( args [ 0 ] )
if ( ! isNaN ( parsed ) && parsed > 0 && parsed < 25 ) {
zoom = parsed
}
}
2023-04-16 04:13:09 +02:00
featuresToShow . addCallbackAndRunD ( ( features ) = > {
2023-04-16 04:26:50 +02:00
if ( features . length === 0 ) {
return
}
2023-04-16 04:13:09 +02:00
const bboxGeojson = GeoOperations . bbox ( { features , type : "FeatureCollection" } )
const [ lon , lat ] = GeoOperations . centerpointCoordinates ( bboxGeojson )
mla . bounds . setData ( BBox . get ( bboxGeojson ) )
mla . location . setData ( { lon , lat } )
} )
2023-03-28 05:13:48 +02:00
mla . zoom . setData ( zoom )
mla . allowMoving . setData ( false )
mla . allowZooming . setData ( false )
2022-10-28 04:33:05 +02:00
2023-03-28 05:13:48 +02:00
ShowDataLayer . showMultipleLayers (
mlmap ,
new StaticFeatureSource ( featuresToShow ) ,
state . layout . layers
)
2022-10-28 04:33:05 +02:00
2023-04-16 04:13:09 +02:00
return new SvelteUIElement ( MaplibreMap , { map : mlmap } )
. SetClass ( "h-40 rounded" )
. SetStyle ( "overflow: hidden; pointer-events: none;" )
2022-10-28 04:33:05 +02:00
}
}