Better social images

This commit is contained in:
pietervdvn 2022-03-08 04:09:03 +01:00
parent 54158767d2
commit 135d8644da
25 changed files with 6032 additions and 668 deletions

View file

@ -8,6 +8,7 @@ import {ExtractImages} from "./Conversion/FixImages";
import ExtraLinkConfig from "./ExtraLinkConfig";
export default class LayoutConfig {
public static readonly defaultSocialImage = "assets/SocialImage.png"
public readonly id: string;
public readonly maintainer: string;
public readonly credits?: string;
@ -103,10 +104,10 @@ export default class LayoutConfig {
this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, context + ".shortdescription");
this.descriptionTail = json.descriptionTail === undefined ? undefined : new Translation(json.descriptionTail, context + ".descriptionTail");
this.icon = json.icon;
this.socialImage = json.socialImage;
if (this.socialImage === null || this.socialImage === "" || this.socialImage === undefined) {
this.socialImage = json.socialImage ?? LayoutConfig.defaultSocialImage;
if (this.socialImage === "") {
if (official) {
throw "Theme " + json.id + " has no social image defined"
throw "Theme " + json.id + " has empty string as social image"
}
}
this.startZoom = json.startZoom;

View file

@ -432,27 +432,32 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
/**
* Apply a function on every leaf of the JSON; used to rewrite parts of the JSON
* @param json
* @param f
* @constructor
*/
static WalkJson(json: any, f: (v: number | string | boolean | undefined) => any) {
static WalkJson(json: any, f: (v: number | string | boolean | undefined) => any, isLeaf: (object) => boolean = undefined) {
if (json === undefined) {
return f(undefined)
}
const jtp = typeof json
if (jtp === "boolean" || jtp === "string" || jtp === "number") {
if(isLeaf !== undefined) {
if(jtp === "object"){
if(isLeaf(json)){
return f(json)
}
if (json.map !== undefined) {
} else {
return json
}
}else if (jtp === "boolean" || jtp === "string" || jtp === "number") {
return f(json)
}
if (Array.isArray(json)) {
return json.map(sub => {
return Utils.WalkJson(sub, f);
return Utils.WalkJson(sub, f, isLeaf);
})
}
const cp = {...json}
for (const key in json) {
cp[key] = Utils.WalkJson(json[key], f)
cp[key] = Utils.WalkJson(json[key], f, isLeaf)
}
return cp
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.1 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.1 MiB

View file

@ -1 +1,55 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 141.73 141.73"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style></defs><g id="Laag_1" data-name="Laag 1"><circle class="cls-1" cx="70.87" cy="70.87" r="70.87"/></g><g id="Laag_2" data-name="Laag 2"><path class="cls-2" d="M102.39,75a18.18,18.18,0,0,0-3.92.43L92.87,57a7,7,0,0,0-6.77-5H80.67v2.59H86.1a4.45,4.45,0,0,1,4.29,3.19l1.72,5.66H55.54l-2-4.89h3.72S62,57.77,62,54.14H46.39v4.33h4.35l2.55,6.25L47.67,76.27A18.31,18.31,0,1,0,59,96.27h8l1-.43L93.33,67.37,96,76.15a18.28,18.28,0,1,0,6.4-1.17ZM41,109a15.72,15.72,0,1,1,5.58-30.4l-7.69,15.8L40,96.27H56.38A15.74,15.74,0,0,1,41,109Zm15.7-15.33H42.07l6.8-14a15.71,15.71,0,0,1,7.8,13.56C56.67,93.42,56.66,93.55,56.65,93.68ZM50,77.39l4.61-9.45,10.5,25.74H59.24c0-.13,0-.26,0-.39A18.33,18.33,0,0,0,50,77.39ZM67.45,92.56,56.59,66H91.13ZM102.39,109a15.71,15.71,0,0,1-5.65-30.38l4.56,15,2.48-.76-4.56-15A15.72,15.72,0,1,1,102.39,109Z"/><path class="cls-2" d="M78.72,40.26a13.89,13.89,0,0,1-5.58,1.25,9.86,9.86,0,0,1-5.6-1.61,9,9,0,0,1-3.39-4.41h9.4l1.07-2.89-.13-.36h-11a2.91,2.91,0,0,1,0-.4v-.57c0-.4,0-.79.05-1.17h12l1.08-2.93L76.36,27H64.13a8.69,8.69,0,0,1,3.48-4.43A10.82,10.82,0,0,1,73.55,21a16.47,16.47,0,0,1,4.55.68l.13,0,1.08-3-.15-.05a16.56,16.56,0,0,0-5.3-.81,14.91,14.91,0,0,0-8.42,2.35A11.73,11.73,0,0,0,60.66,27h-2.3l-1.08,2.93.19.19h2.69c0,.16,0,.32,0,.49v1.23c0,.14,0,.29,0,.42h-1.8L57.28,35.3l.19.19h3.21a12.2,12.2,0,0,0,4.48,6.72,12.47,12.47,0,0,0,7.64,2.46A16.44,16.44,0,0,0,79,43.39l.09,0v-3l-.28-.16Z"/></g></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 141.73 141.73"
version="1.1"
id="svg14"
sodipodi:docname="rental.svg"
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview16"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="2.6516417"
inkscape:cx="41.10661"
inkscape:cy="42.615109"
inkscape:current-layer="svg14" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style>
</defs>
<g
id="g838">
<g
id="Laag_1"
data-name="Laag 1">
<circle
class="cls-1"
cx="70.87"
cy="70.87"
r="70.87"
id="circle6" />
</g>
<g
id="Laag_2"
data-name="Laag 2">
<path
class="cls-2"
d="M102.39,75a18.18,18.18,0,0,0-3.92.43L92.87,57a7,7,0,0,0-6.77-5H80.67v2.59H86.1a4.45,4.45,0,0,1,4.29,3.19l1.72,5.66H55.54l-2-4.89h3.72S62,57.77,62,54.14H46.39v4.33h4.35l2.55,6.25L47.67,76.27A18.31,18.31,0,1,0,59,96.27h8l1-.43L93.33,67.37,96,76.15a18.28,18.28,0,1,0,6.4-1.17ZM41,109a15.72,15.72,0,1,1,5.58-30.4l-7.69,15.8L40,96.27H56.38A15.74,15.74,0,0,1,41,109Zm15.7-15.33H42.07l6.8-14a15.71,15.71,0,0,1,7.8,13.56C56.67,93.42,56.66,93.55,56.65,93.68ZM50,77.39l4.61-9.45,10.5,25.74H59.24c0-.13,0-.26,0-.39A18.33,18.33,0,0,0,50,77.39ZM67.45,92.56,56.59,66H91.13ZM102.39,109a15.71,15.71,0,0,1-5.65-30.38l4.56,15,2.48-.76-4.56-15A15.72,15.72,0,1,1,102.39,109Z"
id="path9" />
<path
class="cls-2"
d="M78.72,40.26a13.89,13.89,0,0,1-5.58,1.25,9.86,9.86,0,0,1-5.6-1.61,9,9,0,0,1-3.39-4.41h9.4l1.07-2.89-.13-.36h-11a2.91,2.91,0,0,1,0-.4v-.57c0-.4,0-.79.05-1.17h12l1.08-2.93L76.36,27H64.13a8.69,8.69,0,0,1,3.48-4.43A10.82,10.82,0,0,1,73.55,21a16.47,16.47,0,0,1,4.55.68l.13,0,1.08-3-.15-.05a16.56,16.56,0,0,0-5.3-.81,14.91,14.91,0,0,0-8.42,2.35A11.73,11.73,0,0,0,60.66,27h-2.3l-1.08,2.93.19.19h2.69c0,.16,0,.32,0,.49v1.23c0,.14,0,.29,0,.42h-1.8L57.28,35.3l.19.19h3.21a12.2,12.2,0,0,0,4.48,6.72,12.47,12.47,0,0,0,7.64,2.46A16.44,16.44,0,0,0,79,43.39l.09,0v-3l-.28-.16Z"
id="path11" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -2,16 +2,34 @@
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="100%"
height="100%"
width="14px"
height="14px"
viewBox="0 0 14 14"
id="svg2">
id="svg2"
sodipodi:docname="recycling-14.svg"
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
units="px"
inkscape:zoom="60.071429"
inkscape:cx="6.9916766"
inkscape:cy="7.0083234"
inkscape:current-layer="svg2" />
<metadata
id="metadata8">
<rdf:RDF>
@ -20,7 +38,6 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@ -32,9 +49,9 @@
x="0"
y="0"
id="canvas"
style="fill:none;stroke:none;visibility:hidden" />
style="visibility:hidden;fill:none;stroke:none" />
<path
d="M 5.111113,8.690628 3.513352,5.804047 0.3,5.804047 1.60621,6.5880837 0.798678,8.031102 c -0.06887,0.130859 -0.103304,0.267511 -0.103301,0.409961 -3e-6,0.142456 0.03443,0.27911 0.103301,0.40996 l 1.271077,2.298282 c 0.05733,-0.166376 0.11466,-0.309011 0.171995,-0.427902 L 3.82273,7.906591 5.111113,8.690628 z m -2.38799,2.316224 c -0.09194,0.154416 -0.137914,0.320611 -0.13791,0.498585 -4e-6,0.273307 0.09456,0.504931 0.283685,0.694868 0.189119,0.189939 0.415298,0.284906 0.678537,0.284906 l 3.161963,0 0,-2.654413 -3.333432,0 C 3.352886,9.878288 3.266892,10.0327 3.117975,10.294041 l -0.394852,0.712811 z m 4.278351,-6.5745954 3.196047,0 L 11.812587,1.54622 10.506901,2.3302555 9.698844,0.8866933 C 9.549912,0.6137609 9.320934,0.4772893 9.011916,0.4772767 l -2.543205,0 c 0.10312,0.1185426 0.189116,0.2372528 0.257992,0.3561331 L 8.289856,3.6482199 8.032389,3.8086154 7.001474,4.4322566 z M 5.437797,0.6197306 C 5.07108,0.6197421 4.796134,0.7859374 4.61296,1.1183163 L 3.015198,3.9690109 C 3.622066,4.3372941 4.360906,4.7767964 5.231719,5.2875185 5.746994,4.372999 6.302478,3.3752843 6.898173,2.2943703 L 6.262635,1.1183163 C 6.079446,0.7859374 5.804501,0.6197421 5.437797,0.6197306 l 0,0 z m 4.106882,9.1751824 0,-0.320793 0,-1.228795 L 7.946393,11.131363 9.544679,14 l 0,-1.55013 1.597761,0 c 0.309366,0 0.54411,-0.136653 0.704231,-0.409962 l 1.271602,-2.298279 c -0.171656,0.04749 -0.314811,0.07123 -0.42946,0.07123 L 9.544679,9.794909 z m 2.37121,-4.88147 c -0.05735,0.035533 -0.79636,0.4750321 -2.217045,1.3185066 0.710337,1.2708484 1.271764,2.2745434 1.684282,3.0110934 l 1.288383,0 c 0.378233,2e-6 0.658946,-0.166373 0.842142,-0.499132 0.171629,-0.320788 0.165862,-0.647379 -0.01731,-0.979774 l -1.58045,-2.850694 z"
d="M 5.111113,8.690628 3.513352,5.804047 H 0.3 L 1.60621,6.5880837 0.798678,8.031102 c -0.06887,0.130859 -0.103304,0.267511 -0.103301,0.409961 -3e-6,0.142456 0.03443,0.27911 0.103301,0.40996 l 1.271077,2.298282 c 0.05733,-0.166376 0.11466,-0.309011 0.171995,-0.427902 L 3.82273,7.906591 Z m -2.38799,2.316224 c -0.09194,0.154416 -0.137914,0.320611 -0.13791,0.498585 -4e-6,0.273307 0.09456,0.504931 0.283685,0.694868 0.189119,0.189939 0.415298,0.284906 0.678537,0.284906 H 6.709398 V 9.830798 H 3.375966 C 3.352886,9.878288 3.266892,10.0327 3.117975,10.294041 Z M 7.001474,4.4322566 h 3.196047 L 11.812587,1.54622 10.506901,2.3302555 9.698844,0.8866933 C 9.549912,0.6137609 9.320934,0.4772893 9.011916,0.4772767 H 6.468711 c 0.10312,0.1185426 0.189116,0.2372528 0.257992,0.3561331 L 8.289856,3.6482199 8.032389,3.8086154 Z M 5.437797,0.6197306 C 5.07108,0.6197421 4.796134,0.7859374 4.61296,1.1183163 L 3.015198,3.9690109 C 3.622066,4.3372941 4.360906,4.7767964 5.231719,5.2875185 5.746994,4.372999 6.302478,3.3752843 6.898173,2.2943703 L 6.262635,1.1183163 C 6.079446,0.7859374 5.804501,0.6197421 5.437797,0.6197306 Z M 9.544679,9.794913 V 9.47412 8.245325 L 7.946393,11.131363 9.544679,14 v -1.55013 h 1.597761 c 0.309366,0 0.54411,-0.136653 0.704231,-0.409962 l 1.271602,-2.298279 c -0.171656,0.04749 -0.314811,0.07123 -0.42946,0.07123 L 9.544679,9.794909 Z m 2.37121,-4.88147 c -0.05735,0.035533 -0.79636,0.4750321 -2.217045,1.3185066 0.710337,1.2708484 1.271764,2.2745434 1.684282,3.0110934 h 1.288383 c 0.378233,2e-6 0.658946,-0.166373 0.842142,-0.499132 0.171629,-0.320788 0.165862,-0.647379 -0.01731,-0.979774 l -1.58045,-2.850694 z"
id="recycling"
style="fill:#000000;fill-opacity:1;stroke:none" />
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -352,7 +352,8 @@
"zh_Hant": "這間商業空間是否允許犬隻?",
"ru": "Впускают ли собак в это здание?",
"pl": "Czy w tej firmie psy są dozwolone?",
"ja": "犬を飼うことができますか?"
"ja": "犬を飼うことができますか?",
"id": "Apakah anjing diperbolehkan dalam bisnis ini?"
},
"mappings": [
{
@ -435,7 +436,8 @@
"zh_Hant": "允許犬隻而且可以自由跑動",
"ru": "Собак свободно впускают",
"pl": "Psy dozwolone i mogą biegać bez ograniczeń",
"ja": "犬同伴可能、自由に走り回れる"
"ja": "犬同伴可能、自由に走り回れる",
"id": "Anjing diperbolehkan dan dapat berkeliaran dengan bebas"
}
}
]
@ -754,7 +756,8 @@
"it": "Si trova sotto il livello stradale",
"nb_NO": "Under bakken",
"ca": "Situat a planta subterrani",
"ja": "地下にあります"
"ja": "地下にあります",
"id": "Terletak di bawah tanah"
},
"hideInAnswer": true
},
@ -776,7 +779,8 @@
"it": "Si trova al pianoterra",
"nb_NO": "På gateplan",
"ca": "Situat a planta zero",
"ja": "1階にあります"
"ja": "1階にあります",
"id": "Terletak di lantai dasar"
}
},
{
@ -798,7 +802,8 @@
"it": "Si trova al pianoterra",
"nb_NO": "På gateplan",
"ca": "Situat a planta zero",
"ja": "1階にあります"
"ja": "1階にあります",
"id": "Terletak di lantai dasar"
}
},
{
@ -830,7 +835,8 @@
"nl": "Bevindt zich in de eerste kelderverdieping",
"zh_Hant": "位於地下一樓",
"de": "Ist im 1. Untergeschoss",
"hu": "Az első alagsori szinten"
"hu": "Az első alagsori szinten",
"id": "Terletak di lantai basement pertama"
}
}
]

