diff --git a/langs/en.json b/langs/en.json index 270b42ff3..627b652bc 100644 --- a/langs/en.json +++ b/langs/en.json @@ -192,6 +192,13 @@ "customThemeIntro": "These are previously visited user-generated themes.", "customThemeTitle": "Custom themes", "download": { + "custom": { + "download": "Download PNG of {width}mm wide and {height}mm high", + "downloadHelper": "This is meant for print", + "height": "Image height (in mm):", + "title": "Download an image with a custom width and height", + "width": "Image width (in mm): " + }, "downloadAsPdf": "Download a PDF of the current map", "downloadAsPdfHelper": "Ideal to print the current map", "downloadAsPng": "Download as image", diff --git a/src/Models/ThemeConfig/Json/LineRenderingConfigJson.ts b/src/Models/ThemeConfig/Json/LineRenderingConfigJson.ts index 8294a0618..8c2ae5672 100644 --- a/src/Models/ThemeConfig/Json/LineRenderingConfigJson.ts +++ b/src/Models/ThemeConfig/Json/LineRenderingConfigJson.ts @@ -38,7 +38,7 @@ export default interface LineRenderingConfigJson { /** * question: Should a dasharray be used to render the lines? * The dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap, ...'. For example, `5 6` will be 5 pixels of line followed by a 6 pixel gap. - * Cannot be a dynamic property due to a mapbox limitation + * Cannot be a dynamic property due to a MapLibre limitation (see https://github.com/maplibre/maplibre-gl-js/issues/1235) * ifunset: Ways are rendered with a full line */ dashArray?: string diff --git a/src/Models/ThemeConfig/LineRenderingConfig.ts b/src/Models/ThemeConfig/LineRenderingConfig.ts index 260ab6414..57897166f 100644 --- a/src/Models/ThemeConfig/LineRenderingConfig.ts +++ b/src/Models/ThemeConfig/LineRenderingConfig.ts @@ -7,7 +7,7 @@ import { TagsFilter } from "../../Logic/Tags/TagsFilter" export default class LineRenderingConfig extends WithContextLoader { public readonly color: TagRenderingConfig public readonly width: TagRenderingConfig - public readonly dashArray: TagRenderingConfig + public readonly dashArray: string public readonly lineCap: TagRenderingConfig public readonly offset: TagRenderingConfig public readonly fill: TagRenderingConfig @@ -19,7 +19,7 @@ export default class LineRenderingConfig extends WithContextLoader { super(json, context) this.color = this.tr("color", "#0000ff") this.width = this.tr("width", "7") - this.dashArray = this.tr("dashArray", "") + this.dashArray = json.dashArray this.lineCap = this.tr("lineCap", "round") this.fill = this.tr("fill", undefined) this.fillColor = this.tr("fillColor", undefined) diff --git a/src/UI/DownloadFlow/DownloadPanel.svelte b/src/UI/DownloadFlow/DownloadPanel.svelte index 2385f6e04..56fdea15e 100644 --- a/src/UI/DownloadFlow/DownloadPanel.svelte +++ b/src/UI/DownloadFlow/DownloadPanel.svelte @@ -8,6 +8,10 @@ import { SvgToPdf } from "../../Utils/svgToPdf" import ThemeViewState from "../../Models/ThemeViewState" import DownloadPdf from "./DownloadPdf.svelte" + import { PngMapCreator } from "../../Utils/pngMapCreator" + import { UIEventSource } from "../../Logic/UIEventSource" + import ValidatedInput from "../InputElement/ValidatedInput.svelte" + import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource" export let state: ThemeViewState let isLoading = state.dataIsLoading @@ -34,9 +38,21 @@ mapExtent: state.mapProperties.bounds.data, width: maindiv.offsetWidth, height: maindiv.offsetHeight, - noSelfIntersectingLines, + noSelfIntersectingLines }) } + + let customWidth = LocalStorageSource.Get("custom-png-width", "20") + let customHeight = LocalStorageSource.Get("custom-png-height", "20") + + async function offerCustomPng(): Promise { + console.log("Creating a custom size png with dimensions", customWidth.data + "mm *", customHeight.data + "mm") + const creator = new PngMapCreator(state, { + height: Number(customHeight.data), width: Number(customWidth.data) + }) + return await creator.CreatePng("belowmap") + } + {#if $isLoading} @@ -107,5 +123,26 @@ {/each} +
+

+

+
+ + +
+
+ + +
+ offerCustomPng()} + {state} + mimetype="image/png" + /> +
+ {/if} diff --git a/src/UI/Map/MapLibreAdaptor.ts b/src/UI/Map/MapLibreAdaptor.ts index 933775e34..de753d910 100644 --- a/src/UI/Map/MapLibreAdaptor.ts +++ b/src/UI/Map/MapLibreAdaptor.ts @@ -357,7 +357,8 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap { const targetW = Math.max(element.getBoundingClientRect().width * 4, ...labels.map(l => l.getBoundingClientRect().width)) const targetH = element.getBoundingClientRect().height + - Math.max(...labels.map(l => l.getBoundingClientRect().height)) + Math.max(...labels.map(l => l.getBoundingClientRect().height * 2 /* A bit of buffer to catch eventual 'margin-top'*/)) + // Force a wider view for icon badges element.style.width = targetW + "px" // Force more height to include labels diff --git a/src/UI/Map/ShowDataLayer.ts b/src/UI/Map/ShowDataLayer.ts index 700bd28b6..3079740b4 100644 --- a/src/UI/Map/ShowDataLayer.ts +++ b/src/UI/Map/ShowDataLayer.ts @@ -351,7 +351,8 @@ class LineRenderingLayer { "line-color": ["feature-state", "color"], "line-opacity": ["feature-state", "color-opacity"], "line-width": ["feature-state", "width"], - "line-offset": ["feature-state", "offset"] + "line-offset": ["feature-state", "offset"], + "line-dasharray": this._config.dashArray?.split(" ")?.map(s => Number(s)) }, layout: { "line-cap": "round" diff --git a/src/Utils/pngMapCreator.ts b/src/Utils/pngMapCreator.ts index cb115a148..d96b3a2c8 100644 --- a/src/Utils/pngMapCreator.ts +++ b/src/Utils/pngMapCreator.ts @@ -67,7 +67,6 @@ export class PngMapCreator { const newZoom = settings.zoom.data + Math.log2(pixelRatio) - 1 const rasterLayerProperties = settings.rasterLayer.data?.properties ?? AvailableRasterLayers.defaultBackgroundLayer.properties const style = rasterLayerProperties?.style ?? rasterLayerProperties?.url -console.log("Png-map-creator: initing MlMap with style", style, rasterLayerProperties) const mapElem = new MlMap({ container: div.id, style,