@chrtco/sdk 0.10.53 → 0.10.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +16 -3
- package/dist/atlas/browser.cjs +673 -17
- package/dist/atlas/browser.cjs.map +1 -1
- package/dist/atlas/browser.d.cts +36 -2
- package/dist/atlas/browser.d.ts +36 -2
- package/dist/atlas/browser.js +670 -16
- package/dist/atlas/browser.js.map +1 -1
- package/dist/index.cjs +1593 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +338 -8
- package/dist/index.d.ts +338 -8
- package/dist/index.js +1559 -159
- package/dist/index.js.map +1 -1
- package/dist/{symbol-families-De7sN-p5.d.cts → symbol-family-ids-elOgiCo8.d.cts} +27 -25
- package/dist/{symbol-families-De7sN-p5.d.ts → symbol-family-ids-elOgiCo8.d.ts} +27 -25
- package/package.json +1 -1
package/dist/atlas/browser.js
CHANGED
|
@@ -18817,9 +18817,9 @@ function arcSegmentSvg(token, sweepDeg) {
|
|
|
18817
18817
|
const box = segmentBox(sweepDeg);
|
|
18818
18818
|
const end = sweepDeg + JOINT_OVERLAP_DEG;
|
|
18819
18819
|
const core = token === "CHBRN" ? OBSCURED_CORE_WIDTH : CORE_WIDTH;
|
|
18820
|
-
const
|
|
18821
|
-
const outline = annularSectorPath(end,
|
|
18822
|
-
const inner = annularSectorPath(end,
|
|
18820
|
+
const R2 = SECTOR_ARC_RADIUS;
|
|
18821
|
+
const outline = annularSectorPath(end, R2 - OUTLINE_WIDTH / 2, R2 + OUTLINE_WIDTH / 2, box);
|
|
18822
|
+
const inner = annularSectorPath(end, R2 - core / 2, R2 + core / 2, box);
|
|
18823
18823
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${box.w}" height="${box.h}" viewBox="0 0 ${box.w} ${box.h}"><path d="${outline}" fill="CHBLK"/><path d="${inner}" fill="${token}"/></svg>`;
|
|
18824
18824
|
}
|
|
18825
18825
|
function legSvg() {
|
|
@@ -18971,17 +18971,17 @@ async function decode(spec) {
|
|
|
18971
18971
|
var scratch = null;
|
|
18972
18972
|
function scratchContext() {
|
|
18973
18973
|
if (!scratch) {
|
|
18974
|
-
const
|
|
18975
|
-
scratch =
|
|
18974
|
+
const canvas2 = document.createElement("canvas");
|
|
18975
|
+
scratch = canvas2.getContext("2d", { willReadFrequently: true });
|
|
18976
18976
|
if (!scratch) throw new Error("symbol-images: no 2d canvas context");
|
|
18977
18977
|
}
|
|
18978
18978
|
return scratch;
|
|
18979
18979
|
}
|
|
18980
18980
|
function rasterise(src, spec) {
|
|
18981
18981
|
const ctx = scratchContext();
|
|
18982
|
-
const
|
|
18983
|
-
|
|
18984
|
-
|
|
18982
|
+
const canvas2 = ctx.canvas;
|
|
18983
|
+
canvas2.width = spec.width;
|
|
18984
|
+
canvas2.height = spec.height;
|
|
18985
18985
|
ctx.drawImage(src.img, 0, -src.y, src.width, src.height);
|
|
18986
18986
|
return ctx.getImageData(0, 0, spec.width, spec.height);
|
|
18987
18987
|
}
|
|
@@ -19331,13 +19331,13 @@ function decodeSvgToImage(themedSvg, size) {
|
|
|
19331
19331
|
}
|
|
19332
19332
|
async function imageToBitmap(img, size) {
|
|
19333
19333
|
try {
|
|
19334
|
-
const
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
const ctx =
|
|
19334
|
+
const canvas2 = document.createElement("canvas");
|
|
19335
|
+
canvas2.width = size.w;
|
|
19336
|
+
canvas2.height = size.h;
|
|
19337
|
+
const ctx = canvas2.getContext("2d");
|
|
19338
19338
|
if (!ctx) return null;
|
|
19339
19339
|
ctx.drawImage(img, 0, 0, size.w, size.h);
|
|
19340
|
-
return await createImageBitmap(
|
|
19340
|
+
return await createImageBitmap(canvas2);
|
|
19341
19341
|
} catch {
|
|
19342
19342
|
return null;
|
|
19343
19343
|
}
|
|
@@ -20329,6 +20329,263 @@ function getThemedS101Svg(symbolName, table = "DAY") {
|
|
|
20329
20329
|
});
|
|
20330
20330
|
}
|
|
20331
20331
|
|
|
20332
|
+
// src/atlas/look-painter.ts
|
|
20333
|
+
function painter(w, h) {
|
|
20334
|
+
const acc = new Float32Array(w * h * 4);
|
|
20335
|
+
const over = (x, y, c, cov) => {
|
|
20336
|
+
if (x < 0 || y < 0 || x >= w || y >= h || cov <= 0) return;
|
|
20337
|
+
const k = (y * w + x) * 4;
|
|
20338
|
+
const a = c[3] / 255 * Math.min(1, cov);
|
|
20339
|
+
acc[k] = c[0] * a + acc[k] * (1 - a);
|
|
20340
|
+
acc[k + 1] = c[1] * a + acc[k + 1] * (1 - a);
|
|
20341
|
+
acc[k + 2] = c[2] * a + acc[k + 2] * (1 - a);
|
|
20342
|
+
acc[k + 3] = a + acc[k + 3] * (1 - a);
|
|
20343
|
+
};
|
|
20344
|
+
const dot = (cx, cy, r, c) => {
|
|
20345
|
+
for (let y = Math.floor(cy - r - 1); y <= Math.ceil(cy + r + 1); y++) {
|
|
20346
|
+
for (let x = Math.floor(cx - r - 1); x <= Math.ceil(cx + r + 1); x++) over(x, y, c, r + 0.5 - Math.hypot(x + 0.5 - cx, y + 0.5 - cy));
|
|
20347
|
+
}
|
|
20348
|
+
};
|
|
20349
|
+
const stroke = (pts, r, c) => {
|
|
20350
|
+
const cov = new Float32Array(w * h);
|
|
20351
|
+
for (let i = 1; i < pts.length; i++) {
|
|
20352
|
+
const [x0, y0] = pts[i - 1];
|
|
20353
|
+
const [x1, y1] = pts[i];
|
|
20354
|
+
const n = Math.max(1, Math.ceil(Math.hypot(x1 - x0, y1 - y0) * 2));
|
|
20355
|
+
for (let t = 0; t <= n; t++) {
|
|
20356
|
+
const cx = x0 + (x1 - x0) * t / n;
|
|
20357
|
+
const cy = y0 + (y1 - y0) * t / n;
|
|
20358
|
+
for (let y = Math.floor(cy - r - 1); y <= Math.ceil(cy + r + 1); y++) {
|
|
20359
|
+
for (let x = Math.floor(cx - r - 1); x <= Math.ceil(cx + r + 1); x++) {
|
|
20360
|
+
if (x < 0 || y < 0 || x >= w || y >= h) continue;
|
|
20361
|
+
const v = Math.max(0, Math.min(1, r + 0.5 - Math.hypot(x + 0.5 - cx, y + 0.5 - cy)));
|
|
20362
|
+
if (v > cov[y * w + x]) cov[y * w + x] = v;
|
|
20363
|
+
}
|
|
20364
|
+
}
|
|
20365
|
+
}
|
|
20366
|
+
}
|
|
20367
|
+
for (let k = 0; k < cov.length; k++) if (cov[k] > 0) over(k % w, Math.floor(k / w), c, cov[k]);
|
|
20368
|
+
};
|
|
20369
|
+
const fill = (pts, c) => {
|
|
20370
|
+
const y0 = Math.max(0, Math.floor(Math.min(...pts.map((p) => p[1]))));
|
|
20371
|
+
const y1 = Math.min(h - 1, Math.ceil(Math.max(...pts.map((p) => p[1]))));
|
|
20372
|
+
const x0 = Math.max(0, Math.floor(Math.min(...pts.map((p) => p[0]))));
|
|
20373
|
+
const x1 = Math.min(w - 1, Math.ceil(Math.max(...pts.map((p) => p[0]))));
|
|
20374
|
+
for (let y = y0; y <= y1; y++) {
|
|
20375
|
+
for (let x = x0; x <= x1; x++) {
|
|
20376
|
+
let inside = 0;
|
|
20377
|
+
for (let sy = 0; sy < 4; sy++) for (let sx = 0; sx < 4; sx++) {
|
|
20378
|
+
const px = x + (sx + 0.5) / 4;
|
|
20379
|
+
const py = y + (sy + 0.5) / 4;
|
|
20380
|
+
let odd = false;
|
|
20381
|
+
for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {
|
|
20382
|
+
const [xi, yi] = pts[i];
|
|
20383
|
+
const [xj, yj] = pts[j];
|
|
20384
|
+
if (yi > py !== yj > py && px < (xj - xi) * (py - yi) / (yj - yi) + xi) odd = !odd;
|
|
20385
|
+
}
|
|
20386
|
+
if (odd) inside++;
|
|
20387
|
+
}
|
|
20388
|
+
over(x, y, c, inside / 16);
|
|
20389
|
+
}
|
|
20390
|
+
}
|
|
20391
|
+
};
|
|
20392
|
+
const data = () => {
|
|
20393
|
+
const out = new Uint8Array(w * h * 4);
|
|
20394
|
+
for (let k = 0; k < w * h; k++) {
|
|
20395
|
+
const a = acc[k * 4 + 3];
|
|
20396
|
+
if (a <= 0) continue;
|
|
20397
|
+
out[k * 4] = Math.round(acc[k * 4] / a);
|
|
20398
|
+
out[k * 4 + 1] = Math.round(acc[k * 4 + 1] / a);
|
|
20399
|
+
out[k * 4 + 2] = Math.round(acc[k * 4 + 2] / a);
|
|
20400
|
+
out[k * 4 + 3] = Math.round(a * 255);
|
|
20401
|
+
}
|
|
20402
|
+
return out;
|
|
20403
|
+
};
|
|
20404
|
+
return { dot, stroke, fill, data };
|
|
20405
|
+
}
|
|
20406
|
+
function turn([x, y], cx, cy, deg) {
|
|
20407
|
+
const r = deg * Math.PI / 180;
|
|
20408
|
+
const dx = x - cx;
|
|
20409
|
+
const dy = y - cy;
|
|
20410
|
+
return [cx + dx * Math.cos(r) - dy * Math.sin(r), cy + dx * Math.sin(r) + dy * Math.cos(r)];
|
|
20411
|
+
}
|
|
20412
|
+
|
|
20413
|
+
// src/atlas/uschart1-marks.ts
|
|
20414
|
+
var CLASSIC_MARK_TONES = {
|
|
20415
|
+
color: { magenta: "#953699", green: "#068b00", ink: "#000000", open: "#ffffff" },
|
|
20416
|
+
// A laser printer's greys: red lighter than green, so a banded mark still
|
|
20417
|
+
// shows its bands. The label (R, G) says which is which, as it always does.
|
|
20418
|
+
mono: { magenta: "#8c8c8c", green: "#4d4d4d", ink: "#000000", open: "#ffffff" }
|
|
20419
|
+
};
|
|
20420
|
+
var PREFIX = { color: "chrt-look-cl-", mono: "chrt-look-cm-" };
|
|
20421
|
+
function classicMarkId(ink, name) {
|
|
20422
|
+
return PREFIX[ink] + name;
|
|
20423
|
+
}
|
|
20424
|
+
function classicMarkInk(id) {
|
|
20425
|
+
for (const ink of ["color", "mono"]) {
|
|
20426
|
+
if (id.startsWith(PREFIX[ink]) && CLASSIC_MARK_NAMES.includes(id.slice(PREFIX[ink].length))) return ink;
|
|
20427
|
+
}
|
|
20428
|
+
return null;
|
|
20429
|
+
}
|
|
20430
|
+
var COLOURS = ["red", "green", "black", "yellow", "white"];
|
|
20431
|
+
var BOARDS = ["triangle-up", "triangle-down", "square", "rhombus"];
|
|
20432
|
+
var paints = COLOURS.flatMap((a) => [
|
|
20433
|
+
a,
|
|
20434
|
+
...COLOURS.filter((b) => b !== a).flatMap((b) => [`${a}-${b}-h`, `${a}-${b}-v`])
|
|
20435
|
+
]);
|
|
20436
|
+
var BUOY_NAMES = paints.map((p) => `buoy-${p}`);
|
|
20437
|
+
var BOARD_NAMES = BOARDS.flatMap((s) => paints.map((p) => `board-${s}-${p}`));
|
|
20438
|
+
var CLASSIC_MARK_NAMES = ["flare", "disc", ...BUOY_NAMES, ...BOARD_NAMES];
|
|
20439
|
+
var num = (attr) => ["to-number", ["coalesce", ["get", attr], ["get", attr.toLowerCase()], 0], 0];
|
|
20440
|
+
var LOZENGE_BUOY = ["!", ["in", num("BOYSHP"), ["literal", [7, 8]]]];
|
|
20441
|
+
var DAYBEACON = ["!", ["in", num("BCNSHP"), ["literal", [3, 4, 6]]]];
|
|
20442
|
+
var R = 2;
|
|
20443
|
+
var S = 64 * R;
|
|
20444
|
+
var C0 = S / 2;
|
|
20445
|
+
var BUOY_LENGTH = 12.5;
|
|
20446
|
+
var BUOY_HALF_WIDTH = 3.4;
|
|
20447
|
+
var DISC_RADIUS = 8.5;
|
|
20448
|
+
var BOARD_SIDE = 8;
|
|
20449
|
+
var SB = 96 * R;
|
|
20450
|
+
var CB = SB / 2;
|
|
20451
|
+
var FLARE_SCALE = 0.6;
|
|
20452
|
+
var FLARE_ANCHOR = 18;
|
|
20453
|
+
function paintOf(ink, c) {
|
|
20454
|
+
const t = CLASSIC_MARK_TONES[ink];
|
|
20455
|
+
return c === "red" ? t.magenta : c === "green" ? t.green : c === "black" ? t.ink : t.open;
|
|
20456
|
+
}
|
|
20457
|
+
function circle(cx, cy, r) {
|
|
20458
|
+
return Array.from({ length: 33 }, (_, i) => [cx + r * Math.cos(i / 32 * 2 * Math.PI), cy + r * Math.sin(i / 32 * 2 * Math.PI)]);
|
|
20459
|
+
}
|
|
20460
|
+
function flare(ink) {
|
|
20461
|
+
const path = [[16.3, 28], [11.8, 7.1], [11.8, 4.9], [12.4, 3.5], [13.2, 3], [14.3, 2.1], [16, 1.9], [17.4, 2.1], [18.5, 2.4], [19.6, 3.2], [20.2, 4.6], [20.4, 5.7], [20.4, 6.9]];
|
|
20462
|
+
const k = 0.9698;
|
|
20463
|
+
const place = ([x, y]) => {
|
|
20464
|
+
const [rx, ry] = turn([(x - 16.3) * 0.9 * FLARE_SCALE, (y - 28) * 0.9 * FLARE_SCALE], 0, 0, 135);
|
|
20465
|
+
return [((rx + 10 - 16.1) * k + 16) * 2 * R, ((ry + 10 - 14.95) * k + 16) * 2 * R];
|
|
20466
|
+
};
|
|
20467
|
+
const t = CLASSIC_MARK_TONES[ink];
|
|
20468
|
+
return { width: S, height: S, pixelRatio: R, ops: [{ fill: path.map(place), c: t.magenta }, { dot: [FLARE_ANCHOR * R, FLARE_ANCHOR * R], r: 2.6 * R, c: t.ink }] };
|
|
20469
|
+
}
|
|
20470
|
+
function disc(ink) {
|
|
20471
|
+
return { width: S, height: S, pixelRatio: R, ops: [{ fill: circle(C0, C0, DISC_RADIUS * R), c: CLASSIC_MARK_TONES[ink].magenta }] };
|
|
20472
|
+
}
|
|
20473
|
+
function buoy(ink, c1, c2, split) {
|
|
20474
|
+
const ops = [];
|
|
20475
|
+
const t = CLASSIC_MARK_TONES[ink];
|
|
20476
|
+
const L = BUOY_LENGTH;
|
|
20477
|
+
const W = BUOY_HALF_WIDTH;
|
|
20478
|
+
const lean = 45;
|
|
20479
|
+
const at = (a, b) => turn([CB + b * R, CB - a * R], CB, CB, lean);
|
|
20480
|
+
const foot = 1.6;
|
|
20481
|
+
const outline = [at(foot, 0), at(foot + L / 2, -W), at(foot + L, 0), at(foot + L / 2, W)];
|
|
20482
|
+
if (split === null) ops.push({ fill: outline, c: paintOf(ink, c1) });
|
|
20483
|
+
else if (split === "h") {
|
|
20484
|
+
ops.push({ fill: [at(foot, 0), at(foot + L / 2, -W), at(foot + L / 2, W)], c: paintOf(ink, c2) });
|
|
20485
|
+
ops.push({ fill: [at(foot + L / 2, -W), at(foot + L, 0), at(foot + L / 2, W)], c: paintOf(ink, c1) });
|
|
20486
|
+
} else {
|
|
20487
|
+
ops.push({ fill: [at(foot, 0), at(foot + L / 2, -W), at(foot + L, 0)], c: paintOf(ink, c1) });
|
|
20488
|
+
ops.push({ fill: [at(foot, 0), at(foot + L, 0), at(foot + L / 2, W)], c: paintOf(ink, c2) });
|
|
20489
|
+
}
|
|
20490
|
+
ops.push({ stroke: [...outline, outline[0]], r: 0.35 * R, c: t.ink });
|
|
20491
|
+
if (split === "v") ops.push({ stroke: [at(foot, 0), at(foot + L, 0)], r: 0.3 * R, c: t.ink });
|
|
20492
|
+
if (split === "h") ops.push({ stroke: [at(foot + L / 2, -W), at(foot + L / 2, W)], r: 0.3 * R, c: t.ink });
|
|
20493
|
+
const ring = circle(CB, CB, 2 * R);
|
|
20494
|
+
ops.push({ fill: ring, c: t.open });
|
|
20495
|
+
ops.push({ stroke: ring, r: 0.35 * R, c: t.ink });
|
|
20496
|
+
return { width: SB, height: SB, pixelRatio: R, ops };
|
|
20497
|
+
}
|
|
20498
|
+
function boardOutline(shape) {
|
|
20499
|
+
const h = BOARD_SIDE / 2 * R;
|
|
20500
|
+
switch (shape) {
|
|
20501
|
+
case "triangle-up":
|
|
20502
|
+
return [[C0 - h, C0 + h * 0.58], [C0 + h, C0 + h * 0.58], [C0, C0 - h * 1.15]];
|
|
20503
|
+
case "triangle-down":
|
|
20504
|
+
return [[C0 - h, C0 - h * 0.58], [C0, C0 + h * 1.15], [C0 + h, C0 - h * 0.58]];
|
|
20505
|
+
case "square":
|
|
20506
|
+
return [[C0 - h * 0.85, C0 - h * 0.85], [C0 + h * 0.85, C0 - h * 0.85], [C0 + h * 0.85, C0 + h * 0.85], [C0 - h * 0.85, C0 + h * 0.85]];
|
|
20507
|
+
case "rhombus":
|
|
20508
|
+
return [[C0, C0 - h * 1.2], [C0 + h * 1.2, C0], [C0, C0 + h * 1.2], [C0 - h * 1.2, C0]];
|
|
20509
|
+
}
|
|
20510
|
+
}
|
|
20511
|
+
function half(pts, axis, first) {
|
|
20512
|
+
const inside = (p) => first ? p[axis] <= C0 : p[axis] >= C0;
|
|
20513
|
+
const out = [];
|
|
20514
|
+
for (let i = 0; i < pts.length; i++) {
|
|
20515
|
+
const a = pts[i];
|
|
20516
|
+
const b = pts[(i + 1) % pts.length];
|
|
20517
|
+
if (inside(a)) out.push(a);
|
|
20518
|
+
if (inside(a) !== inside(b)) {
|
|
20519
|
+
const t = (C0 - a[axis]) / (b[axis] - a[axis]);
|
|
20520
|
+
out.push([a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t]);
|
|
20521
|
+
}
|
|
20522
|
+
}
|
|
20523
|
+
return out;
|
|
20524
|
+
}
|
|
20525
|
+
function chord(pts, axis) {
|
|
20526
|
+
const top = half(pts, axis, true);
|
|
20527
|
+
return top.filter((p) => Math.abs(p[axis] - C0) < 1e-9);
|
|
20528
|
+
}
|
|
20529
|
+
function board(ink, shape, c1, c2, split) {
|
|
20530
|
+
const pts = boardOutline(shape);
|
|
20531
|
+
const ops = [];
|
|
20532
|
+
if (split === null) ops.push({ fill: pts, c: paintOf(ink, c1) });
|
|
20533
|
+
else {
|
|
20534
|
+
const axis = split === "h" ? 1 : 0;
|
|
20535
|
+
ops.push({ fill: half(pts, axis, true), c: paintOf(ink, c1) });
|
|
20536
|
+
ops.push({ fill: half(pts, axis, false), c: paintOf(ink, c2) });
|
|
20537
|
+
}
|
|
20538
|
+
const ink0 = CLASSIC_MARK_TONES[ink].ink;
|
|
20539
|
+
ops.push({ stroke: [...pts, pts[0]], r: 0.45 * R, c: ink0 });
|
|
20540
|
+
if (split !== null) ops.push({ stroke: chord(pts, split === "h" ? 1 : 0), r: 0.3 * R, c: ink0 });
|
|
20541
|
+
return { width: S, height: S, pixelRatio: R, ops };
|
|
20542
|
+
}
|
|
20543
|
+
function classicDrawing(ink, name) {
|
|
20544
|
+
if (name === "flare") return flare(ink);
|
|
20545
|
+
if (name === "disc") return disc(ink);
|
|
20546
|
+
const m = /^(buoy|board-(triangle-up|triangle-down|square|rhombus))-([a-z]+)(?:-([a-z]+)-([hv]))?$/.exec(name);
|
|
20547
|
+
if (!m || !CLASSIC_MARK_NAMES.includes(name)) throw new Error(`classic-marks: no mark ${name}`);
|
|
20548
|
+
const c1 = m[3];
|
|
20549
|
+
const c2 = m[4] ?? m[3];
|
|
20550
|
+
const split = m[5] ?? null;
|
|
20551
|
+
return m[1] === "buoy" ? buoy(ink, c1, c2, split) : board(ink, m[2], c1, c2, split);
|
|
20552
|
+
}
|
|
20553
|
+
function rgba(hex) {
|
|
20554
|
+
return [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16), 255];
|
|
20555
|
+
}
|
|
20556
|
+
function paintDrawing(d) {
|
|
20557
|
+
const p = painter(d.width, d.height);
|
|
20558
|
+
for (const op of d.ops) {
|
|
20559
|
+
if ("fill" in op) p.fill(op.fill, rgba(op.c));
|
|
20560
|
+
else if ("stroke" in op) p.stroke(op.stroke, op.r, rgba(op.c));
|
|
20561
|
+
else p.dot(op.dot[0], op.dot[1], op.r, rgba(op.c));
|
|
20562
|
+
}
|
|
20563
|
+
return p.data();
|
|
20564
|
+
}
|
|
20565
|
+
function drawingSvg(d) {
|
|
20566
|
+
const f = (n) => String(Math.round(n * 100) / 100);
|
|
20567
|
+
const pts = (ps) => ps.map(([x, y]) => `${f(x)},${f(y)}`).join(" ");
|
|
20568
|
+
const body = d.ops.map(
|
|
20569
|
+
(op) => "fill" in op ? `<polygon points="${pts(op.fill)}" fill="${op.c}"/>` : "stroke" in op ? `<polyline points="${pts(op.stroke)}" fill="none" stroke="${op.c}" stroke-width="${f(op.r * 2)}" stroke-linecap="round" stroke-linejoin="round"/>` : `<circle cx="${f(op.dot[0])}" cy="${f(op.dot[1])}" r="${f(op.r)}" fill="${op.c}"/>`
|
|
20570
|
+
).join("");
|
|
20571
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${d.width}" height="${d.height}" viewBox="0 0 ${d.width} ${d.height}">${body}</svg>`;
|
|
20572
|
+
}
|
|
20573
|
+
function classicMarkSvgs(ink) {
|
|
20574
|
+
return CLASSIC_MARK_NAMES.map((name) => {
|
|
20575
|
+
const d = classicDrawing(ink, name);
|
|
20576
|
+
return { id: classicMarkId(ink, name), svg: drawingSvg(d), width: d.width, height: d.height, pixelRatio: d.pixelRatio };
|
|
20577
|
+
});
|
|
20578
|
+
}
|
|
20579
|
+
function classicMarkImage(id) {
|
|
20580
|
+
const ink = classicMarkInk(id);
|
|
20581
|
+
if (!ink) throw new Error(`classic-marks: no mark ${id}`);
|
|
20582
|
+
const d = classicDrawing(ink, id.slice(PREFIX[ink].length));
|
|
20583
|
+
return { id, width: d.width, height: d.height, pixelRatio: d.pixelRatio, data: paintDrawing(d) };
|
|
20584
|
+
}
|
|
20585
|
+
function classicMarkImages(ink) {
|
|
20586
|
+
return CLASSIC_MARK_NAMES.map((name) => classicMarkImage(classicMarkId(ink, name)));
|
|
20587
|
+
}
|
|
20588
|
+
|
|
20332
20589
|
// src/atlas/symbol-image-specs.ts
|
|
20333
20590
|
var SUPERSAMPLE = 2;
|
|
20334
20591
|
var BASE_PATTERN_GLYPHS = [
|
|
@@ -20385,9 +20642,30 @@ function s101ImageSpecs(palette) {
|
|
|
20385
20642
|
return [{ id, svg: svg2, ...declared(id, svg2), pixelRatio: SUPERSAMPLE, sdf: false }];
|
|
20386
20643
|
});
|
|
20387
20644
|
}
|
|
20645
|
+
function usChart1ImageSpecs(palette) {
|
|
20646
|
+
const ink = palette === "EINK_MONO" ? "mono" : "color";
|
|
20647
|
+
return classicMarkSvgs(ink).map((m) => ({ ...m, sdf: false }));
|
|
20648
|
+
}
|
|
20388
20649
|
function symbolImageSpecs(palette, family) {
|
|
20389
|
-
|
|
20390
|
-
|
|
20650
|
+
return [...s52ImageSpecs(palette), ...basePatternImageSpecs(palette), ...familyOwnImageSpecs(palette, family)];
|
|
20651
|
+
}
|
|
20652
|
+
function familyOwnImageSpecs(palette, family) {
|
|
20653
|
+
switch (family) {
|
|
20654
|
+
case "s52":
|
|
20655
|
+
return [];
|
|
20656
|
+
case "s101":
|
|
20657
|
+
return s101ImageSpecs(palette);
|
|
20658
|
+
case "int1":
|
|
20659
|
+
return rasterImageSpecs(palette);
|
|
20660
|
+
case "uschart1":
|
|
20661
|
+
return [...rasterImageSpecs(palette), ...usChart1ImageSpecs(palette)];
|
|
20662
|
+
case "chrt":
|
|
20663
|
+
return chrtImageSpecs(palette);
|
|
20664
|
+
default: {
|
|
20665
|
+
const unhandled = family;
|
|
20666
|
+
throw new Error(`no symbol family ${String(unhandled)}`);
|
|
20667
|
+
}
|
|
20668
|
+
}
|
|
20391
20669
|
}
|
|
20392
20670
|
var IMAGE_PROPS = /* @__PURE__ */ new Set([
|
|
20393
20671
|
"icon-image",
|
|
@@ -20470,6 +20748,380 @@ async function loadChrtRasterSymbolImages(map, colorTable = "DAY") {
|
|
|
20470
20748
|
async function reloadChrtRasterSymbolImages(map, colorTable) {
|
|
20471
20749
|
await rethemeSymbolImages(map, rasterImageSpecs(colorTable));
|
|
20472
20750
|
}
|
|
20751
|
+
|
|
20752
|
+
// src/atlas/look-paper.ts
|
|
20753
|
+
var CLASSIC_TONES = {
|
|
20754
|
+
/** Land. */
|
|
20755
|
+
land: "#ebe2c8",
|
|
20756
|
+
/** The blue tint, to the 18 ft curve. */
|
|
20757
|
+
shallow: "#d8f0f5",
|
|
20758
|
+
/** Deep water: the paper. */
|
|
20759
|
+
deep: "#ffffff",
|
|
20760
|
+
/** The foreshore, and salt marsh. */
|
|
20761
|
+
drying: "#c1d1af",
|
|
20762
|
+
/** Magenta: lights, flares, discs, limits, cautions, red aids. */
|
|
20763
|
+
magenta: "#953699",
|
|
20764
|
+
/** Green aids. */
|
|
20765
|
+
green: "#068b00",
|
|
20766
|
+
/** Black: line-work, lettering, soundings, land contours. */
|
|
20767
|
+
ink: "#000000",
|
|
20768
|
+
/** Depth contours and their values. */
|
|
20769
|
+
contour: "#5f5f5f"
|
|
20770
|
+
};
|
|
20771
|
+
var CLASSIC_IMAGE_NAMES = ["hatch", ...CLASSIC_MARK_NAMES];
|
|
20772
|
+
var PREFIX2 = "chrt-look-cl-";
|
|
20773
|
+
var DAY_TO_CLASSIC = {
|
|
20774
|
+
// Land: LANDA, CHRTland's land and its cover but wetland, slopes.
|
|
20775
|
+
"#d4c69d": CLASSIC_TONES.land,
|
|
20776
|
+
"#e6d1a1": CLASSIC_TONES.land,
|
|
20777
|
+
"#bcc5a1": CLASSIC_TONES.land,
|
|
20778
|
+
"#cac6bf": CLASSIC_TONES.land,
|
|
20779
|
+
"#dbd0af": CLASSIC_TONES.land,
|
|
20780
|
+
"#c8b078": CLASSIC_TONES.land,
|
|
20781
|
+
// Marsh.
|
|
20782
|
+
"#b6c0b1": CLASSIC_TONES.drying,
|
|
20783
|
+
// The drying foreshore (DEPIT).
|
|
20784
|
+
"#009678": CLASSIC_TONES.drying,
|
|
20785
|
+
// Inland water and the shallow depth tints (DEPVS, DEPMS, DEPMD) where
|
|
20786
|
+
// other classes use them: lakes, rivers, canals, locks, swept areas.
|
|
20787
|
+
"#7fbfdf": CLASSIC_TONES.shallow,
|
|
20788
|
+
"#a7d4e8": CLASSIC_TONES.shallow,
|
|
20789
|
+
"#cae7f3": CLASSIC_TONES.shallow,
|
|
20790
|
+
"#b9cfdd": CLASSIC_TONES.shallow,
|
|
20791
|
+
// Deep water (DEPDW).
|
|
20792
|
+
"#ecf7fc": CLASSIC_TONES.deep,
|
|
20793
|
+
// Magentas (CHMGD, CHMGF).
|
|
20794
|
+
"#d200d2": CLASSIC_TONES.magenta,
|
|
20795
|
+
"#c545c3": CLASSIC_TONES.magenta,
|
|
20796
|
+
// Brown structures (CHBRN): buildings, bridges, dams, in black.
|
|
20797
|
+
"#ab7948": CLASSIC_TONES.ink,
|
|
20798
|
+
// Black and the near-blacks of the lettering.
|
|
20799
|
+
"#000000": CLASSIC_TONES.ink,
|
|
20800
|
+
"#1a1d23": CLASSIC_TONES.ink,
|
|
20801
|
+
"#4a5560": CLASSIC_TONES.ink,
|
|
20802
|
+
"#5b4f3a": CLASSIC_TONES.ink,
|
|
20803
|
+
"#bfa88a": CLASSIC_TONES.ink,
|
|
20804
|
+
// Depth contours and area outlines.
|
|
20805
|
+
"#555555": CLASSIC_TONES.contour,
|
|
20806
|
+
// CHRTland's contours: black, as the paper chart's.
|
|
20807
|
+
"#958666": CLASSIC_TONES.ink,
|
|
20808
|
+
"#78694b": CLASSIC_TONES.ink
|
|
20809
|
+
};
|
|
20810
|
+
var HATCH_RATIO = 4;
|
|
20811
|
+
function hatch() {
|
|
20812
|
+
const d = 12;
|
|
20813
|
+
const w = d * 2;
|
|
20814
|
+
const half2 = 0.9;
|
|
20815
|
+
const data = new Uint8Array(w * w * 4);
|
|
20816
|
+
for (let y = 0; y < w; y++) {
|
|
20817
|
+
for (let x = 0; x < w; x++) {
|
|
20818
|
+
const t = (x + y + 1) % d;
|
|
20819
|
+
const dist = Math.min(t, d - t) / Math.SQRT2;
|
|
20820
|
+
const cov = Math.max(0, Math.min(1, half2 + 0.5 - dist));
|
|
20821
|
+
data[(y * w + x) * 4 + 3] = Math.round(cov * 255);
|
|
20822
|
+
}
|
|
20823
|
+
}
|
|
20824
|
+
return { size: w, data };
|
|
20825
|
+
}
|
|
20826
|
+
function classicImages() {
|
|
20827
|
+
const h = hatch();
|
|
20828
|
+
return [
|
|
20829
|
+
{ name: "hatch", width: h.size, height: h.size, pixelRatio: HATCH_RATIO, data: h.data },
|
|
20830
|
+
...classicMarkImages("color").map((i) => ({ name: i.id.slice(PREFIX2.length), width: i.width, height: i.height, pixelRatio: i.pixelRatio, data: i.data }))
|
|
20831
|
+
];
|
|
20832
|
+
}
|
|
20833
|
+
|
|
20834
|
+
// src/atlas/look-wash-tones.ts
|
|
20835
|
+
var WASH_TONES = {
|
|
20836
|
+
paper: [250, 244, 222],
|
|
20837
|
+
land: [165, 186, 118],
|
|
20838
|
+
// A clear light blue against the shore (owner, 2026-11-02): the 1860 sheet's grey-blue read grey-green on the cream.
|
|
20839
|
+
water: [128, 178, 222],
|
|
20840
|
+
flat: [226, 206, 150],
|
|
20841
|
+
town: [186, 72, 52],
|
|
20842
|
+
road: [192, 124, 72]
|
|
20843
|
+
};
|
|
20844
|
+
function washOver(under, tone, a) {
|
|
20845
|
+
const k = Math.max(0, Math.min(1, a));
|
|
20846
|
+
return [0, 1, 2].map((i) => under[i] * (1 - k * (1 - tone[i] / 255)));
|
|
20847
|
+
}
|
|
20848
|
+
function rgbHex(rgb) {
|
|
20849
|
+
return `#${rgb.map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, "0")).join("")}`;
|
|
20850
|
+
}
|
|
20851
|
+
var WASH_TINTS = (() => {
|
|
20852
|
+
const paper = WASH_TONES.paper;
|
|
20853
|
+
const land = washOver(paper, WASH_TONES.land, 0.6);
|
|
20854
|
+
return {
|
|
20855
|
+
paper: rgbHex(paper),
|
|
20856
|
+
land: rgbHex(land),
|
|
20857
|
+
/** Water to the 18 ft curve. */
|
|
20858
|
+
shallow: rgbHex(washOver(paper, WASH_TONES.water, 0.4)),
|
|
20859
|
+
/** A pond or lake. */
|
|
20860
|
+
lake: rgbHex(washOver(paper, WASH_TONES.water, 0.26)),
|
|
20861
|
+
/** Drying flats. */
|
|
20862
|
+
flat: rgbHex(washOver(paper, WASH_TONES.flat, 0.375)),
|
|
20863
|
+
/** A town, laid over the land. */
|
|
20864
|
+
town: rgbHex(washOver(land, WASH_TONES.town, 0.42)),
|
|
20865
|
+
/** A road's core, over the land. */
|
|
20866
|
+
road: rgbHex(washOver(land, WASH_TONES.road, 0.45))
|
|
20867
|
+
};
|
|
20868
|
+
})();
|
|
20869
|
+
|
|
20870
|
+
// src/atlas/chart-look.ts
|
|
20871
|
+
var LOOK_TONES = {
|
|
20872
|
+
// Black on white: the sheet prints in black alone (DeviceGray).
|
|
20873
|
+
engraved: { ink: "#000000", paper: "#ffffff" },
|
|
20874
|
+
// The 1860 sheet's ink, a warm black (#382d20, sampled), on white; the wash,
|
|
20875
|
+
// multiplied over it, tones the paper and colours the land and water
|
|
20876
|
+
// (look-wash-tones.ts WASH_TONES).
|
|
20877
|
+
handcolored: { ink: "#382d20", paper: "#ffffff" }
|
|
20878
|
+
};
|
|
20879
|
+
var LOOK_IMAGE_NAMES = [
|
|
20880
|
+
"stipple-flats",
|
|
20881
|
+
"stipple-1fm",
|
|
20882
|
+
"stipple-2fm",
|
|
20883
|
+
"stipple-3fm",
|
|
20884
|
+
"marsh",
|
|
20885
|
+
"woods",
|
|
20886
|
+
// The Survey's symbols (lookSymbols).
|
|
20887
|
+
"buoy-nun-red",
|
|
20888
|
+
"buoy-nun-green",
|
|
20889
|
+
"buoy-nun-black",
|
|
20890
|
+
"buoy-nun-yellow",
|
|
20891
|
+
"buoy-can-red",
|
|
20892
|
+
"buoy-can-green",
|
|
20893
|
+
"buoy-can-black",
|
|
20894
|
+
"buoy-can-yellow",
|
|
20895
|
+
"buoy-spar-red",
|
|
20896
|
+
"buoy-spar-green",
|
|
20897
|
+
"buoy-spar-black",
|
|
20898
|
+
"buoy-spar-yellow",
|
|
20899
|
+
"buoy-other-red",
|
|
20900
|
+
"buoy-other-green",
|
|
20901
|
+
"buoy-other-black",
|
|
20902
|
+
"buoy-other-yellow",
|
|
20903
|
+
"beacon",
|
|
20904
|
+
"light",
|
|
20905
|
+
"light-major",
|
|
20906
|
+
"lightship",
|
|
20907
|
+
"landmark",
|
|
20908
|
+
"anchor",
|
|
20909
|
+
"fog"
|
|
20910
|
+
];
|
|
20911
|
+
var IMAGE_PREFIX = { engraved: "chrt-look-en-", handcolored: "chrt-look-hc-", paper: "chrt-look-cl-" };
|
|
20912
|
+
function lookImageId(look, name) {
|
|
20913
|
+
return IMAGE_PREFIX[look] + name;
|
|
20914
|
+
}
|
|
20915
|
+
function imageNames(look) {
|
|
20916
|
+
return look === "paper" ? CLASSIC_IMAGE_NAMES : LOOK_IMAGE_NAMES;
|
|
20917
|
+
}
|
|
20918
|
+
function lookOfImageId(id) {
|
|
20919
|
+
for (const look of Object.keys(IMAGE_PREFIX)) {
|
|
20920
|
+
if (id.startsWith(IMAGE_PREFIX[look]) && imageNames(look).includes(id.slice(IMAGE_PREFIX[look].length))) return look;
|
|
20921
|
+
}
|
|
20922
|
+
return null;
|
|
20923
|
+
}
|
|
20924
|
+
var PAINT = {
|
|
20925
|
+
red: [184, 69, 47, 255],
|
|
20926
|
+
green: [79, 122, 58, 255],
|
|
20927
|
+
yellow: [214, 176, 72, 255],
|
|
20928
|
+
light: [232, 196, 92, 210]
|
|
20929
|
+
};
|
|
20930
|
+
function lookSymbols(look, ink) {
|
|
20931
|
+
const R2 = 2;
|
|
20932
|
+
const S2 = 64 * R2;
|
|
20933
|
+
const c0 = S2 / 2;
|
|
20934
|
+
const out = [];
|
|
20935
|
+
const coloured = look === "handcolored";
|
|
20936
|
+
const tilt = 28;
|
|
20937
|
+
const line = 0.75 * R2;
|
|
20938
|
+
const B = 1.55;
|
|
20939
|
+
const shapes = {
|
|
20940
|
+
nun: [[0, 0], [-3.2, -6], [0, -16], [3.2, -6]],
|
|
20941
|
+
can: [[-3.4, 0], [-3.4, -9], [3.4, -9], [3.4, 0]],
|
|
20942
|
+
spar: [[-0.9, 0], [-0.9, -16], [0.9, -16], [0.9, 0]],
|
|
20943
|
+
other: Array.from({ length: 20 }, (_, i) => [4.2 * Math.sin(i / 20 * 2 * Math.PI), -5 - 4.6 * Math.cos(i / 20 * 2 * Math.PI)])
|
|
20944
|
+
};
|
|
20945
|
+
for (const shape of ["nun", "can", "spar", "other"]) {
|
|
20946
|
+
for (const colour of ["red", "green", "black", "yellow"]) {
|
|
20947
|
+
const p = painter(S2, S2);
|
|
20948
|
+
const pts = shapes[shape].map(([x, y]) => turn([c0 + x * B * R2, c0 + y * B * R2], c0, c0, tilt));
|
|
20949
|
+
const solid = colour === "black" || colour === "green";
|
|
20950
|
+
if (coloured) p.fill(pts, colour === "black" ? ink : PAINT[colour]);
|
|
20951
|
+
else if (solid) p.fill(pts, ink);
|
|
20952
|
+
p.stroke([...pts, pts[0]], line / 2, ink);
|
|
20953
|
+
p.dot(c0, c0, 1.1 * R2, ink);
|
|
20954
|
+
out.push({ name: `buoy-${shape}-${colour}`, data: p.data(), size: S2 });
|
|
20955
|
+
}
|
|
20956
|
+
}
|
|
20957
|
+
{
|
|
20958
|
+
const p = painter(S2, S2);
|
|
20959
|
+
p.stroke([[c0, c0], [c0, c0 - 22 * R2]], 0.6 * R2, ink);
|
|
20960
|
+
p.dot(c0, c0 - 22 * R2, 2.2 * R2, ink);
|
|
20961
|
+
p.dot(c0, c0, 1.2 * R2, ink);
|
|
20962
|
+
out.push({ name: "beacon", data: p.data(), size: S2 });
|
|
20963
|
+
}
|
|
20964
|
+
for (const [name, r, rays] of [["light", 13, 12], ["light-major", 18, 16]]) {
|
|
20965
|
+
const p = painter(S2, S2);
|
|
20966
|
+
if (coloured) p.dot(c0, c0, r * 0.75 * R2, PAINT.light);
|
|
20967
|
+
for (let i = 0; i < rays; i++) {
|
|
20968
|
+
const a = i / rays * 2 * Math.PI;
|
|
20969
|
+
const len = i % 2 === 0 ? r : r * 0.62;
|
|
20970
|
+
p.stroke([[c0 + Math.cos(a) * 3 * R2, c0 + Math.sin(a) * 3 * R2], [c0 + Math.cos(a) * len * R2, c0 + Math.sin(a) * len * R2]], 0.38 * R2, ink);
|
|
20971
|
+
}
|
|
20972
|
+
p.dot(c0, c0, 2.8 * R2, ink);
|
|
20973
|
+
out.push({ name, data: p.data(), size: S2 });
|
|
20974
|
+
}
|
|
20975
|
+
{
|
|
20976
|
+
const p = painter(S2, S2);
|
|
20977
|
+
const hull = [[-8, 0], [8, 0], [5.5, 3.2], [-5.5, 3.2]].map(([x, y]) => [c0 + x * R2, c0 + y * R2]);
|
|
20978
|
+
p.fill(hull, coloured ? PAINT.red : ink);
|
|
20979
|
+
p.stroke([...hull, hull[0]], 0.35 * R2, ink);
|
|
20980
|
+
p.stroke([[c0, c0], [c0, c0 - 11 * R2]], 0.45 * R2, ink);
|
|
20981
|
+
for (let i = 0; i < 8; i++) {
|
|
20982
|
+
const a = i / 8 * 2 * Math.PI;
|
|
20983
|
+
p.stroke([[c0, c0 - 11 * R2], [c0 + Math.cos(a) * 3.6 * R2, c0 - 11 * R2 + Math.sin(a) * 3.6 * R2]], 0.28 * R2, ink);
|
|
20984
|
+
}
|
|
20985
|
+
out.push({ name: "lightship", data: p.data(), size: S2 });
|
|
20986
|
+
}
|
|
20987
|
+
{
|
|
20988
|
+
const p = painter(S2, S2);
|
|
20989
|
+
const ring = Array.from({ length: 33 }, (_, i) => [c0 + 4.6 * R2 * Math.cos(i / 32 * 2 * Math.PI), c0 + 4.6 * R2 * Math.sin(i / 32 * 2 * Math.PI)]);
|
|
20990
|
+
p.stroke(ring, 0.45 * R2, ink);
|
|
20991
|
+
p.dot(c0, c0, 1.2 * R2, ink);
|
|
20992
|
+
out.push({ name: "landmark", data: p.data(), size: S2 });
|
|
20993
|
+
}
|
|
20994
|
+
{
|
|
20995
|
+
const p = painter(S2, S2);
|
|
20996
|
+
const y0 = c0 - 7 * R2;
|
|
20997
|
+
p.stroke([[c0, y0], [c0, c0 + 7 * R2]], 0.5 * R2, ink);
|
|
20998
|
+
p.stroke([[c0 - 3.5 * R2, y0 + 2.2 * R2], [c0 + 3.5 * R2, y0 + 2.2 * R2]], 0.45 * R2, ink);
|
|
20999
|
+
const ring = Array.from({ length: 17 }, (_, i) => [c0 + 1.3 * R2 * Math.cos(i / 16 * 2 * Math.PI), y0 - 1.3 * R2 + 1.3 * R2 * Math.sin(i / 16 * 2 * Math.PI)]);
|
|
21000
|
+
p.stroke(ring, 0.35 * R2, ink);
|
|
21001
|
+
const arm = Array.from({ length: 13 }, (_, i) => {
|
|
21002
|
+
const a = Math.PI * (0.15 + 0.7 * (i / 12));
|
|
21003
|
+
return [c0 + 5.5 * R2 * Math.cos(a), c0 + 1.5 * R2 + 5.5 * R2 * Math.sin(a)];
|
|
21004
|
+
});
|
|
21005
|
+
p.stroke(arm, 0.5 * R2, ink);
|
|
21006
|
+
p.stroke([arm[0], [arm[0][0] + 1.6 * R2, arm[0][1] - 1.4 * R2]], 0.45 * R2, ink);
|
|
21007
|
+
p.stroke([arm[12], [arm[12][0] - 1.6 * R2, arm[12][1] - 1.4 * R2]], 0.45 * R2, ink);
|
|
21008
|
+
out.push({ name: "anchor", data: p.data(), size: S2 });
|
|
21009
|
+
}
|
|
21010
|
+
{
|
|
21011
|
+
const p = painter(S2, S2);
|
|
21012
|
+
for (const r of [6, 9, 12]) {
|
|
21013
|
+
const arc = Array.from({ length: 13 }, (_, i) => {
|
|
21014
|
+
const a = (-115 + 50 * i / 12) * (Math.PI / 180);
|
|
21015
|
+
return [c0 + r * R2 * Math.cos(a), c0 + r * R2 * Math.sin(a)];
|
|
21016
|
+
});
|
|
21017
|
+
p.stroke(arc, 0.42 * R2, ink);
|
|
21018
|
+
}
|
|
21019
|
+
out.push({ name: "fog", data: p.data(), size: S2 });
|
|
21020
|
+
}
|
|
21021
|
+
return out;
|
|
21022
|
+
}
|
|
21023
|
+
var IMAGE_RATIO = 4;
|
|
21024
|
+
function hash(a, b, seed) {
|
|
21025
|
+
let h = a * 374761393 + b * 668265263 + seed * 2147483647 | 0;
|
|
21026
|
+
h = Math.imul(h ^ h >>> 13, 1274126177);
|
|
21027
|
+
return ((h ^ h >>> 16) >>> 0) / 4294967296;
|
|
21028
|
+
}
|
|
21029
|
+
function canvas(w, h) {
|
|
21030
|
+
const data = new Uint8Array(w * h * 4);
|
|
21031
|
+
const put = (x, y, a) => {
|
|
21032
|
+
const xi = (x % w + w) % w;
|
|
21033
|
+
const yi = (y % h + h) % h;
|
|
21034
|
+
const k = (yi * w + xi) * 4 + 3;
|
|
21035
|
+
data[k] = Math.min(255, Math.max(data[k], Math.round(a * 255)));
|
|
21036
|
+
};
|
|
21037
|
+
const dot = (cx, cy, r, a = 1) => {
|
|
21038
|
+
for (let y = Math.floor(cy - r - 1); y <= Math.ceil(cy + r + 1); y++) {
|
|
21039
|
+
for (let x = Math.floor(cx - r - 1); x <= Math.ceil(cx + r + 1); x++) {
|
|
21040
|
+
const d = Math.hypot(x + 0.5 - cx, y + 0.5 - cy);
|
|
21041
|
+
const cov = Math.max(0, Math.min(1, r + 0.5 - d));
|
|
21042
|
+
if (cov > 0) put(x, y, cov * a);
|
|
21043
|
+
}
|
|
21044
|
+
}
|
|
21045
|
+
};
|
|
21046
|
+
const line = (x0, y0, x1, y1, r) => {
|
|
21047
|
+
const n = Math.max(1, Math.ceil(Math.hypot(x1 - x0, y1 - y0) * 2));
|
|
21048
|
+
for (let i = 0; i <= n; i++) dot(x0 + (x1 - x0) * i / n, y0 + (y1 - y0) * i / n, r);
|
|
21049
|
+
};
|
|
21050
|
+
return { data, dot, line };
|
|
21051
|
+
}
|
|
21052
|
+
function lookImages(look) {
|
|
21053
|
+
if (look === "paper") return classicImages().map((i) => ({ ...i, id: lookImageId("paper", i.name) }));
|
|
21054
|
+
const [ir, ig, ib] = [1, 3, 5].map((i) => parseInt(LOOK_TONES[look].ink.slice(i, i + 2), 16));
|
|
21055
|
+
const finish = (name, w, h, data) => {
|
|
21056
|
+
for (let k = 0; k < data.length; k += 4) {
|
|
21057
|
+
data[k] = ir;
|
|
21058
|
+
data[k + 1] = ig;
|
|
21059
|
+
data[k + 2] = ib;
|
|
21060
|
+
}
|
|
21061
|
+
return { id: lookImageId(look, name), width: w, height: h, pixelRatio: IMAGE_RATIO, data };
|
|
21062
|
+
};
|
|
21063
|
+
const out = [];
|
|
21064
|
+
for (const [id, step, r, seed] of [
|
|
21065
|
+
["stipple-flats", 5, 0.95, 1],
|
|
21066
|
+
["stipple-1fm", 6, 0.9, 2],
|
|
21067
|
+
["stipple-2fm", 8, 0.85, 3],
|
|
21068
|
+
["stipple-3fm", 11, 0.8, 4]
|
|
21069
|
+
]) {
|
|
21070
|
+
const n = 8;
|
|
21071
|
+
const w = step * n;
|
|
21072
|
+
const c = canvas(w, w);
|
|
21073
|
+
for (let j = 0; j < n; j++) for (let i = 0; i < n; i++) {
|
|
21074
|
+
c.dot((i + 0.2 + 0.6 * hash(i, j, seed)) * step, (j + 0.2 + 0.6 * hash(j, i, seed + 7)) * step, r * (0.8 + 0.4 * hash(i, j, seed + 3)));
|
|
21075
|
+
}
|
|
21076
|
+
out.push(finish(id, w, w, c.data));
|
|
21077
|
+
}
|
|
21078
|
+
{
|
|
21079
|
+
const w = 96;
|
|
21080
|
+
const h = 64;
|
|
21081
|
+
const c = canvas(w, h);
|
|
21082
|
+
for (const [x, y] of [[16, 22], [64, 22], [40, 54], [88, 54]]) {
|
|
21083
|
+
c.line(x - 9, y, x + 9, y, 0.55);
|
|
21084
|
+
c.line(x, y, x, y - 9, 0.5);
|
|
21085
|
+
c.line(x - 3, y, x - 7, y - 7, 0.45);
|
|
21086
|
+
c.line(x + 3, y, x + 7, y - 7, 0.45);
|
|
21087
|
+
}
|
|
21088
|
+
out.push(finish("marsh", w, h, c.data));
|
|
21089
|
+
}
|
|
21090
|
+
{
|
|
21091
|
+
const n = 6;
|
|
21092
|
+
const step = 12;
|
|
21093
|
+
const w = n * step;
|
|
21094
|
+
const c = canvas(w, w);
|
|
21095
|
+
for (let j = 0; j < n; j++) for (let i = 0; i < n; i++) {
|
|
21096
|
+
const x = (i + 0.25 + 0.5 * hash(i, j, 31)) * step;
|
|
21097
|
+
const y = (j + 0.25 + 0.5 * hash(j, i, 37)) * step;
|
|
21098
|
+
for (let a = 0; a < 2 * Math.PI; a += 0.25) c.dot(x + 2.4 * Math.cos(a), y + 2.4 * Math.sin(a), 0.4);
|
|
21099
|
+
c.line(x + 1.5, y + 3, x + 3, y + 2.4, 0.55);
|
|
21100
|
+
}
|
|
21101
|
+
out.push(finish("woods", w, w, c.data));
|
|
21102
|
+
}
|
|
21103
|
+
for (const sym of lookSymbols(look, [ir, ig, ib, 255])) {
|
|
21104
|
+
out.push({ id: lookImageId(look, sym.name), width: sym.size, height: sym.size, pixelRatio: 2, data: sym.data });
|
|
21105
|
+
}
|
|
21106
|
+
return out;
|
|
21107
|
+
}
|
|
21108
|
+
|
|
21109
|
+
// src/atlas/chart-look-images-browser.ts
|
|
21110
|
+
var IMAGES = /* @__PURE__ */ new Map();
|
|
21111
|
+
function provideChartLookImages(map) {
|
|
21112
|
+
map.on("styleimagemissing", (e) => {
|
|
21113
|
+
const mark = classicMarkInk(e.id) !== null;
|
|
21114
|
+
const look = mark ? null : lookOfImageId(e.id);
|
|
21115
|
+
if (!mark && look === null || map.hasImage(e.id)) return;
|
|
21116
|
+
if (!IMAGES.has(e.id)) {
|
|
21117
|
+
if (mark) IMAGES.set(e.id, classicMarkImage(e.id));
|
|
21118
|
+
else for (const image2 of lookImages(look)) IMAGES.set(image2.id, image2);
|
|
21119
|
+
}
|
|
21120
|
+
const image = IMAGES.get(e.id);
|
|
21121
|
+
if (!image) return;
|
|
21122
|
+
map.addImage(e.id, { width: image.width, height: image.height, data: new Uint8Array(image.data) }, { pixelRatio: image.pixelRatio });
|
|
21123
|
+
});
|
|
21124
|
+
}
|
|
20473
21125
|
export {
|
|
20474
21126
|
BASE_PATTERN_GLYPHS,
|
|
20475
21127
|
basePatternImageSpecs,
|
|
@@ -20485,6 +21137,7 @@ export {
|
|
|
20485
21137
|
loadSymbolImageSpecs,
|
|
20486
21138
|
loadSymbolImages,
|
|
20487
21139
|
loadThemedBridgeImages,
|
|
21140
|
+
provideChartLookImages,
|
|
20488
21141
|
rasterImageSpecs,
|
|
20489
21142
|
reloadChrtRasterSymbolImages,
|
|
20490
21143
|
reloadS101SymbolImages,
|
|
@@ -20494,6 +21147,7 @@ export {
|
|
|
20494
21147
|
s101ImageSpecs,
|
|
20495
21148
|
s52ImageSpecs,
|
|
20496
21149
|
styleImageIds,
|
|
20497
|
-
symbolImageSpecs
|
|
21150
|
+
symbolImageSpecs,
|
|
21151
|
+
usChart1ImageSpecs
|
|
20498
21152
|
};
|
|
20499
21153
|
//# sourceMappingURL=browser.js.map
|