From 0ed7c9925af1c16d597994f0718e9528eaa5b9c6 Mon Sep 17 00:00:00 2001 From: Brian Sperlongano Date: Fri, 22 Dec 2023 20:45:47 -0500 Subject: [PATCH 1/3] 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 2/3] 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 3/3] 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(); }