import { createLocation } from "./create_location.js";
import { logger } from "./utils.js";
import { random } from "./random_utils.js";
import { parseSvgMetadata } from "./svg_metadata.js";
import MapModel from "./models/map.js";
/**
* Fetches an SVG topo map from `url`, extracts its embedded site/label metadata (via
* parseSvgMetadata — no DOMParser, so this runs in the worker like every other generator),
* and generates a shimmed Location for every marker. Returns a Map model carrying every
* generated Location plus the ordered marker instructions a renderer needs to place them
* on the SVG.
*
* @param {Object} [options={}]
* @param {String} options.url the SVG's URL
* @returns {Map} the generated map
*/
export async function createMap({ url } = {}) {
logger.start("createMap", { url });
const response = await fetch(url);
const svgText = await response.text();
const meta = parseSvgMetadata(svgText);
const locations = [];
const markers = [];
let ptr = 1;
meta.sites.forEach(({ id, types }) => {
if (!types.length) return;
const loc = createLocation({ type: random(types), shim: true });
locations.push(loc);
markers.push({ targetIds: [id], kind: "site", ptr: ptr++, locGuid: loc.guid });
});
const grouped = new Map();
const ungrouped = [];
meta.labels.forEach(({ id, type, group }) => {
if (group) {
if (!grouped.has(group)) grouped.set(group, { type, ids: [] });
grouped.get(group).ids.push(id);
} else {
ungrouped.push({ id, type });
}
});
grouped.forEach(({ type, ids }) => {
const loc = createLocation({ type, shim: true });
locations.push(loc);
markers.push({ targetIds: ids, kind: "label", ptr: null, locGuid: loc.guid });
});
ungrouped.forEach(({ id, type }) => {
const loc = createLocation({ type, shim: true });
locations.push(loc);
markers.push({ targetIds: [id], kind: "label", ptr: ptr++, locGuid: loc.guid });
});
return logger.end(
new MapModel({
url,
name: meta.name,
width: meta.width,
height: meta.height,
locations,
markers,
}),
);
}