View file

@ -19,7 +19,7 @@
"pt_BR": "Abrir mapa AED"
},
"maintainer": "MapComplete",
"icon": "./assets/themes/aed/logo.svg",
"icon": "./assets/themes/aed/aed.svg",
"description": {
"en": "On this map, one can find and mark nearby defibrillators",
"ca": "En aquest mapa , qualsevol pot trobar i marcar els desfibril·ladors externs automàtics més propers",

View file

@ -1,8 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" width="375px" height="375px" viewBox="0 0 375 375" version="1.1">
<g id="surface1">
<rect x="0" y="0" width="375" height="375" style="fill:rgb(0%,53.333336%,33.333334%);fill-opacity:1;stroke:none;"/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 279.210938 32.8125 L 309.375 32.8125 L 309.375 63.179688 L 339.742188 63.179688 L 339.742188 93.34375 L 309.375 93.34375 L 309.375 123.710938 L 279.210938 123.710938 L 279.210938 93.34375 L 248.84375 93.34375 L 248.84375 63.179688 L 279.210938 63.179688 Z M 279.210938 32.8125 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 96.808594 114.742188 C 57.675781 115.148438 22.621094 154.074219 33.21875 205.433594 C 41.167969 244.769531 82.949219 295.71875 155.707031 345.039062 C 228.464844 295.515625 270.246094 244.566406 278.191406 205.433594 C 288.789062 153.871094 253.941406 115.148438 214.605469 114.742188 C 194.429688 114.335938 169.15625 125.136719 155.707031 150.816406 C 142.253906 125.136719 116.984375 114.335938 96.808594 114.742188 Z M 187.09375 145.925781 L 152.851562 216.238281 L 196.261719 216.238281 L 120.246094 304.6875 L 149.59375 235.394531 L 107.40625 235.394531 Z M 187.09375 145.925781 "/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="375px"
height="375px"
viewBox="0 0 375 375"
version="1.1"
id="svg9"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs13" />
<g
id="surface1">
<rect
x="0"
y="0"
width="375"
height="375"
style="fill:rgb(0%,53.333336%,33.333334%);fill-opacity:1;stroke:none;"
id="rect2" />
<path
style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;"
d="M 279.210938 32.8125 L 309.375 32.8125 L 309.375 63.179688 L 339.742188 63.179688 L 339.742188 93.34375 L 309.375 93.34375 L 309.375 123.710938 L 279.210938 123.710938 L 279.210938 93.34375 L 248.84375 93.34375 L 248.84375 63.179688 L 279.210938 63.179688 Z M 279.210938 32.8125 "
id="path4" />
<path
style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;"
d="M 96.808594 114.742188 C 57.675781 115.148438 22.621094 154.074219 33.21875 205.433594 C 41.167969 244.769531 82.949219 295.71875 155.707031 345.039062 C 228.464844 295.515625 270.246094 244.566406 278.191406 205.433594 C 288.789062 153.871094 253.941406 115.148438 214.605469 114.742188 C 194.429688 114.335938 169.15625 125.136719 155.707031 150.816406 C 142.253906 125.136719 116.984375 114.335938 96.808594 114.742188 Z M 187.09375 145.925781 L 152.851562 216.238281 L 196.261719 216.238281 L 120.246094 304.6875 L 149.59375 235.394531 L 107.40625 235.394531 Z M 187.09375 145.925781 "
id="path6" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -4,7 +4,7 @@
"nl": "Open AED-kaart - Brugge edition"
},
"maintainer": "MapComplete",
"icon": "./assets/themes/aed/logo.svg",
"icon": "./assets/themes/aed/aed.svg",
"description": {
"nl": "Op deze kaart kan je informatie over AEDs vinden en verbeteren + een export van de brugse defibrillatoren"
},

