refactoring(maplibre): add pointRendering

This commit is contained in:
Pieter Vander Vennet 2023-03-23 00:58:21 +01:00
parent 4f2bbf4b54
commit 1b3609b13f
10 changed files with 316 additions and 122 deletions

View file

@ -2,6 +2,8 @@ import { Feature, Polygon } from "geojson"
import * as editorlayerindex from "../assets/editor-layer-index.json"
import * as globallayers from "../assets/global-raster-layers.json"
import { BBox } from "../Logic/BBox"
import { Store, Stores } from "../Logic/UIEventSource"
import { GeoOperations } from "../Logic/GeoOperations"
export class AvailableRasterLayers {
public static EditorLayerIndex: (Feature<Polygon, EditorLayerIndexProperties> &
@ -33,6 +35,35 @@ export class AvailableRasterLayers {
properties: AvailableRasterLayers.osmCartoProperties,
geometry: BBox.global.asGeometry(),
}
public static layersAvailableAt(
location: Store<{ lon: number; lat: number }>
): Store<RasterLayerPolygon[]> {
const availableLayersBboxes = Stores.ListStabilized(
location.mapD((loc) => {
const lonlat: [number, number] = [loc.lon, loc.lat]
return AvailableRasterLayers.EditorLayerIndex.filter((eliPolygon) =>
BBox.get(eliPolygon).contains(lonlat)
)
})
)
const available = Stores.ListStabilized(
availableLayersBboxes.map((eliPolygons) => {
const loc = location.data
const lonlat: [number, number] = [loc.lon, loc.lat]
const matching: RasterLayerPolygon[] = eliPolygons.filter((eliPolygon) => {
if (eliPolygon.geometry === null) {
return true // global ELI-layer
}
return GeoOperations.inside(lonlat, eliPolygon)
})
matching.unshift(AvailableRasterLayers.osmCarto)
matching.push(...AvailableRasterLayers.globalLayers)
return matching
})
)
return available
}
}
export class RasterLayerUtils {

View file

@ -5,12 +5,13 @@ import { TagUtils } from "../../Logic/Tags/TagUtils"
import { Utils } from "../../Utils"
import Svg from "../../Svg"
import WithContextLoader from "./WithContextLoader"
import { UIEventSource } from "../../Logic/UIEventSource"
import { Store } from "../../Logic/UIEventSource"
import BaseUIElement from "../../UI/BaseUIElement"
import { FixedUiElement } from "../../UI/Base/FixedUiElement"
import Img from "../../UI/Base/Img"
import Combine from "../../UI/Base/Combine"
import { VariableUiElement } from "../../UI/Base/VariableUIElement"
import { OsmTags } from "../OsmFeature"
export default class PointRenderingConfig extends WithContextLoader {
private static readonly allowed_location_codes = new Set<string>([
@ -164,7 +165,7 @@ export default class PointRenderingConfig extends WithContextLoader {
return PointRenderingConfig.FromHtmlMulti(htmlDefs, rotation, false, defaultPin)
}
public GetSimpleIcon(tags: UIEventSource<any>): BaseUIElement {
public GetSimpleIcon(tags: Store<OsmTags>): BaseUIElement {
const self = this
if (this.icon === undefined) {
return undefined
@ -175,7 +176,7 @@ export default class PointRenderingConfig extends WithContextLoader {
}
public GenerateLeafletStyle(
tags: UIEventSource<any>,
tags: Store<OsmTags>,
clickable: boolean,
options?: {
noSize?: false | boolean
@ -183,11 +184,7 @@ export default class PointRenderingConfig extends WithContextLoader {
}
): {
html: BaseUIElement
iconSize: [number, number]
iconAnchor: [number, number]
popupAnchor: [number, number]
iconUrl: string
className: string
} {
function num(str, deflt = 40) {
const n = Number(str)
@ -211,20 +208,21 @@ export default class PointRenderingConfig extends WithContextLoader {
let iconH = num(iconSize[1])
const mode = iconSize[2]?.trim()?.toLowerCase() ?? "center"
let anchorW = iconW / 2
// in MapLibre, the offset is relative to the _center_ of the object, with left = [-x, 0] and up = [0,-y]
let anchorW = 0
let anchorH = iconH / 2
if (mode === "left") {
anchorW = 0
anchorW = -iconW / 2
}
if (mode === "right") {
anchorW = iconW
anchorW = iconW / 2
}
if (mode === "top") {
anchorH = 0
anchorH = -iconH / 2
}
if (mode === "bottom") {
anchorH = iconH
anchorH = iconH / 2
}
const icon = this.GetSimpleIcon(tags)
@ -264,15 +262,11 @@ export default class PointRenderingConfig extends WithContextLoader {
}
return {
html: htmlEl,
iconSize: [iconW, iconH],
iconAnchor: [anchorW, anchorH],
popupAnchor: [0, 3 - anchorH],
iconUrl: undefined,
className: clickable ? "leaflet-div-icon" : "leaflet-div-icon unclickable",
}
}
private GetBadges(tags: UIEventSource<any>): BaseUIElement {
private GetBadges(tags: Store<OsmTags>): BaseUIElement {
if (this.iconBadges.length === 0) {
return undefined
}
@ -304,7 +298,7 @@ export default class PointRenderingConfig extends WithContextLoader {
).SetClass("absolute bottom-0 right-1/3 h-1/2 w-0")
}
private GetLabel(tags: UIEventSource<any>): BaseUIElement {
private GetLabel(tags: Store<OsmTags>): BaseUIElement {
if (this.label === undefined) {
return undefined
}