From f47e78f487a88667b09f114094fada4078a036d4 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 3 Aug 2023 11:18:51 -0400 Subject: [PATCH 01/55] Add first six shields for Nova Scotia scenic drives --- icons/shield_ca_ns_s_et.svg | 24 ++++++++++++++++++++++++ icons/shield_ca_ns_s_fdlt.svg | 30 ++++++++++++++++++++++++++++++ icons/shield_ca_ns_s_lr.svg | 29 +++++++++++++++++++++++++++++ icons/shield_ca_ns_s_md.svg | 25 +++++++++++++++++++++++++ icons/shield_ca_ns_s_mt.svg | 31 +++++++++++++++++++++++++++++++ icons/shield_ca_ns_s_st.svg | 22 ++++++++++++++++++++++ src/js/shield_defs.js | 24 ++++++++++++++++++++++++ 7 files changed, 185 insertions(+) create mode 100644 icons/shield_ca_ns_s_et.svg create mode 100644 icons/shield_ca_ns_s_fdlt.svg create mode 100644 icons/shield_ca_ns_s_lr.svg create mode 100644 icons/shield_ca_ns_s_md.svg create mode 100644 icons/shield_ca_ns_s_mt.svg create mode 100644 icons/shield_ca_ns_s_st.svg diff --git a/icons/shield_ca_ns_s_et.svg b/icons/shield_ca_ns_s_et.svg new file mode 100644 index 000000000..d1298c67e --- /dev/null +++ b/icons/shield_ca_ns_s_et.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_fdlt.svg b/icons/shield_ca_ns_s_fdlt.svg new file mode 100644 index 000000000..d206bb49a --- /dev/null +++ b/icons/shield_ca_ns_s_fdlt.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_lr.svg b/icons/shield_ca_ns_s_lr.svg new file mode 100644 index 000000000..2d7dda103 --- /dev/null +++ b/icons/shield_ca_ns_s_lr.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_md.svg b/icons/shield_ca_ns_s_md.svg new file mode 100644 index 000000000..a29278b22 --- /dev/null +++ b/icons/shield_ca_ns_s_md.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_mt.svg b/icons/shield_ca_ns_s_mt.svg new file mode 100644 index 000000000..f02f86e2e --- /dev/null +++ b/icons/shield_ca_ns_s_mt.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_st.svg b/icons/shield_ca_ns_s_st.svg new file mode 100644 index 000000000..6a49ffde3 --- /dev/null +++ b/icons/shield_ca_ns_s_st.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 1949d4580..2e0c583fb 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -891,6 +891,9 @@ export function loadShields() { Color.shields.brown, Color.shields.white ); + shields["CA:NS:S"] = { + notext: true, + }; // Northwest Territories shields["CA:NT"] = { @@ -4201,6 +4204,27 @@ export function loadShields() { // Ref-specific cases. Each entry should be documented in CONTRIBUTE.md + shields["CA:NS:S"].overrideByRef = { + ET: { + spriteBlank: "shield_ca_ns_s_et", + }, + FdLt: { + spriteBlank: "shield_ca_ns_s_fdlt", + }, + LR: { + spriteBlank: "shield_ca_ns_s_lr", + }, + MD: { + spriteBlank: "shield_ca_ns_s_md", + }, + MT: { + spriteBlank: "shield_ca_ns_s_mt", + }, + ST: { + spriteBlank: "shield_ca_ns_s_st", + }, + }; + shields["CA:ON:primary"].overrideByRef = { QEW: { textColor: Color.shields.blue, From 0d3a752d25f13d0477a31c69118a38c9f0e7c88a Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 3 Aug 2023 16:37:39 -0400 Subject: [PATCH 02/55] Add shield for Cabot Trail and Bras d'Or Lakes Scenic Drive --- icons/shield_ca_ns_s_bdolsd.svg | 27 +++++++++++++++++++++++++++ icons/shield_ca_ns_s_ct.svg | 24 ++++++++++++++++++++++++ src/js/shield_defs.js | 6 ++++++ 3 files changed, 57 insertions(+) create mode 100644 icons/shield_ca_ns_s_bdolsd.svg create mode 100644 icons/shield_ca_ns_s_ct.svg diff --git a/icons/shield_ca_ns_s_bdolsd.svg b/icons/shield_ca_ns_s_bdolsd.svg new file mode 100644 index 000000000..77c3796ec --- /dev/null +++ b/icons/shield_ca_ns_s_bdolsd.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_ct.svg b/icons/shield_ca_ns_s_ct.svg new file mode 100644 index 000000000..7ac826b5f --- /dev/null +++ b/icons/shield_ca_ns_s_ct.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 2e0c583fb..ae69ff0a2 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -4205,6 +4205,12 @@ export function loadShields() { // Ref-specific cases. Each entry should be documented in CONTRIBUTE.md shields["CA:NS:S"].overrideByRef = { + BdOLSD: { + spriteBlank: "shield_ca_ns_s_bdolsd", + }, + CT: { + spriteBlank: "shield_ca_ns_s_ct", + }, ET: { spriteBlank: "shield_ca_ns_s_et", }, From 5cb46f730d719b0f52fc6c34136c853ac5a9f4d9 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 3 Aug 2023 21:11:15 -0400 Subject: [PATCH 03/55] Add two more nova scotia scenic drive shields --- icons/shield_ca_ns_s_cet.svg | 29 +++++++++++++++++++++++++++++ icons/shield_ca_ns_s_gt.svg | 24 ++++++++++++++++++++++++ src/js/shield_defs.js | 6 ++++++ 3 files changed, 59 insertions(+) create mode 100644 icons/shield_ca_ns_s_cet.svg create mode 100644 icons/shield_ca_ns_s_gt.svg diff --git a/icons/shield_ca_ns_s_cet.svg b/icons/shield_ca_ns_s_cet.svg new file mode 100644 index 000000000..716210c4f --- /dev/null +++ b/icons/shield_ca_ns_s_cet.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_gt.svg b/icons/shield_ca_ns_s_gt.svg new file mode 100644 index 000000000..65746f200 --- /dev/null +++ b/icons/shield_ca_ns_s_gt.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index ae69ff0a2..38c5469b3 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -4208,6 +4208,9 @@ export function loadShields() { BdOLSD: { spriteBlank: "shield_ca_ns_s_bdolsd", }, + CeT: { + spriteBlank: "shield_ca_ns_s_cet", + }, CT: { spriteBlank: "shield_ca_ns_s_ct", }, @@ -4217,6 +4220,9 @@ export function loadShields() { FdLt: { spriteBlank: "shield_ca_ns_s_fdlt", }, + GT: { + spriteBlank: "shield_ca_ns_s_gt", + }, LR: { spriteBlank: "shield_ca_ns_s_lr", }, From e70fe3bc15588577d08150caf43075674d704c00 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:56:49 -0400 Subject: [PATCH 04/55] Convert nova scotia scenic route shields to 17x21 --- icons/shield_ca_ns_s_bdolsd.svg | 29 +++++++++++---------------- icons/shield_ca_ns_s_cet.svg | 32 +++++++++++------------------- icons/shield_ca_ns_s_ct.svg | 22 +++++++-------------- icons/shield_ca_ns_s_et.svg | 22 +++++++-------------- icons/shield_ca_ns_s_fdlt.svg | 35 ++++++++++++++------------------- icons/shield_ca_ns_s_gt.svg | 23 ++++++++-------------- icons/shield_ca_ns_s_lr.svg | 27 +++++++------------------ icons/shield_ca_ns_s_md.svg | 27 +++++++++++-------------- icons/shield_ca_ns_s_mt.svg | 32 ++++++++++-------------------- icons/shield_ca_ns_s_st.svg | 19 ++++++------------ 10 files changed, 94 insertions(+), 174 deletions(-) diff --git a/icons/shield_ca_ns_s_bdolsd.svg b/icons/shield_ca_ns_s_bdolsd.svg index 77c3796ec..d27a52a11 100644 --- a/icons/shield_ca_ns_s_bdolsd.svg +++ b/icons/shield_ca_ns_s_bdolsd.svg @@ -1,27 +1,20 @@ - + - - + - - + + + + + + + + - + - - - - - - - - - - - - diff --git a/icons/shield_ca_ns_s_cet.svg b/icons/shield_ca_ns_s_cet.svg index 716210c4f..f8523af35 100644 --- a/icons/shield_ca_ns_s_cet.svg +++ b/icons/shield_ca_ns_s_cet.svg @@ -1,29 +1,21 @@ - + - - + - - + + + + + + + + + - + - - - - - - - - - - - - - - diff --git a/icons/shield_ca_ns_s_ct.svg b/icons/shield_ca_ns_s_ct.svg index 7ac826b5f..fa2c05e5b 100644 --- a/icons/shield_ca_ns_s_ct.svg +++ b/icons/shield_ca_ns_s_ct.svg @@ -1,24 +1,16 @@ - + - - + - - + + + + - + - - - - - - - - - diff --git a/icons/shield_ca_ns_s_et.svg b/icons/shield_ca_ns_s_et.svg index d1298c67e..23ec82fc3 100644 --- a/icons/shield_ca_ns_s_et.svg +++ b/icons/shield_ca_ns_s_et.svg @@ -1,24 +1,16 @@ - + - - + - - + + + + - + - - - - - - - - - diff --git a/icons/shield_ca_ns_s_fdlt.svg b/icons/shield_ca_ns_s_fdlt.svg index d206bb49a..8f057fcc1 100644 --- a/icons/shield_ca_ns_s_fdlt.svg +++ b/icons/shield_ca_ns_s_fdlt.svg @@ -1,30 +1,25 @@ - + - - + - - + + - + - - - - - - - - - - - - + + + + + + + + + + - - diff --git a/icons/shield_ca_ns_s_gt.svg b/icons/shield_ca_ns_s_gt.svg index 65746f200..b907a78cf 100644 --- a/icons/shield_ca_ns_s_gt.svg +++ b/icons/shield_ca_ns_s_gt.svg @@ -1,24 +1,17 @@ - + - - + - - + + + + + - + - - - - - - - - - diff --git a/icons/shield_ca_ns_s_lr.svg b/icons/shield_ca_ns_s_lr.svg index 2d7dda103..a478d5625 100644 --- a/icons/shield_ca_ns_s_lr.svg +++ b/icons/shield_ca_ns_s_lr.svg @@ -1,29 +1,16 @@ - + - - - + - - + + + + - + - - - - - - - - - - - - - diff --git a/icons/shield_ca_ns_s_md.svg b/icons/shield_ca_ns_s_md.svg index a29278b22..5e35b59b6 100644 --- a/icons/shield_ca_ns_s_md.svg +++ b/icons/shield_ca_ns_s_md.svg @@ -1,25 +1,20 @@ - + - - + - - + + + + + + + + - - - - - - - - - - - + diff --git a/icons/shield_ca_ns_s_mt.svg b/icons/shield_ca_ns_s_mt.svg index f02f86e2e..2c36efcf6 100644 --- a/icons/shield_ca_ns_s_mt.svg +++ b/icons/shield_ca_ns_s_mt.svg @@ -1,31 +1,19 @@ - + - - - + - - - - + + + + + + - + - - - - - - - - - - - - - + diff --git a/icons/shield_ca_ns_s_st.svg b/icons/shield_ca_ns_s_st.svg index 6a49ffde3..46ee7ebe1 100644 --- a/icons/shield_ca_ns_s_st.svg +++ b/icons/shield_ca_ns_s_st.svg @@ -1,22 +1,15 @@ - + - - + - - - + + + - - - - - - - + From 0a8ae07eb5ccbe5da6b0d048a67b50d8e081cbc4 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 7 Aug 2023 17:21:26 -0400 Subject: [PATCH 05/55] Add shields for Kejimkujik Scenic Drive and the Digby Necks and Islands Scenic Drive routes --- icons/shield_ca_ns_s_dnisd.svg | 12 ++++++++++++ icons/shield_ca_ns_s_ksd.svg | 19 +++++++++++++++++++ src/js/shield_defs.js | 6 ++++++ 3 files changed, 37 insertions(+) create mode 100644 icons/shield_ca_ns_s_dnisd.svg create mode 100644 icons/shield_ca_ns_s_ksd.svg diff --git a/icons/shield_ca_ns_s_dnisd.svg b/icons/shield_ca_ns_s_dnisd.svg new file mode 100644 index 000000000..b46081a94 --- /dev/null +++ b/icons/shield_ca_ns_s_dnisd.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/icons/shield_ca_ns_s_ksd.svg b/icons/shield_ca_ns_s_ksd.svg new file mode 100644 index 000000000..5270f0e63 --- /dev/null +++ b/icons/shield_ca_ns_s_ksd.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index e4569967e..f19797ca9 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -4218,6 +4218,9 @@ export function loadShields() { CT: { spriteBlank: "shield_ca_ns_s_ct", }, + DNISD: { + spriteBlank: "shield_ca_ns_s_dnisd", + }, ET: { spriteBlank: "shield_ca_ns_s_et", }, @@ -4227,6 +4230,9 @@ export function loadShields() { GT: { spriteBlank: "shield_ca_ns_s_gt", }, + KSD: { + spriteBlank: "shield_ca_ns_s_ksd", + }, LR: { spriteBlank: "shield_ca_ns_s_lr", }, From bab0b012d91d9f77a570e7f480954735f13fe9ea Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 7 Aug 2023 17:32:25 -0400 Subject: [PATCH 06/55] Fix eagle plumage --- icons/shield_ca_ns_s_bdolsd.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icons/shield_ca_ns_s_bdolsd.svg b/icons/shield_ca_ns_s_bdolsd.svg index d27a52a11..fddb5e67c 100644 --- a/icons/shield_ca_ns_s_bdolsd.svg +++ b/icons/shield_ca_ns_s_bdolsd.svg @@ -7,7 +7,7 @@ - + From 0016b5a660a69f7904a136381637592d124ba80e Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:50:52 -0400 Subject: [PATCH 07/55] Fix ref case (re: #912) --- src/js/shield_defs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 85bb761e6..4f02d56bb 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -4227,7 +4227,7 @@ export function loadShields() { ET: { spriteBlank: "shield_ca_ns_s_et", }, - FdLt: { + FdLT: { spriteBlank: "shield_ca_ns_s_fdlt", }, GT: { From 2507426bbcdf94f44913cfb603d2381ef02656b7 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Sat, 16 Dec 2023 22:40:51 -0500 Subject: [PATCH 08/55] Add firefox/safari options --- dev/README.md | 2 +- scripts/generate_samples.ts | 38 ++++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/dev/README.md b/dev/README.md index 1b7c23781..5c81836a3 100644 --- a/dev/README.md +++ b/dev/README.md @@ -19,4 +19,4 @@ Map sample images can be generated with a script. See [sample_locations.json](te 1. Create a JSON file with the map location and clipping rectangles 2. Start the server in the background with `npm start &` 3. Configure playwright: either `npx playwright install chromium` or `export CHROME_BIN=/usr/bin/chromium` -4. Run the generate_samples script and pass the JSON file location: `npm run generate_samples -- test/sample_locations.json`` +4. Run the generate_samples script and pass the JSON file location: `npm run generate_samples -- chrome test/sample_locations.json``. You may also use "firefox" or "safari". diff --git a/scripts/generate_samples.ts b/scripts/generate_samples.ts index 3093bba0f..2d0c6f5ce 100644 --- a/scripts/generate_samples.ts +++ b/scripts/generate_samples.ts @@ -1,5 +1,11 @@ import fs from "node:fs"; -import { chromium } from "@playwright/test"; +import { + Browser, + BrowserContext, + chromium, + firefox, + webkit, +} from "@playwright/test"; import type * as maplibre from "maplibre-gl"; // Declare a global augmentation for the Window interface @@ -33,23 +39,37 @@ const loadSampleLocations = (filePath: string): SampleSpecification[] => { const sampleFolder = "./samples"; -const jsonSampleLocations = process.argv[2] ?? "test/sample_locations.json"; +const jsonSampleLocations = process.argv[3] ?? "test/sample_locations.json"; console.log(`Loading sample locations from ${jsonSampleLocations}`); +const browserType = process.argv[2] ?? "chrome"; +console.log(`Using browser type: ${browserType}`); + const screenshots: SampleSpecification[] = loadSampleLocations(jsonSampleLocations); fs.mkdirSync(sampleFolder, { recursive: true }); -const browser = await chromium.launch({ - executablePath: process.env.CHROME_BIN, - args: ["--headless=new"], -}); -const context = await browser.newContext({ +let browser: Browser; + +switch (browserType) { + case "chrome": + default: + browser = await chromium.launch({ + executablePath: process.env.CHROME_BIN, + args: ["--headless=new"], + }); + break; + case "firefox": + browser = await firefox.launch(); + break; + case "safari": + browser = await webkit.launch(); +} + +const context: BrowserContext = await browser.newContext({ bypassCSP: true, - userAgent: - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", }); const page = await context.newPage(); From 6b7bb439de6df3619f8d91e5c216ae40fc17d9eb Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 18 Dec 2023 18:42:32 -0500 Subject: [PATCH 09/55] typing --- shieldlib/src/shield_text.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/shieldlib/src/shield_text.ts b/shieldlib/src/shield_text.ts index 350f7f02c..36ae645fb 100644 --- a/shieldlib/src/shield_text.ts +++ b/shieldlib/src/shield_text.ts @@ -170,15 +170,15 @@ export function layoutShieldText( ctx.textAlign = "center"; ctx.textBaseline = "top"; - var metrics = ctx.measureText(text); + var metrics: TextMetrics = ctx.measureText(text); - var textWidth = metrics.width; - var textHeight = metrics.actualBoundingBoxDescent; + var textWidth: number = metrics.width; + var textHeight: number = metrics.actualBoundingBoxDescent; - var availHeight = bounds.height - padTop - padBot; - var availWidth = bounds.width - padLeft - padRight; + var availHeight: number = bounds.height - padTop - padBot; + var availWidth: number = bounds.width - padLeft - padRight; - var xBaseline = padLeft + availWidth / 2; + var xBaseline: number = padLeft + availWidth / 2; let textLayoutFunc = drawTextFunctions[textLayoutDef.constraintFunc]; From 7a7b88cd0c3f3065d496d6a56a70b956b4fb2486 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 18 Dec 2023 23:07:10 -0500 Subject: [PATCH 10/55] Cross-browser compatibility --- shieldlib/src/shield.js | 12 ++++--- shieldlib/src/shield_banner.ts | 6 ++-- shieldlib/src/shield_text.ts | 65 +++++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/shieldlib/src/shield.js b/shieldlib/src/shield.js index f8d3c342d..a5cbe1ce6 100644 --- a/shieldlib/src/shield.js +++ b/shieldlib/src/shield.js @@ -100,7 +100,8 @@ function drawShieldText(r, ctx, shieldDef, routeDef) { var shieldBounds = null; var shieldArtwork = getRasterShieldBlank(r, shieldDef, routeDef); - let yOffset = bannerCount * r.px(r.options.bannerHeight); + let yOffset = + bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding); if (shieldArtwork == null) { ctx.translate(0, yOffset); @@ -132,7 +133,8 @@ function drawShieldText(r, ctx, shieldDef, routeDef) { shieldBounds ); - textLayout.yBaseline += bannerCount * r.px(r.options.bannerHeight); + textLayout.yBaseline += + bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding); if (typeof r.options.SHIELD_TEXT_HALO_COLOR_OVERRIDE !== "undefined") { ctx.strokeStyle = options.SHIELD_TEXT_HALO_COLOR_OVERRIDE; @@ -150,7 +152,7 @@ function drawShieldText(r, ctx, shieldDef, routeDef) { ctx.lineWidth = r.px(1); ctx.strokeRect( r.px(shieldDef.padding.left - 0.5), - bannerCount * r.px(r.options.bannerHeight) + + bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding) + r.px(shieldDef.padding.top - 0.5), shieldBounds.width - r.px(shieldDef.padding.left + shieldDef.padding.right - 1), @@ -322,7 +324,9 @@ export function generateShieldCtx(r, routeDef) { height = sourceSprite.data.height; } - let bannerHeight = bannerCount * r.px(r.options.bannerHeight); + let bannerHeight = + bannerCount * + (r.px(r.options.bannerHeight) + r.px(r.options.bannerPadding)); height += bannerHeight; //Generate empty canvas sized to the graphic diff --git a/shieldlib/src/shield_banner.ts b/shieldlib/src/shield_banner.ts index 6961865b5..deb86599d 100644 --- a/shieldlib/src/shield_banner.ts +++ b/shieldlib/src/shield_banner.ts @@ -133,7 +133,7 @@ function drawBannerTextComponent( textComponent: boolean ): void { const bannerPadding = { - top: r.options.bannerPadding, + top: 0, bottom: 0, left: 0, right: 0, @@ -161,7 +161,7 @@ function drawBannerTextComponent( text, textLayout.xBaseline, textLayout.yBaseline + - bannerIndex * r.px(r.options.bannerHeight - r.options.bannerPadding) + bannerIndex * r.px(r.options.bannerHeight + r.options.bannerPadding) ); } else { ctx.shadowBlur = 0; @@ -170,7 +170,7 @@ function drawBannerTextComponent( text, textLayout.xBaseline, textLayout.yBaseline + - bannerIndex * r.px(r.options.bannerHeight - r.options.bannerPadding) + bannerIndex * r.px(r.options.bannerHeight + r.options.bannerPadding) ); ctx.shadowColor = null; diff --git a/shieldlib/src/shield_text.ts b/shieldlib/src/shield_text.ts index 36ae645fb..57205a12e 100644 --- a/shieldlib/src/shield_text.ts +++ b/shieldlib/src/shield_text.ts @@ -84,7 +84,6 @@ function rectTextConstraint( ): TextTransform { var scaleHeight = spaceBounds.height / textBounds.height; var scaleWidth = spaceBounds.width / textBounds.width; - return { scale: Math.min(scaleWidth, scaleHeight), valign: VerticalAlignment.Middle, @@ -137,6 +136,12 @@ function triangleDownTextConstraint( }; } +// Warning!!! Hack!!! +function isRunningInWebKit(): boolean { + const userAgent = window.navigator.userAgent; + return /WebKit/i.test(userAgent) && !/Chrome/i.test(userAgent); +} + /** * Determines the position and font size to draw text so that it fits within * a bounding box. @@ -157,34 +162,49 @@ export function layoutShieldText( textLayoutDef: TextLayout, maxFontSize: number = 14 ): TextPlacement { - var padTop = r.px(padding.top) || 0; - var padBot = r.px(padding.bottom) || 0; - var padLeft = r.px(padding.left) || 0; - var padRight = r.px(padding.right) || 0; + let padTop = r.px(padding.top) || 0; + let padBot = r.px(padding.bottom) || 0; + let padLeft = r.px(padding.left) || 0; + let padRight = r.px(padding.right) || 0; - var maxFont = r.px(maxFontSize); + let maxFont = r.px(maxFontSize); //Temporary canvas for text measurment - var ctx = r.gfxFactory.createGraphics(bounds); + let ctx: CanvasRenderingContext2D = r.gfxFactory.createGraphics(bounds); ctx.font = Gfx.shieldFont(Gfx.fontSizeThreshold, r.options.shieldFont); - ctx.textAlign = "center"; + ctx.textAlign = "left"; ctx.textBaseline = "top"; - var metrics: TextMetrics = ctx.measureText(text); + let metrics: TextMetrics = ctx.measureText(text); - var textWidth: number = metrics.width; - var textHeight: number = metrics.actualBoundingBoxDescent; + let textWidth: number = + Math.abs(metrics.actualBoundingBoxLeft) + + Math.abs(metrics.actualBoundingBoxRight); + let textHeight: number = + Math.abs(metrics.actualBoundingBoxDescent) + + Math.abs(metrics.actualBoundingBoxAscent); - var availHeight: number = bounds.height - padTop - padBot; - var availWidth: number = bounds.width - padLeft - padRight; + //Adjust for excess descender text height across browsers + textHeight *= 0.9; - var xBaseline: number = padLeft + availWidth / 2; + //Adjust for excess text height measured in Webkit engine specifically + if (isRunningInWebKit()) { + textHeight *= 0.54; + } + + let availHeight: number = bounds.height - padTop - padBot; + let availWidth: number = bounds.width - padLeft - padRight; + + let xBaseline: number = padLeft + availWidth / 2; let textLayoutFunc = drawTextFunctions[textLayoutDef.constraintFunc]; - let textConstraint = textLayoutFunc( - { height: availHeight, width: availWidth }, - { height: textHeight, width: textWidth }, + let spaceAvail: Dimension = { height: availHeight, width: availWidth }; + let measuredTextBounds: Dimension = { height: textHeight, width: textWidth }; + + let textConstraint: TextTransform = textLayoutFunc( + spaceAvail, + measuredTextBounds, textLayoutDef.options ); @@ -195,20 +215,23 @@ export function layoutShieldText( ); ctx.font = Gfx.shieldFont(fontSize, r.options.shieldFont); - ctx.textAlign = "center"; + ctx.textAlign = "left"; ctx.textBaseline = "top"; metrics = ctx.measureText(text); - textHeight = metrics.actualBoundingBoxDescent; + textHeight = + Math.abs(metrics.actualBoundingBoxDescent) + + Math.abs(metrics.actualBoundingBoxAscent); let yBaseline: number; switch (textConstraint.valign) { case VerticalAlignment.Top: - yBaseline = padTop; + yBaseline = padTop + metrics.actualBoundingBoxAscent; break; case VerticalAlignment.Bottom: - yBaseline = padTop + availHeight - textHeight; + yBaseline = + padTop + availHeight - textHeight + metrics.actualBoundingBoxAscent; break; case VerticalAlignment.Middle: default: From 6d461defdf6ab1e42e2e4c4cdb34b6530e7ef340 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 18 Dec 2023 23:32:17 -0500 Subject: [PATCH 11/55] Add check for undefined window (for test cases) --- shieldlib/src/shield_text.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shieldlib/src/shield_text.ts b/shieldlib/src/shield_text.ts index 57205a12e..ef7aee582 100644 --- a/shieldlib/src/shield_text.ts +++ b/shieldlib/src/shield_text.ts @@ -138,6 +138,9 @@ function triangleDownTextConstraint( // Warning!!! Hack!!! function isRunningInWebKit(): boolean { + if (typeof window === "undefined") { + return false; + } const userAgent = window.navigator.userAgent; return /WebKit/i.test(userAgent) && !/Chrome/i.test(userAgent); } From de7869017aa3c8e24f9f9f99171ff41ab0303948 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 18 Dec 2023 23:37:49 -0500 Subject: [PATCH 12/55] Revert minor spacing --- shieldlib/src/shield_text.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/shieldlib/src/shield_text.ts b/shieldlib/src/shield_text.ts index ef7aee582..1e5815421 100644 --- a/shieldlib/src/shield_text.ts +++ b/shieldlib/src/shield_text.ts @@ -84,6 +84,7 @@ function rectTextConstraint( ): TextTransform { var scaleHeight = spaceBounds.height / textBounds.height; var scaleWidth = spaceBounds.width / textBounds.width; + return { scale: Math.min(scaleWidth, scaleHeight), valign: VerticalAlignment.Middle, From c19fb5f3bef7f3232d9f233ad63fe6872916e7e1 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Tue, 19 Dec 2023 20:08:47 -0500 Subject: [PATCH 13/55] Slightly reduce 2->3 shield threshold to 11.9px --- shieldlib/src/screen_gfx.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shieldlib/src/screen_gfx.ts b/shieldlib/src/screen_gfx.ts index eec3087e8..9db1b2d8b 100644 --- a/shieldlib/src/screen_gfx.ts +++ b/shieldlib/src/screen_gfx.ts @@ -5,7 +5,9 @@ import rgba from "color-rgba"; const defaultFontFamily = '"sans-serif-condensed", "Arial Narrow", sans-serif'; export const shieldFont = (size: number, fontFamily: string) => `condensed 500 ${size}px ${fontFamily || defaultFontFamily}`; -export const fontSizeThreshold = 12; + +//If a computed shield font size is below this value, choose a wider shield if possible +export const fontSizeThreshold = 11.9; // Replaces `sourceVal` with a blend of `lightenVal` and `darkenVal` proportional to the brightness; // i.e. white becomes `darkenVal`, black becomes `lightenVal`, and anit-aliased pixels remain anit-aliased From e2e235f5ca9cc2f202904753bd898a4c4875b1d5 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Tue, 19 Dec 2023 20:27:41 -0500 Subject: [PATCH 14/55] Slightly reduce 2->3 shield threshold to 11.8px --- shieldlib/src/screen_gfx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shieldlib/src/screen_gfx.ts b/shieldlib/src/screen_gfx.ts index 9db1b2d8b..3be40e4be 100644 --- a/shieldlib/src/screen_gfx.ts +++ b/shieldlib/src/screen_gfx.ts @@ -7,7 +7,7 @@ export const shieldFont = (size: number, fontFamily: string) => `condensed 500 ${size}px ${fontFamily || defaultFontFamily}`; //If a computed shield font size is below this value, choose a wider shield if possible -export const fontSizeThreshold = 11.9; +export const fontSizeThreshold = 11.8; // Replaces `sourceVal` with a blend of `lightenVal` and `darkenVal` proportional to the brightness; // i.e. white becomes `darkenVal`, black becomes `lightenVal`, and anit-aliased pixels remain anit-aliased From 29cc67abb606091fc3bcbf06414547148cc22275 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Tue, 19 Dec 2023 20:44:38 -0500 Subject: [PATCH 15/55] Slightly reduce 2->3 shield threshold to 11.5px --- shieldlib/src/screen_gfx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shieldlib/src/screen_gfx.ts b/shieldlib/src/screen_gfx.ts index 3be40e4be..4df4a72c0 100644 --- a/shieldlib/src/screen_gfx.ts +++ b/shieldlib/src/screen_gfx.ts @@ -7,7 +7,7 @@ export const shieldFont = (size: number, fontFamily: string) => `condensed 500 ${size}px ${fontFamily || defaultFontFamily}`; //If a computed shield font size is below this value, choose a wider shield if possible -export const fontSizeThreshold = 11.8; +export const fontSizeThreshold = 11.5; // Replaces `sourceVal` with a blend of `lightenVal` and `darkenVal` proportional to the brightness; // i.e. white becomes `darkenVal`, black becomes `lightenVal`, and anit-aliased pixels remain anit-aliased From 002c7ca2089af130d46a20d746552f72db22a43a Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Tue, 19 Dec 2023 20:50:38 -0500 Subject: [PATCH 16/55] Slightly reduce 2->3 shield threshold to 11px --- shieldlib/src/screen_gfx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shieldlib/src/screen_gfx.ts b/shieldlib/src/screen_gfx.ts index 4df4a72c0..ac9915a34 100644 --- a/shieldlib/src/screen_gfx.ts +++ b/shieldlib/src/screen_gfx.ts @@ -7,7 +7,7 @@ export const shieldFont = (size: number, fontFamily: string) => `condensed 500 ${size}px ${fontFamily || defaultFontFamily}`; //If a computed shield font size is below this value, choose a wider shield if possible -export const fontSizeThreshold = 11.5; +export const fontSizeThreshold = 11; // Replaces `sourceVal` with a blend of `lightenVal` and `darkenVal` proportional to the brightness; // i.e. white becomes `darkenVal`, black becomes `lightenVal`, and anit-aliased pixels remain anit-aliased From 1c65cc6b46ef71a84598ff3c50e84abb52b4d462 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Tue, 19 Dec 2023 20:55:41 -0500 Subject: [PATCH 17/55] Change 2->3 shield threshold to 11.8px --- shieldlib/src/screen_gfx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shieldlib/src/screen_gfx.ts b/shieldlib/src/screen_gfx.ts index ac9915a34..3be40e4be 100644 --- a/shieldlib/src/screen_gfx.ts +++ b/shieldlib/src/screen_gfx.ts @@ -7,7 +7,7 @@ export const shieldFont = (size: number, fontFamily: string) => `condensed 500 ${size}px ${fontFamily || defaultFontFamily}`; //If a computed shield font size is below this value, choose a wider shield if possible -export const fontSizeThreshold = 11; +export const fontSizeThreshold = 11.8; // Replaces `sourceVal` with a blend of `lightenVal` and `darkenVal` proportional to the brightness; // i.e. white becomes `darkenVal`, black becomes `lightenVal`, and anit-aliased pixels remain anit-aliased From d1eaa59e25f83dba1c537b91a7ce373aa56b974d Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Wed, 20 Dec 2023 22:51:38 -0500 Subject: [PATCH 18/55] Refactor math expression --- shieldlib/src/shield.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shieldlib/src/shield.js b/shieldlib/src/shield.js index a5cbe1ce6..fa20933c6 100644 --- a/shieldlib/src/shield.js +++ b/shieldlib/src/shield.js @@ -325,8 +325,7 @@ export function generateShieldCtx(r, routeDef) { } let bannerHeight = - bannerCount * - (r.px(r.options.bannerHeight) + r.px(r.options.bannerPadding)); + bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding); height += bannerHeight; //Generate empty canvas sized to the graphic From 24c5bcc154e8783738066e608fc745959a653270 Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Wed, 20 Dec 2023 22:45:30 -0800 Subject: [PATCH 19/55] Library icon, taginfo, addition to poi.js --- icons/poi_library.svg | 277 ++++++++++++++++++++++++++++++++++ scripts/taginfo_template.json | 8 + src/layer/poi.js | 10 ++ 3 files changed, 295 insertions(+) create mode 100644 icons/poi_library.svg diff --git a/icons/poi_library.svg b/icons/poi_library.svg new file mode 100644 index 000000000..ec4a6300f --- /dev/null +++ b/icons/poi_library.svg @@ -0,0 +1,277 @@ + + diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index 48cbf2850..173b0c3b1 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -496,6 +496,14 @@ "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_health_cross.svg" }, + { + "key": "amenity", + "value": "library", + "object_types": ["node", "area"], + "description": "Libraries are marked by an icon representing a person reading a book.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_library.svg" + }, { "key": "amenity", "value": "parking", diff --git a/src/layer/poi.js b/src/layer/poi.js index e7df969d5..c1a53ef8a 100644 --- a/src/layer/poi.js +++ b/src/layer/poi.js @@ -59,6 +59,14 @@ var iconDefs = { color: Color.poi.infrastructure, description: "Hospital", }, + library: { + classes: { + library: ["library"], + }, + sprite: "poi_library", + color: Color.poi.infrastructure, + description: "Library", + }, medical: { classes: { hospital: ["clinic"], @@ -267,6 +275,7 @@ export const poi = { "police", "school", "college", + "library", "townhall", ...getSubclasses(iconDefs.pow_christian), ...getSubclasses(iconDefs.pow_buddhist), @@ -294,6 +303,7 @@ export const poi = { [ "bus_stop", "hospital", + "library", "museum", "police", ...getSubclasses(iconDefs.fuel), From efad5a36db756dbb9f53c3d3d77b1c7358a8b813 Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Thu, 21 Dec 2023 07:06:43 -0800 Subject: [PATCH 20/55] code_format --- icons/poi_library.svg | 282 +----------------------------------------- 1 file changed, 5 insertions(+), 277 deletions(-) diff --git a/icons/poi_library.svg b/icons/poi_library.svg index ec4a6300f..4c9aead41 100644 --- a/icons/poi_library.svg +++ b/icons/poi_library.svg @@ -1,277 +1,5 @@ - - + + + + + From 755117b981b481da10895803230ac55b5db76ca9 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Thu, 21 Dec 2023 22:30:36 -0500 Subject: [PATCH 21/55] Fix bad programming decisions from past Brian --- shieldlib/src/shield.js | 77 +++++++++++++++--------------------- shieldlib/src/shield_text.ts | 2 +- 2 files changed, 32 insertions(+), 47 deletions(-) diff --git a/shieldlib/src/shield.js b/shieldlib/src/shield.js index fa20933c6..04ff352f4 100644 --- a/shieldlib/src/shield.js +++ b/shieldlib/src/shield.js @@ -76,18 +76,6 @@ function getDrawFunc(shieldDef) { return ShieldDraw.blank; } -function drawShield(r, ctx, shieldDef, routeDef) { - let bannerCount = getBannerCount(shieldDef); - let yOffset = bannerCount * r.px(r.options.bannerHeight); - - //Shift canvas to draw shield below banner - ctx.save(); - ctx.translate(0, yOffset); - let drawFunc = getDrawFunc(shieldDef); - drawFunc(r, ctx, routeDef.ref); - ctx.restore(); -} - function getDrawHeight(r, shieldDef) { if (typeof shieldDef.shapeBlank != "undefined") { return ShieldDraw.shapeHeight(r, shieldDef.shapeBlank.drawFunc); @@ -95,31 +83,7 @@ function getDrawHeight(r, shieldDef) { return r.shieldSize(); } -function drawShieldText(r, ctx, shieldDef, routeDef) { - var bannerCount = getBannerCount(shieldDef); - var shieldBounds = null; - - var shieldArtwork = getRasterShieldBlank(r, shieldDef, routeDef); - let yOffset = - bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding); - - if (shieldArtwork == null) { - ctx.translate(0, yOffset); - let drawFunc = getDrawFunc(shieldDef); - drawFunc(r, ctx, routeDef.ref); - ctx.translate(0, -yOffset); - - shieldBounds = { - width: ctx.canvas.width, - height: getDrawHeight(r, shieldDef), - }; - } else { - shieldBounds = { - width: shieldArtwork.data.width, - height: shieldArtwork.data.height, - }; - } - +function drawShieldText(r, ctx, shieldDef, routeDef, shieldBounds) { if (shieldDef.notext) { //If the shield definition says not to draw a ref, ignore ref return ctx; @@ -133,9 +97,6 @@ function drawShieldText(r, ctx, shieldDef, routeDef) { shieldBounds ); - textLayout.yBaseline += - bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding); - if (typeof r.options.SHIELD_TEXT_HALO_COLOR_OVERRIDE !== "undefined") { ctx.strokeStyle = options.SHIELD_TEXT_HALO_COLOR_OVERRIDE; ShieldText.drawShieldHaloText(r, ctx, routeDef.ref, textLayout); @@ -152,8 +113,7 @@ function drawShieldText(r, ctx, shieldDef, routeDef) { ctx.lineWidth = r.px(1); ctx.strokeRect( r.px(shieldDef.padding.left - 0.5), - bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding) + - r.px(shieldDef.padding.top - 0.5), + r.px(shieldDef.padding.top - 0.5), shieldBounds.width - r.px(shieldDef.padding.left + shieldDef.padding.right - 1), shieldBounds.height - @@ -296,6 +256,17 @@ function getDrawnShieldBounds(r, shieldDef, ref) { return { width, height }; } +function bannerAreaHeight(r, bannerCount) { + if (bannerCount === 0) { + return 0; + } + return ( + bannerCount * r.px(r.options.bannerHeight) + + //No padding after last banner + (bannerCount - 1) * r.px(r.options.bannerPadding) + ); +} + export function generateShieldCtx(r, routeDef) { let shieldDef = getShieldDef(r.shieldDef, routeDef); @@ -313,19 +284,25 @@ export function generateShieldCtx(r, routeDef) { let width = r.shieldSize(); let height = r.shieldSize(); + let shieldBounds = null; + if (sourceSprite == null) { if (typeof shieldDef.shapeBlank != "undefined") { let bounds = getDrawnShieldBounds(r, shieldDef, routeDef.ref); width = bounds.width; height = bounds.height; } + shieldBounds = { + width: width, + height: getDrawHeight(r, shieldDef), + }; } else { width = sourceSprite.data.width; height = sourceSprite.data.height; + shieldBounds = { width, height }; } - let bannerHeight = - bannerCount * r.px(r.options.bannerHeight + r.options.bannerPadding); + let bannerHeight = bannerAreaHeight(r, bannerCount); height += bannerHeight; //Generate empty canvas sized to the graphic @@ -341,9 +318,15 @@ export function generateShieldCtx(r, routeDef) { // Add the halo around modifier plaque text drawBannerHalos(r, ctx, shieldDef); + //Shift canvas to draw shield below banner + ctx.save(); + ctx.translate(0, bannerHeight); + if (sourceSprite == null) { - drawShield(r, ctx, shieldDef, routeDef); + let drawFunc = getDrawFunc(shieldDef); + drawFunc(r, ctx, routeDef.ref); } else { + //This is a raw copy, so the yOffset (bannerHeight) is needed Gfx.transposeImageData( ctx, sourceSprite, @@ -355,7 +338,9 @@ export function generateShieldCtx(r, routeDef) { } // Draw the shield text - drawShieldText(r, ctx, shieldDef, routeDef); + drawShieldText(r, ctx, shieldDef, routeDef, shieldBounds); + + ctx.restore(); // Add modifier plaque text drawBanners(r, ctx, shieldDef); diff --git a/shieldlib/src/shield_text.ts b/shieldlib/src/shield_text.ts index 1e5815421..5bc1071d0 100644 --- a/shieldlib/src/shield_text.ts +++ b/shieldlib/src/shield_text.ts @@ -84,7 +84,7 @@ function rectTextConstraint( ): TextTransform { var scaleHeight = spaceBounds.height / textBounds.height; var scaleWidth = spaceBounds.width / textBounds.width; - + return { scale: Math.min(scaleWidth, scaleHeight), valign: VerticalAlignment.Middle, From 0ed7c9925af1c16d597994f0718e9528eaa5b9c6 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 22 Dec 2023 20:45:47 -0500 Subject: [PATCH 22/55] Convert POI code to TS --- shieldlib/src/shield_renderer.ts | 2 +- src/js/poi.js | 41 -------------------- src/js/poi.ts | 66 ++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 42 deletions(-) delete mode 100644 src/js/poi.js create mode 100644 src/js/poi.ts diff --git a/shieldlib/src/shield_renderer.ts b/shieldlib/src/shield_renderer.ts index 3596d0875..cc8c30e93 100644 --- a/shieldlib/src/shield_renderer.ts +++ b/shieldlib/src/shield_renderer.ts @@ -245,7 +245,7 @@ export class AbstractShieldRenderer { } /** Get a blank route shield graphics context in a specified size */ - public createGraphics(bounds: Bounds) { + public createGraphics(bounds: Bounds): CanvasRenderingContext2D { return this._renderContext.gfxFactory.createGraphics(bounds); } diff --git a/src/js/poi.js b/src/js/poi.js deleted file mode 100644 index ff3bc6c7c..000000000 --- a/src/js/poi.js +++ /dev/null @@ -1,41 +0,0 @@ -import { transposeImageData } from "@americana/maplibre-shield-generator"; - -export function missingIconHandler(shieldRenderer, map, e) { - try { - missingIconLoader(shieldRenderer, map, e); - } catch (err) { - console.error(`Exception while loading image ‘${e?.id}’:\n`, err); - } -} - -export function missingIconLoader(shieldRenderer, map, e) { - var sprite = e.id.split("\n")[1].split("=")[1]; - var color = e.id.split("\n")[2].split("=")[1]; - - var sourceSprite = map.style.getImage(sprite); - - var width = sourceSprite.data.width; - var height = sourceSprite.data.height; - - var ctx = shieldRenderer.createGraphics({ width, height }); - transposeImageData(ctx, sourceSprite, 0, false, color); - - if (ctx == null) { - // Want to return null here, but that gives a corrupted display. See #243 - console.warn("Didn't produce an icon for", JSON.stringify(e.id)); - ctx = shieldRenderer.createGraphics({ width: 1, height: 1 }); - } - - const imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height); - map.addImage( - e.id, - { - width: ctx.canvas.width, - height: ctx.canvas.height, - data: imgData.data, - }, - { - pixelRatio: shieldRenderer.pixelRatio(), - } - ); -} diff --git a/src/js/poi.ts b/src/js/poi.ts new file mode 100644 index 000000000..8f6da6688 --- /dev/null +++ b/src/js/poi.ts @@ -0,0 +1,66 @@ +import { + transposeImageData, + AbstractShieldRenderer, +} from "@americana/maplibre-shield-generator"; +import { Map, MapStyleImageMissingEvent, StyleImage } from "maplibre-gl"; + +export function missingIconHandler( + shieldRenderer: AbstractShieldRenderer, + map: Map, + e: MapStyleImageMissingEvent +) { + try { + missingIconLoader(shieldRenderer, map, e); + } catch (err) { + console.error(`Exception while loading image ‘${e?.id}’:\n`, err); + } +} + +export function missingIconLoader( + shieldRenderer: AbstractShieldRenderer, + map: Map, + e: MapStyleImageMissingEvent +) { + const sprite: string = e.id.split("\n")[1].split("=")[1]; + const color: string = e.id.split("\n")[2].split("=")[1]; + + const sourceSprite: StyleImage = map.style.getImage(sprite); + + if (!sourceSprite) { + console.error(`No such sprite ${sprite}`); + return; + } + + const width: number = sourceSprite.data.width; + const height: number = sourceSprite.data.height; + + let ctx: CanvasRenderingContext2D = shieldRenderer.createGraphics({ + width, + height, + }); + transposeImageData(ctx, sourceSprite, 0, false, color); + + if (ctx == null) { + // Want to return null here, but that gives a corrupted display. See #243 + console.warn("Didn't produce an icon for", JSON.stringify(e.id)); + ctx = shieldRenderer.createGraphics({ width: 1, height: 1 }); + } + + const imgData: ImageData = ctx.getImageData( + 0, + 0, + ctx.canvas.width, + ctx.canvas.height + ); + map.addImage( + e.id, + { + width: ctx.canvas.width, + height: ctx.canvas.height, + data: imgData.data, + }, + { + pixelRatio: shieldRenderer.pixelRatio(), + } + ); +} From 737dae4f67770081a02ffb25bf2f6b41997f1c42 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 22 Dec 2023 21:19:36 -0500 Subject: [PATCH 23/55] Add sprite safety check --- shieldlib/src/shield_renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shieldlib/src/shield_renderer.ts b/shieldlib/src/shield_renderer.ts index cc8c30e93..9f023376c 100644 --- a/shieldlib/src/shield_renderer.ts +++ b/shieldlib/src/shield_renderer.ts @@ -70,7 +70,7 @@ class MaplibreGLSpriteRepository implements SpriteRepository { options: StyleImageMetadata, update: boolean ): void { - if (update) { + if (update && this.map.listImages().includes(spriteID)) { this.map.removeImage(spriteID); this.map.addImage(spriteID, image); } else { From afc1bd820c68b1165b7a26b954ead99812ac94a1 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 22 Dec 2023 21:46:19 -0500 Subject: [PATCH 24/55] Fix ShieldJSON race condition --- shieldlib/src/shield.js | 5 +++++ shieldlib/src/shield_renderer.ts | 1 + 2 files changed, 6 insertions(+) diff --git a/shieldlib/src/shield.js b/shieldlib/src/shield.js index f8d3c342d..e521455eb 100644 --- a/shieldlib/src/shield.js +++ b/shieldlib/src/shield.js @@ -203,6 +203,11 @@ function refForDefs(routeDef, shieldDef) { } function getShieldDef(shields, routeDef) { + if (!shields) { + //This occurs if the ShieldJSON is loaded from the network and hasn't loaded yet. + return null; + } + var shieldDef = shields[routeDef.network]; if (routeDef == null) { diff --git a/shieldlib/src/shield_renderer.ts b/shieldlib/src/shield_renderer.ts index 9f023376c..826555688 100644 --- a/shieldlib/src/shield_renderer.ts +++ b/shieldlib/src/shield_renderer.ts @@ -106,6 +106,7 @@ export class AbstractShieldRenderer { this._renderContext.options = shieldSpec.options; this._renderContext.shieldDef = shieldSpec.networks; this._fontSpec = "1em " + shieldSpec.options.shieldFont; + console.log("ShieldJSON loaded"); if (this._map) { this.reloadShieldsOnFontLoad(); } From a16733c4d990ccc2e71165cbe78c7f01c284a0b4 Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Sun, 24 Dec 2023 11:41:13 -0800 Subject: [PATCH 25/55] Universities from z10 --- src/layer/poi.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/layer/poi.js b/src/layer/poi.js index c2447533d..07982176d 100644 --- a/src/layer/poi.js +++ b/src/layer/poi.js @@ -275,7 +275,7 @@ export const poi = { "parking", "police", "school", - "college", + ...getSubclasses(iconDefs.college), "townhall", ...getSubclasses(iconDefs.pow_christian), ...getSubclasses(iconDefs.pow_buddhist), @@ -296,9 +296,15 @@ export const poi = { [ "match", ["get", "subclass"], - ["station", "halt"], + [ + ...getSubclasses(iconDefs.college), + ], + 10, + [ + "station", + "halt"], 12, - ["bus_station", "subway", ...getSubclasses(iconDefs.college)], + ["bus_station", "subway"], 14, [ "bus_stop", From c08648c5ef29ca9c257cab982a411a416682d9db Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Mon, 1 Jan 2024 09:51:56 -0800 Subject: [PATCH 26/55] Added sample location and changed to upright book icon --- icons/poi_book_upright.svg | 6 ++++++ icons/poi_library.svg | 5 ----- src/layer/poi.js | 2 +- test/sample_locations.json | 8 ++++++++ 4 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 icons/poi_book_upright.svg delete mode 100644 icons/poi_library.svg diff --git a/icons/poi_book_upright.svg b/icons/poi_book_upright.svg new file mode 100644 index 000000000..b13bdc7bc --- /dev/null +++ b/icons/poi_book_upright.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/icons/poi_library.svg b/icons/poi_library.svg deleted file mode 100644 index 4c9aead41..000000000 --- a/icons/poi_library.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/layer/poi.js b/src/layer/poi.js index a43716955..dae11fbdc 100644 --- a/src/layer/poi.js +++ b/src/layer/poi.js @@ -63,7 +63,7 @@ var iconDefs = { classes: { library: ["library"], }, - sprite: "poi_library", + sprite: "poi_book_upright", color: Color.poi.infrastructure, description: "Library", }, diff --git a/test/sample_locations.json b/test/sample_locations.json index 9fc9c110a..3f3505dab 100644 --- a/test/sample_locations.json +++ b/test/sample_locations.json @@ -47,5 +47,13 @@ "width": 400, "height": 400 } + }, + { + "location": "17/40.753326/-73.982224", + "name": "library_z17", + "viewport": { + "width": 400, + "height": 400 + } } ] From c7c5a7d2023726d1d1a03c46cef855806ce4f512 Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Mon, 1 Jan 2024 10:07:38 -0800 Subject: [PATCH 27/55] Update taginfo_template.json --- scripts/taginfo_template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index f014d1101..cb0191bee 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -500,7 +500,7 @@ "key": "amenity", "value": "library", "object_types": ["node", "area"], - "description": "Libraries are marked by an icon representing a person reading a book.", + "description": "Libraries are marked by an icon representing a book.", "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_library.svg" }, From cb0ae4c20b7eec609a5cac9a47499d2c45783db9 Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Mon, 1 Jan 2024 10:08:30 -0800 Subject: [PATCH 28/55] Update taginfo_template.json --- scripts/taginfo_template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index cb0191bee..c099b5b06 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -502,7 +502,7 @@ "object_types": ["node", "area"], "description": "Libraries are marked by an icon representing a book.", "doc_url": "https://openmaptiles.org/schema/#poi", - "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_library.svg" + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_book_upright.svg" }, { "key": "amenity", From 1196781b66e241c058ac667674d2a7845c34bf23 Mon Sep 17 00:00:00 2001 From: Jeroen van der Gun Date: Sun, 7 Jan 2024 01:43:50 +0100 Subject: [PATCH 29/55] White shield border for Irish N-road and British A-road --- src/js/shield_defs.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index a906aeb39..275f6157f 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -3320,6 +3320,7 @@ export function loadShields() { shields["omt-ie-national"] = roundedRectShield( Color.shields.green, + Color.shields.white, Color.shields.yellow ); @@ -3535,6 +3536,7 @@ export function loadShields() { shields["omt-gb-trunk"] = roundedRectShield( Color.shields.green, + Color.shields.white, Color.shields.yellow ); From b97ca662dd895e01e111359f83b627260466de23 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 11 Jan 2024 06:22:11 -0500 Subject: [PATCH 30/55] Adding vehicle POI icons --- icons/poi_car_repair.svg | 4 ++++ icons/poi_car_shop.svg | 4 ++++ icons/poi_taxi.svg | 5 +++++ src/layer/poi.js | 35 ++++++++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 icons/poi_car_repair.svg create mode 100644 icons/poi_car_shop.svg create mode 100644 icons/poi_taxi.svg diff --git a/icons/poi_car_repair.svg b/icons/poi_car_repair.svg new file mode 100644 index 000000000..042bff803 --- /dev/null +++ b/icons/poi_car_repair.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/poi_car_shop.svg b/icons/poi_car_shop.svg new file mode 100644 index 000000000..cfcf82ba7 --- /dev/null +++ b/icons/poi_car_shop.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/poi_taxi.svg b/icons/poi_taxi.svg new file mode 100644 index 000000000..c8dcb2193 --- /dev/null +++ b/icons/poi_taxi.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/layer/poi.js b/src/layer/poi.js index c2447533d..6059fdd24 100644 --- a/src/layer/poi.js +++ b/src/layer/poi.js @@ -35,6 +35,30 @@ var iconDefs = { color: Color.poi.transport, description: "Bus stop", }, + car_repair: { + classes: { + car: ["car_repair"], + }, + sprite: "poi_car_repair", + color: Color.poi.consumer, + description: "Car mechanic", + }, + car_shop: { + classes: { + car: ["car"], + }, + sprite: "poi_car_shop", + color: Color.poi.consumer, + description: "Car dealership", + }, + taxi: { + classes: { + office: ["taxi"], + }, + sprite: "poi_taxi", + color: Color.poi.transport, + description: "Taxi stand", + }, coffee: { classes: { cafe: ["cafe"], @@ -259,6 +283,8 @@ export const poi = { ...getSubclasses(iconDefs.bar), ...getSubclasses(iconDefs.coffee), ...getSubclasses(iconDefs.supermarket), + ...getSubclasses(iconDefs.car_shop), + ...getSubclasses(iconDefs.car_repair), ], Color.poi.consumer, [ @@ -266,6 +292,7 @@ export const poi = { "bus_stop", ...getSubclasses(iconDefs.railway_station), ...getSubclasses(iconDefs.railway_stop), + ...getSubclasses(iconDefs.taxi), ], Color.poi.transport, ["museum"], @@ -320,7 +347,13 @@ export const poi = { "tram_stop", ], 15, - [...getSubclasses(iconDefs.bar), ...getSubclasses(iconDefs.coffee)], + [ + ...getSubclasses(iconDefs.bar), + ...getSubclasses(iconDefs.coffee), + ...getSubclasses(iconDefs.car_shop), + ...getSubclasses(iconDefs.car_repair), + ...getSubclasses(iconDefs.taxi), + ], 16, ["clinic", "doctors", "parking"], 17, From 1e7b889bfaa72948830baada27a6d3757ecaa010 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 11 Jan 2024 20:43:17 -0500 Subject: [PATCH 31/55] Updating taginfo with vehicle icons --- scripts/taginfo_template.json | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index 868967ced..043e7fae9 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -399,6 +399,14 @@ "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_school.svg" }, + { + "key": "amenity", + "value": "taxi", + "object_types": ["node", "area"], + "description": "Taxi stands are marked by an icon representing the front view of a taxi cab.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_taxi.svg" + }, { "key": "amenity", "value": "kindergarten", @@ -632,6 +640,22 @@ "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_pow_taoist.svg" }, + { + "key": "shop", + "value": "car", + "object_types": ["node", "area"], + "description": "Car dealerships are marked by an icon representing a front facing vehicle.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_car_shop.svg" + }, + { + "key": "shop", + "value": "car_repair", + "object_types": ["node", "area"], + "description": "Car dealerships are marked by an icon representing a front facing vehicle with a wrench above it.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_car_repair.svg" + }, { "key": "shop", "value": "supermarket", From 7b984830ccd331086873e183d0c312dcb97efc74 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 11 Jan 2024 20:44:03 -0500 Subject: [PATCH 32/55] Updating sample locations with NoVA car-centric intersection --- test/sample_locations.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/sample_locations.json b/test/sample_locations.json index 2ff11454f..2505eb3dd 100644 --- a/test/sample_locations.json +++ b/test/sample_locations.json @@ -55,5 +55,13 @@ "width": 400, "height": 400 } + }, + { + "location": "16/38.896954/-77.108406", + "name": "virginia_", + "viewport": { + "width": 400, + "height": 400 + } } ] From 60cd926159ecd4f1587f3009e08de74726ff0367 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 11 Jan 2024 20:45:56 -0500 Subject: [PATCH 33/55] Updating typo in taginfo --- scripts/taginfo_template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index 043e7fae9..7ca152068 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -652,7 +652,7 @@ "key": "shop", "value": "car_repair", "object_types": ["node", "area"], - "description": "Car dealerships are marked by an icon representing a front facing vehicle with a wrench above it.", + "description": "Car mechanic shops are marked by an icon representing a front facing vehicle with a wrench above it.", "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_car_repair.svg" }, From b6aa55bcf7858f0922738cf373304f058fec3085 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 12 Jan 2024 19:59:40 -0500 Subject: [PATCH 34/55] Script for icon gridding --- CONTRIBUTING.md | 6 + package-lock.json | 663 ++++++++++++++++++++++++++++++++++++++----- package.json | 2 + scripts/icon_grid.ts | 69 +++++ 4 files changed, 669 insertions(+), 71 deletions(-) create mode 100644 scripts/icon_grid.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 216ac2039..41a359531 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -269,6 +269,12 @@ The MUTCD’s standard colors are designed for high-contrast backgrounds and leg See the [developer tools](dev/README.md) for an importable, Inkscape-compatible palette file. +### Icon Grid Alignment + +There is a utility script called icon_grid that will generate a pixel grid on an SVG. This can be used to check how well the icon will align to the pixel grid. Run this utility as follows: + +`npm run icon_grid -- icons/poi_fuel.svg` + ### Font Sizes Shields should target 8-14px text actual-size character heights for readability: diff --git a/package-lock.json b/package-lock.json index 7833bdf99..51fca5472 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", + "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", @@ -74,6 +75,91 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/@basemaps/sprites/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@basemaps/sprites/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@basemaps/sprites/node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@basemaps/sprites/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.45.0.tgz", + "integrity": "sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==", + "dev": true, + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", @@ -426,6 +512,456 @@ "node": ">=12" } }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz", + "integrity": "sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.1" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.2.tgz", + "integrity": "sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.1" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.1.tgz", + "integrity": "sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.1.tgz", + "integrity": "sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.1.tgz", + "integrity": "sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.1.tgz", + "integrity": "sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.1.tgz", + "integrity": "sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.1.tgz", + "integrity": "sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.1.tgz", + "integrity": "sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.2.tgz", + "integrity": "sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.1" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.2.tgz", + "integrity": "sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.1" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.2.tgz", + "integrity": "sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.1" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.2.tgz", + "integrity": "sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.1" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.2.tgz", + "integrity": "sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.1" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.2.tgz", + "integrity": "sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.1" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.2.tgz", + "integrity": "sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "optional": true, + "dependencies": { + "@emnapi/runtime": "^0.45.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.2.tgz", + "integrity": "sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.2.tgz", + "integrity": "sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -719,6 +1255,16 @@ "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==" }, + "node_modules/@types/sharp": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.32.0.tgz", + "integrity": "sha512-OOi3kL+FZDnPhVzsfD37J88FNeZh6gQsGcLc95NbeURRGvmSjeXiDcyWzF2o3yh/gQAUn2uhh/e+CPCa5nwAxw==", + "deprecated": "This is a stub types definition. sharp provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "sharp": "*" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -1990,10 +2536,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -3273,9 +3822,9 @@ "dev": true }, "node_modules/node-abi": { - "version": "3.51.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", - "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", + "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==", "dev": true, "dependencies": { "semver": "^7.3.5" @@ -4348,78 +4897,43 @@ "dev": true }, "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "version": "0.33.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.2.tgz", + "integrity": "sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==", "dev": true, "hasInstallScript": true, "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=14.15.0" + "libvips": ">=8.15.1", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sharp/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sharp/node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.2", + "@img/sharp-darwin-x64": "0.33.2", + "@img/sharp-libvips-darwin-arm64": "1.0.1", + "@img/sharp-libvips-darwin-x64": "1.0.1", + "@img/sharp-libvips-linux-arm": "1.0.1", + "@img/sharp-libvips-linux-arm64": "1.0.1", + "@img/sharp-libvips-linux-s390x": "1.0.1", + "@img/sharp-libvips-linux-x64": "1.0.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.1", + "@img/sharp-libvips-linuxmusl-x64": "1.0.1", + "@img/sharp-linux-arm": "0.33.2", + "@img/sharp-linux-arm64": "0.33.2", + "@img/sharp-linux-s390x": "0.33.2", + "@img/sharp-linux-x64": "0.33.2", + "@img/sharp-linuxmusl-arm64": "0.33.2", + "@img/sharp-linuxmusl-x64": "0.33.2", + "@img/sharp-wasm32": "0.33.2", + "@img/sharp-win32-ia32": "0.33.2", + "@img/sharp-win32-x64": "0.33.2" } }, "node_modules/shebang-command": { @@ -4703,9 +5217,9 @@ "dev": true }, "node_modules/streamx": { - "version": "2.15.5", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.5.tgz", - "integrity": "sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==", + "version": "2.15.6", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", + "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", "dev": true, "dependencies": { "fast-fifo": "^1.1.0", @@ -5003,6 +5517,13 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true, + "optional": true + }, "node_modules/tsx": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.6.2.tgz", diff --git a/package.json b/package.json index ecef53ce5..95bdd315a 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "code_format:svgo": "svgo -q -f icons/", "extract_layer": "node scripts/extract_layer", "generate_samples": "tsx scripts/generate_samples.ts", + "icon_grid": "tsx scripts/icon_grid.ts", "presprites": "shx rm -rf dist/sprites", "serve": "tsx scripts/serve", "shields": "node scripts/generate_shield_defs.js -o dist/shields.json", @@ -55,6 +56,7 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", + "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts new file mode 100644 index 000000000..75384de5e --- /dev/null +++ b/scripts/icon_grid.ts @@ -0,0 +1,69 @@ +import sharp from "sharp"; +import fs from "fs"; +import path from "path"; + +const svgFilename = process.argv[2]; +const outputFilenameBase = path.parse(svgFilename).name; +const outputFilename = `${outputFilenameBase}_preview.png`; +const scale = 40; + +// Function to generate a pixel grid +function generateGridPattern(): Buffer { + const gridSvg = ` + + + + + `; + return Buffer.from(gridSvg); +} + +// Convert and scale SVG +async function convertAndScaleSVG(svgFilename: string): Promise { + try { + const svgBuffer = fs.readFileSync(svgFilename); + + // Get dimensions of the original SVG + const metadata = await sharp(svgBuffer).metadata(); + const width = metadata.width! * scale; + const height = metadata.height! * scale; + + // Resize the SVG + const resizedSvgBuffer = await sharp(svgBuffer, { + density: 72 * scale, + }) + .resize(width, height) + .toBuffer(); + + // Generate a pixel grid pattern + const gridPattern = generateGridPattern(); + + // Composite the scaled image over the grid + sharp({ + create: { + width: width, + height: height, + channels: 4, + background: { r: 255, g: 255, b: 255, alpha: 0 }, + }, + }) + .composite([ + { input: resizedSvgBuffer, blend: "over" }, + { input: generateGridPattern(), tile: true, blend: "over" }, + ]) + .toFile(outputFilename) + .then(() => console.log(`Wrote ${outputFilename}`)) + .catch((err) => console.error(err)); + } catch (error) { + console.error("Error:", error); + } +} + +if (!svgFilename) { + console.error("Please provide an SVG filename."); + process.exit(1); +} + +convertAndScaleSVG(svgFilename); From 07d90adb2e3bf1a8ba60c48efb60da3d3d7893cb Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 12 Jan 2024 20:25:37 -0500 Subject: [PATCH 35/55] Fix odd/even alignment --- scripts/icon_grid.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 75384de5e..61e6a7b4e 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -8,14 +8,15 @@ const outputFilename = `${outputFilenameBase}_preview.png`; const scale = 40; // Function to generate a pixel grid -function generateGridPattern(): Buffer { +function generateGridPattern(xOffset: number, yOffset: number): Buffer { const gridSvg = ` - - + - `; return Buffer.from(gridSvg); } @@ -37,8 +38,11 @@ async function convertAndScaleSVG(svgFilename: string): Promise { .resize(width, height) .toBuffer(); + const xOffset: number = width % 2 == 0 ? scale / 2 : 0; + const yOffset: number = height % 2 == 0 ? scale / 2 : 0; + // Generate a pixel grid pattern - const gridPattern = generateGridPattern(); + const gridPattern = generateGridPattern(xOffset, yOffset); // Composite the scaled image over the grid sharp({ @@ -51,7 +55,7 @@ async function convertAndScaleSVG(svgFilename: string): Promise { }) .composite([ { input: resizedSvgBuffer, blend: "over" }, - { input: generateGridPattern(), tile: true, blend: "over" }, + { input: gridPattern, tile: true, blend: "over" }, ]) .toFile(outputFilename) .then(() => console.log(`Wrote ${outputFilename}`)) From 938d897176f16f9a504cc399b8c58c4181d626a8 Mon Sep 17 00:00:00 2001 From: Josh Lee Date: Mon, 15 Jan 2024 09:58:08 -0500 Subject: [PATCH 36/55] Correct dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Need to actually depend on sharp, not just type definitions And the type definitions actually say  WARN  deprecated @types/sharp@0.32.0: This is a stub types definition. sharp provides its own type definitions, so you do not need this installed. So remove them --- package-lock.json | 12 +----------- package.json | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 51fca5472..623957d73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,6 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", - "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", @@ -44,6 +43,7 @@ "open": "^8.4.2", "pbf": "^3.2.1", "prettier": "^2.3.2", + "sharp": "^0.33.2", "shx": "^0.3.4", "svgo": "^2.8.0", "tsx": "^4.6.2", @@ -1255,16 +1255,6 @@ "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==" }, - "node_modules/@types/sharp": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.32.0.tgz", - "integrity": "sha512-OOi3kL+FZDnPhVzsfD37J88FNeZh6gQsGcLc95NbeURRGvmSjeXiDcyWzF2o3yh/gQAUn2uhh/e+CPCa5nwAxw==", - "deprecated": "This is a stub types definition. sharp provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "sharp": "*" - } - }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", diff --git a/package.json b/package.json index 95bdd315a..a55d536da 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "@types/color-namer": "^1.3.0", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", - "@types/sharp": "^0.32.0", "benchmark": "^2.1.4", "canvas": "^2.11.0", "chai": "^4.3.7", @@ -71,6 +70,7 @@ "open": "^8.4.2", "pbf": "^3.2.1", "prettier": "^2.3.2", + "sharp": "^0.33.2", "shx": "^0.3.4", "svgo": "^2.8.0", "tsx": "^4.6.2", From 0a457ad6fdf7c76570a857d5237fe78559eb62bf Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 13:46:28 -0500 Subject: [PATCH 37/55] Update scripts/icon_grid.ts Co-authored-by: Josh Lee --- scripts/icon_grid.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 61e6a7b4e..59c8cb65e 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -70,4 +70,9 @@ if (!svgFilename) { process.exit(1); } -convertAndScaleSVG(svgFilename); +try { + await convertAndScaleSVG(svgFilename); +} catch (error) { + console.error("Error: ", error); + process.exit(1); +} From 407ff3785228737a809ea6fa37926b6efe420190 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 13:46:34 -0500 Subject: [PATCH 38/55] Update scripts/icon_grid.ts Co-authored-by: Josh Lee --- scripts/icon_grid.ts | 65 ++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 59c8cb65e..e5e9420b4 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -23,46 +23,41 @@ function generateGridPattern(xOffset: number, yOffset: number): Buffer { // Convert and scale SVG async function convertAndScaleSVG(svgFilename: string): Promise { - try { - const svgBuffer = fs.readFileSync(svgFilename); + const svgBuffer = fs.readFileSync(svgFilename); - // Get dimensions of the original SVG - const metadata = await sharp(svgBuffer).metadata(); - const width = metadata.width! * scale; - const height = metadata.height! * scale; + // Get dimensions of the original SVG + const metadata = await sharp(svgBuffer).metadata(); + const width = metadata.width! * scale; + const height = metadata.height! * scale; - // Resize the SVG - const resizedSvgBuffer = await sharp(svgBuffer, { - density: 72 * scale, - }) - .resize(width, height) - .toBuffer(); + // Resize the SVG + const resizedSvgBuffer = await sharp(svgBuffer, { + density: 72 * scale, + }) + .resize(width, height) + .toBuffer(); - const xOffset: number = width % 2 == 0 ? scale / 2 : 0; - const yOffset: number = height % 2 == 0 ? scale / 2 : 0; + const xOffset: number = width % 2 == 0 ? scale / 2 : 0; + const yOffset: number = height % 2 == 0 ? scale / 2 : 0; - // Generate a pixel grid pattern - const gridPattern = generateGridPattern(xOffset, yOffset); + // Generate a pixel grid pattern + const gridPattern = generateGridPattern(xOffset, yOffset); - // Composite the scaled image over the grid - sharp({ - create: { - width: width, - height: height, - channels: 4, - background: { r: 255, g: 255, b: 255, alpha: 0 }, - }, - }) - .composite([ - { input: resizedSvgBuffer, blend: "over" }, - { input: gridPattern, tile: true, blend: "over" }, - ]) - .toFile(outputFilename) - .then(() => console.log(`Wrote ${outputFilename}`)) - .catch((err) => console.error(err)); - } catch (error) { - console.error("Error:", error); - } + // Composite the scaled image over the grid + await sharp({ + create: { + width, + height, + channels: 4, + background: { r: 255, g: 255, b: 255, alpha: 0 }, + }, + }) + .composite([ + { input: resizedSvgBuffer, blend: "over" }, + { input: gridPattern, tile: true, blend: "over" }, + ]) + .toFile(outputFilename); + console.log(`Wrote ${outputFilename}`); } if (!svgFilename) { From df84136528061aeaa3113db6be7f231be5fc4093 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 18:51:25 -0500 Subject: [PATCH 39/55] Light gray background --- scripts/icon_grid.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index e5e9420b4..899a7cd3e 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -49,7 +49,7 @@ async function convertAndScaleSVG(svgFilename: string): Promise { width, height, channels: 4, - background: { r: 255, g: 255, b: 255, alpha: 0 }, + background: { r: 211, g: 211, b: 211, alpha: 1 }, // Light gray to show white borders }, }) .composite([ From 11897813e6d9ed71df13ccedb0b90358c9a2b26e Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Mon, 15 Jan 2024 18:55:04 -0500 Subject: [PATCH 40/55] offset bugfix --- scripts/icon_grid.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/icon_grid.ts b/scripts/icon_grid.ts index 899a7cd3e..72996e16b 100644 --- a/scripts/icon_grid.ts +++ b/scripts/icon_grid.ts @@ -37,8 +37,8 @@ async function convertAndScaleSVG(svgFilename: string): Promise { .resize(width, height) .toBuffer(); - const xOffset: number = width % 2 == 0 ? scale / 2 : 0; - const yOffset: number = height % 2 == 0 ? scale / 2 : 0; + const xOffset: number = metadata.width! % 2 == 0 ? scale / 2 : 0; + const yOffset: number = metadata.height! % 2 == 0 ? scale / 2 : 0; // Generate a pixel grid pattern const gridPattern = generateGridPattern(xOffset, yOffset); From 5e5ab5d228597400f9838d1c388ef7b3a8efbc9a Mon Sep 17 00:00:00 2001 From: b1tw153 Date: Sun, 21 Jan 2024 09:26:24 -0800 Subject: [PATCH 41/55] adding az shield --- icons/shield_us_az_scenic.svg | 16 ++++++++++++++++ src/js/shield_defs.js | 6 ++++++ 2 files changed, 22 insertions(+) create mode 100644 icons/shield_us_az_scenic.svg diff --git a/icons/shield_us_az_scenic.svg b/icons/shield_us_az_scenic.svg new file mode 100644 index 000000000..bff968fbd --- /dev/null +++ b/icons/shield_us_az_scenic.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 275f6157f..04bfd834b 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -653,6 +653,12 @@ export function loadShields() { )) ); + // Arizona + shields["US:AZ:Scenic"] = { + spriteBlank: "shield_us_az_scenic", + notext: true, + }; + // Arkansas shields["US:AR"] = { spriteBlank: ["shield_us_ar_2", "shield_us_ar_3"], From 42499fb9a57dae4bf2bdb97050d3067455dd21eb Mon Sep 17 00:00:00 2001 From: Will Date: Fri, 26 Jan 2024 06:19:07 -0500 Subject: [PATCH 42/55] Adding hotel and hostel POI icons --- icons/poi_hostel.svg | 3 +++ icons/poi_hotel.svg | 3 +++ scripts/taginfo_template.json | 33 ++++++++++++++++++++++++++++++++- src/layer/poi.js | 20 ++++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 icons/poi_hostel.svg create mode 100644 icons/poi_hotel.svg diff --git a/icons/poi_hostel.svg b/icons/poi_hostel.svg new file mode 100644 index 000000000..04d8bf388 --- /dev/null +++ b/icons/poi_hostel.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/poi_hotel.svg b/icons/poi_hotel.svg new file mode 100644 index 000000000..576f5a1d7 --- /dev/null +++ b/icons/poi_hotel.svg @@ -0,0 +1,3 @@ + + + diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index a1891714f..32399044d 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -487,6 +487,38 @@ "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_town_hall.svg" }, + { + "key": "tourism", + "value": "guest_house", + "object_types": ["node", "area"], + "description": "Guest houses are marked by an icon representing a person laying in a bed.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_hotel.svg" + }, + { + "key": "tourism", + "value": "hostel", + "object_types": ["node", "area"], + "description": "Hostels are marked by an icon representing two people laying in a bunk bed.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_hostel.svg" + }, + { + "key": "tourism", + "value": "hotel", + "object_types": ["node", "area"], + "description": "Hotels are marked by an icon representing a person laying in a bed.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_hotel.svg" + }, + { + "key": "tourism", + "value": "motel", + "object_types": ["node", "area"], + "description": "Motels are marked by an icon representing a person laying in a bed.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_hotel.svg" + }, { "key": "tourism", "value": "museum", @@ -495,7 +527,6 @@ "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_museum.svg" }, - { "key": "amenity", "value": "clinic", diff --git a/src/layer/poi.js b/src/layer/poi.js index 59b4dc77e..cd9c3d1ed 100644 --- a/src/layer/poi.js +++ b/src/layer/poi.js @@ -83,6 +83,22 @@ var iconDefs = { color: Color.poi.infrastructure, description: "Hospital", }, + hotel: { + classes: { + lodging: ["hotel", "motel", "guest_house"], + }, + sprite: "poi_hotel", + color: Color.poi.consumer, + description: "Hotel", + }, + hostel: { + classes: { + lodging: ["hostel"], + }, + sprite: "poi_hostel", + color: Color.poi.consumer, + description: "Hostel", + }, library: { classes: { library: ["library"], @@ -293,6 +309,8 @@ export const poi = { ...getSubclasses(iconDefs.supermarket), ...getSubclasses(iconDefs.car_shop), ...getSubclasses(iconDefs.car_repair), + ...getSubclasses(iconDefs.hotel), + ...getSubclasses(iconDefs.hostel), ], Color.poi.consumer, [ @@ -363,6 +381,8 @@ export const poi = { ...getSubclasses(iconDefs.car_shop), ...getSubclasses(iconDefs.car_repair), ...getSubclasses(iconDefs.taxi), + ...getSubclasses(iconDefs.hotel), + ...getSubclasses(iconDefs.hostel), ], 16, ["clinic", "doctors", "parking"], From fe3979be01d214390efa734f865dc9052c965d1e Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 1 Feb 2024 06:37:07 -0500 Subject: [PATCH 43/55] Adding sample locations for hotel and hostel poi --- test/sample_locations.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/sample_locations.json b/test/sample_locations.json index 8b448923e..8a150106d 100644 --- a/test/sample_locations.json +++ b/test/sample_locations.json @@ -71,5 +71,21 @@ "width": 400, "height": 400 } + }, + { + "location": "16/38.906341/-77.025889", + "name": "dc_logan_circle", + "viewport": { + "width": 400, + "height": 400 + } + }, + { + "location": "16/40.755264/-73.987405", + "name": "manhattan_times_square", + "viewport": { + "width": 400, + "height": 400 + } } ] From 6c91bc56d543802fb4183ae863c1a62737b3e377 Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Sat, 17 Feb 2024 22:06:29 -0800 Subject: [PATCH 44/55] Bookstore taginfo, poi, sample location --- icons/shield_us_az_scenic.svg | 28 ++++++++++++++-------------- scripts/taginfo_template.json | 8 ++++++++ src/layer/poi.js | 10 ++++++++++ test/sample_locations.json | 2 +- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/icons/shield_us_az_scenic.svg b/icons/shield_us_az_scenic.svg index bff968fbd..d027e8acd 100644 --- a/icons/shield_us_az_scenic.svg +++ b/icons/shield_us_az_scenic.svg @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index 32399044d..bea48d109 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -679,6 +679,14 @@ "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_pow_taoist.svg" }, + { + "key": "shop", + "value": "books", + "object_types": ["node", "area"], + "description": "Bookstores are marked by an icon representing a book.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_book_upright.svg" + }, { "key": "shop", "value": "car", diff --git a/src/layer/poi.js b/src/layer/poi.js index cd9c3d1ed..f13ef15ff 100644 --- a/src/layer/poi.js +++ b/src/layer/poi.js @@ -19,6 +19,14 @@ var iconDefs = { color: Color.poi.consumer, description: "Bar or pub", }, + bookstore: { + classes: { + library: ["books"], + }, + sprite: "poi_book_upright", + color: Color.poi.consumer, + description: "Bookstore", + }, bus_station: { classes: { bus: ["bus_station"], @@ -305,6 +313,7 @@ export const poi = { [ ...getSubclasses(iconDefs.fuel), ...getSubclasses(iconDefs.bar), + ...getSubclasses(iconDefs.bookstore), ...getSubclasses(iconDefs.coffee), ...getSubclasses(iconDefs.supermarket), ...getSubclasses(iconDefs.car_shop), @@ -377,6 +386,7 @@ export const poi = { 15, [ ...getSubclasses(iconDefs.bar), + ...getSubclasses(iconDefs.bookstore), ...getSubclasses(iconDefs.coffee), ...getSubclasses(iconDefs.car_shop), ...getSubclasses(iconDefs.car_repair), diff --git a/test/sample_locations.json b/test/sample_locations.json index 8a150106d..dd5ba8dfe 100644 --- a/test/sample_locations.json +++ b/test/sample_locations.json @@ -49,7 +49,7 @@ } }, { - "location": "17/40.753326/-73.982224", + "location": "17/40.753922/-73.984244", "name": "library_z17", "viewport": { "width": 400, From ffce2c581ec42756275299e0ebffee17cc0c89b7 Mon Sep 17 00:00:00 2001 From: wmisener <58491489+wmisener@users.noreply.github.com> Date: Sun, 18 Feb 2024 17:58:35 -0800 Subject: [PATCH 45/55] Post office icon, taginfo, rendering --- icons/poi_envelope.svg | 3 +++ scripts/taginfo_template.json | 8 ++++++++ src/layer/poi.js | 10 ++++++++++ 3 files changed, 21 insertions(+) create mode 100644 icons/poi_envelope.svg diff --git a/icons/poi_envelope.svg b/icons/poi_envelope.svg new file mode 100644 index 000000000..65113dabc --- /dev/null +++ b/icons/poi_envelope.svg @@ -0,0 +1,3 @@ + + + diff --git a/scripts/taginfo_template.json b/scripts/taginfo_template.json index 32399044d..17bd981a5 100644 --- a/scripts/taginfo_template.json +++ b/scripts/taginfo_template.json @@ -487,6 +487,14 @@ "doc_url": "https://openmaptiles.org/schema/#poi", "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_town_hall.svg" }, + { + "key": "amenity", + "value": "post_office", + "object_types": ["node", "area"], + "description": "Post offices are marked by an icon representing an envelope.", + "doc_url": "https://openmaptiles.org/schema/#poi", + "icon_url": "https://raw.githubusercontent.com/ZeLonewolf/openstreetmap-americana/main/icons/poi_envelope.svg" + }, { "key": "tourism", "value": "guest_house", diff --git a/src/layer/poi.js b/src/layer/poi.js index cd9c3d1ed..a6b7aa9ac 100644 --- a/src/layer/poi.js +++ b/src/layer/poi.js @@ -140,6 +140,14 @@ var iconDefs = { color: Color.poi.infrastructure, description: "Police station", }, + post_office: { + classes: { + post: ["post_office"], + }, + sprite: "poi_envelope", + color: Color.poi.infrastructure, + description: "Post office", + }, pow_buddhist: { classes: { place_of_worship: ["buddhist"], @@ -331,6 +339,7 @@ export const poi = { "college", "library", "townhall", + ...getSubclasses(iconDefs.post_office), ...getSubclasses(iconDefs.pow_christian), ...getSubclasses(iconDefs.pow_buddhist), ...getSubclasses(iconDefs.pow_hindu), @@ -361,6 +370,7 @@ export const poi = { "museum", "police", ...getSubclasses(iconDefs.fuel), + ...getSubclasses(iconDefs.post_office), ...getSubclasses(iconDefs.pow_buddhist), ...getSubclasses(iconDefs.pow_christian), ...getSubclasses(iconDefs.pow_hindu), From c6a1e522de5da98e60a5877868ecbae52404e6f3 Mon Sep 17 00:00:00 2001 From: Clay Smalley Date: Mon, 1 Apr 2024 11:13:30 -0400 Subject: [PATCH 46/55] add Weld County Parkway shield --- src/js/shield_defs.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 04bfd834b..c9c799428 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -847,6 +847,10 @@ export function loadShields() { Color.shields.green, Color.shields.white ); + shields["US:CO:Weld:WCP"] = { + ...pentagonUpShield(3, 15, Color.shields.purple, Color.shields.green), + textHaloColor: Color.shields.white, + }; // Connecticut shields["US:CT"] = roundedRectShield( From 026a44d1868ac95f0637b418c288afac48d05415 Mon Sep 17 00:00:00 2001 From: Clay Smalley Date: Mon, 1 Apr 2024 12:31:41 -0400 Subject: [PATCH 47/55] add county-assigned US National Park shields --- src/js/shield_defs.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 04bfd834b..f275351d6 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -1638,6 +1638,13 @@ export function loadShields() { ["TRK"], Color.shields.blue ); + ["Sussex", "Warren"].forEach( + (county) => + (shields[`US:NJ:${county}:NPS`] = pillShield( + Color.shields.brown, + Color.shields.white + )) + ); // New Mexico shields["US:NM"] = pillShield( @@ -2242,6 +2249,10 @@ export function loadShields() { bottom: 8, }, }; + shields["US:SD:Custer:NPS"] = roundedRectShield( + Color.shields.brown, + Color.shields.yellow + ); // Tennessee shields["US:TN:primary"] = { From 55e3d766e83ef143ea677f3b02a18db01134b65e Mon Sep 17 00:00:00 2001 From: Clay Smalley Date: Tue, 2 Apr 2024 16:40:59 -0400 Subject: [PATCH 48/55] change Weld County Parkway shield from purple to blue --- src/js/shield_defs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index a30384cee..73003e18f 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -848,7 +848,7 @@ export function loadShields() { Color.shields.white ); shields["US:CO:Weld:WCP"] = { - ...pentagonUpShield(3, 15, Color.shields.purple, Color.shields.green), + ...pentagonUpShield(3, 15, Color.shields.blue, Color.shields.green), textHaloColor: Color.shields.white, }; From 5bad43ec7881e2dc5edcd6a2bca3f276872aaebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Fri, 26 Jan 2024 19:03:59 -0800 Subject: [PATCH 49/55] Renamed shield image names based on structured route properties The name of each shield image in the style is now based on structured route properties and can includes the route name and color. --- src/js/shield_format.ts | 14 ++----- src/layer/highway_shield.js | 47 +++++++++--------------- test/shield_format/shield_format.spec.ts | 4 +- test/spec/highway_shield.js | 28 +++++++------- test/spec/shield.js | 22 +++++------ 5 files changed, 50 insertions(+), 65 deletions(-) diff --git a/src/js/shield_format.ts b/src/js/shield_format.ts index ae6ffdd32..10368bbf5 100644 --- a/src/js/shield_format.ts +++ b/src/js/shield_format.ts @@ -3,6 +3,8 @@ import type { RouteParser, } from "@americana/maplibre-shield-generator"; +import { parseImageName } from "../layer/highway_shield.js"; + export const shieldPredicate: StringPredicate = (imageID: string) => imageID && imageID.startsWith("shield"); @@ -14,16 +16,8 @@ export const networkPredicate: StringPredicate = (network: string) => export const routeParser: RouteParser = { parse: (id: string) => { - //Americana format is `${shield}\n${network}=${ref}\n${name}` - let id_parts: string[] = id.split("\n"); - let network_ref = id_parts[1].split("="); - - return { - network: network_ref[0], - ref: network_ref[1], - name: id_parts[2], - }; + return parseImageName(id); }, format: (network: string, ref: string, name: string) => - `shield\n${network}=${ref}\n${name}`, + `shield\n${network}\n${ref}\n${name}\n`, }; diff --git a/src/layer/highway_shield.js b/src/layer/highway_shield.js index 319a37224..2e2d65d75 100644 --- a/src/layer/highway_shield.js +++ b/src/layer/highway_shield.js @@ -1,33 +1,23 @@ "use strict"; -export const namedRouteNetworks = [ - "US:CT:Parkway", - "US:KY:Parkway", - "US:NH:Turnpike", - "US:NY:Parkway", - "US:TX:Fort_Bend:FBCTRA", - "US:TX:Harris:HCTRA", -]; +const orderedRouteAttributes = ["network", "ref", "name", "color"]; export function getImageNameExpression(routeIndex) { - return [ - "concat", - "shield\n", - ["get", "route_" + routeIndex], - [ - "match", - ["get", "route_" + routeIndex], - namedRouteNetworks.map((n) => n + "="), - ["concat", "\n", ["get", "name"]], - "", - ], - ]; + let concat = ["concat", "shield"]; + for (let attr of orderedRouteAttributes) { + concat.push("\n"); + concat.push(["coalesce", ["get", `route_${routeIndex}_${attr}`], ""]); + } + return concat; } function routeConcurrency(routeIndex) { return [ "case", - ["!=", ["get", "route_" + routeIndex], null], + [ + "any", + ...orderedRouteAttributes.map(a => ["has", `route_${routeIndex}_${a}`]), + ], ["image", getImageNameExpression(routeIndex)], ["literal", ""], ]; @@ -37,12 +27,14 @@ function routeConcurrency(routeIndex) { * Returns a structured representation of the given image name. * * @param name An image name in the format returned by `routeConcurrency`. + * @return An object with the keys in `orderedRouteAttributes` plus the full image name in `imageName`. */ export function parseImageName(imageName) { let lines = imageName.split("\n"); - let [, network, ref] = lines[1].match(/^(.*?)=(.*)/) || []; - let name = lines[2]; - return { imageName, network, ref, name }; + lines.shift(); // "shield" + let parsed = Object.fromEntries(orderedRouteAttributes.map((a, i) => [a, lines[i]])); + parsed.imageName = imageName; + return parsed; } let shieldTextField = ["format"]; @@ -113,11 +105,6 @@ export const shield = { }, filter: [ "any", - ["has", "route_1"], - ["has", "route_2"], - ["has", "route_3"], - ["has", "route_4"], - ["has", "route_5"], - ["has", "route_6"], + ...orderedRouteAttributes.map(a => ["has", `route_1_${a}`]), ], }; diff --git a/test/shield_format/shield_format.spec.ts b/test/shield_format/shield_format.spec.ts index 0c72201ef..f79177a7e 100644 --- a/test/shield_format/shield_format.spec.ts +++ b/test/shield_format/shield_format.spec.ts @@ -1,10 +1,11 @@ import { expect } from "chai"; import { shieldPredicate, routeParser } from "../../src/js/shield_format.js"; -const image_id_I95 = "shield\nUS:I=95"; +const image_id_I95 = "shield\nUS:I\n95\nEye Ninety-Five"; const route_def_I95 = { network: "US:I", ref: "95", + name: "Eye Ninety-Five", }; describe("shield_format", function () { @@ -19,6 +20,7 @@ describe("shield_format", function () { let extractedDef = routeParser.parse(image_id_I95); expect(extractedDef.network).to.be.equal(route_def_I95.network); expect(extractedDef.ref).to.be.equal(route_def_I95.ref); + expect(extractedDef.name).to.be.equal(route_def_I95.name); }); }); }); diff --git a/test/spec/highway_shield.js b/test/spec/highway_shield.js index 14df94866..cf7c38570 100644 --- a/test/spec/highway_shield.js +++ b/test/spec/highway_shield.js @@ -17,20 +17,20 @@ describe("highway_shield", function () { .createExpression(HighwayShieldLayers.getImageNameExpression(1)) .value.expression.evaluate(expressionContext(properties)); - let expectImageName = (network, ref, name, expectedImageName) => { + let expectImageName = (network, ref, name, color, expectedImageName) => { let properties = { - route_1: `${network || ""}=${ref || ""}`, - name: name || null, + route_1_network: network || "", + route_1_ref: ref || "", + route_1_name: name || "", + route_1_color: color || "", }; let evaluated = evaluatedExpression(properties); let expectedProperties = { imageName: expectedImageName, network: network || "", ref: ref || "", - name: - !ref && HighwayShieldLayers.namedRouteNetworks.includes(network) - ? name - : undefined, + name: name || "", + color: color || "", }; expect(HighwayShieldLayers.parseImageName(evaluated)).to.be.deep.equal( expectedProperties @@ -38,28 +38,30 @@ describe("highway_shield", function () { }; it("parses an image name for a numbered route", function () { - expectImageName("NET", "REF", undefined, "shield\nNET=REF"); - expectImageName("NET", "REF", "NAME", "shield\nNET=REF"); + expectImageName("NET", "REF", undefined, undefined, "shield\nNET\nREF\n\n"); + expectImageName("NET", "REF", "NAME", undefined, "shield\nNET\nREF\nNAME\n"); }); it("parses an image name for an unnumbered route", function () { - expectImageName("NET", undefined, undefined, "shield\nNET="); + expectImageName("NET", undefined, undefined, undefined, "shield\nNET\n\n\n"); }); it("parses an image name for a named route", function () { expectImageName( "US:KY:Parkway", undefined, "NAME", - "shield\nUS:KY:Parkway=\nNAME" + undefined, + "shield\nUS:KY:Parkway\n\nNAME\n" ); expectImageName( "US:KY:Parkway", "REF", "NAME", - "shield\nUS:KY:Parkway=REF" + undefined, + "shield\nUS:KY:Parkway\nREF\nNAME\n" ); }); it("parses an image name for a network-independent route", function () { - expectImageName(undefined, "REF", "NAME", "shield\n=REF"); + expectImageName(undefined, "REF", "NAME", undefined, "shield\n\nREF\nNAME\n"); }); }); }); diff --git a/test/spec/shield.js b/test/spec/shield.js index 2fb4b4bf2..29beb569d 100644 --- a/test/spec/shield.js +++ b/test/spec/shield.js @@ -25,11 +25,11 @@ const shieldRenderer = new ShieldRenderer(shields, routeParser) const handler = shieldRenderer.getStyleImageMissingHandler(); -handler({ id: "shield\nBAB=5" }); -handler({ id: "shield\nUS:RI=" }); -handler({ id: "shield\nUS:RI=ABC123" }); -handler({ id: "shield\nUS:RI=Equator" }); -handler({ id: "shield\nrwn=" }); +handler({ id: "shield\nBAB\n5\n\n" }); +handler({ id: "shield\nUS:RI\n\n\n" }); +handler({ id: "shield\nUS:RI\nABC123\n\n" }); +handler({ id: "shield\nUS:RI\nEquator\n\n" }); +handler({ id: "shield\nrwn\n\n\n" }); handler({ id: "foo" }); function isBlankSprite(id) { @@ -39,8 +39,8 @@ function isBlankSprite(id) { describe("shield", function () { describe("#isValidNetwork", function () { it("rejects a recreational network", function () { - expect(isBlankSprite("shield\nBAB=5")).to.be.false; - expect(isBlankSprite("shield\nrwn=")).to.be.true; + expect(isBlankSprite("shield\nBAB\n5\n\n")).to.be.false; + expect(isBlankSprite("shield\nrwn\n\n\n")).to.be.true; }); it("rejects other missing image prefixes", function () { expect(mockRepo.hasSprite("foo")).to.be.false; @@ -48,12 +48,12 @@ describe("shield", function () { }); describe("#isValidRef", function () { it("rejects an empty ref", function () { - expect(isBlankSprite("shield\nUS:RI=")).to.be.true; + expect(isBlankSprite("shield\nUS:RI\n\n\n")).to.be.true; }); it("rejects a long ref", function () { - expect(mockRepo.hasSprite("shield\nUS:RI=ABC123")).to.be.true; - expect(isBlankSprite("shield\nUS:RI=ABC123")).to.be.false; - expect(isBlankSprite("shield\nUS:RI=Equator")).to.be.true; + expect(mockRepo.hasSprite("shield\nUS:RI\nABC123\n\n")).to.be.true; + expect(isBlankSprite("shield\nUS:RI\nABC123\n\n")).to.be.false; + expect(isBlankSprite("shield\nUS:RI\nEquator\n\n")).to.be.true; }); }); }); From f83d0fe79446001eadf53f589eae24b6f0c9f775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Fri, 26 Jan 2024 19:18:35 -0800 Subject: [PATCH 50/55] Upgraded to OpenMapTiles v3.15 tileset --- src/configs/config.aws.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configs/config.aws.js b/src/configs/config.aws.js index 9727e7f64..51e032ebc 100644 --- a/src/configs/config.aws.js +++ b/src/configs/config.aws.js @@ -3,7 +3,7 @@ /* Planetiler tile server, hosted at AWS */ -const OPENMAPTILES_URL = "https://tile.ourmap.us/data/v3.json"; +const OPENMAPTILES_URL = "https://tile.ourmap.us/data/omt_3_15.json"; /* The following two variables override the color of the bounding box and halo of From 8719c55106a420251661343acb8e0733d738b221 Mon Sep 17 00:00:00 2001 From: Clay Smalley Date: Thu, 18 Apr 2024 10:43:09 -0400 Subject: [PATCH 51/55] change shields of Lincoln and Rock Counties, Minnesota --- src/js/shield_defs.js | 39 ++++++++++++++++++++++++------------- src/layer/highway_shield.js | 8 +++++--- test/spec/highway_shield.js | 32 ++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 73003e18f..8b16d9543 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -1276,7 +1276,6 @@ export function loadShields() { "Lake", "Lake_of_the_Woods", "Le_Sueur", - "Lincoln", "Lyon", "Mahnomen", "Marshall", @@ -1302,7 +1301,6 @@ export function loadShields() { "Redwood", "Renville", "Rice", - "Rock", "Roseau", "Saint_Louis", "Scott", @@ -1325,11 +1323,7 @@ export function loadShields() { "Yellow_Medicine", ].forEach( (county) => - ([ - shields[`US:MN:${county}:CSAH`], - shields[`US:MN:${county}:CR`], - shields[`US:MN:${county}:Park_Access`], - ] = [ + ([shields[`US:MN:${county}:CSAH`], shields[`US:MN:${county}:CR`]] = [ pentagonUpShield( 3, 15, @@ -1338,15 +1332,32 @@ export function loadShields() { Color.shields.white ), roundedRectShield(Color.shields.white, Color.shields.black), - trapezoidDownShield( - 10, - Color.shields.brown, - Color.shields.white, - Color.shields.white, - 2 - ), ]) ); + ["CSAH", "CR"].forEach( + (network) => + (shields[`US:MN:Lincoln:${network}`] = pentagonUpShield( + 3, + 15, + Color.shields.blue, + Color.shields.yellow, + Color.shields.white + )) + ); + ["CSAH", "CR"].forEach( + (network) => + (shields[`US:MN:Rock:${network}`] = roundedRectShield( + Color.shields.white, + Color.shields.black + )) + ); + shields[`US:MN:Hennepin:Park_Access`] = trapezoidDownShield( + 10, + Color.shields.brown, + Color.shields.white, + Color.shields.white, + 2 + ); // Missouri shields["US:MO"] = { diff --git a/src/layer/highway_shield.js b/src/layer/highway_shield.js index 2e2d65d75..6c24abb43 100644 --- a/src/layer/highway_shield.js +++ b/src/layer/highway_shield.js @@ -16,7 +16,7 @@ function routeConcurrency(routeIndex) { "case", [ "any", - ...orderedRouteAttributes.map(a => ["has", `route_${routeIndex}_${a}`]), + ...orderedRouteAttributes.map((a) => ["has", `route_${routeIndex}_${a}`]), ], ["image", getImageNameExpression(routeIndex)], ["literal", ""], @@ -32,7 +32,9 @@ function routeConcurrency(routeIndex) { export function parseImageName(imageName) { let lines = imageName.split("\n"); lines.shift(); // "shield" - let parsed = Object.fromEntries(orderedRouteAttributes.map((a, i) => [a, lines[i]])); + let parsed = Object.fromEntries( + orderedRouteAttributes.map((a, i) => [a, lines[i]]) + ); parsed.imageName = imageName; return parsed; } @@ -105,6 +107,6 @@ export const shield = { }, filter: [ "any", - ...orderedRouteAttributes.map(a => ["has", `route_1_${a}`]), + ...orderedRouteAttributes.map((a) => ["has", `route_1_${a}`]), ], }; diff --git a/test/spec/highway_shield.js b/test/spec/highway_shield.js index cf7c38570..20939d3f4 100644 --- a/test/spec/highway_shield.js +++ b/test/spec/highway_shield.js @@ -38,11 +38,29 @@ describe("highway_shield", function () { }; it("parses an image name for a numbered route", function () { - expectImageName("NET", "REF", undefined, undefined, "shield\nNET\nREF\n\n"); - expectImageName("NET", "REF", "NAME", undefined, "shield\nNET\nREF\nNAME\n"); + expectImageName( + "NET", + "REF", + undefined, + undefined, + "shield\nNET\nREF\n\n" + ); + expectImageName( + "NET", + "REF", + "NAME", + undefined, + "shield\nNET\nREF\nNAME\n" + ); }); it("parses an image name for an unnumbered route", function () { - expectImageName("NET", undefined, undefined, undefined, "shield\nNET\n\n\n"); + expectImageName( + "NET", + undefined, + undefined, + undefined, + "shield\nNET\n\n\n" + ); }); it("parses an image name for a named route", function () { expectImageName( @@ -61,7 +79,13 @@ describe("highway_shield", function () { ); }); it("parses an image name for a network-independent route", function () { - expectImageName(undefined, "REF", "NAME", undefined, "shield\n\nREF\nNAME\n"); + expectImageName( + undefined, + "REF", + "NAME", + undefined, + "shield\n\nREF\nNAME\n" + ); }); }); }); From 27abb30aede278f1e6b29b6ae5bdd70ca0eedb92 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 18 Apr 2024 14:29:17 -0400 Subject: [PATCH 52/55] Override by name instead of by ref --- src/js/shield_defs.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 16d8b1dcc..05091733b 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -3627,41 +3627,41 @@ export function loadShields() { // Ref-specific cases. Each entry should be documented in CONTRIBUTE.md - shields["CA:NS:S"].overrideByRef = { - BdOLSD: { + shields["CA:NS:S"].overrideByName = { + "Bras d'Or Lakes Scenic Drive": { spriteBlank: "shield_ca_ns_s_bdolsd", }, - CeT: { + "Ceilidh Trail": { spriteBlank: "shield_ca_ns_s_cet", }, - CT: { + "Cabot Trail": { spriteBlank: "shield_ca_ns_s_ct", }, - DNISD: { + "Digby Neck and Islands Scenic Drive": { spriteBlank: "shield_ca_ns_s_dnisd", }, - ET: { + "Evangeline Trail": { spriteBlank: "shield_ca_ns_s_et", }, - FdLT: { + "Fleur-de-lis Trail": { spriteBlank: "shield_ca_ns_s_fdlt", }, - GT: { + "Glooscap Trail": { spriteBlank: "shield_ca_ns_s_gt", }, - KSD: { + "Kejimkujik Scenic Drive": { spriteBlank: "shield_ca_ns_s_ksd", }, - LR: { + "Lighthouse Route": { spriteBlank: "shield_ca_ns_s_lr", }, - MD: { + "Marine Drive": { spriteBlank: "shield_ca_ns_s_md", }, - MT: { + "Marconi Trail": { spriteBlank: "shield_ca_ns_s_mt", }, - ST: { + "Sunrise Trail": { spriteBlank: "shield_ca_ns_s_st", }, }; From 5163ebf7d0f3952e0a790afd5bc97f424d35e024 Mon Sep 17 00:00:00 2001 From: Clay Smalley Date: Sat, 20 Apr 2024 14:02:54 -0400 Subject: [PATCH 53/55] add shields for Sierra County, CA and Washington County, UT --- src/js/shield_defs.js | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 4864535cc..528a99740 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -775,11 +775,14 @@ export function loadShields() { ["BUS"], Color.shields.green ); - shields["US:CA:CR"] = pentagonUpShield( - 3, - 15, - Color.shields.blue, - Color.shields.yellow + ["CR", "Sierra"].forEach( + (county) => + (shields[`US:CA:${county}`] = pentagonUpShield( + 3, + 15, + Color.shields.blue, + Color.shields.yellow + )) ); shields["US:CA:Mendocino"] = roundedRectShield( Color.shields.green, @@ -1141,8 +1144,8 @@ export function loadShields() { "Webster", "Winn", ].forEach( - (county) => - (shields[`US:LA:${county}`] = pentagonUpShield( + (parish) => + (shields[`US:LA:${parish}`] = pentagonUpShield( 3, 15, Color.shields.blue, @@ -2484,11 +2487,14 @@ export function loadShields() { bottom: 5, }, }; - shields["US:UT:Wayne"] = pentagonUpShield( - 3, - 15, - Color.shields.blue, - Color.shields.yellow + ["Wayne", "Washington"].forEach( + (county) => + (shields[`US:UT:${county}`] = pentagonUpShield( + 3, + 15, + Color.shields.blue, + Color.shields.yellow + )) ); // Virginia From 122c44b7c81baeaf8baa6171bd0eafe0ef24fd41 Mon Sep 17 00:00:00 2001 From: Clay Smalley Date: Sat, 20 Apr 2024 14:13:10 -0400 Subject: [PATCH 54/55] add Mississippi Scenic Route shields --- src/js/shield_defs.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 4864535cc..29faa11e8 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -1424,6 +1424,11 @@ export function loadShields() { // Mississippi shields["US:MS"] = ovalShield(Color.shields.white, Color.shields.black); + shields["US:MS:Scenic"] = banneredShield( + ovalShield(Color.shields.white, Color.shields.blue), + ["SCEN"], + Color.shields.blue + ); [ "Alcorn", "Calhoun", From 090400bbc4b5c66b30eedee09d747c9e8cb0898b Mon Sep 17 00:00:00 2001 From: Clay Smalley Date: Sun, 21 Apr 2024 16:03:02 -0400 Subject: [PATCH 55/55] update shield defs that use refsByName --- src/js/shield_defs.js | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/js/shield_defs.js b/src/js/shield_defs.js index 2772801b3..03f6c1bd9 100644 --- a/src/js/shield_defs.js +++ b/src/js/shield_defs.js @@ -3739,23 +3739,13 @@ export function loadShields() { }; shields["US:KY:Parkway"].refsByName = { - // FIXME: This object contains both spelled-out and abbreviated road - // names to accommodate both the abbreviated names from OpenMapTiles and - // the spelled-out names from Planetiler. - // https://github.com/onthegomap/planetiler/issues/14 "Audubon Parkway": "AU", "Bluegrass Parkway": "BG", - "Bluegrass Pkwy": "BG", "Cumberland Parkway": "LN", - "Cumberland Pkwy": "LN", "Hal Rogers Parkway": "HR", - "Hal Rogers Pkwy": "HR", "Mountain Parkway": "MP", - "Mountain Pkwy": "MP", "Purchase Parkway": "JC", - "Purchase Pkwy": "JC", "Western Kentucky Parkway": "WK", - "Western Kentucky Pkwy": "WK", }; shields["US:CT:Parkway"].overrideByName = { @@ -3795,15 +3785,13 @@ export function loadShields() { }; shields["US:NY:Parkway"].refsByName = { - "Bear Mountain Parkway": "BMP", - "Bronx and Pelham Parkway": "PP", + "Bear Mountain State Parkway": "BMP", "Bronx River Parkway": "BRP", "Cross County Parkway": "CCP", "Hutchinson River Parkway": "HRP", "Korean War Veterans Parkway": "KWVP", "Mosholu Parkway": "MP", "Niagara Scenic Parkway": "NSP", - "Pelham Parkway": "PP", "Saw Mill River Parkway": "SMP", "Sprain Brook Parkway": "SBP", "Taconic State Parkway": "TSP", @@ -3823,14 +3811,7 @@ export function loadShields() { "Fort Bend Westpark Tollway": "WPT", }; shields["US:TX:Harris:HCTRA"].refsByName = { - "East Sam Houston Tollway North": "SHT", - "East Sam Houston Tollway South": "SHT", - "North Sam Houston Tollway East": "SHT", - "North Sam Houston Tollway West": "SHT", - "South Sam Houston Tollway East": "SHT", - "South Sam Houston Tollway West": "SHT", - "West Sam Houston Tollway North": "SHT", - "West Sam Houston Tollway South": "SHT", + "Sam Houston Tollway": "SHT", "Fort Bend Toll Road": "FBTR", "Hardy Toll Road": "HTR", "Tomball Tollway": "TBT",