MapComplete/src/UI/Popup/MinimapViz.ts

117 lines
4.5 KiB
TypeScript
Raw Normal View History

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"
import { GeoOperations } from "../../Logic/GeoOperations"
import { BBox } from "../../Logic/BBox"
export class MinimapViz implements SpecialVisualization {
funcName = "minimap"
docs = "A small map showing the selected feature."
2023-09-27 22:21:35 +02:00
needsUrls = []
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",
2024-04-24 00:28:29 +02:00
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",
2024-04-24 00:28:29 +02:00
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}`"
2023-03-28 05:13:48 +02:00
constr(
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature
2023-03-28 05:13:48 +02:00
) {
if (state === undefined || feature === undefined) {
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) => {
if (featuresById === undefined) {
return []
}
2023-03-28 05:13:48 +02:00
const properties = tagSource.data
const features: Feature[] = []
for (const key of keys) {
const value = properties[key]
if (value === undefined || value === null) {
continue
}
let idList = [value]
if (Array.isArray(value)) {
idList = value
} else if (
key !== "id" &&
typeof value === "string" &&
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)
if (feature === undefined) {
console.warn("No feature found for id ", id)
continue
}
2023-03-28 05:13:48 +02:00
features.push(feature)
}
}
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)
2024-04-24 00:28:29 +02:00
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
2023-10-06 02:23:24 +02:00
const mla = new MapLibreAdaptor(mlmap, {
2023-10-06 03:34:26 +02:00
rasterLayer: state.mapProperties.rasterLayer,
2024-04-24 00:43:13 +02:00
zoom: new UIEventSource<number>(17),
maxzoom: new UIEventSource<number>(17)
2023-10-06 02:23:24 +02:00
})
2023-03-28 05:13:48 +02:00
2024-04-24 00:28:29 +02:00
mla.allowMoving.setData(false)
mla.allowZooming.setData(false)
mla.location.setData({lon, lat})
if (args[0]) {
const parsed = Number(args[0])
if (!isNaN(parsed) && parsed > 0 && parsed < 25) {
2024-04-24 00:28:29 +02:00
mla.zoom.setData(parsed)
}
}
2024-04-24 00:28:29 +02:00
mlmap.addCallbackAndRun(map => console.log("Map for minimap vis is now", map))
2023-03-28 05:13:48 +02:00
ShowDataLayer.showMultipleLayers(
mlmap,
new StaticFeatureSource(featuresToShow),
2024-04-24 00:28:29 +02:00
state.layout.layers,
{zoomToFeatures: true}
2023-03-28 05:13:48 +02:00
)
2024-04-13 02:40:21 +02:00
return new SvelteUIElement(MaplibreMap, {
interactive: false,
map: mlmap,
2024-04-24 00:28:29 +02:00
mapProperties: mla
2024-04-13 02:40:21 +02:00
})
.SetClass("h-40 rounded")
.SetStyle("overflow: hidden; pointer-events: none;")
}
}