From fc3e0625326f7ed6d2a824c8b7331cd8da92a0d8 Mon Sep 17 00:00:00 2001 From: Patrick Browne Date: Fri, 17 Feb 2023 13:14:04 +0100 Subject: [PATCH] feat: Improve styling of SVG map --- website/src/pages/api/v0.ts | 84 +++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/website/src/pages/api/v0.ts b/website/src/pages/api/v0.ts index 9da461c6..789dda36 100644 --- a/website/src/pages/api/v0.ts +++ b/website/src/pages/api/v0.ts @@ -23,10 +23,48 @@ const cors = initMiddleware( }) ); +const truthy = (x: T): x is Exclude => { + return Boolean(x); +}; const makeMapshaperStyleCommands = ( + shapeStyles: Record< + string, + null | { + fill?: string; + stroke?: string; + } + > +) => { + return Object.entries(shapeStyles) + .map(([shapeName, style]) => { + if (style === null) { + return style; + } + return `-style target='${shapeName}' ${Object.entries(style) + .map(([propName, propValue]) => { + return `${propName}='${propValue}'`; + }) + .join(" ")}`; + }) + .filter(truthy); +}; +const getShapeZIndex = (shape: string) => { + if (shape.includes("country")) { + return 3; + } else if (shape.includes("cantons")) { + return 2; + } else if (shape.includes("lakes")) { + return 1; + } + return 0; +}; +const shapeIndexComparator = (a: string, b: string) => { + const za = getShapeZIndex(a); + const zb = getShapeZIndex(b); + return za === zb ? 0 : za < zb ? -1 : 1; }; export default async function handler( @@ -45,17 +83,47 @@ export default async function handler( } const cwd = process.cwd(); + const shpFilenames = [...options.shapes] + .map((shapeName) => { + return path.join(cwd, "public", "swiss-maps", year, `${shapeName}.shp`); + }) + .sort(shapeIndexComparator); + + const hasCantons = shapes.has("cantons"); + const hasMunicipalities = shapes.has("municipalities"); + const hasLakes = shapes.has("lakes"); + + const shapeStyles = { + country: { + fill: hasCantons || hasMunicipalities ? "transparent" : "#eee", + stroke: "#111", + }, + lakes: hasLakes + ? { + fill: "#a1d0f7", + } + : null, + cantons: hasCantons + ? { + fill: hasMunicipalities ? "transparent" : "#eee", + stroke: "#666", + } + : null, + municipalities: hasMunicipalities + ? { + fill: "#eee", + stroke: hasCantons ? "#bbb" : "#666", + } + : null, + }; + + const styleCommands = makeMapshaperStyleCommands(shapeStyles); + const output = await generate({ ...options, - shpFilenames: [...options.shapes].map((shapeName) => { - return path.join(cwd, "public", "swiss-maps", year, `${shapeName}.shp`); - }), + shpFilenames: shpFilenames, mapshaperCommands: [ - // svg coloring, otherwise is all bblack - shapes.has("cantons") - ? `-style fill='#e6e6e6' stroke='#999' target='cantons'` - : "", - shapes.has("lakes") ? `-style fill='#a1d0f7' target='lakes'` : "", + ...styleCommands, `-o output.${format} format=${format} target=*`, ], });