@diagrammo/dgmo 0.20.3 → 0.21.1
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/dist/advanced.cjs +867 -286
- package/dist/advanced.js +866 -286
- package/dist/auto.cjs +635 -284
- package/dist/auto.js +113 -113
- package/dist/auto.mjs +635 -284
- package/dist/cli.cjs +156 -156
- package/dist/editor.cjs +6 -2
- package/dist/editor.js +6 -2
- package/dist/highlight.cjs +6 -2
- package/dist/highlight.js +6 -2
- package/dist/index.cjs +628 -281
- package/dist/index.js +628 -281
- package/dist/internal.cjs +867 -286
- package/dist/internal.js +866 -286
- package/dist/map-data/PROVENANCE.json +1 -1
- package/dist/map-data/mountain-ranges.json +1 -0
- package/docs/language-reference.md +27 -25
- package/gallery/fixtures/map-choropleth.dgmo +7 -7
- package/gallery/fixtures/map-direct-color.dgmo +10 -0
- package/gallery/fixtures/map-pois.dgmo +4 -4
- package/gallery/fixtures/map-region-scope.dgmo +8 -8
- package/gallery/fixtures/map-route.dgmo +5 -6
- package/package.json +1 -1
- package/src/advanced.ts +14 -0
- package/src/completion.ts +10 -4
- package/src/d3.ts +15 -9
- package/src/editor/keywords.ts +6 -2
- package/src/map/data/PROVENANCE.json +1 -1
- package/src/map/data/mountain-ranges.json +1 -0
- package/src/map/geo-query.ts +277 -0
- package/src/map/geo.ts +258 -1
- package/src/map/invert.ts +111 -0
- package/src/map/layout.ts +333 -139
- package/src/map/load-data.ts +7 -1
- package/src/map/parser.ts +142 -33
- package/src/map/renderer.ts +57 -6
- package/src/map/resolved-types.ts +21 -2
- package/src/map/resolver.ts +219 -53
- package/src/map/types.ts +57 -14
- package/src/utils/reserved-key-registry.ts +7 -7
- package/dist/advanced.d.cts +0 -5290
- package/dist/advanced.d.ts +0 -5290
- package/dist/auto.d.cts +0 -39
- package/dist/auto.d.ts +0 -39
- package/dist/index.d.cts +0 -336
- package/dist/index.d.ts +0 -336
- package/dist/internal.d.cts +0 -5290
- package/dist/internal.d.ts +0 -5290
package/dist/auto.mjs
CHANGED
|
@@ -758,13 +758,9 @@ var init_reserved_key_registry = __esm({
|
|
|
758
758
|
"icon"
|
|
759
759
|
]);
|
|
760
760
|
MAP_REGISTRY = staticRegistry([
|
|
761
|
-
"
|
|
761
|
+
"value",
|
|
762
762
|
"label",
|
|
763
|
-
"
|
|
764
|
-
"description",
|
|
765
|
-
"weight",
|
|
766
|
-
"style",
|
|
767
|
-
"date"
|
|
763
|
+
"style"
|
|
768
764
|
]);
|
|
769
765
|
ORG_REGISTRY = staticRegistry([
|
|
770
766
|
"color",
|
|
@@ -15795,7 +15791,8 @@ function parseMap(content) {
|
|
|
15795
15791
|
continue;
|
|
15796
15792
|
}
|
|
15797
15793
|
if (open.route && indent > open.route.indent) {
|
|
15798
|
-
open.route.route.
|
|
15794
|
+
const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
|
|
15795
|
+
open.route.route.legs.push(leg);
|
|
15799
15796
|
continue;
|
|
15800
15797
|
}
|
|
15801
15798
|
if (open.poi && indent > open.poi.indent) {
|
|
@@ -15826,6 +15823,10 @@ function parseMap(content) {
|
|
|
15826
15823
|
handleTag(trimmed, lineNumber);
|
|
15827
15824
|
continue;
|
|
15828
15825
|
}
|
|
15826
|
+
if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
|
|
15827
|
+
handleDirective(firstWord, "", lineNumber);
|
|
15828
|
+
continue;
|
|
15829
|
+
}
|
|
15829
15830
|
if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
|
|
15830
15831
|
handleDirective(
|
|
15831
15832
|
firstWord,
|
|
@@ -15890,13 +15891,20 @@ function parseMap(content) {
|
|
|
15890
15891
|
);
|
|
15891
15892
|
d.projection = value;
|
|
15892
15893
|
break;
|
|
15893
|
-
case "metric":
|
|
15894
|
-
dup(d.
|
|
15895
|
-
|
|
15894
|
+
case "region-metric": {
|
|
15895
|
+
dup(d.regionMetric);
|
|
15896
|
+
const { label: rmLabel, colorName: rmColor } = peelTrailingColorName(value);
|
|
15897
|
+
d.regionMetric = rmLabel;
|
|
15898
|
+
if (rmColor) d.regionMetricColor = rmColor;
|
|
15899
|
+
break;
|
|
15900
|
+
}
|
|
15901
|
+
case "poi-metric":
|
|
15902
|
+
dup(d.poiMetric);
|
|
15903
|
+
d.poiMetric = value;
|
|
15896
15904
|
break;
|
|
15897
|
-
case "
|
|
15898
|
-
dup(d.
|
|
15899
|
-
d.
|
|
15905
|
+
case "flow-metric":
|
|
15906
|
+
dup(d.flowMetric);
|
|
15907
|
+
d.flowMetric = value;
|
|
15900
15908
|
break;
|
|
15901
15909
|
case "scale":
|
|
15902
15910
|
dup(d.scale);
|
|
@@ -15938,6 +15946,21 @@ function parseMap(content) {
|
|
|
15938
15946
|
case "no-legend":
|
|
15939
15947
|
d.noLegend = true;
|
|
15940
15948
|
break;
|
|
15949
|
+
case "no-insets":
|
|
15950
|
+
d.noInsets = true;
|
|
15951
|
+
break;
|
|
15952
|
+
case "relief":
|
|
15953
|
+
d.relief = true;
|
|
15954
|
+
break;
|
|
15955
|
+
case "muted":
|
|
15956
|
+
case "natural":
|
|
15957
|
+
if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
|
|
15958
|
+
pushWarning(
|
|
15959
|
+
line12,
|
|
15960
|
+
`Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
|
|
15961
|
+
);
|
|
15962
|
+
d.basemapStyle = key;
|
|
15963
|
+
break;
|
|
15941
15964
|
case "subtitle":
|
|
15942
15965
|
dup(d.subtitle);
|
|
15943
15966
|
d.subtitle = value;
|
|
@@ -16015,14 +16038,14 @@ function parseMap(content) {
|
|
|
16015
16038
|
line12
|
|
16016
16039
|
);
|
|
16017
16040
|
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16018
|
-
let
|
|
16019
|
-
const
|
|
16020
|
-
if (
|
|
16021
|
-
delete meta["
|
|
16022
|
-
|
|
16023
|
-
if (!Number.isFinite(
|
|
16024
|
-
pushError(line12, `
|
|
16025
|
-
|
|
16041
|
+
let valueNum;
|
|
16042
|
+
const value = meta["value"];
|
|
16043
|
+
if (value !== void 0) {
|
|
16044
|
+
delete meta["value"];
|
|
16045
|
+
valueNum = Number(value);
|
|
16046
|
+
if (!Number.isFinite(valueNum)) {
|
|
16047
|
+
pushError(line12, `value must be a number (got "${value}").`);
|
|
16048
|
+
valueNum = void 0;
|
|
16026
16049
|
}
|
|
16027
16050
|
}
|
|
16028
16051
|
let regionName = split.name;
|
|
@@ -16040,7 +16063,8 @@ function parseMap(content) {
|
|
|
16040
16063
|
lineNumber: line12
|
|
16041
16064
|
};
|
|
16042
16065
|
if (regionScope !== void 0) region.scope = regionScope;
|
|
16043
|
-
if (
|
|
16066
|
+
if (valueNum !== void 0) region.value = valueNum;
|
|
16067
|
+
if (split.color) region.color = split.color;
|
|
16044
16068
|
regions.push(region);
|
|
16045
16069
|
}
|
|
16046
16070
|
function handlePoi(rest, line12, indent) {
|
|
@@ -16065,28 +16089,81 @@ function parseMap(content) {
|
|
|
16065
16089
|
const poi = { pos, tags, meta, lineNumber: line12 };
|
|
16066
16090
|
if (split.alias) poi.alias = split.alias;
|
|
16067
16091
|
if (label !== void 0) poi.label = label;
|
|
16092
|
+
if (split.color) poi.color = split.color;
|
|
16068
16093
|
pois.push(poi);
|
|
16069
16094
|
open.poi = { poi, indent };
|
|
16070
16095
|
}
|
|
16071
16096
|
function handleRoute(rest, line12, indent) {
|
|
16072
|
-
const
|
|
16073
|
-
|
|
16097
|
+
const split = rest ? splitNameAndMeta(
|
|
16098
|
+
rest,
|
|
16099
|
+
registry(),
|
|
16100
|
+
aliasMap,
|
|
16101
|
+
void 0,
|
|
16102
|
+
diagnostics,
|
|
16103
|
+
line12
|
|
16104
|
+
) : { name: "", meta: {}, alias: void 0 };
|
|
16105
|
+
const pos = parsePos(split.name, line12);
|
|
16106
|
+
if (!pos || pos.kind === "name" && !pos.name) {
|
|
16107
|
+
pushError(
|
|
16108
|
+
line12,
|
|
16109
|
+
"route requires an origin: `route <origin> [style: arc]`."
|
|
16110
|
+
);
|
|
16111
|
+
return;
|
|
16112
|
+
}
|
|
16113
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16114
|
+
const originLabel = meta["label"];
|
|
16115
|
+
const originValue = meta["value"];
|
|
16116
|
+
const style = meta["style"] === "arc" ? "arc" : "straight";
|
|
16117
|
+
const route = {
|
|
16118
|
+
origin: pos,
|
|
16119
|
+
...split.alias !== void 0 && { originAlias: split.alias },
|
|
16120
|
+
...originLabel !== void 0 && { originLabel },
|
|
16121
|
+
...originValue !== void 0 && { originValue },
|
|
16122
|
+
originTags: tags,
|
|
16123
|
+
style,
|
|
16124
|
+
legs: [],
|
|
16125
|
+
lineNumber: line12
|
|
16126
|
+
};
|
|
16074
16127
|
routes.push(route);
|
|
16075
16128
|
open.route = { route, indent };
|
|
16076
16129
|
}
|
|
16077
|
-
function
|
|
16078
|
-
|
|
16079
|
-
|
|
16130
|
+
function parseLeg(trimmed, line12, headerStyle) {
|
|
16131
|
+
let arrowStyle = "straight";
|
|
16132
|
+
let label;
|
|
16133
|
+
let rest = trimmed;
|
|
16134
|
+
const m = trimmed.match(LEG_ARROW_RE);
|
|
16135
|
+
if (m) {
|
|
16136
|
+
const arr = classifyArrow(m[1], line12);
|
|
16137
|
+
arrowStyle = arr.style;
|
|
16138
|
+
label = arr.label;
|
|
16139
|
+
rest = m[2];
|
|
16140
|
+
}
|
|
16141
|
+
const split = splitNameAndMeta(
|
|
16142
|
+
rest,
|
|
16143
|
+
registry(),
|
|
16144
|
+
aliasMap,
|
|
16145
|
+
void 0,
|
|
16146
|
+
diagnostics,
|
|
16147
|
+
line12
|
|
16148
|
+
);
|
|
16149
|
+
const pos = parsePos(split.name, line12) ?? {
|
|
16080
16150
|
kind: "name",
|
|
16081
16151
|
name: split.name
|
|
16082
16152
|
};
|
|
16083
|
-
const
|
|
16084
|
-
|
|
16085
|
-
|
|
16153
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16154
|
+
const value = meta["value"];
|
|
16155
|
+
const destLabel = meta["label"];
|
|
16156
|
+
const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
|
|
16157
|
+
return {
|
|
16158
|
+
...label !== void 0 && { label },
|
|
16159
|
+
style,
|
|
16160
|
+
...value !== void 0 && { value },
|
|
16161
|
+
dest: pos,
|
|
16162
|
+
...split.alias !== void 0 && { destAlias: split.alias },
|
|
16163
|
+
...destLabel !== void 0 && { destLabel },
|
|
16164
|
+
destTags: tags,
|
|
16086
16165
|
lineNumber: line12
|
|
16087
16166
|
};
|
|
16088
|
-
if (split.alias) stop.alias = split.alias;
|
|
16089
|
-
return stop;
|
|
16090
16167
|
}
|
|
16091
16168
|
function handleEdges(trimmed, line12) {
|
|
16092
16169
|
const parts = trimmed.split(ARROW_SPLIT);
|
|
@@ -16188,7 +16265,7 @@ function partitionMeta(meta, tagGroupNames) {
|
|
|
16188
16265
|
function poiName(pos) {
|
|
16189
16266
|
return pos.kind === "name" ? pos.name : void 0;
|
|
16190
16267
|
}
|
|
16191
|
-
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
|
|
16268
|
+
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
|
|
16192
16269
|
var init_parser12 = __esm({
|
|
16193
16270
|
"src/map/parser.ts"() {
|
|
16194
16271
|
"use strict";
|
|
@@ -16202,12 +16279,14 @@ var init_parser12 = __esm({
|
|
|
16202
16279
|
SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
|
|
16203
16280
|
ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
|
|
16204
16281
|
HUB_RE = /^(->|~>)\s+(.+)$/;
|
|
16282
|
+
LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
|
|
16205
16283
|
AT_RE = /(^|[\s,])at\s*:/i;
|
|
16206
16284
|
DIRECTIVE_SET = /* @__PURE__ */ new Set([
|
|
16207
16285
|
"region",
|
|
16208
16286
|
"projection",
|
|
16209
|
-
"metric",
|
|
16210
|
-
"
|
|
16287
|
+
"region-metric",
|
|
16288
|
+
"poi-metric",
|
|
16289
|
+
"flow-metric",
|
|
16211
16290
|
"scale",
|
|
16212
16291
|
"region-labels",
|
|
16213
16292
|
"poi-labels",
|
|
@@ -16215,6 +16294,8 @@ var init_parser12 = __esm({
|
|
|
16215
16294
|
"default-state",
|
|
16216
16295
|
"active-tag",
|
|
16217
16296
|
"no-legend",
|
|
16297
|
+
"no-insets",
|
|
16298
|
+
"relief",
|
|
16218
16299
|
"subtitle",
|
|
16219
16300
|
"caption"
|
|
16220
16301
|
]);
|
|
@@ -45413,7 +45494,7 @@ var init_renderer15 = __esm({
|
|
|
45413
45494
|
|
|
45414
45495
|
// src/map/geo.ts
|
|
45415
45496
|
import { feature } from "topojson-client";
|
|
45416
|
-
import { geoBounds } from "d3-geo";
|
|
45497
|
+
import { geoBounds, geoArea } from "d3-geo";
|
|
45417
45498
|
function geomObject(topo) {
|
|
45418
45499
|
const key = Object.keys(topo.objects)[0];
|
|
45419
45500
|
return topo.objects[key];
|
|
@@ -45441,6 +45522,74 @@ function featureBbox(topo, geomId) {
|
|
|
45441
45522
|
[b[1][0], b[1][1]]
|
|
45442
45523
|
];
|
|
45443
45524
|
}
|
|
45525
|
+
function explodePolygons(gj) {
|
|
45526
|
+
const g = gj.geometry ?? gj;
|
|
45527
|
+
const t = g.type;
|
|
45528
|
+
const coords = g.coordinates;
|
|
45529
|
+
if (t === "Polygon") {
|
|
45530
|
+
return [
|
|
45531
|
+
{ type: "Feature", geometry: { type: "Polygon", coordinates: coords } }
|
|
45532
|
+
];
|
|
45533
|
+
}
|
|
45534
|
+
if (t === "MultiPolygon") {
|
|
45535
|
+
return coords.map((rings) => ({
|
|
45536
|
+
type: "Feature",
|
|
45537
|
+
geometry: { type: "Polygon", coordinates: rings }
|
|
45538
|
+
}));
|
|
45539
|
+
}
|
|
45540
|
+
return [];
|
|
45541
|
+
}
|
|
45542
|
+
function bboxGap(a, b) {
|
|
45543
|
+
const lonGap = Math.max(0, a[0][0] - b[1][0], b[0][0] - a[1][0]);
|
|
45544
|
+
const latGap = Math.max(0, a[0][1] - b[1][1], b[0][1] - a[1][1]);
|
|
45545
|
+
return Math.max(lonGap, latGap);
|
|
45546
|
+
}
|
|
45547
|
+
function featureBboxPrimary(topo, geomId) {
|
|
45548
|
+
const geom = geomObject(topo).geometries.find((g) => g.id === geomId);
|
|
45549
|
+
if (!geom) return null;
|
|
45550
|
+
const gj = feature(topo, geom);
|
|
45551
|
+
const parts = explodePolygons(gj);
|
|
45552
|
+
if (parts.length <= 1) return featureBbox(topo, geomId);
|
|
45553
|
+
const polys = parts.map((p) => {
|
|
45554
|
+
const b = geoBounds(p);
|
|
45555
|
+
if (!b || !Number.isFinite(b[0][0])) return null;
|
|
45556
|
+
const wraps = b[1][0] < b[0][0];
|
|
45557
|
+
const bbox = [
|
|
45558
|
+
[b[0][0], b[0][1]],
|
|
45559
|
+
[b[1][0], b[1][1]]
|
|
45560
|
+
];
|
|
45561
|
+
return { bbox, area: geoArea(p), wraps };
|
|
45562
|
+
}).filter(
|
|
45563
|
+
(p) => p !== null
|
|
45564
|
+
);
|
|
45565
|
+
if (polys.length <= 1 || polys.some((p) => p.wraps))
|
|
45566
|
+
return featureBbox(topo, geomId);
|
|
45567
|
+
const maxArea = Math.max(...polys.map((p) => p.area));
|
|
45568
|
+
const anchor = polys.find((p) => p.area === maxArea);
|
|
45569
|
+
const cluster = [
|
|
45570
|
+
[anchor.bbox[0][0], anchor.bbox[0][1]],
|
|
45571
|
+
[anchor.bbox[1][0], anchor.bbox[1][1]]
|
|
45572
|
+
];
|
|
45573
|
+
const remaining = polys.filter((p) => p !== anchor);
|
|
45574
|
+
let added = true;
|
|
45575
|
+
while (added) {
|
|
45576
|
+
added = false;
|
|
45577
|
+
for (let i = remaining.length - 1; i >= 0; i--) {
|
|
45578
|
+
const p = remaining[i];
|
|
45579
|
+
const near = bboxGap(p.bbox, cluster) <= DETACH_GAP_DEG;
|
|
45580
|
+
const large = p.area >= DETACH_AREA_FRAC * maxArea;
|
|
45581
|
+
if (near || large) {
|
|
45582
|
+
cluster[0][0] = Math.min(cluster[0][0], p.bbox[0][0]);
|
|
45583
|
+
cluster[0][1] = Math.min(cluster[0][1], p.bbox[0][1]);
|
|
45584
|
+
cluster[1][0] = Math.max(cluster[1][0], p.bbox[1][0]);
|
|
45585
|
+
cluster[1][1] = Math.max(cluster[1][1], p.bbox[1][1]);
|
|
45586
|
+
remaining.splice(i, 1);
|
|
45587
|
+
added = true;
|
|
45588
|
+
}
|
|
45589
|
+
}
|
|
45590
|
+
}
|
|
45591
|
+
return cluster;
|
|
45592
|
+
}
|
|
45444
45593
|
function unionExtent(boxes, points) {
|
|
45445
45594
|
const lats = [];
|
|
45446
45595
|
const lons = [];
|
|
@@ -45479,11 +45628,13 @@ function unionLongitudes(lons) {
|
|
|
45479
45628
|
}
|
|
45480
45629
|
return { west: pts[gapIdx], east: pts[gapIdx - 1] + 360 };
|
|
45481
45630
|
}
|
|
45482
|
-
var fold;
|
|
45631
|
+
var fold, DETACH_GAP_DEG, DETACH_AREA_FRAC;
|
|
45483
45632
|
var init_geo = __esm({
|
|
45484
45633
|
"src/map/geo.ts"() {
|
|
45485
45634
|
"use strict";
|
|
45486
45635
|
fold = (s) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim();
|
|
45636
|
+
DETACH_GAP_DEG = 10;
|
|
45637
|
+
DETACH_AREA_FRAC = 0.25;
|
|
45487
45638
|
}
|
|
45488
45639
|
});
|
|
45489
45640
|
|
|
@@ -45492,6 +45643,11 @@ var resolver_exports = {};
|
|
|
45492
45643
|
__export(resolver_exports, {
|
|
45493
45644
|
resolveMap: () => resolveMap
|
|
45494
45645
|
});
|
|
45646
|
+
function usStateFromBareScope(scope) {
|
|
45647
|
+
if (!scope) return null;
|
|
45648
|
+
const up = scope.toUpperCase();
|
|
45649
|
+
return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
|
|
45650
|
+
}
|
|
45495
45651
|
function looksUS(lat, lon) {
|
|
45496
45652
|
if (lat < 15 || lat > 72) return false;
|
|
45497
45653
|
return lon >= -180 && lon <= -64 || lon >= 172;
|
|
@@ -45541,9 +45697,9 @@ function resolveMap(parsed, data) {
|
|
|
45541
45697
|
const f = fold(r.name);
|
|
45542
45698
|
return usStateIndex.has(f) && !countryIndex.has(f);
|
|
45543
45699
|
}) || parsed.regions.some(
|
|
45544
|
-
(r) => r.scope === "US" || r.scope?.startsWith("US-")
|
|
45700
|
+
(r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
|
|
45545
45701
|
) || parsed.pois.some(
|
|
45546
|
-
(p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
|
|
45702
|
+
(p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
|
|
45547
45703
|
);
|
|
45548
45704
|
const regions = [];
|
|
45549
45705
|
const seenRegion = /* @__PURE__ */ new Map();
|
|
@@ -45582,12 +45738,12 @@ function resolveMap(parsed, data) {
|
|
|
45582
45738
|
chosen = { ...inState, layer: "us-state" };
|
|
45583
45739
|
} else {
|
|
45584
45740
|
chosen = { ...inCountry, layer: "country" };
|
|
45741
|
+
warn2(
|
|
45742
|
+
r.lineNumber,
|
|
45743
|
+
`"${r.name}" is both a country and a US state \u2014 resolved as ${chosen.layer} (${chosen.id}). Pin it with an ISO code (${inState.id} / ${inCountry.id}) or name + scope ("${r.name} US" / "${r.name} ${inCountry.id}").`,
|
|
45744
|
+
"W_MAP_REGION_AMBIGUOUS"
|
|
45745
|
+
);
|
|
45585
45746
|
}
|
|
45586
|
-
warn2(
|
|
45587
|
-
r.lineNumber,
|
|
45588
|
-
`"${r.name}" is both a country and a US state \u2014 resolved as ${chosen.layer} (${chosen.id}). Pin it with an ISO code (${inState.id} / ${inCountry.id}) or name + scope ("${r.name} US" / "${r.name} ${inCountry.id}").`,
|
|
45589
|
-
"W_MAP_REGION_AMBIGUOUS"
|
|
45590
|
-
);
|
|
45591
45747
|
} else if (inState) {
|
|
45592
45748
|
chosen = { ...inState, layer: "us-state" };
|
|
45593
45749
|
} else if (inCountry) {
|
|
@@ -45610,7 +45766,8 @@ function resolveMap(parsed, data) {
|
|
|
45610
45766
|
iso: chosen.id,
|
|
45611
45767
|
name: chosen.name,
|
|
45612
45768
|
layer: chosen.layer,
|
|
45613
|
-
...r.
|
|
45769
|
+
...r.value !== void 0 && { value: r.value },
|
|
45770
|
+
...r.color !== void 0 && { color: r.color },
|
|
45614
45771
|
tags: r.tags,
|
|
45615
45772
|
meta: r.meta,
|
|
45616
45773
|
lineNumber: r.lineNumber
|
|
@@ -45668,9 +45825,10 @@ function resolveMap(parsed, data) {
|
|
|
45668
45825
|
let cands = idxs.map((i) => data.gazetteer.cities[i]);
|
|
45669
45826
|
const scopeUse = scope ?? scopeHint;
|
|
45670
45827
|
if (scopeUse) {
|
|
45671
|
-
const
|
|
45828
|
+
const bareState = usStateFromBareScope(scopeUse);
|
|
45829
|
+
const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
|
|
45672
45830
|
const filtered = cands.filter(
|
|
45673
|
-
(c2) =>
|
|
45831
|
+
(c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
|
|
45674
45832
|
);
|
|
45675
45833
|
if (filtered.length) cands = filtered;
|
|
45676
45834
|
else if (scope) {
|
|
@@ -45751,6 +45909,7 @@ function resolveMap(parsed, data) {
|
|
|
45751
45909
|
lat,
|
|
45752
45910
|
lon,
|
|
45753
45911
|
...p.label !== void 0 && { label: p.label },
|
|
45912
|
+
...p.color !== void 0 && { color: p.color },
|
|
45754
45913
|
tags: p.tags,
|
|
45755
45914
|
meta: p.meta,
|
|
45756
45915
|
lineNumber: p.lineNumber
|
|
@@ -45799,33 +45958,89 @@ function resolveMap(parsed, data) {
|
|
|
45799
45958
|
lineNumber: e.lineNumber
|
|
45800
45959
|
});
|
|
45801
45960
|
}
|
|
45802
|
-
const
|
|
45803
|
-
|
|
45804
|
-
|
|
45805
|
-
|
|
45806
|
-
|
|
45807
|
-
if (
|
|
45808
|
-
|
|
45809
|
-
|
|
45810
|
-
|
|
45811
|
-
const poi = {
|
|
45961
|
+
const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
|
|
45962
|
+
const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
|
|
45963
|
+
if (pos.kind === "coords") {
|
|
45964
|
+
const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
|
|
45965
|
+
if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
|
|
45966
|
+
if (!registry.has(id)) {
|
|
45967
|
+
registerPoi(
|
|
45968
|
+
id,
|
|
45969
|
+
{
|
|
45812
45970
|
id,
|
|
45813
|
-
...
|
|
45814
|
-
lat:
|
|
45815
|
-
lon:
|
|
45816
|
-
|
|
45817
|
-
|
|
45818
|
-
|
|
45819
|
-
|
|
45820
|
-
}
|
|
45821
|
-
|
|
45822
|
-
|
|
45823
|
-
} else {
|
|
45824
|
-
id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
|
|
45971
|
+
...alias !== void 0 && { name: alias },
|
|
45972
|
+
lat: pos.lat,
|
|
45973
|
+
lon: pos.lon,
|
|
45974
|
+
...label !== void 0 && { label },
|
|
45975
|
+
tags,
|
|
45976
|
+
meta,
|
|
45977
|
+
lineNumber: line12
|
|
45978
|
+
},
|
|
45979
|
+
line12
|
|
45980
|
+
);
|
|
45825
45981
|
}
|
|
45826
|
-
|
|
45982
|
+
return id;
|
|
45983
|
+
}
|
|
45984
|
+
const f = fold(pos.name);
|
|
45985
|
+
if (registry.has(f)) return f;
|
|
45986
|
+
const aliased = declaredByName.get(f);
|
|
45987
|
+
if (aliased) return aliased;
|
|
45988
|
+
const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
|
|
45989
|
+
if (got.kind !== "ok") return null;
|
|
45990
|
+
noteCountry(got.iso);
|
|
45991
|
+
registerPoi(
|
|
45992
|
+
f,
|
|
45993
|
+
{
|
|
45994
|
+
id: f,
|
|
45995
|
+
name: pos.name,
|
|
45996
|
+
lat: got.lat,
|
|
45997
|
+
lon: got.lon,
|
|
45998
|
+
...label !== void 0 && { label },
|
|
45999
|
+
tags,
|
|
46000
|
+
meta,
|
|
46001
|
+
lineNumber: line12
|
|
46002
|
+
},
|
|
46003
|
+
line12
|
|
46004
|
+
);
|
|
46005
|
+
return f;
|
|
46006
|
+
};
|
|
46007
|
+
const routes = [];
|
|
46008
|
+
for (const rt of parsed.routes) {
|
|
46009
|
+
const originId = resolveStop(
|
|
46010
|
+
rt.origin,
|
|
46011
|
+
rt.originAlias,
|
|
46012
|
+
rt.originLabel,
|
|
46013
|
+
rt.originTags,
|
|
46014
|
+
rt.originValue,
|
|
46015
|
+
rt.lineNumber
|
|
46016
|
+
);
|
|
46017
|
+
if (!originId) continue;
|
|
46018
|
+
const stopIds = [originId];
|
|
46019
|
+
const legs = [];
|
|
46020
|
+
let prevId = originId;
|
|
46021
|
+
for (const leg of rt.legs) {
|
|
46022
|
+
const destId = resolveStop(
|
|
46023
|
+
leg.dest,
|
|
46024
|
+
leg.destAlias,
|
|
46025
|
+
leg.destLabel,
|
|
46026
|
+
leg.destTags,
|
|
46027
|
+
void 0,
|
|
46028
|
+
// a leg's `value:` is leg thickness, not the dest's size
|
|
46029
|
+
leg.lineNumber
|
|
46030
|
+
);
|
|
46031
|
+
if (!destId) continue;
|
|
46032
|
+
legs.push({
|
|
46033
|
+
fromId: prevId,
|
|
46034
|
+
toId: destId,
|
|
46035
|
+
...leg.label !== void 0 && { label: leg.label },
|
|
46036
|
+
style: leg.style,
|
|
46037
|
+
...leg.value !== void 0 && { value: leg.value },
|
|
46038
|
+
lineNumber: leg.lineNumber
|
|
46039
|
+
});
|
|
46040
|
+
if (!stopIds.includes(destId)) stopIds.push(destId);
|
|
46041
|
+
prevId = destId;
|
|
45827
46042
|
}
|
|
45828
|
-
routes.push({ stopIds,
|
|
46043
|
+
routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
|
|
45829
46044
|
}
|
|
45830
46045
|
const subdivisions = [];
|
|
45831
46046
|
if (usSubdivisionReferenced || parsed.directives.region === "us-states")
|
|
@@ -45837,7 +46052,7 @@ function resolveMap(parsed, data) {
|
|
|
45837
46052
|
}
|
|
45838
46053
|
for (const r of regions) {
|
|
45839
46054
|
if (r.layer === "country") {
|
|
45840
|
-
const bb =
|
|
46055
|
+
const bb = featureBboxPrimary(data.worldCoarse, r.iso);
|
|
45841
46056
|
if (bb) regionBoxes.push(bb);
|
|
45842
46057
|
}
|
|
45843
46058
|
}
|
|
@@ -45851,6 +46066,7 @@ function resolveMap(parsed, data) {
|
|
|
45851
46066
|
const lonSpan = extent2[1][0] - extent2[0][0];
|
|
45852
46067
|
const latSpan = extent2[1][1] - extent2[0][1];
|
|
45853
46068
|
const span = Math.max(lonSpan, latSpan);
|
|
46069
|
+
const maxAbsLat = Math.max(Math.abs(extent2[0][1]), Math.abs(extent2[1][1]));
|
|
45854
46070
|
const usDominant = (subdivisions.includes("us-states") || regions.some((r) => r.layer === "us-state")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
|
|
45855
46071
|
let projection;
|
|
45856
46072
|
const override = parsed.directives.projection;
|
|
@@ -45858,12 +46074,10 @@ function resolveMap(parsed, data) {
|
|
|
45858
46074
|
projection = override;
|
|
45859
46075
|
} else if (usDominant) {
|
|
45860
46076
|
projection = "albers-usa";
|
|
45861
|
-
} else if (span > WORLD_SPAN) {
|
|
46077
|
+
} else if (span > WORLD_SPAN || maxAbsLat > MERCATOR_MAX_LAT) {
|
|
45862
46078
|
projection = "equirectangular";
|
|
45863
|
-
} else if (span < MERCATOR_MAX_SPAN) {
|
|
45864
|
-
projection = "mercator";
|
|
45865
46079
|
} else {
|
|
45866
|
-
projection = "
|
|
46080
|
+
projection = "mercator";
|
|
45867
46081
|
}
|
|
45868
46082
|
if (lonSpan >= 180) {
|
|
45869
46083
|
extent2 = [
|
|
@@ -45917,14 +46131,14 @@ function firstError(diags) {
|
|
|
45917
46131
|
const e = diags.find((d) => d.severity === "error");
|
|
45918
46132
|
return e ? formatDgmoError(e) : null;
|
|
45919
46133
|
}
|
|
45920
|
-
var WORLD_SPAN,
|
|
46134
|
+
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
|
|
45921
46135
|
var init_resolver2 = __esm({
|
|
45922
46136
|
"src/map/resolver.ts"() {
|
|
45923
46137
|
"use strict";
|
|
45924
46138
|
init_diagnostics();
|
|
45925
46139
|
init_geo();
|
|
45926
46140
|
WORLD_SPAN = 90;
|
|
45927
|
-
|
|
46141
|
+
MERCATOR_MAX_LAT = 80;
|
|
45928
46142
|
PAD_FRACTION = 0.05;
|
|
45929
46143
|
WORLD_LAT_SOUTH = -58;
|
|
45930
46144
|
WORLD_LAT_NORTH = 78;
|
|
@@ -45949,114 +46163,59 @@ var init_resolver2 = __esm({
|
|
|
45949
46163
|
"north macedonia": "macedonia",
|
|
45950
46164
|
"czech republic": "czechia"
|
|
45951
46165
|
};
|
|
45952
|
-
|
|
45953
|
-
|
|
45954
|
-
|
|
45955
|
-
|
|
45956
|
-
|
|
45957
|
-
|
|
45958
|
-
|
|
45959
|
-
|
|
45960
|
-
|
|
45961
|
-
|
|
45962
|
-
|
|
45963
|
-
|
|
45964
|
-
|
|
45965
|
-
|
|
45966
|
-
|
|
45967
|
-
|
|
45968
|
-
|
|
45969
|
-
|
|
45970
|
-
|
|
45971
|
-
|
|
45972
|
-
|
|
45973
|
-
|
|
45974
|
-
|
|
45975
|
-
|
|
45976
|
-
|
|
45977
|
-
|
|
45978
|
-
|
|
45979
|
-
|
|
45980
|
-
|
|
45981
|
-
|
|
45982
|
-
|
|
45983
|
-
|
|
45984
|
-
|
|
45985
|
-
|
|
45986
|
-
|
|
45987
|
-
|
|
45988
|
-
|
|
45989
|
-
|
|
45990
|
-
|
|
45991
|
-
|
|
45992
|
-
|
|
45993
|
-
|
|
45994
|
-
|
|
45995
|
-
|
|
45996
|
-
|
|
45997
|
-
|
|
45998
|
-
|
|
45999
|
-
|
|
46000
|
-
|
|
46001
|
-
|
|
46002
|
-
|
|
46003
|
-
|
|
46004
|
-
const [
|
|
46005
|
-
worldCoarse,
|
|
46006
|
-
worldDetail,
|
|
46007
|
-
usStates,
|
|
46008
|
-
lakes,
|
|
46009
|
-
rivers,
|
|
46010
|
-
naLand,
|
|
46011
|
-
naLakes,
|
|
46012
|
-
gazetteer
|
|
46013
|
-
] = await Promise.all([
|
|
46014
|
-
readJson(nb, dir, FILES.worldCoarse),
|
|
46015
|
-
readJson(nb, dir, FILES.worldDetail),
|
|
46016
|
-
readJson(nb, dir, FILES.usStates),
|
|
46017
|
-
// Lakes/rivers/NA assets are optional — older bundles may predate them.
|
|
46018
|
-
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
46019
|
-
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
46020
|
-
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
46021
|
-
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
46022
|
-
readJson(nb, dir, FILES.gazetteer)
|
|
46166
|
+
US_STATE_POSTAL = /* @__PURE__ */ new Set([
|
|
46167
|
+
"AL",
|
|
46168
|
+
"AK",
|
|
46169
|
+
"AZ",
|
|
46170
|
+
"AR",
|
|
46171
|
+
"CA",
|
|
46172
|
+
"CO",
|
|
46173
|
+
"CT",
|
|
46174
|
+
"DE",
|
|
46175
|
+
"FL",
|
|
46176
|
+
"GA",
|
|
46177
|
+
"HI",
|
|
46178
|
+
"ID",
|
|
46179
|
+
"IL",
|
|
46180
|
+
"IN",
|
|
46181
|
+
"IA",
|
|
46182
|
+
"KS",
|
|
46183
|
+
"KY",
|
|
46184
|
+
"LA",
|
|
46185
|
+
"ME",
|
|
46186
|
+
"MD",
|
|
46187
|
+
"MA",
|
|
46188
|
+
"MI",
|
|
46189
|
+
"MN",
|
|
46190
|
+
"MS",
|
|
46191
|
+
"MO",
|
|
46192
|
+
"MT",
|
|
46193
|
+
"NE",
|
|
46194
|
+
"NV",
|
|
46195
|
+
"NH",
|
|
46196
|
+
"NJ",
|
|
46197
|
+
"NM",
|
|
46198
|
+
"NY",
|
|
46199
|
+
"NC",
|
|
46200
|
+
"ND",
|
|
46201
|
+
"OH",
|
|
46202
|
+
"OK",
|
|
46203
|
+
"OR",
|
|
46204
|
+
"PA",
|
|
46205
|
+
"RI",
|
|
46206
|
+
"SC",
|
|
46207
|
+
"SD",
|
|
46208
|
+
"TN",
|
|
46209
|
+
"TX",
|
|
46210
|
+
"UT",
|
|
46211
|
+
"VT",
|
|
46212
|
+
"VA",
|
|
46213
|
+
"WA",
|
|
46214
|
+
"WV",
|
|
46215
|
+
"WI",
|
|
46216
|
+
"WY",
|
|
46217
|
+
"DC"
|
|
46023
46218
|
]);
|
|
46024
|
-
return validate({
|
|
46025
|
-
worldCoarse,
|
|
46026
|
-
worldDetail,
|
|
46027
|
-
usStates,
|
|
46028
|
-
gazetteer,
|
|
46029
|
-
...lakes && { lakes },
|
|
46030
|
-
...rivers && { rivers },
|
|
46031
|
-
...naLand && { naLand },
|
|
46032
|
-
...naLakes && { naLakes }
|
|
46033
|
-
});
|
|
46034
|
-
})().catch((e) => {
|
|
46035
|
-
cache = void 0;
|
|
46036
|
-
throw e;
|
|
46037
|
-
});
|
|
46038
|
-
return cache;
|
|
46039
|
-
}
|
|
46040
|
-
var FILES, CANDIDATE_DIRS, cache;
|
|
46041
|
-
var init_load_data = __esm({
|
|
46042
|
-
"src/map/load-data.ts"() {
|
|
46043
|
-
"use strict";
|
|
46044
|
-
FILES = {
|
|
46045
|
-
worldCoarse: "world-coarse.json",
|
|
46046
|
-
worldDetail: "world-detail.json",
|
|
46047
|
-
usStates: "us-states.json",
|
|
46048
|
-
lakes: "lakes.json",
|
|
46049
|
-
rivers: "rivers.json",
|
|
46050
|
-
naLand: "na-land.json",
|
|
46051
|
-
naLakes: "na-lakes.json",
|
|
46052
|
-
gazetteer: "gazetteer.json"
|
|
46053
|
-
};
|
|
46054
|
-
CANDIDATE_DIRS = [
|
|
46055
|
-
"./data",
|
|
46056
|
-
"./map-data",
|
|
46057
|
-
"../map-data",
|
|
46058
|
-
"../src/map/data"
|
|
46059
|
-
];
|
|
46060
46219
|
}
|
|
46061
46220
|
});
|
|
46062
46221
|
|
|
@@ -46096,8 +46255,19 @@ function projectionFor(family) {
|
|
|
46096
46255
|
return geoEquirectangular();
|
|
46097
46256
|
}
|
|
46098
46257
|
}
|
|
46099
|
-
function mapBackgroundColor(palette) {
|
|
46100
|
-
return mix(
|
|
46258
|
+
function mapBackgroundColor(palette, isDark = false, _dataActive = false) {
|
|
46259
|
+
return mix(
|
|
46260
|
+
palette.colors.blue,
|
|
46261
|
+
palette.bg,
|
|
46262
|
+
isDark ? WATER_TINT_DARK : WATER_TINT_LIGHT
|
|
46263
|
+
);
|
|
46264
|
+
}
|
|
46265
|
+
function mapNeutralLandColor(palette, isDark, _dataActive = false) {
|
|
46266
|
+
return mix(
|
|
46267
|
+
palette.colors.green,
|
|
46268
|
+
palette.bg,
|
|
46269
|
+
isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
|
|
46270
|
+
);
|
|
46101
46271
|
}
|
|
46102
46272
|
function layoutMap(resolved, data, size, opts) {
|
|
46103
46273
|
const { palette, isDark } = opts;
|
|
@@ -46118,28 +46288,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46118
46288
|
}
|
|
46119
46289
|
}
|
|
46120
46290
|
const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
|
|
46121
|
-
const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
|
|
46122
|
-
const neutralFill = mix(palette.colors.green, palette.bg, landTint);
|
|
46123
|
-
const water = mapBackgroundColor(palette);
|
|
46124
46291
|
const usContext = usLayer !== null;
|
|
46125
|
-
const foreignFill = mix(
|
|
46126
|
-
palette.colors.gray,
|
|
46127
|
-
palette.bg,
|
|
46128
|
-
isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46129
|
-
);
|
|
46130
46292
|
const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
|
|
46131
|
-
const
|
|
46293
|
+
const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
|
|
46132
46294
|
const scaleOverride = resolved.directives.scale;
|
|
46133
|
-
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...
|
|
46134
|
-
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...
|
|
46135
|
-
const rampHue = palette.colors.red;
|
|
46136
|
-
const hasRamp =
|
|
46137
|
-
const
|
|
46295
|
+
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
|
|
46296
|
+
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
|
|
46297
|
+
const rampHue = resolveColor(resolved.directives.regionMetricColor ?? "", palette) ?? palette.colors.red;
|
|
46298
|
+
const hasRamp = values.length > 0;
|
|
46299
|
+
const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
|
|
46138
46300
|
const matchColorGroup = (v) => {
|
|
46139
46301
|
const lv = v.trim().toLowerCase();
|
|
46140
46302
|
if (lv === "none") return null;
|
|
46141
|
-
if (
|
|
46142
|
-
return SCORE_NAME;
|
|
46303
|
+
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
46143
46304
|
const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
46144
46305
|
return tg ? tg.name : v;
|
|
46145
46306
|
};
|
|
@@ -46150,11 +46311,20 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46150
46311
|
} else if (resolved.directives.activeTag !== void 0) {
|
|
46151
46312
|
activeGroup = matchColorGroup(resolved.directives.activeTag);
|
|
46152
46313
|
} else {
|
|
46153
|
-
activeGroup =
|
|
46314
|
+
activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
|
|
46154
46315
|
}
|
|
46155
|
-
const activeIsScore =
|
|
46316
|
+
const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
|
|
46317
|
+
const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
|
|
46318
|
+
const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
|
|
46319
|
+
const water = mapBackgroundColor(palette, isDark, mutedBasemap);
|
|
46320
|
+
const lakeStroke = mix(regionStroke, water, 45);
|
|
46321
|
+
const foreignFill = mix(
|
|
46322
|
+
palette.colors.gray,
|
|
46323
|
+
palette.bg,
|
|
46324
|
+
mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46325
|
+
);
|
|
46156
46326
|
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
46157
|
-
const
|
|
46327
|
+
const fillForValue = (s) => {
|
|
46158
46328
|
const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
|
|
46159
46329
|
const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
|
|
46160
46330
|
return mix(rampHue, rampBase, pct);
|
|
@@ -46177,9 +46347,16 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46177
46347
|
isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT
|
|
46178
46348
|
);
|
|
46179
46349
|
};
|
|
46350
|
+
const directFill = (name) => {
|
|
46351
|
+
const hex = name ? resolveColor(name, palette) : null;
|
|
46352
|
+
if (!hex) return null;
|
|
46353
|
+
return mix(hex, palette.bg, isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT);
|
|
46354
|
+
};
|
|
46180
46355
|
const regionFill = (r) => {
|
|
46356
|
+
const direct = directFill(r.color);
|
|
46357
|
+
if (direct) return direct;
|
|
46181
46358
|
if (activeIsScore) {
|
|
46182
|
-
return r.
|
|
46359
|
+
return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
|
|
46183
46360
|
}
|
|
46184
46361
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
46185
46362
|
};
|
|
@@ -46231,6 +46408,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46231
46408
|
const fitIsGlobal = fitGB[1][0] - fitGB[0][0] >= 270 || fitGB[1][1] - fitGB[0][1] >= 130;
|
|
46232
46409
|
let path;
|
|
46233
46410
|
let project;
|
|
46411
|
+
let stretchParams = null;
|
|
46234
46412
|
if (fitIsGlobal) {
|
|
46235
46413
|
const cb = geoPath(projection).bounds(fitTarget);
|
|
46236
46414
|
const bx0 = cb[0][0];
|
|
@@ -46241,6 +46419,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46241
46419
|
const oy = fitBox[0][1];
|
|
46242
46420
|
const sx = cw > 0 ? (fitBox[1][0] - ox) / cw : 1;
|
|
46243
46421
|
const sy = ch > 0 ? (fitBox[1][1] - oy) / ch : 1;
|
|
46422
|
+
stretchParams = { sx, sy, ox, oy, bx0, by0 };
|
|
46244
46423
|
const stretch = (x, y) => [
|
|
46245
46424
|
ox + (x - bx0) * sx,
|
|
46246
46425
|
oy + (y - by0) * sy
|
|
@@ -46272,7 +46451,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46272
46451
|
const insets = [];
|
|
46273
46452
|
const insetRegions = [];
|
|
46274
46453
|
const insetLabelSeeds = [];
|
|
46275
|
-
if (resolved.projection === "albers-usa" && usLayer) {
|
|
46454
|
+
if (resolved.projection === "albers-usa" && usLayer && !resolved.directives.noInsets) {
|
|
46276
46455
|
const PAD = 8;
|
|
46277
46456
|
const GAP = 12;
|
|
46278
46457
|
const yB = height - FIT_PAD;
|
|
@@ -46303,38 +46482,14 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46303
46482
|
}
|
|
46304
46483
|
return y;
|
|
46305
46484
|
};
|
|
46306
|
-
const
|
|
46485
|
+
const coastFloor = (x0, xr) => {
|
|
46307
46486
|
const n = 24;
|
|
46308
|
-
const pts = [];
|
|
46309
46487
|
let maxY = -Infinity;
|
|
46310
46488
|
for (let i = 0; i <= n; i++) {
|
|
46311
|
-
const
|
|
46312
|
-
|
|
46313
|
-
|
|
46314
|
-
|
|
46315
|
-
if (y > maxY) maxY = y;
|
|
46316
|
-
}
|
|
46317
|
-
}
|
|
46318
|
-
if (pts.length === 0) return () => yB - height * 0.42;
|
|
46319
|
-
let m = 0;
|
|
46320
|
-
if (pts.length >= 2) {
|
|
46321
|
-
let sx = 0, sy = 0, sxx = 0, sxy = 0;
|
|
46322
|
-
for (const [x, y] of pts) {
|
|
46323
|
-
sx += x;
|
|
46324
|
-
sy += y;
|
|
46325
|
-
sxx += x * x;
|
|
46326
|
-
sxy += x * y;
|
|
46327
|
-
}
|
|
46328
|
-
const den = pts.length * sxx - sx * sx;
|
|
46329
|
-
if (den !== 0) m = (pts.length * sxy - sx * sy) / den;
|
|
46330
|
-
}
|
|
46331
|
-
m = Math.max(-0.35, Math.min(0.35, m));
|
|
46332
|
-
let c = -Infinity;
|
|
46333
|
-
for (const [x, y] of pts) {
|
|
46334
|
-
const need = y - m * x + GAP;
|
|
46335
|
-
if (need > c) c = need;
|
|
46336
|
-
}
|
|
46337
|
-
return (x) => m * x + c;
|
|
46489
|
+
const y = at(x0 + (xr - x0) * i / n);
|
|
46490
|
+
if (y > maxY) maxY = y;
|
|
46491
|
+
}
|
|
46492
|
+
return maxY;
|
|
46338
46493
|
};
|
|
46339
46494
|
const placeInset = (iso, proj, boxX, iwReq) => {
|
|
46340
46495
|
const f = usLayer.get(iso);
|
|
@@ -46343,19 +46498,15 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46343
46498
|
const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD);
|
|
46344
46499
|
if (iw < 24) return boxX;
|
|
46345
46500
|
const xr = x0 + iw + 2 * PAD;
|
|
46346
|
-
const
|
|
46347
|
-
const
|
|
46348
|
-
const yR = top(xr);
|
|
46501
|
+
const floor = coastFloor(x0, xr);
|
|
46502
|
+
const topGuess = floor > -Infinity ? floor + GAP : yB - height * 0.42;
|
|
46349
46503
|
proj.fitWidth(iw, f);
|
|
46350
46504
|
const bb = geoPath(proj).bounds(f);
|
|
46351
46505
|
const sh = Number.isFinite(bb[0][0]) ? bb[1][1] - bb[0][1] : iw;
|
|
46352
46506
|
const needH = sh + 2 * PAD;
|
|
46353
|
-
let topFit =
|
|
46507
|
+
let topFit = topGuess;
|
|
46354
46508
|
const bottom = Math.min(topFit + needH, yB);
|
|
46355
46509
|
if (bottom - topFit < needH) topFit = bottom - needH;
|
|
46356
|
-
const lift = topFit - Math.max(yL, yR);
|
|
46357
|
-
const topL = yL + lift;
|
|
46358
|
-
const topR = yR + lift;
|
|
46359
46510
|
proj.fitExtent(
|
|
46360
46511
|
[
|
|
46361
46512
|
[x0 + PAD, topFit + PAD],
|
|
@@ -46374,15 +46525,18 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46374
46525
|
}
|
|
46375
46526
|
insets.push({
|
|
46376
46527
|
x: x0,
|
|
46377
|
-
y:
|
|
46528
|
+
y: topFit,
|
|
46378
46529
|
w: xr - x0,
|
|
46379
|
-
h: bottom -
|
|
46530
|
+
h: bottom - topFit,
|
|
46380
46531
|
points: [
|
|
46381
|
-
[x0,
|
|
46382
|
-
[xr,
|
|
46532
|
+
[x0, topFit],
|
|
46533
|
+
[xr, topFit],
|
|
46383
46534
|
[xr, bottom],
|
|
46384
46535
|
[x0, bottom]
|
|
46385
|
-
]
|
|
46536
|
+
],
|
|
46537
|
+
// The FITTED inset projection (just fit to this box) — captured so the
|
|
46538
|
+
// geo-query can invert pixels inside the frame back to AK/HI coords.
|
|
46539
|
+
projection: proj
|
|
46386
46540
|
});
|
|
46387
46541
|
insetRegions.push({
|
|
46388
46542
|
id: iso,
|
|
@@ -46391,7 +46545,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46391
46545
|
stroke: regionStroke,
|
|
46392
46546
|
lineNumber,
|
|
46393
46547
|
layer: "us-state",
|
|
46394
|
-
...r?.
|
|
46548
|
+
...r?.value !== void 0 && { value: r.value },
|
|
46395
46549
|
...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46396
46550
|
});
|
|
46397
46551
|
const ctr = geoPath(proj).centroid(f);
|
|
@@ -46534,7 +46688,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46534
46688
|
lineNumber,
|
|
46535
46689
|
layer,
|
|
46536
46690
|
...label !== void 0 && { label },
|
|
46537
|
-
...isThisLayer && r.
|
|
46691
|
+
...isThisLayer && r.value !== void 0 && { value: r.value },
|
|
46538
46692
|
...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46539
46693
|
});
|
|
46540
46694
|
}
|
|
@@ -46552,13 +46706,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46552
46706
|
id: "lake",
|
|
46553
46707
|
d,
|
|
46554
46708
|
fill: water,
|
|
46555
|
-
stroke:
|
|
46709
|
+
stroke: lakeStroke,
|
|
46556
46710
|
lineNumber: -1,
|
|
46557
46711
|
layer: "base"
|
|
46558
46712
|
});
|
|
46559
46713
|
}
|
|
46560
46714
|
}
|
|
46561
|
-
const
|
|
46715
|
+
const relief = [];
|
|
46716
|
+
let reliefHatch = null;
|
|
46717
|
+
if (resolved.directives.relief === true && data.mountainRanges) {
|
|
46718
|
+
for (const [, f] of decodeLayer(data.mountainRanges)) {
|
|
46719
|
+
const viewF = isGlobalView ? dropFrameFillers(f) : cullFeatureToView(f);
|
|
46720
|
+
if (!viewF) continue;
|
|
46721
|
+
const area2 = path.area(viewF);
|
|
46722
|
+
if (!Number.isFinite(area2) || area2 < RELIEF_MIN_AREA) continue;
|
|
46723
|
+
const box = path.bounds(viewF);
|
|
46724
|
+
if (box[1][0] - box[0][0] < RELIEF_MIN_DIM || box[1][1] - box[0][1] < RELIEF_MIN_DIM)
|
|
46725
|
+
continue;
|
|
46726
|
+
const d = path(viewF) ?? "";
|
|
46727
|
+
if (!d) continue;
|
|
46728
|
+
relief.push({ d });
|
|
46729
|
+
}
|
|
46730
|
+
if (relief.length) {
|
|
46731
|
+
const darkTone = isDark ? palette.bg : palette.text;
|
|
46732
|
+
const lightTone = isDark ? palette.text : palette.bg;
|
|
46733
|
+
const landLum = relativeLuminance(neutralFill);
|
|
46734
|
+
const tone = Math.abs(landLum - relativeLuminance(darkTone)) > 0.04 ? darkTone : lightTone;
|
|
46735
|
+
reliefHatch = {
|
|
46736
|
+
color: mix(tone, neutralFill, RELIEF_HATCH_STRENGTH),
|
|
46737
|
+
spacing: RELIEF_HATCH_SPACING,
|
|
46738
|
+
width: RELIEF_HATCH_WIDTH
|
|
46739
|
+
};
|
|
46740
|
+
}
|
|
46741
|
+
}
|
|
46742
|
+
const riverColor = mix(water, regionStroke, 16);
|
|
46562
46743
|
const rivers = [];
|
|
46563
46744
|
if (data.rivers) {
|
|
46564
46745
|
for (const [, f] of decodeLayer(data.rivers)) {
|
|
@@ -46569,16 +46750,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46569
46750
|
rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
|
|
46570
46751
|
}
|
|
46571
46752
|
}
|
|
46572
|
-
const sizeVals = resolved.pois.map((p) => Number(p.meta["
|
|
46753
|
+
const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46573
46754
|
const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
|
|
46574
46755
|
const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
|
|
46575
46756
|
const radiusFor = (p) => {
|
|
46576
|
-
const v = Number(p.meta["
|
|
46757
|
+
const v = Number(p.meta["value"]);
|
|
46577
46758
|
if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
|
|
46578
46759
|
const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
|
|
46579
46760
|
return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
|
|
46580
46761
|
};
|
|
46581
46762
|
const poiFill = (p) => {
|
|
46763
|
+
const directHex = p.color ? resolveColor(p.color, palette) : null;
|
|
46764
|
+
if (directHex)
|
|
46765
|
+
return { fill: directHex, stroke: mix(directHex, palette.text, 18) };
|
|
46582
46766
|
for (const group of resolved.tagGroups) {
|
|
46583
46767
|
const val = p.tags[group.name.toLowerCase()];
|
|
46584
46768
|
if (!val) continue;
|
|
@@ -46640,7 +46824,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46640
46824
|
lineNumber: e.p.lineNumber,
|
|
46641
46825
|
implicit: !!e.p.implicit,
|
|
46642
46826
|
isOrigin: originIds.has(e.p.id),
|
|
46643
|
-
...num !== void 0 && { routeNumber: num }
|
|
46827
|
+
...num !== void 0 && { routeNumber: num },
|
|
46828
|
+
...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
|
|
46644
46829
|
});
|
|
46645
46830
|
});
|
|
46646
46831
|
}
|
|
@@ -46676,26 +46861,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46676
46861
|
const by = b.cy - (b.cy - py) / tb * trimB;
|
|
46677
46862
|
return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
|
|
46678
46863
|
};
|
|
46864
|
+
const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
|
|
46865
|
+
const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
|
|
46866
|
+
const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
|
|
46867
|
+
const routeWidthFor = (v) => {
|
|
46868
|
+
if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
|
|
46869
|
+
const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
|
|
46870
|
+
return W_MIN + t * (W_MAX - W_MIN);
|
|
46871
|
+
};
|
|
46679
46872
|
for (const rt of resolved.routes) {
|
|
46680
|
-
const
|
|
46681
|
-
|
|
46682
|
-
const
|
|
46683
|
-
const b = poiScreen.get(rt.stopIds[i]);
|
|
46873
|
+
for (const leg of rt.legs) {
|
|
46874
|
+
const a = poiScreen.get(leg.fromId);
|
|
46875
|
+
const b = poiScreen.get(leg.toId);
|
|
46684
46876
|
if (!a || !b) continue;
|
|
46877
|
+
const mx = (a.cx + b.cx) / 2;
|
|
46878
|
+
const my = (a.cy + b.cy) / 2;
|
|
46685
46879
|
legs.push({
|
|
46686
|
-
d: legPath(a, b,
|
|
46687
|
-
width:
|
|
46880
|
+
d: legPath(a, b, leg.style === "arc", 0),
|
|
46881
|
+
width: routeWidthFor(Number(leg.value)),
|
|
46688
46882
|
color: mix(palette.text, palette.bg, 72),
|
|
46689
46883
|
arrow: true,
|
|
46690
|
-
lineNumber:
|
|
46884
|
+
lineNumber: leg.lineNumber,
|
|
46885
|
+
...leg.label !== void 0 && {
|
|
46886
|
+
label: leg.label,
|
|
46887
|
+
labelX: mx,
|
|
46888
|
+
labelY: my - 4
|
|
46889
|
+
}
|
|
46691
46890
|
});
|
|
46692
46891
|
}
|
|
46693
46892
|
}
|
|
46694
|
-
const weightVals = resolved.edges.map((e) => Number(e.meta["
|
|
46893
|
+
const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46695
46894
|
const wMin = weightVals.length ? Math.min(...weightVals) : 0;
|
|
46696
46895
|
const wMax = weightVals.length ? Math.max(...weightVals) : 0;
|
|
46697
46896
|
const widthFor = (e) => {
|
|
46698
|
-
const v = Number(e.meta["
|
|
46897
|
+
const v = Number(e.meta["value"]);
|
|
46699
46898
|
if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
|
|
46700
46899
|
const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
|
|
46701
46900
|
return W_MIN + t * (W_MAX - W_MIN);
|
|
@@ -46958,8 +47157,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46958
47157
|
activeGroup,
|
|
46959
47158
|
...hasRamp && {
|
|
46960
47159
|
ramp: {
|
|
46961
|
-
...resolved.directives.
|
|
46962
|
-
metric: resolved.directives.
|
|
47160
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47161
|
+
metric: resolved.directives.regionMetric
|
|
46963
47162
|
},
|
|
46964
47163
|
min: rampMin,
|
|
46965
47164
|
max: rampMax,
|
|
@@ -46979,19 +47178,24 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46979
47178
|
...resolved.caption !== void 0 && { caption: resolved.caption },
|
|
46980
47179
|
regions,
|
|
46981
47180
|
rivers,
|
|
47181
|
+
relief,
|
|
47182
|
+
reliefHatch,
|
|
46982
47183
|
legs,
|
|
46983
47184
|
pois,
|
|
46984
47185
|
labels,
|
|
46985
47186
|
legend,
|
|
46986
47187
|
insets,
|
|
46987
|
-
insetRegions
|
|
47188
|
+
insetRegions,
|
|
47189
|
+
projection,
|
|
47190
|
+
stretch: stretchParams
|
|
46988
47191
|
};
|
|
46989
47192
|
}
|
|
46990
|
-
var FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK,
|
|
47193
|
+
var FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT_LIGHT, WATER_TINT_DARK, RIVER_WIDTH, RELIEF_MIN_AREA, RELIEF_MIN_DIM, RELIEF_HATCH_SPACING, RELIEF_HATCH_WIDTH, RELIEF_HATCH_STRENGTH, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, MUTED_FOREIGN_LIGHT, MUTED_FOREIGN_DARK, COLO_R, GOLDEN_ANGLE, FAN_STEP, ARC_CURVE_FRAC, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, US_NON_CONUS;
|
|
46991
47194
|
var init_layout15 = __esm({
|
|
46992
47195
|
"src/map/layout.ts"() {
|
|
46993
47196
|
"use strict";
|
|
46994
47197
|
init_color_utils();
|
|
47198
|
+
init_colors();
|
|
46995
47199
|
init_label_layout();
|
|
46996
47200
|
init_legend_constants();
|
|
46997
47201
|
init_title_constants();
|
|
@@ -47004,14 +47208,22 @@ var init_layout15 = __esm({
|
|
|
47004
47208
|
W_MAX = 8;
|
|
47005
47209
|
FONT = 11;
|
|
47006
47210
|
COLO_EPS = 1.5;
|
|
47007
|
-
LAND_TINT_LIGHT =
|
|
47008
|
-
LAND_TINT_DARK =
|
|
47211
|
+
LAND_TINT_LIGHT = 12;
|
|
47212
|
+
LAND_TINT_DARK = 24;
|
|
47009
47213
|
TAG_TINT_LIGHT = 60;
|
|
47010
47214
|
TAG_TINT_DARK = 68;
|
|
47011
|
-
|
|
47215
|
+
WATER_TINT_LIGHT = 13;
|
|
47216
|
+
WATER_TINT_DARK = 14;
|
|
47012
47217
|
RIVER_WIDTH = 1.3;
|
|
47218
|
+
RELIEF_MIN_AREA = 12;
|
|
47219
|
+
RELIEF_MIN_DIM = 2;
|
|
47220
|
+
RELIEF_HATCH_SPACING = 3;
|
|
47221
|
+
RELIEF_HATCH_WIDTH = 0.25;
|
|
47222
|
+
RELIEF_HATCH_STRENGTH = 32;
|
|
47013
47223
|
FOREIGN_TINT_LIGHT = 30;
|
|
47014
47224
|
FOREIGN_TINT_DARK = 62;
|
|
47225
|
+
MUTED_FOREIGN_LIGHT = 28;
|
|
47226
|
+
MUTED_FOREIGN_DARK = 16;
|
|
47015
47227
|
COLO_R = 9;
|
|
47016
47228
|
GOLDEN_ANGLE = 2.399963229728653;
|
|
47017
47229
|
FAN_STEP = 16;
|
|
@@ -47066,7 +47278,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47066
47278
|
const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
|
|
47067
47279
|
if (r.layer !== "base") {
|
|
47068
47280
|
p.classed("dgmo-map-region", true).attr("data-region", r.id);
|
|
47069
|
-
if (r.
|
|
47281
|
+
if (r.value !== void 0) p.attr("data-value", r.value);
|
|
47070
47282
|
if (r.tags) {
|
|
47071
47283
|
for (const [group, value] of Object.entries(r.tags)) {
|
|
47072
47284
|
p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
@@ -47084,6 +47296,20 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47084
47296
|
}
|
|
47085
47297
|
};
|
|
47086
47298
|
for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
|
|
47299
|
+
if (layout.relief.length && layout.reliefHatch) {
|
|
47300
|
+
const h = layout.reliefHatch;
|
|
47301
|
+
const rangeClipId = "dgmo-relief-clip";
|
|
47302
|
+
const landClipId = "dgmo-relief-land";
|
|
47303
|
+
const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
|
|
47304
|
+
for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
|
|
47305
|
+
const landClip = defs.append("clipPath").attr("id", landClipId);
|
|
47306
|
+
for (const r of layout.regions)
|
|
47307
|
+
if (r.id !== "lake") landClip.append("path").attr("d", r.d);
|
|
47308
|
+
const gRelief = svg.append("g").attr("clip-path", `url(#${landClipId})`).append("g").attr("class", "dgmo-map-relief").attr("clip-path", `url(#${rangeClipId})`).attr("stroke", h.color).attr("stroke-width", h.width).attr("vector-effect", "non-scaling-stroke");
|
|
47309
|
+
for (let y = h.spacing; y < height; y += h.spacing) {
|
|
47310
|
+
gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
|
|
47311
|
+
}
|
|
47312
|
+
}
|
|
47087
47313
|
if (layout.rivers.length) {
|
|
47088
47314
|
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none");
|
|
47089
47315
|
for (const r of layout.rivers) {
|
|
@@ -47127,6 +47353,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47127
47353
|
gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r + 3).attr("fill", "none").attr("stroke", poi.stroke).attr("stroke-width", 1.5);
|
|
47128
47354
|
}
|
|
47129
47355
|
const c = gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r).attr("fill", poi.fill).attr("stroke", poi.stroke).attr("stroke-width", 1).attr("data-line-number", poi.lineNumber).attr("data-poi", poi.id);
|
|
47356
|
+
if (poi.tags) {
|
|
47357
|
+
for (const [group, value] of Object.entries(poi.tags)) {
|
|
47358
|
+
c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
47359
|
+
}
|
|
47360
|
+
}
|
|
47130
47361
|
if (onClickItem) {
|
|
47131
47362
|
c.style("cursor", "pointer").on(
|
|
47132
47363
|
"click",
|
|
@@ -47176,7 +47407,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47176
47407
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
47177
47408
|
const ramp = layout.legend.ramp;
|
|
47178
47409
|
const scoreGroup = ramp ? {
|
|
47179
|
-
name: ramp.metric?.trim() || "
|
|
47410
|
+
name: ramp.metric?.trim() || "Value",
|
|
47180
47411
|
entries: [],
|
|
47181
47412
|
gradient: {
|
|
47182
47413
|
min: ramp.min,
|
|
@@ -47203,7 +47434,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47203
47434
|
}
|
|
47204
47435
|
}
|
|
47205
47436
|
if (layout.title) {
|
|
47206
|
-
svg.append("text").attr("x", width / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("fill", palette.text).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("stroke-opacity", 0.7).text(layout.title);
|
|
47437
|
+
svg.append("text").attr("class", "dgmo-map-title").attr("x", width / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("fill", palette.text).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("stroke-opacity", 0.7).text(layout.title);
|
|
47207
47438
|
}
|
|
47208
47439
|
if (layout.subtitle) {
|
|
47209
47440
|
svg.append("text").attr("x", width / 2).attr("y", TITLE_Y + TITLE_FONT_SIZE).attr("text-anchor", "middle").attr("font-size", LABEL_FONT + 1).attr("fill", palette.textMuted).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 3).attr("stroke-linejoin", "round").attr("stroke-opacity", 0.7).text(layout.subtitle);
|
|
@@ -47235,6 +47466,120 @@ var init_renderer16 = __esm({
|
|
|
47235
47466
|
}
|
|
47236
47467
|
});
|
|
47237
47468
|
|
|
47469
|
+
// src/map/load-data.ts
|
|
47470
|
+
var load_data_exports = {};
|
|
47471
|
+
__export(load_data_exports, {
|
|
47472
|
+
loadMapData: () => loadMapData
|
|
47473
|
+
});
|
|
47474
|
+
async function loadNodeBuiltins() {
|
|
47475
|
+
const [{ readFile }, { fileURLToPath }, { dirname, resolve }] = await Promise.all([
|
|
47476
|
+
import("fs/promises"),
|
|
47477
|
+
import("url"),
|
|
47478
|
+
import("path")
|
|
47479
|
+
]);
|
|
47480
|
+
return { readFile, fileURLToPath, dirname, resolve };
|
|
47481
|
+
}
|
|
47482
|
+
async function readJson(nb, dir, name) {
|
|
47483
|
+
return JSON.parse(await nb.readFile(nb.resolve(dir, name), "utf8"));
|
|
47484
|
+
}
|
|
47485
|
+
async function firstExistingDir(nb, baseDir) {
|
|
47486
|
+
for (const rel of CANDIDATE_DIRS) {
|
|
47487
|
+
const dir = nb.resolve(baseDir, rel);
|
|
47488
|
+
try {
|
|
47489
|
+
await nb.readFile(nb.resolve(dir, FILES.gazetteer), "utf8");
|
|
47490
|
+
return dir;
|
|
47491
|
+
} catch {
|
|
47492
|
+
}
|
|
47493
|
+
}
|
|
47494
|
+
throw new Error(
|
|
47495
|
+
`map data assets not found near ${baseDir} (looked in ${CANDIDATE_DIRS.join(", ")}). Run \`pnpm build:map-data\` and \`pnpm build\`.`
|
|
47496
|
+
);
|
|
47497
|
+
}
|
|
47498
|
+
function validate(data) {
|
|
47499
|
+
const topoOk = (t) => !!t && t.type === "Topology" && !!t.objects;
|
|
47500
|
+
if (!topoOk(data.worldCoarse) || !topoOk(data.worldDetail) || !topoOk(data.usStates) || !data.gazetteer || !Array.isArray(data.gazetteer.cities) || !data.gazetteer.byName) {
|
|
47501
|
+
throw new Error("map data assets are malformed (failed shape validation)");
|
|
47502
|
+
}
|
|
47503
|
+
return data;
|
|
47504
|
+
}
|
|
47505
|
+
function moduleBaseDir(nb) {
|
|
47506
|
+
try {
|
|
47507
|
+
const url = import.meta.url;
|
|
47508
|
+
if (url) return nb.dirname(nb.fileURLToPath(url));
|
|
47509
|
+
} catch {
|
|
47510
|
+
}
|
|
47511
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
47512
|
+
return process.cwd();
|
|
47513
|
+
}
|
|
47514
|
+
function loadMapData() {
|
|
47515
|
+
cache ??= (async () => {
|
|
47516
|
+
const nb = await loadNodeBuiltins();
|
|
47517
|
+
const dir = await firstExistingDir(nb, moduleBaseDir(nb));
|
|
47518
|
+
const [
|
|
47519
|
+
worldCoarse,
|
|
47520
|
+
worldDetail,
|
|
47521
|
+
usStates,
|
|
47522
|
+
lakes,
|
|
47523
|
+
rivers,
|
|
47524
|
+
mountainRanges,
|
|
47525
|
+
naLand,
|
|
47526
|
+
naLakes,
|
|
47527
|
+
gazetteer
|
|
47528
|
+
] = await Promise.all([
|
|
47529
|
+
readJson(nb, dir, FILES.worldCoarse),
|
|
47530
|
+
readJson(nb, dir, FILES.worldDetail),
|
|
47531
|
+
readJson(nb, dir, FILES.usStates),
|
|
47532
|
+
// Lakes/rivers/mountain/NA assets are optional — older bundles may predate them.
|
|
47533
|
+
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
47534
|
+
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
47535
|
+
readJson(nb, dir, FILES.mountainRanges).catch(
|
|
47536
|
+
() => void 0
|
|
47537
|
+
),
|
|
47538
|
+
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
47539
|
+
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
47540
|
+
readJson(nb, dir, FILES.gazetteer)
|
|
47541
|
+
]);
|
|
47542
|
+
return validate({
|
|
47543
|
+
worldCoarse,
|
|
47544
|
+
worldDetail,
|
|
47545
|
+
usStates,
|
|
47546
|
+
gazetteer,
|
|
47547
|
+
...lakes && { lakes },
|
|
47548
|
+
...rivers && { rivers },
|
|
47549
|
+
...mountainRanges && { mountainRanges },
|
|
47550
|
+
...naLand && { naLand },
|
|
47551
|
+
...naLakes && { naLakes }
|
|
47552
|
+
});
|
|
47553
|
+
})().catch((e) => {
|
|
47554
|
+
cache = void 0;
|
|
47555
|
+
throw e;
|
|
47556
|
+
});
|
|
47557
|
+
return cache;
|
|
47558
|
+
}
|
|
47559
|
+
var FILES, CANDIDATE_DIRS, cache;
|
|
47560
|
+
var init_load_data = __esm({
|
|
47561
|
+
"src/map/load-data.ts"() {
|
|
47562
|
+
"use strict";
|
|
47563
|
+
FILES = {
|
|
47564
|
+
worldCoarse: "world-coarse.json",
|
|
47565
|
+
worldDetail: "world-detail.json",
|
|
47566
|
+
usStates: "us-states.json",
|
|
47567
|
+
lakes: "lakes.json",
|
|
47568
|
+
rivers: "rivers.json",
|
|
47569
|
+
mountainRanges: "mountain-ranges.json",
|
|
47570
|
+
naLand: "na-land.json",
|
|
47571
|
+
naLakes: "na-lakes.json",
|
|
47572
|
+
gazetteer: "gazetteer.json"
|
|
47573
|
+
};
|
|
47574
|
+
CANDIDATE_DIRS = [
|
|
47575
|
+
"./data",
|
|
47576
|
+
"./map-data",
|
|
47577
|
+
"../map-data",
|
|
47578
|
+
"../src/map/data"
|
|
47579
|
+
];
|
|
47580
|
+
}
|
|
47581
|
+
});
|
|
47582
|
+
|
|
47238
47583
|
// src/pyramid/renderer.ts
|
|
47239
47584
|
var renderer_exports17 = {};
|
|
47240
47585
|
__export(renderer_exports17, {
|
|
@@ -55363,15 +55708,17 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
55363
55708
|
if (detectedType === "map") {
|
|
55364
55709
|
const { parseMap: parseMap2 } = await Promise.resolve().then(() => (init_parser12(), parser_exports11));
|
|
55365
55710
|
const { resolveMap: resolveMap2 } = await Promise.resolve().then(() => (init_resolver2(), resolver_exports));
|
|
55366
|
-
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55367
55711
|
const { renderMapForExport: renderMapForExport2 } = await Promise.resolve().then(() => (init_renderer16(), renderer_exports16));
|
|
55368
55712
|
const effectivePalette2 = await resolveExportPalette(theme, palette);
|
|
55369
55713
|
const mapParsed = parseMap2(content);
|
|
55370
|
-
let mapData;
|
|
55371
|
-
|
|
55372
|
-
|
|
55373
|
-
|
|
55374
|
-
|
|
55714
|
+
let mapData = options?.mapData;
|
|
55715
|
+
if (!mapData) {
|
|
55716
|
+
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55717
|
+
try {
|
|
55718
|
+
mapData = await loadMapData2();
|
|
55719
|
+
} catch {
|
|
55720
|
+
return "";
|
|
55721
|
+
}
|
|
55375
55722
|
}
|
|
55376
55723
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
55377
55724
|
const container2 = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|
|
@@ -56405,13 +56752,17 @@ var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
56405
56752
|
// Map (§24B) directives
|
|
56406
56753
|
"region",
|
|
56407
56754
|
"projection",
|
|
56408
|
-
"metric",
|
|
56409
|
-
"
|
|
56755
|
+
"region-metric",
|
|
56756
|
+
"poi-metric",
|
|
56757
|
+
"flow-metric",
|
|
56410
56758
|
"region-labels",
|
|
56411
56759
|
"poi-labels",
|
|
56412
56760
|
"default-country",
|
|
56413
56761
|
"default-state",
|
|
56414
56762
|
"no-legend",
|
|
56763
|
+
"no-insets",
|
|
56764
|
+
"muted",
|
|
56765
|
+
"natural",
|
|
56415
56766
|
"subtitle",
|
|
56416
56767
|
"caption",
|
|
56417
56768
|
"poi",
|
|
@@ -57079,7 +57430,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
57079
57430
|
|
|
57080
57431
|
// src/auto/index.ts
|
|
57081
57432
|
init_safe_href();
|
|
57082
|
-
var VERSION = "0.
|
|
57433
|
+
var VERSION = "0.21.1";
|
|
57083
57434
|
var DEFAULTS = {
|
|
57084
57435
|
theme: "auto",
|
|
57085
57436
|
palette: "nord",
|