diff --git a/langs/ca.json b/langs/ca.json
index 4178af93c..160df95aa 100644
--- a/langs/ca.json
+++ b/langs/ca.json
@@ -186,10 +186,7 @@
"includeMetaData": "Incloure metadades (darrer editor, valors calculats, ...)",
"licenseInfo": "
Avís de drets de còpia Les dades proveïdes estan sota ODbL. Es poden reutilitzar de forma gratuïta, però l'atribució a © Contribuïdors d'OpenStreetMap s'ha de mostrar Qualsevol canvi s'ha de publicar sota la mateixa llicència Llegeix sencer l'avís de drets de còpia per més detalls.",
"noDataLoaded": "No s'han carregat dades. La baixada estarà disponible aviat",
- "pdf": {
- "current_view_a3": "Exporta un PDF (A3, vertical) de la vista actual",
- "current_view_a4": "Exporta un PDF (A4, horitzontal) de la vista actual"
- },
+ "pdf": {},
"title": "Descarrega",
"uploadGpx": "Pujar la teva traça a OpenStreetMap"
},
diff --git a/langs/cs.json b/langs/cs.json
index b13b7a81c..d2e244343 100644
--- a/langs/cs.json
+++ b/langs/cs.json
@@ -186,10 +186,7 @@
"includeMetaData": "Zahrnout metadata (poslední editor, vypočtené hodnoty, ...)",
"licenseInfo": "Upozornění na autorská práva Poskytovaná data jsou dostupná pod ODbL. Opětovné použití je zdarma pro jakýkoli účel, ale musí být uveden zdroj © přispěvatelé OpenStreetMap Jakákoli změna musí být publikována pod stejnou licencí < /ul> Podrobnosti naleznete v úplném upozornění na autorská práva .",
"noDataLoaded": "Zatím nejsou načtena žádná data. Brzy bude k dispozici ke stažení",
- "pdf": {
- "current_view_a3": "Export aktuálního zobrazení do formátu PDF (A3, na výšku)",
- "current_view_a4": "Export aktuálního zobrazení do formátu PDF (A4, na šířku)"
- },
+ "pdf": {},
"title": "Stáhnout",
"uploadGpx": "Nahrajte svou trasu do OpenStreetMap"
},
diff --git a/langs/de.json b/langs/de.json
index db6deaa5f..7ad20cda6 100644
--- a/langs/de.json
+++ b/langs/de.json
@@ -188,10 +188,7 @@
"includeMetaData": "Metadaten übernehmen (letzter Bearbeiter, berechnete Werte, ...)",
"licenseInfo": "Copyright-Hinweis Die bereitgestellten Daten sind unter ODbL verfügbar. Die Wiederverwendung ist für jeden Zweck frei, aber die Namensnennung © OpenStreetMap contributors ist darzustellen Jede Änderung muss unter der gleichen Lizenz veröffentlicht werden Bitte lesen Sie den vollständigen Copyright-Hinweis für weitere Details.",
"noDataLoaded": "Noch keine Daten geladen. Download in Kürze verfügbar",
- "pdf": {
- "current_view_a3": "PDF (A3, Hochformat) der aktuellen Ansicht exportieren",
- "current_view_a4": "PDF (A4, Querformat) der aktuellen Ansicht exportieren"
- },
+ "pdf": {},
"title": "Download",
"uploadGpx": "Einen Track auf OpenStreetMap hochladen"
},
diff --git a/langs/en.json b/langs/en.json
index 517f735ba..76a866620 100644
--- a/langs/en.json
+++ b/langs/en.json
@@ -189,8 +189,7 @@
"licenseInfo": "Copyright notice The provided data is available under ODbL. Reusing it is gratis for any purpose, but the attribution © OpenStreetMap contributors must be shown Any change must be published under the same license Please read the full copyright notice for details.",
"noDataLoaded": "No data is loaded yet. Download will be available soon",
"pdf": {
- "current_view_a3": "Export a PDF (A3, portrait) of the current view",
- "current_view_a4": "Export a PDF (A4, landscape) of the current view"
+ "current_view_generic": "Export a PDF off the current view for {paper_size} in {orientation} orientation"
},
"title": "Download",
"uploadGpx": "Upload your track to OpenStreetMap"
diff --git a/langs/nl.json b/langs/nl.json
index e5295c36e..178893e8d 100644
--- a/langs/nl.json
+++ b/langs/nl.json
@@ -186,10 +186,7 @@
"includeMetaData": "Exporteer metadata (zoals laatste aanpassing, berekende waardes, …)",
"licenseInfo": "Copyright De voorziene data is beschikbaar onder de ODbL. Het hergebruiken van deze data is gratis voor elke toepassing, maar de bronvermelding © OpenStreetMap bijdragers is vereist Elke wijziging aan deze data moet opnieuw gepubliceerd worden onder dezelfde licentie Gelieve de volledige licentie te lezen voor details",
"noDataLoaded": "Er is nog geen data ingeladen. Downloaden kan zodra de data geladen is.",
- "pdf": {
- "current_view_a3": "Exporteer de zichtbare regio als PDF (A3, staand)",
- "current_view_a4": "Exporteer de zichtbare regio als PDF (A4, liggend)"
- },
+ "pdf": {},
"title": "Download",
"uploadGpx": "Track uploaden naar OpenStreetMap"
},
diff --git a/langs/pl.json b/langs/pl.json
index 9ffa00e7b..46be4e416 100644
--- a/langs/pl.json
+++ b/langs/pl.json
@@ -186,10 +186,7 @@
"includeMetaData": "Dołącz metadane (ostatni edytor, obliczone wartości, ...)",
"licenseInfo": "Informacja o prawach autorskich Podane dane są dostępne na licencji ODbL. Ponowne użycie jest darmowe, ale musi być podane źródło © autorzy OpenStreetMap Jakakolwiek zmiana musi być opublikowana na tej samej licencji. Proszę przeczytać pełną informację o prawach autorskich dla szczegółów.",
"noDataLoaded": "Nie załadowano jeszcze żadnych danych. Pobranie będzie wkrótce dostępne",
- "pdf": {
- "current_view_a3": "Eksportuj PDF (A3, pionowy) obecnego widoku",
- "current_view_a4": "Eksportuj PDF (A4, poziomy) obecnego widoku"
- },
+ "pdf": {},
"title": "Pobierz",
"uploadGpx": "Prześlij swój ślad do OpenStreetMap"
},
diff --git a/package-lock.json b/package-lock.json
index e8378f401..92308eaa6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "mapcomplete",
- "version": "0.34.4",
+ "version": "0.34.7",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "mapcomplete",
- "version": "0.34.4",
+ "version": "0.34.7",
"license": "GPL-3.0-or-later",
"dependencies": {
"@rgossiaux/svelte-headlessui": "^1.0.2",
@@ -19,6 +19,7 @@
"@turf/length": "^6.5.0",
"@turf/turf": "^6.5.0",
"@types/dompurify": "^3.0.2",
+ "@types/qrcode-generator": "^1.0.6",
"@types/showdown": "^2.0.0",
"chart.js": "^3.8.0",
"country-language": "^0.1.7",
@@ -49,6 +50,7 @@
"papaparse": "^5.3.1",
"pic4carto": "^2.1.15",
"prompt-sync": "^4.2.0",
+ "qrcode-generator": "^1.4.4",
"showdown": "^2.1.0",
"svg-path-parser": "^1.1.0",
"tailwind-merge": "^1.13.1",
@@ -3914,6 +3916,15 @@
"integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==",
"dev": true
},
+ "node_modules/@types/qrcode-generator": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/qrcode-generator/-/qrcode-generator-1.0.6.tgz",
+ "integrity": "sha512-XasuPjhHBC4hyOJ/pHaUNTj+tNxA1SyZpXaS/FOUxEVX03D1gFM8UmMKSIs+pPHLAmRZpU6j9KYxvo+lfsvhKw==",
+ "deprecated": "This is a stub types definition for qrcode-generator (https://github.com/kazuhikoarase/qrcode-generator). qrcode-generator provides its own type definitions, so you don't need @types/qrcode-generator installed!",
+ "dependencies": {
+ "qrcode-generator": "*"
+ }
+ },
"node_modules/@types/raf": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz",
@@ -9985,6 +9996,11 @@
"node": ">=6"
}
},
+ "node_modules/qrcode-generator": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz",
+ "integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw=="
+ },
"node_modules/qs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
@@ -16280,6 +16296,14 @@
"integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==",
"dev": true
},
+ "@types/qrcode-generator": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/qrcode-generator/-/qrcode-generator-1.0.6.tgz",
+ "integrity": "sha512-XasuPjhHBC4hyOJ/pHaUNTj+tNxA1SyZpXaS/FOUxEVX03D1gFM8UmMKSIs+pPHLAmRZpU6j9KYxvo+lfsvhKw==",
+ "requires": {
+ "qrcode-generator": "*"
+ }
+ },
"@types/raf": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz",
@@ -20740,6 +20764,11 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
},
+ "qrcode-generator": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz",
+ "integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw=="
+ },
"qs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
diff --git a/package.json b/package.json
index a0a0d9371..539a9061b 100644
--- a/package.json
+++ b/package.json
@@ -105,6 +105,7 @@
"@turf/length": "^6.5.0",
"@turf/turf": "^6.5.0",
"@types/dompurify": "^3.0.2",
+ "@types/qrcode-generator": "^1.0.6",
"@types/showdown": "^2.0.0",
"chart.js": "^3.8.0",
"country-language": "^0.1.7",
@@ -135,6 +136,7 @@
"papaparse": "^5.3.1",
"pic4carto": "^2.1.15",
"prompt-sync": "^4.2.0",
+ "qrcode-generator": "^1.4.4",
"showdown": "^2.1.0",
"svg-path-parser": "^1.1.0",
"tailwind-merge": "^1.13.1",
diff --git a/public/assets/templates/CurrentMapWithHeaderA4.svg b/public/assets/templates/CurrentMapWithHeaderA4.svg
index bb34e1552..14305013a 100644
--- a/public/assets/templates/CurrentMapWithHeaderA4.svg
+++ b/public/assets/templates/CurrentMapWithHeaderA4.svg
@@ -7,7 +7,7 @@
viewBox="0 0 297 210"
version="1.1"
id="svg5"
- inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ inkscape:version="1.3 (1:1.3+202307231459+0e150ed6c4)"
sodipodi:docname="CurrentMapWithHeaderA4.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
@@ -15,6 +15,12 @@
xmlns:svg="http://www.w3.org/2000/svg">
+
+
+
+
+ inkscape:snap-global="false"
+ inkscape:showpageshadow="0"
+ inkscape:deskcolor="#d1d1d1" />
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect4913);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect10255);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
-
+ id="tspan1">
+ style="font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;white-space:pre;shape-inside:url(#rect19138);display:inline;fill:#000000;stroke:#000000;stroke-width:0.377953;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
$general.pdf.versionInfo
+ id="tspan22">$general.pdf.versionInfo
$general.pdf.attr
- $general.pdf.attr
$general.pdf.attrBackground
- $general.pdf.attrBackground
$general.pdf.generatedWith
+ id="tspan28">$general.pdf.generatedWith
$map(current)
+ id="tspan30">$map(current)
$img(layouticon)
+ id="tspan32">
$img(layouticon)
+
+ $img(qr)
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect62798);display:inline;fill:#000000;fill-opacity:1;stroke:none" />
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect81706);display:inline;fill:#000000;fill-opacity:1;stroke:none" />
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;line-height:1.05;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;white-space:pre;shape-inside:url(#rect20599);display:inline;fill:#000000;stroke-width:3.77953;stroke-linecap:round;stroke-linejoin:round" />
${title}
+ id="tspan37">${title}
diff --git a/public/assets/templates/CurrentMapWithHeaderA3.svg b/public/assets/templates/CurrentMapWithHeader_A3_Landscape.svg
similarity index 61%
rename from public/assets/templates/CurrentMapWithHeaderA3.svg
rename to public/assets/templates/CurrentMapWithHeader_A3_Landscape.svg
index 3aa1102d6..954c2c4d9 100644
--- a/public/assets/templates/CurrentMapWithHeaderA3.svg
+++ b/public/assets/templates/CurrentMapWithHeader_A3_Landscape.svg
@@ -2,19 +2,25 @@
+
+ inkscape:snap-global="false"
+ inkscape:showpageshadow="0"
+ inkscape:deskcolor="#d1d1d1" />
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect4913);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect10255);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
$map(current)
+ id="tspan1">$map(current)
$general.pdf.attr
- $general.pdf.attr
$general.pdf.attrBackground
- $general.pdf.attrBackground
$general.pdf.generatedWith
-
+ y="31.434374"
+ id="tspan23">
$general.pdf.generatedWith
+ style="font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;white-space:pre;shape-inside:url(#rect19138);display:inline;fill:#000000;stroke:#000000;stroke-width:0.377953;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
$general.pdf.versionInfo
+ id="tspan28">$general.pdf.versionInfo
$img(layouticon)
+ id="tspan30">$img(layouticon)
+
+ $img(qr)
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect62798);display:inline;fill:#000000;fill-opacity:1;stroke:none" />
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect81706);display:inline;fill:#000000;fill-opacity:1;stroke:none" />
${title}
+ id="tspan33">${title}
+ sodipodi:role="line"
+ id="tspan53307"
+ style="stroke-width:0.264583"
+ x="105.86118"
+ y="116.25558" />
diff --git a/public/assets/templates/CurrentMapWithHeader_A3_Portrait.svg b/public/assets/templates/CurrentMapWithHeader_A3_Portrait.svg
new file mode 100644
index 000000000..45c0fa501
--- /dev/null
+++ b/public/assets/templates/CurrentMapWithHeader_A3_Portrait.svg
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $map(current)
+ $general.pdf.attr
+ $general.pdf.attrBackground
+ $general.pdf.generatedWith
+
+
+ $general.pdf.versionInfo
+
+ $img(layouticon)
+
+
+
+
+ $img(qr)
+
+
+
+
+
+ ${title}
+
+
+
+
diff --git a/src/UI/DownloadFlow/DownloadPdf.svelte b/src/UI/DownloadFlow/DownloadPdf.svelte
index 77e043c0f..1a6255e30 100644
--- a/src/UI/DownloadFlow/DownloadPdf.svelte
+++ b/src/UI/DownloadFlow/DownloadPdf.svelte
@@ -11,14 +11,11 @@
import Locale from "../i18n/Locale"
import { UIEventSource } from "../../Logic/UIEventSource"
import DownloadHelper from "./DownloadHelper"
+ import Qr from "../../Utils/Qr";
export let templateName: string
export let state: ThemeViewState
const template: PdfTemplateInfo = SvgToPdf.templates[templateName]
- let mainText: Translation =
- typeof template.description === "string"
- ? new Translation(template.description)
- : template.description
let t = Translations.t.general.download
const downloadHelper = new DownloadHelper(state)
@@ -32,8 +29,14 @@
const creator = new SvgToPdf(title, templates, {
state,
freeComponentId: "belowmap",
- createImage: (key: string, width: string, height: string) =>
- downloadHelper.createImage(key, width, height),
+ createImage: (key: string, width: string, height: string) => {
+ console.log("Creating an image for key", key)
+ if(key === "qr"){
+ const toShare = window.location.href.split("#")[0]
+ return new Qr(toShare).toImageElement(parseFloat(width), parseFloat(height))
+ }
+ return downloadHelper.createImage(key, width, height);
+ },
textSubstitutions: >{
"layout.title": state.layout.title,
layoutid: state.layout.id,
@@ -59,7 +62,7 @@
extension="pdf"
helperText={t.downloadAsPdfHelper}
metaIsIncluded={false}
- {mainText}
+ mainText={t.pdf.current_view_generic.Subs({orientation: template.orientation, paper_size: template.format.toUpperCase()})}
mimetype="application/pdf"
{state}
/>
diff --git a/src/Utils/Qr.ts b/src/Utils/Qr.ts
new file mode 100644
index 000000000..55be7626a
--- /dev/null
+++ b/src/Utils/Qr.ts
@@ -0,0 +1,26 @@
+import Qrcode from "qrcode-generator"
+
+/**
+ * Creates a QR-code as Blob
+ */
+export default class Qr {
+ private _textToShow: string
+
+ constructor(textToShow: string) {
+ this._textToShow = textToShow
+ }
+
+ public toImageElement(totalSize: number): string {
+ console.log("Creating a QR code for", this._textToShow)
+ const typeNumber = 0
+ const errorCorrectionLevel = "L"
+ const qr = Qrcode(typeNumber, errorCorrectionLevel)
+ qr.addData(this._textToShow)
+ qr.make()
+ const moduleCount = qr.getModuleCount()
+ const img = document.createElement("img")
+ const cellSize = Math.round(totalSize / moduleCount)
+ console.log("Cellsize", cellSize)
+ return qr.createDataURL(cellSize)
+ }
+}
diff --git a/src/Utils/pngMapCreator.ts b/src/Utils/pngMapCreator.ts
index 9df52fc66..d0ba245f7 100644
--- a/src/Utils/pngMapCreator.ts
+++ b/src/Utils/pngMapCreator.ts
@@ -73,6 +73,8 @@ export class PngMapCreator {
pixelRatio,
})
+ console.log("Creating a map with size", this._options.width, this._options.height)
+
const map = new UIEventSource(mapElem)
const mla = new MapLibreAdaptor(map)
mla.zoom.setData(newZoom)
@@ -81,10 +83,10 @@ export class PngMapCreator {
mla.allowZooming.setData(false)
mla.allowMoving.setData(false)
- this._state?.showNormalDataOn(map)
- console.log("Creating a map with size", this._options.width, this._options.height)
-
setState("Waiting for the data")
+ this._state?.showNormalDataOn(map)
+ setState("Waiting for the data")
+
await this._state.dataIsLoading.AsPromise((loading) => !loading)
setState("Waiting for styles to be fully loaded")
while (!map?.data?.isStyleLoaded()) {
diff --git a/src/Utils/svgToPdf.ts b/src/Utils/svgToPdf.ts
index de26d92fb..d4ff238e6 100644
--- a/src/Utils/svgToPdf.ts
+++ b/src/Utils/svgToPdf.ts
@@ -313,6 +313,9 @@ class SvgToPdfInternals {
console.log("Creating image with key", key, "searching rect in", x, y)
const rectangle: SVGRectElement = this.page.findSmallestRectContaining(x, y, false)
console.log("Got rect", rectangle)
+ if (!rectangle) {
+ throw new Error("No rectangle found for tspan with text:" + txt)
+ }
const w = SvgToPdfInternals.attrNumber(rectangle, "width")
const h = SvgToPdfInternals.attrNumber(rectangle, "height")
x = SvgToPdfInternals.attrNumber(rectangle, "x")
@@ -320,23 +323,25 @@ class SvgToPdfInternals {
// Actually, dots per mm, not dots per inch ;)
const dpi = 60
+
const img = this.page.options.createImage(key, dpi * w + "px", dpi * h + "px")
-
- const canvas = document.createElement("canvas")
- const ctx = canvas.getContext("2d")
-
- canvas.width = w * dpi
- canvas.height = h * dpi
- img.style.width = `${w * dpi}px`
- img.style.height = `${h * dpi}px`
-
- ctx.drawImage(img, 0, 0, w * dpi, h * dpi)
- const base64img = canvas.toDataURL("image/png")
- // Don't ask me why this magicFactor transformation is needed - but it works
- const magicFactor = 3.8
- this.addMatrix(this.doc.Matrix(1 / magicFactor, 0, 0, 1 / magicFactor, 0, 0))
- this.doc.addImage(base64img, "png", x, y, w, h)
- this.undoTransform()
+ if (typeof img === "string") {
+ this.doc.addImage(img, "png", x, y, w, h)
+ } else {
+ const canvas = document.createElement("canvas")
+ canvas.width = w * dpi
+ canvas.height = h * dpi
+ const ctx = canvas.getContext("2d")
+ img.style.width = `${w * dpi}px`
+ img.style.height = `${h * dpi}px`
+ ctx.drawImage(img, 0, 0, w * dpi, h * dpi)
+ const base64img = canvas.toDataURL("image/png")
+ // Don't ask me why this magicFactor transformation is needed - but it works
+ const magicFactor = 3.8
+ this.addMatrix(this.doc.Matrix(1 / magicFactor, 0, 0, 1 / magicFactor, 0, 0))
+ this.doc.addImage(base64img, "png", x, y, w, h)
+ this.undoTransform()
+ }
this.usedRectangles.add(rectangle.id)
return
}
@@ -557,7 +562,7 @@ export interface SvgToPdfOptions {
*/
state?: ThemeViewState
- createImage(key: string, width: string, height: string): HTMLImageElement
+ createImage(key: string, width: string, height: string): HTMLImageElement | string
}
class SvgToPdfPage {
@@ -1002,7 +1007,13 @@ export interface PdfTemplateInfo {
export class SvgToPdf {
public static readonly templates: Record<
- "flyer_a4" | "poster_a3" | "poster_a2" | "current_view_a4" | "current_view_a3",
+ | "flyer_a4"
+ | "poster_a3"
+ | "poster_a2"
+ | "current_view_a4"
+ | "current_view_a3_portrait"
+ | "current_view_a3_landscape"
+ | "current_view_a2_landscape",
PdfTemplateInfo
> = {
flyer_a4: {
@@ -1037,10 +1048,17 @@ export class SvgToPdf {
isPublic: true,
},
- current_view_a3: {
+ current_view_a3_landscape: {
+ format: "a3",
+ orientation: "landscape",
+ pages: ["./assets/templates/CurrentMapWithHeader_A3_Landscape.svg"],
+ description: Translations.t.general.download.pdf.current_view_a3,
+ isPublic: true,
+ },
+ current_view_a3_portrait: {
format: "a3",
orientation: "portrait",
- pages: ["./assets/templates/CurrentMapWithHeaderA3.svg"],
+ pages: ["./assets/templates/CurrentMapWithHeader_A3_Portrait.svg"],
description: Translations.t.general.download.pdf.current_view_a3,
isPublic: true,
},
diff --git a/src/test.ts b/src/test.ts
index 2f3513167..9888008ee 100644
--- a/src/test.ts
+++ b/src/test.ts
@@ -3,44 +3,17 @@ import SvelteUIElement from "./UI/Base/SvelteUIElement"
import PointRenderingConfig from "./Models/ThemeConfig/PointRenderingConfig"
import { UIEventSource } from "./Logic/UIEventSource"
import Marker from "./UI/Map/Marker.svelte"
-
-class Test {
- public async test() {
- await Utils.waitFor(0)
- const response = await fetch("http://localhost:1235/layers/atm/atm.json", {
- method: "POST",
- headers: {
- "Content-Type": "application/json;charset=utf-8",
- },
- body: JSON.stringify({}),
- })
- }
+import Qrcode from "qrcode-generator"
+import { FixedUiElement } from "./UI/Base/FixedUiElement"
+function generateQr(message: string, attachTo: string) {
+ const typeNumber = 0
+ const errorCorrectionLevel = "L"
+ const qr = Qrcode(typeNumber, errorCorrectionLevel)
+ qr.addData(message)
+ qr.make()
+ document.getElementById(attachTo).innerHTML = qr.createImgTag()
}
-
-const tags = new UIEventSource({
- id: "node/13",
- amenity: "public_bookcase",
-})
-
-const config = new PointRenderingConfig(
- {
- location: ["point"],
- iconSize: "20,20",
- marker: [
- {
- icon: "circle",
- color: "orange",
- },
- {
- icon: "./assets/layers/atm.atm.svg",
- },
- ],
- },
- "test"
+generateQr(
+ "http://127.0.0.1:1234/theme.html?layout=cyclofix&z=14&lat=51.21571770000094&lon=3.219866599996749&layer-range=true&layer-gps_location=false#theme-menu:download",
+ "qr"
)
-
-new SvelteUIElement(Marker, {
- config,
- tags,
-}).AttachTo("maindiv")
-// new Test().test()