@trailstash/ultra
Version:
A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc
59 lines (57 loc) • 2.01 kB
JavaScript
import { getIcon, migrateName } from "@trailstash/pinhead-js";
const fetchedImages = {};
export const handleStyleImageMissing = (map) => async (spriteId) => {
if (spriteId.startsWith("pinhead-js:")) {
if (!fetchedImages[spriteId]) {
fetchedImages[spriteId] = true;
const [id, rawParams] = spriteId.split(":", 2)[1].split("?", 2);
const options = Object.fromEntries(new URLSearchParams(rawParams));
const svgString = getIcon(migrateName(id), options);
const image = new Image();
const svg = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(svg);
image.src = url;
await image.decode();
let pixelRatio = 1;
if (window.devicePixelRatio > 1) {
pixelRatio = 2;
image.width *= 2;
image.height *= 2;
}
map.addImage(spriteId, image, { pixelRatio });
URL.revokeObjectURL(url);
return;
}
}
const builtin = spriteId.match(/(maki|temaki|emoji|pinhead):/);
if (builtin) {
const sprite = map.getSprite();
if (sprite.findIndex(({ id }) => id === builtin[1]) < 0) {
sprite.push({
id: builtin[1],
url: new URL(`sprites/${builtin[1]}`, window.location).toString(),
});
map.setSprite(sprite);
}
} else if (spriteId.startsWith("https://") || spriteId.startsWith("data:")) {
if (!fetchedImages[spriteId]) {
fetchedImages[spriteId] = true;
const image = new Image();
image.crossOrigin = "anonymous";
image.src = spriteId;
await image.decode();
const imageAddOptions = Object.fromEntries(
new URLSearchParams(new URL(spriteId).hash.slice(1)),
);
if (!imageAddOptions.pixelRatio) {
imageAddOptions.pixelRatio = 1;
if (window.devicePixelRatio > 1) {
imageAddOptions.pixelRatio = 2;
image.width *= 2;
image.height *= 2;
}
}
map.addImage(spriteId, image, imageAddOptions);
}
}
};