diff --git a/UI/ExportPDF.ts b/UI/ExportPDF.ts index a2aecec61..fd431eb91 100644 --- a/UI/ExportPDF.ts +++ b/UI/ExportPDF.ts @@ -20,6 +20,8 @@ import BaseLayer from "../Models/BaseLayer"; import LayoutConfig from "../Customizations/JSON/LayoutConfig"; import {FixedUiElement} from "./Base/FixedUiElement"; import Translations from "./i18n/Translations"; +import State from "../State"; +import Constants from "../Models/Constants"; export default class ExportPDF { // dimensions of the map in milimeter @@ -100,7 +102,7 @@ export default class ExportPDF { } private cleanup() { - new FixedUiElement("Screenshot taken!").AttachTo(this.freeDivId) + // new FixedUiElement("Screenshot taken!").AttachTo(this.freeDivId) this._screenhotTaken = true; } @@ -124,28 +126,67 @@ export default class ExportPDF { doc.setDrawColor(255, 255, 255) doc.setFillColor(255, 255, 255) - doc.roundedRect(12, 5, 125, 30, 5, 5, 'FD') + doc.roundedRect(12, 10, 145, 25, 5, 5, 'FD') doc.setFontSize(20) - doc.text(layout.title.txt, 40, 20, { - maxWidth: 100 + doc.textWithLink(layout.title.txt, 40, 18.5, { + maxWidth: 125, + url: window.location.href }) doc.setFontSize(10) - doc.text(t.attr.txt, 40, 25, { - maxWidth: 100 + doc.text(t.generatedWith.txt, 40, 23, { + maxWidth: 125 }) + const backgroundLayer : BaseLayer = State.state.backgroundLayer.data + const attribution = new FixedUiElement(backgroundLayer.layer().getAttribution() ?? backgroundLayer.name).ConstructElement().innerText + doc.textWithLink(t.attr.txt, 40, 26.5, { + maxWidth: 125, + url: "https://www.openstreetmap.org/copyright" + }) + + doc.text(t.attrBackground.Subs({ + background: attribution + }).txt, 40, 30) + + let date = new Date().toISOString().substr(0,16) + + doc.setFontSize(7) + doc.text(t.versionInfo.Subs({ + version: Constants.vNumber, + date: date + }).txt, 40, 34, { + maxWidth: 125 + }) + // Add the logo of the layout let img = document.createElement('img'); const imgSource = layout.icon + const imgType = imgSource.substr(imgSource.lastIndexOf(".") + 1); img.src = imgSource - try { - doc.addImage(img, imgSource.substr(imgSource.lastIndexOf(".")), 15, 12, 20, 20); - } catch (e) { - // TODO: support svg rendering... - console.error(e) + console.log(imgType) + if (imgType.toLowerCase() === "svg") { + new FixedUiElement("").AttachTo(this.freeDivId) + + // This is an svg image, we use the canvas to convert it to a png + const canvas = document.createElement('canvas') + const ctx = canvas.getContext('2d'); + canvas.width = 500 + canvas.height = 500 + img.style.width = "100%" + img.style.height = "100%" + ctx.drawImage(img, 0, 0, 500, 500); + const base64img = canvas.toDataURL("image/png") + doc.addImage(base64img, 'png', 15, 12, 20, 20); + + } else { + try { + doc.addImage(img, imgType, 15, 12, 20, 20); + } catch (e) { + console.error(e) + } } - doc.save("MapComplete_export.pdf"); + doc.save(`MapComplete_${layout.title.txt}_${date}.pdf`); } diff --git a/assets/themes/cycle_infra/cycle_infra.json b/assets/themes/cycle_infra/cycle_infra.json index e24587e6e..d29c483b9 100644 --- a/assets/themes/cycle_infra/cycle_infra.json +++ b/assets/themes/cycle_infra/cycle_infra.json @@ -633,11 +633,15 @@ }, "freeform": { "key": "width:carriageway", - "type": "length", "helperArgs": ["20", "map"] + "type": "length", + "helperArgs": [ + "20", + "map" + ] }, "question": { - "en": "What is the carriage width of this road (in meters)?
This is measured from kerb to kerb, including parking lanes", - "nl": "Hoe breed is de rijbaan in deze straat (in meters)?
Gemeten van stoepsteen tot stoepsten, inclusief parkeerstroken" + "en": "What is the carriage width of this road (in meters)?", + "nl": "Hoe breed is de rijbaan in deze straat (in meters)?" } }, { @@ -971,7 +975,11 @@ }, "freeform": { "key": "cycleway:buffer", - "type": "length", "helperArgs": ["20", "map"] + "type": "length", + "helperArgs": [ + "20", + "map" + ] } }, { @@ -1308,7 +1316,11 @@ }, "freeform": { "key": "width:carriageway", - "type": "length", "helperArgs": ["20", "map"] + "type": "length", + "helperArgs": [ + "20", + "map" + ] }, "question": { "en": "What is the carriage width of this road (in meters)?
This is measured from kerb to kerb, including parking lanes", @@ -1509,7 +1521,11 @@ }, "freeform": { "key": "maxwidth:physical", - "type": "length", "helperArgs": ["20", "map"] + "type": "length", + "helperArgs": [ + "20", + "map" + ] } }, { @@ -1529,8 +1545,11 @@ }, "freeform": { "key": "width:seperation", - "type": "length", - "helperArgs": ["20", "map"] + "type": "length", + "helperArgs": [ + "20", + "map" + ] } }, { diff --git a/index.html b/index.html index a2192f281..eb870680e 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,3 @@ - @@ -24,8 +23,9 @@ - - + + @@ -74,10 +74,7 @@ Loading MapComplete, hang on... -Below +Below
diff --git a/langs/en.json b/langs/en.json index 007035aed..6dbde357d 100644 --- a/langs/en.json +++ b/langs/en.json @@ -62,7 +62,10 @@ }, "general": { "pdf": { - "attr": "Generated with MapComplete.osm.be - map data © OpenStreetMap Contributors, reusable under ODbL" + "generatedWith": "Generated with MapComplete.osm.be", + "attr": "Map data © OpenStreetMap Contributors, reusable under ODbL", + "attrBackground": "Background layer: {background}", + "versionInfo": "v{version} - generated on {date}" }, "loginWithOpenStreetMap": "Login with OpenStreetMap", "welcomeBack": "You are logged in, welcome back!", diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 416f4e318..24f9088ce 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -2364,12 +2364,6 @@ } } } - }, - "presets": { - "0": { - "title": "Paden", - "description": "Voeg een ontbrekend, erkend pad toe." - } } } } \ No newline at end of file diff --git a/langs/themes/en.json b/langs/themes/en.json index 6fb0be015..e8885b11b 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -1108,6 +1108,10 @@ "then": "This is not a cyclestreet." } } + }, + "2": { + "render": "The carriage width of this road is {width:carriageway}m", + "question": "What is the carriage width of this road (in meters)?
This is measured from kerb to kerb, including parking lanes" } } }, diff --git a/langs/themes/nl.json b/langs/themes/nl.json index 17d236cdd..2a30a77cf 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -970,6 +970,10 @@ "then": "Dit is geen fietsstraat" } } + }, + "2": { + "render": "De breedte van deze rijbaan in deze straat is {width:carriageway}m", + "question": "Hoe breed is de rijbaan in deze straat (in meters)?
Gemeten van stoepsteen tot stoepsten, inclusief parkeerstroken" } } }, diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index 9f957553e..b66c97cde 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -2,6 +2,7 @@ import * as fs from "fs"; import {readFileSync, writeFileSync} from "fs"; import {Utils} from "../Utils"; import ScriptUtils from "./ScriptUtils"; +import {Layer} from "leaflet"; const knownLanguages = ["en", "nl", "de", "fr", "es", "gl", "ca"]; @@ -40,12 +41,12 @@ class TranslationPart { } } - recursiveAdd(object: any) { + recursiveAdd(object: any, context: string) { const isProbablyTranslationObject = knownLanguages.map(l => object.hasOwnProperty(l)).filter(x => x).length > 0; if (isProbablyTranslationObject) { - this.addTranslationObject(object) + this.addTranslationObject(object, context) return; } @@ -68,7 +69,7 @@ class TranslationPart { this.contents.set(key, new TranslationPart()) } - (this.contents.get(key) as TranslationPart).recursiveAdd(v); + (this.contents.get(key) as TranslationPart).recursiveAdd(v, context + "." + key); } } @@ -190,7 +191,7 @@ function generateTranslationsObjectFrom(objects: { path: string, parsed: { id: s if (config === undefined) { throw "Got something not parsed! Path is " + layerFile.path } - layerTr.recursiveAdd(config) + layerTr.recursiveAdd(config, layerFile.path) tr.contents.set(config.id, layerTr) } @@ -301,7 +302,7 @@ function mergeThemeTranslations() { const oldLanguages = config.language; const allTranslations = new TranslationPart(); - allTranslations.recursiveAdd(config) + allTranslations.recursiveAdd(config, themeFile.path) const newLanguages = allTranslations.knownLanguages() const languageDiff = newLanguages.filter(l => oldLanguages.indexOf(l) < 0).join(", ") if (languageDiff !== "") {