View file

@ -8,15 +8,5 @@
"sources": [
"https://commons.wikimedia.org/wiki/File:ISO_7010_E010.svg"
]
},
{
"path": "logo.svg",
"license": "CC-BY-SA 4.0",
"authors": [
"M!dgard"
],
"sources": [
"https://commons.wikimedia.org/wiki/File:ISO_7010_E010.svg"
]
}
]

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 54 KiB

View file

@ -25,7 +25,8 @@
"zh_Hant": "長椅的地圖",
"nb_NO": "Et benkekart",
"pt_BR": "Um mapa de bancadas",
"hu": "Padtérkép"
"hu": "Padtérkép",
"id": "Peta bangku"
},
"description": {
"en": "This map shows all benches that are recorded in OpenStreetMap: Individual benches, and benches belonging to public transport stops or shelters. With an OpenStreetMap account, you can map new benches or edit details of existing benches.",

View file

@ -3,12 +3,14 @@
"title": {
"en": "Bicycle rental",
"nl": "Fietsverhuur",
"de": "Fahrradverleih"
"de": "Fahrradverleih",
"id": "Sewa sepeda"
},
"shortDescription": {
"en": "A map with bicycle rental stations and bicycle rental shops",
"nl": "Een kaart met fietsverhuurpunten en fietsverhuurzaken",
"de": "Eine Karte mit Fahrradverleihstationen und Fahrradverleihern"
"de": "Eine Karte mit Fahrradverleihstationen und Fahrradverleihern",
"id": "Peta dengan stasiun persewaan sepeda dan toko penyewaan sepeda"
},
"description": {
"en": "On this map, you'll find the many bicycle rental stations as they are known by OpenStreetMap",

View file

@ -1 +1,56 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 141.73 141.73"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style></defs><g id="Laag_1" data-name="Laag 1"><circle class="cls-1" cx="70.87" cy="70.87" r="70.87"/></g><g id="Laag_2" data-name="Laag 2"><path class="cls-2" d="M102.39,75a18.18,18.18,0,0,0-3.92.43L92.87,57a7,7,0,0,0-6.77-5H80.67v2.59H86.1a4.45,4.45,0,0,1,4.29,3.19l1.72,5.66H55.54l-2-4.89h3.72S62,57.77,62,54.14H46.39v4.33h4.35l2.55,6.25L47.67,76.27A18.31,18.31,0,1,0,59,96.27h8l1-.43L93.33,67.37,96,76.15a18.28,18.28,0,1,0,6.4-1.17ZM41,109a15.72,15.72,0,1,1,5.58-30.4l-7.69,15.8L40,96.27H56.38A15.74,15.74,0,0,1,41,109Zm15.7-15.33H42.07l6.8-14a15.71,15.71,0,0,1,7.8,13.56C56.67,93.42,56.66,93.55,56.65,93.68ZM50,77.39l4.61-9.45,10.5,25.74H59.24c0-.13,0-.26,0-.39A18.33,18.33,0,0,0,50,77.39ZM67.45,92.56,56.59,66H91.13ZM102.39,109a15.71,15.71,0,0,1-5.65-30.38l4.56,15,2.48-.76-4.56-15A15.72,15.72,0,1,1,102.39,109Z"/><path class="cls-2" d="M78.72,40.26a13.89,13.89,0,0,1-5.58,1.25,9.86,9.86,0,0,1-5.6-1.61,9,9,0,0,1-3.39-4.41h9.4l1.07-2.89-.13-.36h-11a2.91,2.91,0,0,1,0-.4v-.57c0-.4,0-.79.05-1.17h12l1.08-2.93L76.36,27H64.13a8.69,8.69,0,0,1,3.48-4.43A10.82,10.82,0,0,1,73.55,21a16.47,16.47,0,0,1,4.55.68l.13,0,1.08-3-.15-.05a16.56,16.56,0,0,0-5.3-.81,14.91,14.91,0,0,0-8.42,2.35A11.73,11.73,0,0,0,60.66,27h-2.3l-1.08,2.93.19.19h2.69c0,.16,0,.32,0,.49v1.23c0,.14,0,.29,0,.42h-1.8L57.28,35.3l.19.19h3.21a12.2,12.2,0,0,0,4.48,6.72,12.47,12.47,0,0,0,7.64,2.46A16.44,16.44,0,0,0,79,43.39l.09,0v-3l-.28-.16Z"/></g></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 150 150"
version="1.1"
id="svg14"
sodipodi:docname="logo.svg"
width="150"
height="150"
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview16"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="4.78212"
inkscape:cx="65.661254"
inkscape:cy="75.280419"
inkscape:current-layer="svg14" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style>
</defs>
<g
id="Laag_1"
data-name="Laag 1"
transform="scale(1.0573395)">
<circle
class="cls-1"
cx="70.870003"
cy="70.870003"
r="70.870003"
id="circle6" />
</g>
<g
id="Laag_2"
data-name="Laag 2"
transform="scale(1.0573395)">
<path
class="cls-2"
d="m 102.39,75 a 18.18,18.18 0 0 0 -3.92,0.43 L 92.87,57 A 7,7 0 0 0 86.1,52 h -5.43 v 2.59 h 5.43 a 4.45,4.45 0 0 1 4.29,3.19 l 1.72,5.66 H 55.54 l -2,-4.89 h 3.72 c 0,0 4.74,-0.78 4.74,-4.41 H 46.39 v 4.33 h 4.35 l 2.55,6.25 -5.62,11.55 a 18.31,18.31 0 1 0 11.33,20 h 8 L 68,95.84 93.33,67.37 96,76.15 a 18.28,18.28 0 1 0 6.4,-1.17 z M 41,109 A 15.72,15.72 0 1 1 46.58,78.6 L 38.89,94.4 40,96.27 H 56.38 A 15.74,15.74 0 0 1 41,109 Z M 56.7,93.67 H 42.07 l 6.8,-14 a 15.71,15.71 0 0 1 7.8,13.56 c 0,0.19 -0.01,0.32 -0.02,0.45 z M 50,77.39 l 4.61,-9.45 10.5,25.74 h -5.87 c 0,-0.13 0,-0.26 0,-0.39 A 18.33,18.33 0 0 0 50,77.39 Z M 67.45,92.56 56.59,66 H 91.13 Z M 102.39,109 A 15.71,15.71 0 0 1 96.74,78.62 l 4.56,15 2.48,-0.76 -4.56,-15 a 15.72,15.72 0 1 1 3.17,31.14 z"
id="path9" />
<path
class="cls-2"
d="m 78.72,40.26 a 13.89,13.89 0 0 1 -5.58,1.25 9.86,9.86 0 0 1 -5.6,-1.61 9,9 0 0 1 -3.39,-4.41 h 9.4 l 1.07,-2.89 -0.13,-0.36 h -11 a 2.91,2.91 0 0 1 0,-0.4 v -0.57 c 0,-0.4 0,-0.79 0.05,-1.17 h 12 L 76.62,27.17 76.36,27 H 64.13 a 8.69,8.69 0 0 1 3.48,-4.43 10.82,10.82 0 0 1 5.94,-1.57 16.47,16.47 0 0 1 4.55,0.68 h 0.13 l 1.08,-3 -0.15,-0.05 a 16.56,16.56 0 0 0 -5.3,-0.81 14.91,14.91 0 0 0 -8.42,2.35 11.73,11.73 0 0 0 -4.78,6.83 h -2.3 l -1.08,2.93 0.19,0.19 h 2.69 c 0,0.16 0,0.32 0,0.49 v 1.23 c 0,0.14 0,0.29 0,0.42 h -1.8 l -1.08,3.04 0.19,0.19 h 3.21 a 12.2,12.2 0 0 0 4.48,6.72 12.47,12.47 0 0 0 7.64,2.46 16.44,16.44 0 0 0 6.2,-1.28 h 0.09 v -3 l -0.28,-0.16 z"
id="path11" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -14,7 +14,8 @@
"de": "Fahrradbibliothek",
"pt_BR": "Bibliotecas de bicicletas",
"pl": "Wypożyczalnie rowerów",
"hu": "Kerékpárkönyvtárak"
"hu": "Kerékpárkönyvtárak",
"id": "Perpustakaan sepeda"
},
"description": {
"nl": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.",

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -1,16 +1,13 @@
{
"id": "mapcomplete-changes",
"title": {
"en": "Changes made with MapComplete",
"de": "Änderungen mit MapComplete"
"en": "Changes made with MapComplete"
},
"shortDescription": {
"en": "Shows changes made by MapComplete",
"de": "Zeigt Änderungen, die von MapComplete vorgenommen wurden"
"en": "Shows changes made by MapComplete"
},
"description": {
"en": "This maps shows all the changes made with MapComplete",
"de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen"
"en": "This maps shows all the changes made with MapComplete"
},
"maintainer": "",
"icon": "./assets/svg/logo.svg",
@ -25,8 +22,7 @@
{
"id": "mapcomplete-changes",
"name": {
"en": "Changeset centers",
"de": "Schwerpunkte von Änderungssätzen"
"en": "Changeset centers"
},
"minzoom": 0,
"source": {
@ -40,41 +36,35 @@
],
"title": {
"render": {
"en": "Changeset for {theme}",
"de": "Änderungssatz für {theme}"
"en": "Changeset for {theme}"
}
},
"description": {
"en": "Shows all MapComplete changes",
"de": "Zeigt alle MapComplete-Änderungen"
"en": "Shows all MapComplete changes"
},
"tagRenderings": [
{
"id": "render_id",
"render": {
"en": "Changeset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>",
"de": "Änderungssatz <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
"en": "Changeset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
}
},
{
"id": "contributor",
"render": {
"en": "Change made by <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>",
"de": "Geändert von <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
"en": "Change made by <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
}
},
{
"id": "theme",
"render": {
"en": "Change with theme <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>",
"de": "Änderung mit Thema <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
"en": "Change with theme <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
},
"mappings": [
{
"if": "theme~http.*",
"then": {
"en": "Change with <b>unofficial</b> theme <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>",
"de": "Änderung mit <b>inoffiziellem</b> Thema <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
"en": "Change with <b>unofficial</b> theme <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
}
}
]
@ -91,11 +81,11 @@
"mappings": [
{
"if": "theme=aed",
"then": "./assets/themes/aed/logo.svg"
"then": "./assets/themes/aed/aed.svg"
},
{
"if": "theme=aed_brugge",
"then": "./assets/themes/aed/logo.svg"
"then": "./assets/themes/aed/aed.svg"
},
{
"if": "theme=artwork",
@ -338,8 +328,7 @@
}
],
"question": {
"en": "Themename contains {search}",
"de": "Themenname enthält {search}"
"en": "Themename contains {search}"
}
}
]
@ -355,8 +344,7 @@
}
],
"question": {
"en": "Made by contributor {search}",
"de": "Erstellt von Mitwirkendem {search}"
"en": "Made by contributor {search}"
}
}
]
@ -372,8 +360,7 @@
}
],
"question": {
"en": "<b>Not</b> made by contributor {search}",
"de": "<b> Nicht</b> erstellt von Mitwirkendem {search}"
"en": "<b>Not</b> made by contributor {search}"
}
}
]
@ -388,8 +375,7 @@
{
"id": "link_to_more",
"render": {
"en": "More statistics can be found <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>here</a>",
"de": "Weitere Statistiken finden Sie <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>hier</a>"
"en": "More statistics can be found <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>here</a>"
}
},
{

View file

@ -9,52 +9,52 @@
"orientation": "portrait-primary, landscape-primary",
"icons": [
{
"src": "assets/generated/svg_mapcomplete_logo72.png",
"src": "assets/generated/images/mapcomplete_logo72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo96.png",
"src": "assets/generated/images/mapcomplete_logo96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo120.png",
"src": "assets/generated/images/mapcomplete_logo120.png",
"sizes": "120x120",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo128.png",
"src": "assets/generated/images/mapcomplete_logo128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo144.png",
"src": "assets/generated/images/mapcomplete_logo144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo152.png",
"src": "assets/generated/images/mapcomplete_logo152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo180.png",
"src": "assets/generated/images/mapcomplete_logo180.png",
"sizes": "180x180",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo192.png",
"src": "assets/generated/images/mapcomplete_logo192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo384.png",
"src": "assets/generated/images/mapcomplete_logo384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "assets/generated/svg_mapcomplete_logo512.png",
"src": "assets/generated/images/mapcomplete_logo512.png",
"sizes": "512x512",
"type": "image/png"
},

View file

@ -8,12 +8,12 @@
"delete": {
"cancel": "Batal",
"cannotBeDeleted": "Fitur ini tidak dapat dihapus",
"delete": "Hapus",
"explanations": {
"selectReason": "Silahkan pilih mengapa fitur ini harus dihapus"
},
"isntAPoint": "Hanya titik yang dapat dihapus, fitur yang dipilih adalah jalan, area, atau relasi.",
"delete": "Hapus",
"isDeleted": "Fitur ini telah dihapus"
"isDeleted": "Fitur ini telah dihapus",
"isntAPoint": "Hanya titik yang dapat dihapus, fitur yang dipilih adalah jalan, area, atau relasi."
},
"favourite": {
"reload": "Muat ulang data"

View file

@ -25,18 +25,18 @@
},
"level": {
"mappings": {
"3": {
"then": "Berlokasi di lantai pertama"
"0": {
"then": "Terletak di bawah tanah"
},
"1": {
"then": "Terletak di lantai dasar"
},
"0": {
"then": "Terletak di bawah tanah"
},
"2": {
"then": "Terletak di lantai dasar"
},
"3": {
"then": "Berlokasi di lantai pertama"
},
"4": {
"then": "Terletak di lantai basement pertama"
}

View file

@ -8,8 +8,15 @@
"title": "Buka Peta Karya Seni"
},
"benches": {
"title": "Bangku",
"shortDescription": "Peta bangku"
"shortDescription": "Peta bangku",
"title": "Bangku"
},
"bicycle_rental": {
"shortDescription": "Peta dengan stasiun persewaan sepeda dan toko penyewaan sepeda",
"title": "Sewa sepeda"
},
"bicyclelib": {
"title": "Perpustakaan sepeda"
},
"cafes_and_pubs": {
"title": "Kafe dan pub"
@ -283,12 +290,5 @@
},
"waste_basket": {
"title": "Keranjang Sampah"
},
"bicyclelib": {
"title": "Perpustakaan sepeda"
},
"bicycle_rental": {
"title": "Sewa sepeda",
"shortDescription": "Peta dengan stasiun persewaan sepeda dan toko penyewaan sepeda"
}
}

View file

@ -1,5 +1,5 @@
import * as fs from "fs";
import {lstatSync, readdirSync, readFileSync} from "fs";
import {existsSync, lstatSync, readdirSync, readFileSync} from "fs";
import {Utils} from "../Utils";
import * as https from "https";
import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson";
@ -146,6 +146,9 @@ export default class ScriptUtils {
}
public static async ReadSvg(path: string): Promise<any>{
if(!existsSync(path)){
throw "File not found: "+path
}
const root = await xml2js.parseStringPromise(readFileSync(path, "UTF8"))
return root.svg
}

View file

@ -102,6 +102,9 @@ class LayerOverviewUtils {
.filter(path => !path.startsWith("./assets/generated"))
let errCount = 0;
for (const path of allSvgs) {
if(path.indexOf("assets/SocialImageTemplate") >= 0){
continue
}
const contents = readFileSync(path, "UTF8")
if (contents.indexOf("data:image/png;") < 0) {
continue;

View file

@ -8,6 +8,7 @@ import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson";
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
import xml2js from 'xml2js';
import ScriptUtils from "./ScriptUtils";
import {Utils} from "../Utils";
const sharp = require('sharp');
const template = readFileSync("theme.html", "utf8");
@ -19,57 +20,110 @@ function enc(str: string): string {
}
async function createIcon(iconPath: string, size: number, alreadyWritten: string[]) {
let name = iconPath.split(".").slice(0, -1).join(".");
let name = iconPath.split(".").slice(0, -1).join("."); // drop svg suffix
if (name.startsWith("./")) {
name = name.substr(2)
}
const newname = `${name}${size}.png`
.replace(/\//g, "_")
.replace("assets_", "assets/generated/");
const newname = `assets/generated/images${name.substring(name.lastIndexOf("/"))}${size}.png`;
if (alreadyWritten.indexOf(newname) >= 0) {
return newname;
}
alreadyWritten.push(newname);
try {
readFileSync(newname);
return newname; // File already exists - nothing to do
} catch (e) {
// Errors are normal here if this file does not exists
if (existsSync(newname)) {
return newname
}
if (!existsSync(iconPath)) {
throw "No file at " + iconPath
}
try {
// We already read to file, in order to crash here if the file is not found
readFileSync(iconPath);
let img = await sharp(iconPath)
let resized = await img.resize(size)
await resized.toFile(newname)
console.log("Written", newname)
} catch (e) {
console.error("Could not read icon", iconPath, "due to", e)
console.error("Could not read icon", iconPath, " to create a PNG due to", e)
}
return newname;
}
async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
async function createSocialImage(layout: LayoutConfig, template: "" | "Wide"): Promise<string> {
if (!layout.icon.endsWith(".svg")) {
console.warn("Not creating a social image for " + layout.id + " as it is _not_ a .svg: " + layout.icon)
return undefined
}
const path = `./assets/generated/images/social_image_${layout.id}_${template}.svg`
if(existsSync(path)){
// return path;
}
const svg = await ScriptUtils.ReadSvg(layout.icon)
let width: string = svg.$.width;
if (width === undefined) {
throw "The logo at " + layout.icon + " does not have a defined width"
}
if (width?.endsWith("px")) {
width = width.substring(0, width.length - 2)
}
if (width?.endsWith("%")) {
throw "The logo at " + layout.icon + " has a relative width; this is not supported"
}
delete svg["defs"]
delete svg["$"]
let templateSvg = await ScriptUtils.ReadSvg("./assets/SocialImageTemplate" + template + ".svg")
templateSvg = Utils.WalkJson(templateSvg,
(leaf) => {
const {cx, cy, r} = leaf["circle"][0].$
return {
$: {
id: "icon",
transform: `translate(${cx - r},${cy - r}) scale(${(r * 2) / Number(width)}) `
},
g: [svg]
}
},
(mightBeTokenToReplace) => {
if (mightBeTokenToReplace?.circle === undefined) {
return false
}
return mightBeTokenToReplace.circle[0]?.$?.style?.indexOf("fill:#ff00ff") >= 0
}
)
const builder = new xml2js.Builder();
const xml = builder.buildObject({svg: templateSvg});
writeFileSync(path, xml)
console.log("Written", path)
return path
}
async function createManifest(layout: LayoutConfig, alreadyWritten: string[]): Promise<{
manifest: any,
whiteIcons: string[]
}> {
const name = layout.id;
Translation.forcedLanguage = "en"
const icons = [];
const whiteIcons: string[] = []
let icon = layout.icon;
if (icon.endsWith(".svg") || icon.startsWith("<svg") || icon.startsWith("<?xml")) {
// This is an svg. Lets create the needed pngs and do some checkes!
const whiteBackgroundPath = "./assets/generated/theme_"+layout.id+"_white_background.svg"
const whiteBackgroundPath = "./assets/generated/images/theme_" + layout.id + "_white_background.svg"
{
const svg = await ScriptUtils.ReadSvg(icon)
const width: string = svg.$.width;
const height: string = svg.$.height;
const builder = new xml2js.Builder();
const withRect = {rect: {"$":{width, height, style: "fill:#ffffff;"}}, ...svg}
const withRect = {rect: {"$": {width, height, style: "fill:#ffffff;"}}, ...svg}
const xml = builder.buildObject({svg: withRect});
writeFileSync(whiteBackgroundPath, xml)
}
@ -77,14 +131,15 @@ async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
let path = layout.icon;
if (layout.icon.startsWith("<")) {
// THis is already the svg
path = "./assets/generated/" + layout.id + "_logo.svg"
path = "./assets/generated/images/" + layout.id + "_logo.svg"
writeFileSync(path, layout.icon)
}
const sizes = [72, 96, 120, 128, 144, 152, 180, 192, 384, 512];
for (const size of sizes) {
const name = await createIcon(path, size, alreadyWritten);
await createIcon(whiteBackgroundPath, size, alreadyWritten)
const whiteIcon = await createIcon(whiteBackgroundPath, size, alreadyWritten)
whiteIcons.push(whiteIcon)
icons.push({
src: name,
sizes: size + "x" + size,
@ -109,7 +164,7 @@ async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
const ogTitle = Translations.WT(layout.title).txt;
const ogDescr = Translations.WT(layout.description ?? "").txt;
return {
const manifest = {
name: name,
short_name: ogTitle,
start_url: `${layout.id.toLowerCase()}.html`,
@ -121,15 +176,32 @@ async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
icons: icons,
categories: ["map", "navigation"]
};
return {
manifest,
whiteIcons
}
}
async function createLandingPage(layout: LayoutConfig, manifest) {
async function createLandingPage(layout: LayoutConfig, manifest, whiteIcons, alreadyWritten) {
Locale.language.setData(layout.language[0]);
const targetLanguage = layout.language[0]
const ogTitle = Translations.WT(layout.title).textFor(targetLanguage).replace(/"/g, '\\"');
const ogDescr = Translations.WT(layout.shortDescription ?? "Easily add and edit geodata with OpenStreetMap").textFor(targetLanguage).replace(/"/g, '\\"');
const ogImage = layout.socialImage;
let ogImage = layout.socialImage;
let twitterImage = ogImage
if (ogImage === LayoutConfig.defaultSocialImage && layout.official) {
ogImage = await createSocialImage(layout, "") ?? layout.socialImage
twitterImage = await createSocialImage(layout, "Wide") ?? layout.socialImage
}
if (twitterImage.endsWith(".svg")) {
// svgs are badly supported as social image, we use a generated svg instead
twitterImage = await createIcon(twitterImage, 512, alreadyWritten);
}
if(ogImage.endsWith(".svg")){
ogImage = await createIcon(ogImage, 512, alreadyWritten)
}
let customCss = "";
if (layout.customCss !== undefined && layout.customCss !== "") {
@ -147,29 +219,26 @@ async function createLandingPage(layout: LayoutConfig, manifest) {
<meta property="og:title" content="${ogTitle}">
<meta property="og:description" content="${ogDescr}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@mapcomplete.osm;be">
<meta name="twitter:site" content="@mapcomplete.osm.be">
<meta name="twitter:creator" content="@pietervdvn">
<meta name="twitter:title" content="${ogTitle}">
<meta name="twitter:description" content="${ogDescr}">
<meta name="twitter:image" content="${ogImage}">`
<meta name="twitter:image" content="${twitterImage}">`
let icon = layout.icon;
if (icon.startsWith("<?xml") || icon.startsWith("<svg")) {
// This already is an svg
icon = `./assets/generated/${layout.id}_icon.svg`
icon = `./assets/generated/images/${layout.id}_icon.svg`
writeFileSync(icon, layout.icon);
}
const apple_icons = []
for (const icon of manifest.icons) {
if (icon.type !== "image/png") {
continue;
}
const whiteBgPath = `./assets/generated/generated_theme_${layout.id}_white_background${icon.sizes.substr(icon.sizes.indexOf("x")+ 1)}.png`
if(!existsSync(whiteBgPath)){
for (const icon of whiteIcons) {
if (!existsSync(icon)) {
continue
}
apple_icons.push(`<link rel="apple-touch-icon" sizes="${icon.sizes}" href="${whiteBgPath}">`)
const size = icon.replace(/[^0-9]/g, "")
apple_icons.push(`<link rel="apple-touch-icon" sizes="${size}x${size}" href="${icon}">`)
}
let themeSpecific = [
@ -206,31 +275,32 @@ async function createIndexFor(theme: LayoutConfig) {
appendFileSync(filename, codeTemplate)
}
function createDir(path){
function createDir(path) {
if (!existsSync(path)) {
mkdirSync(path)
}
}
async function main(): Promise<void>{
async function main(): Promise<void> {
const alreadyWritten = []
createDir("./assets/generated")
createDir("./assets/generated/layers")
createDir("./assets/generated/themes")
createDir("./assets/generated/images")
const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap", "custom", "theme"]
// @ts-ignore
const all: LayoutConfigJson[] = all_known_layouts.themes;
const args = process.argv
const theme = args[2]
if(theme !== undefined){
console.warn("Only generating layout "+theme)
if (theme !== undefined) {
console.warn("Only generating layout " + theme)
}
for (const i in all) {
const layoutConfigJson: LayoutConfigJson = all[i]
if(theme !== undefined && layoutConfigJson.id !== theme){
if (theme !== undefined && layoutConfigJson.id !== theme) {
continue
}
const layout = new LayoutConfig(layoutConfigJson, true, "generating layouts")
@ -244,21 +314,20 @@ async function main(): Promise<void>{
console.log("Could not write manifest for ", layoutName, " because ", err)
}
};
await createManifest(layout, alreadyWritten).then(manifObj => {
const manif = JSON.stringify(manifObj, undefined, 2);
const {manifest, whiteIcons} = await createManifest(layout, alreadyWritten)
const manif = JSON.stringify(manifest, undefined, 2);
const manifestLocation = encodeURIComponent(layout.id.toLowerCase()) + ".webmanifest";
writeFile(manifestLocation, manif, err);
// Create a landing page for the given theme
createLandingPage(layout, manifObj).then(landing => {
createLandingPage(layout, manifest, whiteIcons, alreadyWritten).then(landing => {
writeFile(enc(layout.id) + ".html", landing, err)
});
createIndexFor(layout)
}).catch(e => console.log("Could not generate the manifest: ", e))
}
await createManifest(new LayoutConfig({
const {manifest, whiteIcons} = await createManifest(new LayoutConfig({
icon: "./assets/svg/mapcomplete_logo.svg",
id: "index",
layers: [],
@ -270,10 +339,10 @@ async function main(): Promise<void>{
title: {en: "MapComplete"},
version: Constants.vNumber,
description: {en: "A thematic map viewer and editor based on OpenStreetMap"}
}), alreadyWritten).then(manifObj => {
const manif = JSON.stringify(manifObj, undefined, 2);
}), alreadyWritten);
const manif = JSON.stringify(manifest, undefined, 2);
writeFileSync("index.manifest", manif)
})
}
main().then(() => {