facilmap/leaflet/download-icons.ts

81 wiersze
2.7 KiB
TypeScript
Czysty Zwykły widok Historia

2021-01-23 11:38:26 +00:00
import fetch from "node-fetch";
import * as yauzl from "yauzl";
2021-01-23 11:38:26 +00:00
import util from "util";
import * as svgo from "svgo";
2021-01-23 11:38:26 +00:00
import cheerio from "cheerio";
import highland from "highland";
import fs from "fs";
import { fileURLToPath } from 'url';
2021-01-23 11:38:26 +00:00
const outDir = fileURLToPath(new URL('./assets/icons/osmi', import.meta.url));
2021-01-23 11:38:26 +00:00
function streamEachPromise<T>(stream: Highland.Stream<T>, handle: (item: T) => Promise<void> | void): Promise<void> {
return new Promise((resolve, reject) => {
stream
.flatMap((item) => highland(Promise.resolve(handle(item as T))))
.stopOnError(reject)
.done(resolve);
});
}
async function updateIcons() {
const buffer = await fetch("https://github.com/twain47/Open-SVG-Map-Icons/archive/master.zip").then((res) => res.buffer());
const zip = (await util.promisify(yauzl.fromBuffer)(buffer))!;
const entryStream = highland<yauzl.Entry>((push) => {
2021-01-23 11:38:26 +00:00
zip.on("entry", (entry) => { push(null, entry); });
zip.on("error", (err) => { push(err); });
}).filter((entry) => entry.fileName.endsWith(".svg"));
await streamEachPromise(entryStream, async (entry) => {
const readStream = (await util.promisify(zip.openReadStream.bind(zip))(entry))!;
const content = await highland<Buffer>(readStream).collect().map((buffers) => Buffer.concat(buffers)).toPromise(Promise);
const cleanedContent = cleanIcon(content.toString());
2021-01-23 11:38:26 +00:00
const outFile = `${outDir}/${entry.fileName.split('/').slice(-2).join('_')}`;
await fs.promises.writeFile(outFile, Buffer.from(cleanedContent));
});
}
function cleanIcon(icon: string): string {
const optimized = svgo.optimize(icon);
2021-03-04 15:45:34 +00:00
const $ = cheerio.load(optimized.data, {
2021-01-23 11:38:26 +00:00
xmlMode: true
});
2021-03-04 15:45:34 +00:00
for (const el of $("*").toArray() as cheerio.TagElement[]) {
2021-01-23 11:38:26 +00:00
el.name = el.name.replace(/^svg:/, "");
}
$("metadata,sodipodi\\:namedview,defs,image").remove();
for (const el of $("*").toArray()) {
2021-03-04 15:45:34 +00:00
const $el = $(el);
2021-01-23 11:38:26 +00:00
2021-03-04 15:45:34 +00:00
const fill = $el.css("fill") || $el.attr("fill");
2021-01-23 11:38:26 +00:00
if(fill && fill != "none") {
if(fill != "#ffffff" && fill != "#fff") { // This is the background
$el.remove();
continue;
}
if($el.css("fill"))
$el.css("fill", "#000");
else
$el.attr("fill", "#000");
}
if($el.css("stroke") && $el.css("stroke") != "none")
$el.css("stroke", "#000");
else if($el.attr("stroke") && $el.attr("stroke") != "none")
$el.attr("stroke", "#000");
}
return $(":root").html()!.replace(/(>|^)\s+(<|$)/g, "$1$2");
}
updateIcons().then(() => {
console.log('Success!');
}).catch((err) => {
console.error('Fatal error', err);
});