@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.cjs
CHANGED
|
@@ -760,13 +760,9 @@ var init_reserved_key_registry = __esm({
|
|
|
760
760
|
"icon"
|
|
761
761
|
]);
|
|
762
762
|
MAP_REGISTRY = staticRegistry([
|
|
763
|
-
"
|
|
763
|
+
"value",
|
|
764
764
|
"label",
|
|
765
|
-
"
|
|
766
|
-
"description",
|
|
767
|
-
"weight",
|
|
768
|
-
"style",
|
|
769
|
-
"date"
|
|
765
|
+
"style"
|
|
770
766
|
]);
|
|
771
767
|
ORG_REGISTRY = staticRegistry([
|
|
772
768
|
"color",
|
|
@@ -15779,7 +15775,8 @@ function parseMap(content) {
|
|
|
15779
15775
|
continue;
|
|
15780
15776
|
}
|
|
15781
15777
|
if (open.route && indent > open.route.indent) {
|
|
15782
|
-
open.route.route.
|
|
15778
|
+
const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
|
|
15779
|
+
open.route.route.legs.push(leg);
|
|
15783
15780
|
continue;
|
|
15784
15781
|
}
|
|
15785
15782
|
if (open.poi && indent > open.poi.indent) {
|
|
@@ -15810,6 +15807,10 @@ function parseMap(content) {
|
|
|
15810
15807
|
handleTag(trimmed, lineNumber);
|
|
15811
15808
|
continue;
|
|
15812
15809
|
}
|
|
15810
|
+
if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
|
|
15811
|
+
handleDirective(firstWord, "", lineNumber);
|
|
15812
|
+
continue;
|
|
15813
|
+
}
|
|
15813
15814
|
if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
|
|
15814
15815
|
handleDirective(
|
|
15815
15816
|
firstWord,
|
|
@@ -15874,13 +15875,20 @@ function parseMap(content) {
|
|
|
15874
15875
|
);
|
|
15875
15876
|
d.projection = value;
|
|
15876
15877
|
break;
|
|
15877
|
-
case "metric":
|
|
15878
|
-
dup(d.
|
|
15879
|
-
|
|
15878
|
+
case "region-metric": {
|
|
15879
|
+
dup(d.regionMetric);
|
|
15880
|
+
const { label: rmLabel, colorName: rmColor } = peelTrailingColorName(value);
|
|
15881
|
+
d.regionMetric = rmLabel;
|
|
15882
|
+
if (rmColor) d.regionMetricColor = rmColor;
|
|
15883
|
+
break;
|
|
15884
|
+
}
|
|
15885
|
+
case "poi-metric":
|
|
15886
|
+
dup(d.poiMetric);
|
|
15887
|
+
d.poiMetric = value;
|
|
15880
15888
|
break;
|
|
15881
|
-
case "
|
|
15882
|
-
dup(d.
|
|
15883
|
-
d.
|
|
15889
|
+
case "flow-metric":
|
|
15890
|
+
dup(d.flowMetric);
|
|
15891
|
+
d.flowMetric = value;
|
|
15884
15892
|
break;
|
|
15885
15893
|
case "scale":
|
|
15886
15894
|
dup(d.scale);
|
|
@@ -15922,6 +15930,21 @@ function parseMap(content) {
|
|
|
15922
15930
|
case "no-legend":
|
|
15923
15931
|
d.noLegend = true;
|
|
15924
15932
|
break;
|
|
15933
|
+
case "no-insets":
|
|
15934
|
+
d.noInsets = true;
|
|
15935
|
+
break;
|
|
15936
|
+
case "relief":
|
|
15937
|
+
d.relief = true;
|
|
15938
|
+
break;
|
|
15939
|
+
case "muted":
|
|
15940
|
+
case "natural":
|
|
15941
|
+
if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
|
|
15942
|
+
pushWarning(
|
|
15943
|
+
line12,
|
|
15944
|
+
`Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
|
|
15945
|
+
);
|
|
15946
|
+
d.basemapStyle = key;
|
|
15947
|
+
break;
|
|
15925
15948
|
case "subtitle":
|
|
15926
15949
|
dup(d.subtitle);
|
|
15927
15950
|
d.subtitle = value;
|
|
@@ -15999,14 +16022,14 @@ function parseMap(content) {
|
|
|
15999
16022
|
line12
|
|
16000
16023
|
);
|
|
16001
16024
|
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16002
|
-
let
|
|
16003
|
-
const
|
|
16004
|
-
if (
|
|
16005
|
-
delete meta["
|
|
16006
|
-
|
|
16007
|
-
if (!Number.isFinite(
|
|
16008
|
-
pushError(line12, `
|
|
16009
|
-
|
|
16025
|
+
let valueNum;
|
|
16026
|
+
const value = meta["value"];
|
|
16027
|
+
if (value !== void 0) {
|
|
16028
|
+
delete meta["value"];
|
|
16029
|
+
valueNum = Number(value);
|
|
16030
|
+
if (!Number.isFinite(valueNum)) {
|
|
16031
|
+
pushError(line12, `value must be a number (got "${value}").`);
|
|
16032
|
+
valueNum = void 0;
|
|
16010
16033
|
}
|
|
16011
16034
|
}
|
|
16012
16035
|
let regionName = split.name;
|
|
@@ -16024,7 +16047,8 @@ function parseMap(content) {
|
|
|
16024
16047
|
lineNumber: line12
|
|
16025
16048
|
};
|
|
16026
16049
|
if (regionScope !== void 0) region.scope = regionScope;
|
|
16027
|
-
if (
|
|
16050
|
+
if (valueNum !== void 0) region.value = valueNum;
|
|
16051
|
+
if (split.color) region.color = split.color;
|
|
16028
16052
|
regions.push(region);
|
|
16029
16053
|
}
|
|
16030
16054
|
function handlePoi(rest, line12, indent) {
|
|
@@ -16049,28 +16073,81 @@ function parseMap(content) {
|
|
|
16049
16073
|
const poi = { pos, tags, meta, lineNumber: line12 };
|
|
16050
16074
|
if (split.alias) poi.alias = split.alias;
|
|
16051
16075
|
if (label !== void 0) poi.label = label;
|
|
16076
|
+
if (split.color) poi.color = split.color;
|
|
16052
16077
|
pois.push(poi);
|
|
16053
16078
|
open.poi = { poi, indent };
|
|
16054
16079
|
}
|
|
16055
16080
|
function handleRoute(rest, line12, indent) {
|
|
16056
|
-
const
|
|
16057
|
-
|
|
16081
|
+
const split = rest ? splitNameAndMeta(
|
|
16082
|
+
rest,
|
|
16083
|
+
registry(),
|
|
16084
|
+
aliasMap,
|
|
16085
|
+
void 0,
|
|
16086
|
+
diagnostics,
|
|
16087
|
+
line12
|
|
16088
|
+
) : { name: "", meta: {}, alias: void 0 };
|
|
16089
|
+
const pos = parsePos(split.name, line12);
|
|
16090
|
+
if (!pos || pos.kind === "name" && !pos.name) {
|
|
16091
|
+
pushError(
|
|
16092
|
+
line12,
|
|
16093
|
+
"route requires an origin: `route <origin> [style: arc]`."
|
|
16094
|
+
);
|
|
16095
|
+
return;
|
|
16096
|
+
}
|
|
16097
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16098
|
+
const originLabel = meta["label"];
|
|
16099
|
+
const originValue = meta["value"];
|
|
16100
|
+
const style = meta["style"] === "arc" ? "arc" : "straight";
|
|
16101
|
+
const route = {
|
|
16102
|
+
origin: pos,
|
|
16103
|
+
...split.alias !== void 0 && { originAlias: split.alias },
|
|
16104
|
+
...originLabel !== void 0 && { originLabel },
|
|
16105
|
+
...originValue !== void 0 && { originValue },
|
|
16106
|
+
originTags: tags,
|
|
16107
|
+
style,
|
|
16108
|
+
legs: [],
|
|
16109
|
+
lineNumber: line12
|
|
16110
|
+
};
|
|
16058
16111
|
routes.push(route);
|
|
16059
16112
|
open.route = { route, indent };
|
|
16060
16113
|
}
|
|
16061
|
-
function
|
|
16062
|
-
|
|
16063
|
-
|
|
16114
|
+
function parseLeg(trimmed, line12, headerStyle) {
|
|
16115
|
+
let arrowStyle = "straight";
|
|
16116
|
+
let label;
|
|
16117
|
+
let rest = trimmed;
|
|
16118
|
+
const m = trimmed.match(LEG_ARROW_RE);
|
|
16119
|
+
if (m) {
|
|
16120
|
+
const arr = classifyArrow(m[1], line12);
|
|
16121
|
+
arrowStyle = arr.style;
|
|
16122
|
+
label = arr.label;
|
|
16123
|
+
rest = m[2];
|
|
16124
|
+
}
|
|
16125
|
+
const split = splitNameAndMeta(
|
|
16126
|
+
rest,
|
|
16127
|
+
registry(),
|
|
16128
|
+
aliasMap,
|
|
16129
|
+
void 0,
|
|
16130
|
+
diagnostics,
|
|
16131
|
+
line12
|
|
16132
|
+
);
|
|
16133
|
+
const pos = parsePos(split.name, line12) ?? {
|
|
16064
16134
|
kind: "name",
|
|
16065
16135
|
name: split.name
|
|
16066
16136
|
};
|
|
16067
|
-
const
|
|
16068
|
-
|
|
16069
|
-
|
|
16137
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16138
|
+
const value = meta["value"];
|
|
16139
|
+
const destLabel = meta["label"];
|
|
16140
|
+
const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
|
|
16141
|
+
return {
|
|
16142
|
+
...label !== void 0 && { label },
|
|
16143
|
+
style,
|
|
16144
|
+
...value !== void 0 && { value },
|
|
16145
|
+
dest: pos,
|
|
16146
|
+
...split.alias !== void 0 && { destAlias: split.alias },
|
|
16147
|
+
...destLabel !== void 0 && { destLabel },
|
|
16148
|
+
destTags: tags,
|
|
16070
16149
|
lineNumber: line12
|
|
16071
16150
|
};
|
|
16072
|
-
if (split.alias) stop.alias = split.alias;
|
|
16073
|
-
return stop;
|
|
16074
16151
|
}
|
|
16075
16152
|
function handleEdges(trimmed, line12) {
|
|
16076
16153
|
const parts = trimmed.split(ARROW_SPLIT);
|
|
@@ -16172,7 +16249,7 @@ function partitionMeta(meta, tagGroupNames) {
|
|
|
16172
16249
|
function poiName(pos) {
|
|
16173
16250
|
return pos.kind === "name" ? pos.name : void 0;
|
|
16174
16251
|
}
|
|
16175
|
-
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
|
|
16252
|
+
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
|
|
16176
16253
|
var init_parser12 = __esm({
|
|
16177
16254
|
"src/map/parser.ts"() {
|
|
16178
16255
|
"use strict";
|
|
@@ -16186,12 +16263,14 @@ var init_parser12 = __esm({
|
|
|
16186
16263
|
SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
|
|
16187
16264
|
ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
|
|
16188
16265
|
HUB_RE = /^(->|~>)\s+(.+)$/;
|
|
16266
|
+
LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
|
|
16189
16267
|
AT_RE = /(^|[\s,])at\s*:/i;
|
|
16190
16268
|
DIRECTIVE_SET = /* @__PURE__ */ new Set([
|
|
16191
16269
|
"region",
|
|
16192
16270
|
"projection",
|
|
16193
|
-
"metric",
|
|
16194
|
-
"
|
|
16271
|
+
"region-metric",
|
|
16272
|
+
"poi-metric",
|
|
16273
|
+
"flow-metric",
|
|
16195
16274
|
"scale",
|
|
16196
16275
|
"region-labels",
|
|
16197
16276
|
"poi-labels",
|
|
@@ -16199,6 +16278,8 @@ var init_parser12 = __esm({
|
|
|
16199
16278
|
"default-state",
|
|
16200
16279
|
"active-tag",
|
|
16201
16280
|
"no-legend",
|
|
16281
|
+
"no-insets",
|
|
16282
|
+
"relief",
|
|
16202
16283
|
"subtitle",
|
|
16203
16284
|
"caption"
|
|
16204
16285
|
]);
|
|
@@ -45423,6 +45504,74 @@ function featureBbox(topo, geomId) {
|
|
|
45423
45504
|
[b[1][0], b[1][1]]
|
|
45424
45505
|
];
|
|
45425
45506
|
}
|
|
45507
|
+
function explodePolygons(gj) {
|
|
45508
|
+
const g = gj.geometry ?? gj;
|
|
45509
|
+
const t = g.type;
|
|
45510
|
+
const coords = g.coordinates;
|
|
45511
|
+
if (t === "Polygon") {
|
|
45512
|
+
return [
|
|
45513
|
+
{ type: "Feature", geometry: { type: "Polygon", coordinates: coords } }
|
|
45514
|
+
];
|
|
45515
|
+
}
|
|
45516
|
+
if (t === "MultiPolygon") {
|
|
45517
|
+
return coords.map((rings) => ({
|
|
45518
|
+
type: "Feature",
|
|
45519
|
+
geometry: { type: "Polygon", coordinates: rings }
|
|
45520
|
+
}));
|
|
45521
|
+
}
|
|
45522
|
+
return [];
|
|
45523
|
+
}
|
|
45524
|
+
function bboxGap(a, b) {
|
|
45525
|
+
const lonGap = Math.max(0, a[0][0] - b[1][0], b[0][0] - a[1][0]);
|
|
45526
|
+
const latGap = Math.max(0, a[0][1] - b[1][1], b[0][1] - a[1][1]);
|
|
45527
|
+
return Math.max(lonGap, latGap);
|
|
45528
|
+
}
|
|
45529
|
+
function featureBboxPrimary(topo, geomId) {
|
|
45530
|
+
const geom = geomObject(topo).geometries.find((g) => g.id === geomId);
|
|
45531
|
+
if (!geom) return null;
|
|
45532
|
+
const gj = (0, import_topojson_client.feature)(topo, geom);
|
|
45533
|
+
const parts = explodePolygons(gj);
|
|
45534
|
+
if (parts.length <= 1) return featureBbox(topo, geomId);
|
|
45535
|
+
const polys = parts.map((p) => {
|
|
45536
|
+
const b = (0, import_d3_geo.geoBounds)(p);
|
|
45537
|
+
if (!b || !Number.isFinite(b[0][0])) return null;
|
|
45538
|
+
const wraps = b[1][0] < b[0][0];
|
|
45539
|
+
const bbox = [
|
|
45540
|
+
[b[0][0], b[0][1]],
|
|
45541
|
+
[b[1][0], b[1][1]]
|
|
45542
|
+
];
|
|
45543
|
+
return { bbox, area: (0, import_d3_geo.geoArea)(p), wraps };
|
|
45544
|
+
}).filter(
|
|
45545
|
+
(p) => p !== null
|
|
45546
|
+
);
|
|
45547
|
+
if (polys.length <= 1 || polys.some((p) => p.wraps))
|
|
45548
|
+
return featureBbox(topo, geomId);
|
|
45549
|
+
const maxArea = Math.max(...polys.map((p) => p.area));
|
|
45550
|
+
const anchor = polys.find((p) => p.area === maxArea);
|
|
45551
|
+
const cluster = [
|
|
45552
|
+
[anchor.bbox[0][0], anchor.bbox[0][1]],
|
|
45553
|
+
[anchor.bbox[1][0], anchor.bbox[1][1]]
|
|
45554
|
+
];
|
|
45555
|
+
const remaining = polys.filter((p) => p !== anchor);
|
|
45556
|
+
let added = true;
|
|
45557
|
+
while (added) {
|
|
45558
|
+
added = false;
|
|
45559
|
+
for (let i = remaining.length - 1; i >= 0; i--) {
|
|
45560
|
+
const p = remaining[i];
|
|
45561
|
+
const near = bboxGap(p.bbox, cluster) <= DETACH_GAP_DEG;
|
|
45562
|
+
const large = p.area >= DETACH_AREA_FRAC * maxArea;
|
|
45563
|
+
if (near || large) {
|
|
45564
|
+
cluster[0][0] = Math.min(cluster[0][0], p.bbox[0][0]);
|
|
45565
|
+
cluster[0][1] = Math.min(cluster[0][1], p.bbox[0][1]);
|
|
45566
|
+
cluster[1][0] = Math.max(cluster[1][0], p.bbox[1][0]);
|
|
45567
|
+
cluster[1][1] = Math.max(cluster[1][1], p.bbox[1][1]);
|
|
45568
|
+
remaining.splice(i, 1);
|
|
45569
|
+
added = true;
|
|
45570
|
+
}
|
|
45571
|
+
}
|
|
45572
|
+
}
|
|
45573
|
+
return cluster;
|
|
45574
|
+
}
|
|
45426
45575
|
function unionExtent(boxes, points) {
|
|
45427
45576
|
const lats = [];
|
|
45428
45577
|
const lons = [];
|
|
@@ -45461,13 +45610,15 @@ function unionLongitudes(lons) {
|
|
|
45461
45610
|
}
|
|
45462
45611
|
return { west: pts[gapIdx], east: pts[gapIdx - 1] + 360 };
|
|
45463
45612
|
}
|
|
45464
|
-
var import_topojson_client, import_d3_geo, fold;
|
|
45613
|
+
var import_topojson_client, import_d3_geo, fold, DETACH_GAP_DEG, DETACH_AREA_FRAC;
|
|
45465
45614
|
var init_geo = __esm({
|
|
45466
45615
|
"src/map/geo.ts"() {
|
|
45467
45616
|
"use strict";
|
|
45468
45617
|
import_topojson_client = require("topojson-client");
|
|
45469
45618
|
import_d3_geo = require("d3-geo");
|
|
45470
45619
|
fold = (s) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim();
|
|
45620
|
+
DETACH_GAP_DEG = 10;
|
|
45621
|
+
DETACH_AREA_FRAC = 0.25;
|
|
45471
45622
|
}
|
|
45472
45623
|
});
|
|
45473
45624
|
|
|
@@ -45476,6 +45627,11 @@ var resolver_exports = {};
|
|
|
45476
45627
|
__export(resolver_exports, {
|
|
45477
45628
|
resolveMap: () => resolveMap
|
|
45478
45629
|
});
|
|
45630
|
+
function usStateFromBareScope(scope) {
|
|
45631
|
+
if (!scope) return null;
|
|
45632
|
+
const up = scope.toUpperCase();
|
|
45633
|
+
return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
|
|
45634
|
+
}
|
|
45479
45635
|
function looksUS(lat, lon) {
|
|
45480
45636
|
if (lat < 15 || lat > 72) return false;
|
|
45481
45637
|
return lon >= -180 && lon <= -64 || lon >= 172;
|
|
@@ -45525,9 +45681,9 @@ function resolveMap(parsed, data) {
|
|
|
45525
45681
|
const f = fold(r.name);
|
|
45526
45682
|
return usStateIndex.has(f) && !countryIndex.has(f);
|
|
45527
45683
|
}) || parsed.regions.some(
|
|
45528
|
-
(r) => r.scope === "US" || r.scope?.startsWith("US-")
|
|
45684
|
+
(r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
|
|
45529
45685
|
) || parsed.pois.some(
|
|
45530
|
-
(p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
|
|
45686
|
+
(p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
|
|
45531
45687
|
);
|
|
45532
45688
|
const regions = [];
|
|
45533
45689
|
const seenRegion = /* @__PURE__ */ new Map();
|
|
@@ -45566,12 +45722,12 @@ function resolveMap(parsed, data) {
|
|
|
45566
45722
|
chosen = { ...inState, layer: "us-state" };
|
|
45567
45723
|
} else {
|
|
45568
45724
|
chosen = { ...inCountry, layer: "country" };
|
|
45725
|
+
warn2(
|
|
45726
|
+
r.lineNumber,
|
|
45727
|
+
`"${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}").`,
|
|
45728
|
+
"W_MAP_REGION_AMBIGUOUS"
|
|
45729
|
+
);
|
|
45569
45730
|
}
|
|
45570
|
-
warn2(
|
|
45571
|
-
r.lineNumber,
|
|
45572
|
-
`"${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}").`,
|
|
45573
|
-
"W_MAP_REGION_AMBIGUOUS"
|
|
45574
|
-
);
|
|
45575
45731
|
} else if (inState) {
|
|
45576
45732
|
chosen = { ...inState, layer: "us-state" };
|
|
45577
45733
|
} else if (inCountry) {
|
|
@@ -45594,7 +45750,8 @@ function resolveMap(parsed, data) {
|
|
|
45594
45750
|
iso: chosen.id,
|
|
45595
45751
|
name: chosen.name,
|
|
45596
45752
|
layer: chosen.layer,
|
|
45597
|
-
...r.
|
|
45753
|
+
...r.value !== void 0 && { value: r.value },
|
|
45754
|
+
...r.color !== void 0 && { color: r.color },
|
|
45598
45755
|
tags: r.tags,
|
|
45599
45756
|
meta: r.meta,
|
|
45600
45757
|
lineNumber: r.lineNumber
|
|
@@ -45652,9 +45809,10 @@ function resolveMap(parsed, data) {
|
|
|
45652
45809
|
let cands = idxs.map((i) => data.gazetteer.cities[i]);
|
|
45653
45810
|
const scopeUse = scope ?? scopeHint;
|
|
45654
45811
|
if (scopeUse) {
|
|
45655
|
-
const
|
|
45812
|
+
const bareState = usStateFromBareScope(scopeUse);
|
|
45813
|
+
const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
|
|
45656
45814
|
const filtered = cands.filter(
|
|
45657
|
-
(c2) =>
|
|
45815
|
+
(c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
|
|
45658
45816
|
);
|
|
45659
45817
|
if (filtered.length) cands = filtered;
|
|
45660
45818
|
else if (scope) {
|
|
@@ -45735,6 +45893,7 @@ function resolveMap(parsed, data) {
|
|
|
45735
45893
|
lat,
|
|
45736
45894
|
lon,
|
|
45737
45895
|
...p.label !== void 0 && { label: p.label },
|
|
45896
|
+
...p.color !== void 0 && { color: p.color },
|
|
45738
45897
|
tags: p.tags,
|
|
45739
45898
|
meta: p.meta,
|
|
45740
45899
|
lineNumber: p.lineNumber
|
|
@@ -45783,33 +45942,89 @@ function resolveMap(parsed, data) {
|
|
|
45783
45942
|
lineNumber: e.lineNumber
|
|
45784
45943
|
});
|
|
45785
45944
|
}
|
|
45786
|
-
const
|
|
45787
|
-
|
|
45788
|
-
|
|
45789
|
-
|
|
45790
|
-
|
|
45791
|
-
if (
|
|
45792
|
-
|
|
45793
|
-
|
|
45794
|
-
|
|
45795
|
-
const poi = {
|
|
45945
|
+
const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
|
|
45946
|
+
const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
|
|
45947
|
+
if (pos.kind === "coords") {
|
|
45948
|
+
const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
|
|
45949
|
+
if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
|
|
45950
|
+
if (!registry.has(id)) {
|
|
45951
|
+
registerPoi(
|
|
45952
|
+
id,
|
|
45953
|
+
{
|
|
45796
45954
|
id,
|
|
45797
|
-
...
|
|
45798
|
-
lat:
|
|
45799
|
-
lon:
|
|
45800
|
-
|
|
45801
|
-
|
|
45802
|
-
|
|
45803
|
-
|
|
45804
|
-
}
|
|
45805
|
-
|
|
45806
|
-
|
|
45807
|
-
} else {
|
|
45808
|
-
id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
|
|
45955
|
+
...alias !== void 0 && { name: alias },
|
|
45956
|
+
lat: pos.lat,
|
|
45957
|
+
lon: pos.lon,
|
|
45958
|
+
...label !== void 0 && { label },
|
|
45959
|
+
tags,
|
|
45960
|
+
meta,
|
|
45961
|
+
lineNumber: line12
|
|
45962
|
+
},
|
|
45963
|
+
line12
|
|
45964
|
+
);
|
|
45809
45965
|
}
|
|
45810
|
-
|
|
45966
|
+
return id;
|
|
45811
45967
|
}
|
|
45812
|
-
|
|
45968
|
+
const f = fold(pos.name);
|
|
45969
|
+
if (registry.has(f)) return f;
|
|
45970
|
+
const aliased = declaredByName.get(f);
|
|
45971
|
+
if (aliased) return aliased;
|
|
45972
|
+
const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
|
|
45973
|
+
if (got.kind !== "ok") return null;
|
|
45974
|
+
noteCountry(got.iso);
|
|
45975
|
+
registerPoi(
|
|
45976
|
+
f,
|
|
45977
|
+
{
|
|
45978
|
+
id: f,
|
|
45979
|
+
name: pos.name,
|
|
45980
|
+
lat: got.lat,
|
|
45981
|
+
lon: got.lon,
|
|
45982
|
+
...label !== void 0 && { label },
|
|
45983
|
+
tags,
|
|
45984
|
+
meta,
|
|
45985
|
+
lineNumber: line12
|
|
45986
|
+
},
|
|
45987
|
+
line12
|
|
45988
|
+
);
|
|
45989
|
+
return f;
|
|
45990
|
+
};
|
|
45991
|
+
const routes = [];
|
|
45992
|
+
for (const rt of parsed.routes) {
|
|
45993
|
+
const originId = resolveStop(
|
|
45994
|
+
rt.origin,
|
|
45995
|
+
rt.originAlias,
|
|
45996
|
+
rt.originLabel,
|
|
45997
|
+
rt.originTags,
|
|
45998
|
+
rt.originValue,
|
|
45999
|
+
rt.lineNumber
|
|
46000
|
+
);
|
|
46001
|
+
if (!originId) continue;
|
|
46002
|
+
const stopIds = [originId];
|
|
46003
|
+
const legs = [];
|
|
46004
|
+
let prevId = originId;
|
|
46005
|
+
for (const leg of rt.legs) {
|
|
46006
|
+
const destId = resolveStop(
|
|
46007
|
+
leg.dest,
|
|
46008
|
+
leg.destAlias,
|
|
46009
|
+
leg.destLabel,
|
|
46010
|
+
leg.destTags,
|
|
46011
|
+
void 0,
|
|
46012
|
+
// a leg's `value:` is leg thickness, not the dest's size
|
|
46013
|
+
leg.lineNumber
|
|
46014
|
+
);
|
|
46015
|
+
if (!destId) continue;
|
|
46016
|
+
legs.push({
|
|
46017
|
+
fromId: prevId,
|
|
46018
|
+
toId: destId,
|
|
46019
|
+
...leg.label !== void 0 && { label: leg.label },
|
|
46020
|
+
style: leg.style,
|
|
46021
|
+
...leg.value !== void 0 && { value: leg.value },
|
|
46022
|
+
lineNumber: leg.lineNumber
|
|
46023
|
+
});
|
|
46024
|
+
if (!stopIds.includes(destId)) stopIds.push(destId);
|
|
46025
|
+
prevId = destId;
|
|
46026
|
+
}
|
|
46027
|
+
routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
|
|
45813
46028
|
}
|
|
45814
46029
|
const subdivisions = [];
|
|
45815
46030
|
if (usSubdivisionReferenced || parsed.directives.region === "us-states")
|
|
@@ -45821,7 +46036,7 @@ function resolveMap(parsed, data) {
|
|
|
45821
46036
|
}
|
|
45822
46037
|
for (const r of regions) {
|
|
45823
46038
|
if (r.layer === "country") {
|
|
45824
|
-
const bb =
|
|
46039
|
+
const bb = featureBboxPrimary(data.worldCoarse, r.iso);
|
|
45825
46040
|
if (bb) regionBoxes.push(bb);
|
|
45826
46041
|
}
|
|
45827
46042
|
}
|
|
@@ -45835,6 +46050,7 @@ function resolveMap(parsed, data) {
|
|
|
45835
46050
|
const lonSpan = extent2[1][0] - extent2[0][0];
|
|
45836
46051
|
const latSpan = extent2[1][1] - extent2[0][1];
|
|
45837
46052
|
const span = Math.max(lonSpan, latSpan);
|
|
46053
|
+
const maxAbsLat = Math.max(Math.abs(extent2[0][1]), Math.abs(extent2[1][1]));
|
|
45838
46054
|
const usDominant = (subdivisions.includes("us-states") || regions.some((r) => r.layer === "us-state")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
|
|
45839
46055
|
let projection;
|
|
45840
46056
|
const override = parsed.directives.projection;
|
|
@@ -45842,12 +46058,10 @@ function resolveMap(parsed, data) {
|
|
|
45842
46058
|
projection = override;
|
|
45843
46059
|
} else if (usDominant) {
|
|
45844
46060
|
projection = "albers-usa";
|
|
45845
|
-
} else if (span > WORLD_SPAN) {
|
|
46061
|
+
} else if (span > WORLD_SPAN || maxAbsLat > MERCATOR_MAX_LAT) {
|
|
45846
46062
|
projection = "equirectangular";
|
|
45847
|
-
} else if (span < MERCATOR_MAX_SPAN) {
|
|
45848
|
-
projection = "mercator";
|
|
45849
46063
|
} else {
|
|
45850
|
-
projection = "
|
|
46064
|
+
projection = "mercator";
|
|
45851
46065
|
}
|
|
45852
46066
|
if (lonSpan >= 180) {
|
|
45853
46067
|
extent2 = [
|
|
@@ -45901,14 +46115,14 @@ function firstError(diags) {
|
|
|
45901
46115
|
const e = diags.find((d) => d.severity === "error");
|
|
45902
46116
|
return e ? formatDgmoError(e) : null;
|
|
45903
46117
|
}
|
|
45904
|
-
var WORLD_SPAN,
|
|
46118
|
+
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
|
|
45905
46119
|
var init_resolver2 = __esm({
|
|
45906
46120
|
"src/map/resolver.ts"() {
|
|
45907
46121
|
"use strict";
|
|
45908
46122
|
init_diagnostics();
|
|
45909
46123
|
init_geo();
|
|
45910
46124
|
WORLD_SPAN = 90;
|
|
45911
|
-
|
|
46125
|
+
MERCATOR_MAX_LAT = 80;
|
|
45912
46126
|
PAD_FRACTION = 0.05;
|
|
45913
46127
|
WORLD_LAT_SOUTH = -58;
|
|
45914
46128
|
WORLD_LAT_NORTH = 78;
|
|
@@ -45933,115 +46147,59 @@ var init_resolver2 = __esm({
|
|
|
45933
46147
|
"north macedonia": "macedonia",
|
|
45934
46148
|
"czech republic": "czechia"
|
|
45935
46149
|
};
|
|
45936
|
-
|
|
45937
|
-
|
|
45938
|
-
|
|
45939
|
-
|
|
45940
|
-
|
|
45941
|
-
|
|
45942
|
-
|
|
45943
|
-
|
|
45944
|
-
|
|
45945
|
-
|
|
45946
|
-
|
|
45947
|
-
|
|
45948
|
-
|
|
45949
|
-
|
|
45950
|
-
|
|
45951
|
-
|
|
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
|
-
const [
|
|
45989
|
-
worldCoarse,
|
|
45990
|
-
worldDetail,
|
|
45991
|
-
usStates,
|
|
45992
|
-
lakes,
|
|
45993
|
-
rivers,
|
|
45994
|
-
naLand,
|
|
45995
|
-
naLakes,
|
|
45996
|
-
gazetteer
|
|
45997
|
-
] = await Promise.all([
|
|
45998
|
-
readJson(nb, dir, FILES.worldCoarse),
|
|
45999
|
-
readJson(nb, dir, FILES.worldDetail),
|
|
46000
|
-
readJson(nb, dir, FILES.usStates),
|
|
46001
|
-
// Lakes/rivers/NA assets are optional — older bundles may predate them.
|
|
46002
|
-
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
46003
|
-
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
46004
|
-
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
46005
|
-
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
46006
|
-
readJson(nb, dir, FILES.gazetteer)
|
|
46150
|
+
US_STATE_POSTAL = /* @__PURE__ */ new Set([
|
|
46151
|
+
"AL",
|
|
46152
|
+
"AK",
|
|
46153
|
+
"AZ",
|
|
46154
|
+
"AR",
|
|
46155
|
+
"CA",
|
|
46156
|
+
"CO",
|
|
46157
|
+
"CT",
|
|
46158
|
+
"DE",
|
|
46159
|
+
"FL",
|
|
46160
|
+
"GA",
|
|
46161
|
+
"HI",
|
|
46162
|
+
"ID",
|
|
46163
|
+
"IL",
|
|
46164
|
+
"IN",
|
|
46165
|
+
"IA",
|
|
46166
|
+
"KS",
|
|
46167
|
+
"KY",
|
|
46168
|
+
"LA",
|
|
46169
|
+
"ME",
|
|
46170
|
+
"MD",
|
|
46171
|
+
"MA",
|
|
46172
|
+
"MI",
|
|
46173
|
+
"MN",
|
|
46174
|
+
"MS",
|
|
46175
|
+
"MO",
|
|
46176
|
+
"MT",
|
|
46177
|
+
"NE",
|
|
46178
|
+
"NV",
|
|
46179
|
+
"NH",
|
|
46180
|
+
"NJ",
|
|
46181
|
+
"NM",
|
|
46182
|
+
"NY",
|
|
46183
|
+
"NC",
|
|
46184
|
+
"ND",
|
|
46185
|
+
"OH",
|
|
46186
|
+
"OK",
|
|
46187
|
+
"OR",
|
|
46188
|
+
"PA",
|
|
46189
|
+
"RI",
|
|
46190
|
+
"SC",
|
|
46191
|
+
"SD",
|
|
46192
|
+
"TN",
|
|
46193
|
+
"TX",
|
|
46194
|
+
"UT",
|
|
46195
|
+
"VT",
|
|
46196
|
+
"VA",
|
|
46197
|
+
"WA",
|
|
46198
|
+
"WV",
|
|
46199
|
+
"WI",
|
|
46200
|
+
"WY",
|
|
46201
|
+
"DC"
|
|
46007
46202
|
]);
|
|
46008
|
-
return validate({
|
|
46009
|
-
worldCoarse,
|
|
46010
|
-
worldDetail,
|
|
46011
|
-
usStates,
|
|
46012
|
-
gazetteer,
|
|
46013
|
-
...lakes && { lakes },
|
|
46014
|
-
...rivers && { rivers },
|
|
46015
|
-
...naLand && { naLand },
|
|
46016
|
-
...naLakes && { naLakes }
|
|
46017
|
-
});
|
|
46018
|
-
})().catch((e) => {
|
|
46019
|
-
cache = void 0;
|
|
46020
|
-
throw e;
|
|
46021
|
-
});
|
|
46022
|
-
return cache;
|
|
46023
|
-
}
|
|
46024
|
-
var import_meta, FILES, CANDIDATE_DIRS, cache;
|
|
46025
|
-
var init_load_data = __esm({
|
|
46026
|
-
"src/map/load-data.ts"() {
|
|
46027
|
-
"use strict";
|
|
46028
|
-
import_meta = {};
|
|
46029
|
-
FILES = {
|
|
46030
|
-
worldCoarse: "world-coarse.json",
|
|
46031
|
-
worldDetail: "world-detail.json",
|
|
46032
|
-
usStates: "us-states.json",
|
|
46033
|
-
lakes: "lakes.json",
|
|
46034
|
-
rivers: "rivers.json",
|
|
46035
|
-
naLand: "na-land.json",
|
|
46036
|
-
naLakes: "na-lakes.json",
|
|
46037
|
-
gazetteer: "gazetteer.json"
|
|
46038
|
-
};
|
|
46039
|
-
CANDIDATE_DIRS = [
|
|
46040
|
-
"./data",
|
|
46041
|
-
"./map-data",
|
|
46042
|
-
"../map-data",
|
|
46043
|
-
"../src/map/data"
|
|
46044
|
-
];
|
|
46045
46203
|
}
|
|
46046
46204
|
});
|
|
46047
46205
|
|
|
@@ -46071,8 +46229,19 @@ function projectionFor(family) {
|
|
|
46071
46229
|
return (0, import_d3_geo2.geoEquirectangular)();
|
|
46072
46230
|
}
|
|
46073
46231
|
}
|
|
46074
|
-
function mapBackgroundColor(palette) {
|
|
46075
|
-
return mix(
|
|
46232
|
+
function mapBackgroundColor(palette, isDark = false, _dataActive = false) {
|
|
46233
|
+
return mix(
|
|
46234
|
+
palette.colors.blue,
|
|
46235
|
+
palette.bg,
|
|
46236
|
+
isDark ? WATER_TINT_DARK : WATER_TINT_LIGHT
|
|
46237
|
+
);
|
|
46238
|
+
}
|
|
46239
|
+
function mapNeutralLandColor(palette, isDark, _dataActive = false) {
|
|
46240
|
+
return mix(
|
|
46241
|
+
palette.colors.green,
|
|
46242
|
+
palette.bg,
|
|
46243
|
+
isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
|
|
46244
|
+
);
|
|
46076
46245
|
}
|
|
46077
46246
|
function layoutMap(resolved, data, size, opts) {
|
|
46078
46247
|
const { palette, isDark } = opts;
|
|
@@ -46093,28 +46262,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46093
46262
|
}
|
|
46094
46263
|
}
|
|
46095
46264
|
const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
|
|
46096
|
-
const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
|
|
46097
|
-
const neutralFill = mix(palette.colors.green, palette.bg, landTint);
|
|
46098
|
-
const water = mapBackgroundColor(palette);
|
|
46099
46265
|
const usContext = usLayer !== null;
|
|
46100
|
-
const foreignFill = mix(
|
|
46101
|
-
palette.colors.gray,
|
|
46102
|
-
palette.bg,
|
|
46103
|
-
isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46104
|
-
);
|
|
46105
46266
|
const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
|
|
46106
|
-
const
|
|
46267
|
+
const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
|
|
46107
46268
|
const scaleOverride = resolved.directives.scale;
|
|
46108
|
-
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...
|
|
46109
|
-
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...
|
|
46110
|
-
const rampHue = palette.colors.red;
|
|
46111
|
-
const hasRamp =
|
|
46112
|
-
const
|
|
46269
|
+
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
|
|
46270
|
+
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
|
|
46271
|
+
const rampHue = resolveColor(resolved.directives.regionMetricColor ?? "", palette) ?? palette.colors.red;
|
|
46272
|
+
const hasRamp = values.length > 0;
|
|
46273
|
+
const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
|
|
46113
46274
|
const matchColorGroup = (v) => {
|
|
46114
46275
|
const lv = v.trim().toLowerCase();
|
|
46115
46276
|
if (lv === "none") return null;
|
|
46116
|
-
if (
|
|
46117
|
-
return SCORE_NAME;
|
|
46277
|
+
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
46118
46278
|
const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
46119
46279
|
return tg ? tg.name : v;
|
|
46120
46280
|
};
|
|
@@ -46125,11 +46285,20 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46125
46285
|
} else if (resolved.directives.activeTag !== void 0) {
|
|
46126
46286
|
activeGroup = matchColorGroup(resolved.directives.activeTag);
|
|
46127
46287
|
} else {
|
|
46128
|
-
activeGroup =
|
|
46288
|
+
activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
|
|
46129
46289
|
}
|
|
46130
|
-
const activeIsScore =
|
|
46290
|
+
const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
|
|
46291
|
+
const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
|
|
46292
|
+
const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
|
|
46293
|
+
const water = mapBackgroundColor(palette, isDark, mutedBasemap);
|
|
46294
|
+
const lakeStroke = mix(regionStroke, water, 45);
|
|
46295
|
+
const foreignFill = mix(
|
|
46296
|
+
palette.colors.gray,
|
|
46297
|
+
palette.bg,
|
|
46298
|
+
mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46299
|
+
);
|
|
46131
46300
|
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
46132
|
-
const
|
|
46301
|
+
const fillForValue = (s) => {
|
|
46133
46302
|
const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
|
|
46134
46303
|
const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
|
|
46135
46304
|
return mix(rampHue, rampBase, pct);
|
|
@@ -46152,9 +46321,16 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46152
46321
|
isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT
|
|
46153
46322
|
);
|
|
46154
46323
|
};
|
|
46324
|
+
const directFill = (name) => {
|
|
46325
|
+
const hex = name ? resolveColor(name, palette) : null;
|
|
46326
|
+
if (!hex) return null;
|
|
46327
|
+
return mix(hex, palette.bg, isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT);
|
|
46328
|
+
};
|
|
46155
46329
|
const regionFill = (r) => {
|
|
46330
|
+
const direct = directFill(r.color);
|
|
46331
|
+
if (direct) return direct;
|
|
46156
46332
|
if (activeIsScore) {
|
|
46157
|
-
return r.
|
|
46333
|
+
return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
|
|
46158
46334
|
}
|
|
46159
46335
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
46160
46336
|
};
|
|
@@ -46206,6 +46382,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46206
46382
|
const fitIsGlobal = fitGB[1][0] - fitGB[0][0] >= 270 || fitGB[1][1] - fitGB[0][1] >= 130;
|
|
46207
46383
|
let path;
|
|
46208
46384
|
let project;
|
|
46385
|
+
let stretchParams = null;
|
|
46209
46386
|
if (fitIsGlobal) {
|
|
46210
46387
|
const cb = (0, import_d3_geo2.geoPath)(projection).bounds(fitTarget);
|
|
46211
46388
|
const bx0 = cb[0][0];
|
|
@@ -46216,6 +46393,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46216
46393
|
const oy = fitBox[0][1];
|
|
46217
46394
|
const sx = cw > 0 ? (fitBox[1][0] - ox) / cw : 1;
|
|
46218
46395
|
const sy = ch > 0 ? (fitBox[1][1] - oy) / ch : 1;
|
|
46396
|
+
stretchParams = { sx, sy, ox, oy, bx0, by0 };
|
|
46219
46397
|
const stretch = (x, y) => [
|
|
46220
46398
|
ox + (x - bx0) * sx,
|
|
46221
46399
|
oy + (y - by0) * sy
|
|
@@ -46247,7 +46425,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46247
46425
|
const insets = [];
|
|
46248
46426
|
const insetRegions = [];
|
|
46249
46427
|
const insetLabelSeeds = [];
|
|
46250
|
-
if (resolved.projection === "albers-usa" && usLayer) {
|
|
46428
|
+
if (resolved.projection === "albers-usa" && usLayer && !resolved.directives.noInsets) {
|
|
46251
46429
|
const PAD = 8;
|
|
46252
46430
|
const GAP = 12;
|
|
46253
46431
|
const yB = height - FIT_PAD;
|
|
@@ -46278,38 +46456,14 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46278
46456
|
}
|
|
46279
46457
|
return y;
|
|
46280
46458
|
};
|
|
46281
|
-
const
|
|
46459
|
+
const coastFloor = (x0, xr) => {
|
|
46282
46460
|
const n = 24;
|
|
46283
|
-
const pts = [];
|
|
46284
46461
|
let maxY = -Infinity;
|
|
46285
46462
|
for (let i = 0; i <= n; i++) {
|
|
46286
|
-
const
|
|
46287
|
-
|
|
46288
|
-
|
|
46289
|
-
|
|
46290
|
-
if (y > maxY) maxY = y;
|
|
46291
|
-
}
|
|
46292
|
-
}
|
|
46293
|
-
if (pts.length === 0) return () => yB - height * 0.42;
|
|
46294
|
-
let m = 0;
|
|
46295
|
-
if (pts.length >= 2) {
|
|
46296
|
-
let sx = 0, sy = 0, sxx = 0, sxy = 0;
|
|
46297
|
-
for (const [x, y] of pts) {
|
|
46298
|
-
sx += x;
|
|
46299
|
-
sy += y;
|
|
46300
|
-
sxx += x * x;
|
|
46301
|
-
sxy += x * y;
|
|
46302
|
-
}
|
|
46303
|
-
const den = pts.length * sxx - sx * sx;
|
|
46304
|
-
if (den !== 0) m = (pts.length * sxy - sx * sy) / den;
|
|
46305
|
-
}
|
|
46306
|
-
m = Math.max(-0.35, Math.min(0.35, m));
|
|
46307
|
-
let c = -Infinity;
|
|
46308
|
-
for (const [x, y] of pts) {
|
|
46309
|
-
const need = y - m * x + GAP;
|
|
46310
|
-
if (need > c) c = need;
|
|
46311
|
-
}
|
|
46312
|
-
return (x) => m * x + c;
|
|
46463
|
+
const y = at(x0 + (xr - x0) * i / n);
|
|
46464
|
+
if (y > maxY) maxY = y;
|
|
46465
|
+
}
|
|
46466
|
+
return maxY;
|
|
46313
46467
|
};
|
|
46314
46468
|
const placeInset = (iso, proj, boxX, iwReq) => {
|
|
46315
46469
|
const f = usLayer.get(iso);
|
|
@@ -46318,19 +46472,15 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46318
46472
|
const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD);
|
|
46319
46473
|
if (iw < 24) return boxX;
|
|
46320
46474
|
const xr = x0 + iw + 2 * PAD;
|
|
46321
|
-
const
|
|
46322
|
-
const
|
|
46323
|
-
const yR = top(xr);
|
|
46475
|
+
const floor = coastFloor(x0, xr);
|
|
46476
|
+
const topGuess = floor > -Infinity ? floor + GAP : yB - height * 0.42;
|
|
46324
46477
|
proj.fitWidth(iw, f);
|
|
46325
46478
|
const bb = (0, import_d3_geo2.geoPath)(proj).bounds(f);
|
|
46326
46479
|
const sh = Number.isFinite(bb[0][0]) ? bb[1][1] - bb[0][1] : iw;
|
|
46327
46480
|
const needH = sh + 2 * PAD;
|
|
46328
|
-
let topFit =
|
|
46481
|
+
let topFit = topGuess;
|
|
46329
46482
|
const bottom = Math.min(topFit + needH, yB);
|
|
46330
46483
|
if (bottom - topFit < needH) topFit = bottom - needH;
|
|
46331
|
-
const lift = topFit - Math.max(yL, yR);
|
|
46332
|
-
const topL = yL + lift;
|
|
46333
|
-
const topR = yR + lift;
|
|
46334
46484
|
proj.fitExtent(
|
|
46335
46485
|
[
|
|
46336
46486
|
[x0 + PAD, topFit + PAD],
|
|
@@ -46349,15 +46499,18 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46349
46499
|
}
|
|
46350
46500
|
insets.push({
|
|
46351
46501
|
x: x0,
|
|
46352
|
-
y:
|
|
46502
|
+
y: topFit,
|
|
46353
46503
|
w: xr - x0,
|
|
46354
|
-
h: bottom -
|
|
46504
|
+
h: bottom - topFit,
|
|
46355
46505
|
points: [
|
|
46356
|
-
[x0,
|
|
46357
|
-
[xr,
|
|
46506
|
+
[x0, topFit],
|
|
46507
|
+
[xr, topFit],
|
|
46358
46508
|
[xr, bottom],
|
|
46359
46509
|
[x0, bottom]
|
|
46360
|
-
]
|
|
46510
|
+
],
|
|
46511
|
+
// The FITTED inset projection (just fit to this box) — captured so the
|
|
46512
|
+
// geo-query can invert pixels inside the frame back to AK/HI coords.
|
|
46513
|
+
projection: proj
|
|
46361
46514
|
});
|
|
46362
46515
|
insetRegions.push({
|
|
46363
46516
|
id: iso,
|
|
@@ -46366,7 +46519,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46366
46519
|
stroke: regionStroke,
|
|
46367
46520
|
lineNumber,
|
|
46368
46521
|
layer: "us-state",
|
|
46369
|
-
...r?.
|
|
46522
|
+
...r?.value !== void 0 && { value: r.value },
|
|
46370
46523
|
...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46371
46524
|
});
|
|
46372
46525
|
const ctr = (0, import_d3_geo2.geoPath)(proj).centroid(f);
|
|
@@ -46509,7 +46662,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46509
46662
|
lineNumber,
|
|
46510
46663
|
layer,
|
|
46511
46664
|
...label !== void 0 && { label },
|
|
46512
|
-
...isThisLayer && r.
|
|
46665
|
+
...isThisLayer && r.value !== void 0 && { value: r.value },
|
|
46513
46666
|
...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46514
46667
|
});
|
|
46515
46668
|
}
|
|
@@ -46527,13 +46680,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46527
46680
|
id: "lake",
|
|
46528
46681
|
d,
|
|
46529
46682
|
fill: water,
|
|
46530
|
-
stroke:
|
|
46683
|
+
stroke: lakeStroke,
|
|
46531
46684
|
lineNumber: -1,
|
|
46532
46685
|
layer: "base"
|
|
46533
46686
|
});
|
|
46534
46687
|
}
|
|
46535
46688
|
}
|
|
46536
|
-
const
|
|
46689
|
+
const relief = [];
|
|
46690
|
+
let reliefHatch = null;
|
|
46691
|
+
if (resolved.directives.relief === true && data.mountainRanges) {
|
|
46692
|
+
for (const [, f] of decodeLayer(data.mountainRanges)) {
|
|
46693
|
+
const viewF = isGlobalView ? dropFrameFillers(f) : cullFeatureToView(f);
|
|
46694
|
+
if (!viewF) continue;
|
|
46695
|
+
const area2 = path.area(viewF);
|
|
46696
|
+
if (!Number.isFinite(area2) || area2 < RELIEF_MIN_AREA) continue;
|
|
46697
|
+
const box = path.bounds(viewF);
|
|
46698
|
+
if (box[1][0] - box[0][0] < RELIEF_MIN_DIM || box[1][1] - box[0][1] < RELIEF_MIN_DIM)
|
|
46699
|
+
continue;
|
|
46700
|
+
const d = path(viewF) ?? "";
|
|
46701
|
+
if (!d) continue;
|
|
46702
|
+
relief.push({ d });
|
|
46703
|
+
}
|
|
46704
|
+
if (relief.length) {
|
|
46705
|
+
const darkTone = isDark ? palette.bg : palette.text;
|
|
46706
|
+
const lightTone = isDark ? palette.text : palette.bg;
|
|
46707
|
+
const landLum = relativeLuminance(neutralFill);
|
|
46708
|
+
const tone = Math.abs(landLum - relativeLuminance(darkTone)) > 0.04 ? darkTone : lightTone;
|
|
46709
|
+
reliefHatch = {
|
|
46710
|
+
color: mix(tone, neutralFill, RELIEF_HATCH_STRENGTH),
|
|
46711
|
+
spacing: RELIEF_HATCH_SPACING,
|
|
46712
|
+
width: RELIEF_HATCH_WIDTH
|
|
46713
|
+
};
|
|
46714
|
+
}
|
|
46715
|
+
}
|
|
46716
|
+
const riverColor = mix(water, regionStroke, 16);
|
|
46537
46717
|
const rivers = [];
|
|
46538
46718
|
if (data.rivers) {
|
|
46539
46719
|
for (const [, f] of decodeLayer(data.rivers)) {
|
|
@@ -46544,16 +46724,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46544
46724
|
rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
|
|
46545
46725
|
}
|
|
46546
46726
|
}
|
|
46547
|
-
const sizeVals = resolved.pois.map((p) => Number(p.meta["
|
|
46727
|
+
const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46548
46728
|
const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
|
|
46549
46729
|
const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
|
|
46550
46730
|
const radiusFor = (p) => {
|
|
46551
|
-
const v = Number(p.meta["
|
|
46731
|
+
const v = Number(p.meta["value"]);
|
|
46552
46732
|
if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
|
|
46553
46733
|
const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
|
|
46554
46734
|
return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
|
|
46555
46735
|
};
|
|
46556
46736
|
const poiFill = (p) => {
|
|
46737
|
+
const directHex = p.color ? resolveColor(p.color, palette) : null;
|
|
46738
|
+
if (directHex)
|
|
46739
|
+
return { fill: directHex, stroke: mix(directHex, palette.text, 18) };
|
|
46557
46740
|
for (const group of resolved.tagGroups) {
|
|
46558
46741
|
const val = p.tags[group.name.toLowerCase()];
|
|
46559
46742
|
if (!val) continue;
|
|
@@ -46615,7 +46798,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46615
46798
|
lineNumber: e.p.lineNumber,
|
|
46616
46799
|
implicit: !!e.p.implicit,
|
|
46617
46800
|
isOrigin: originIds.has(e.p.id),
|
|
46618
|
-
...num !== void 0 && { routeNumber: num }
|
|
46801
|
+
...num !== void 0 && { routeNumber: num },
|
|
46802
|
+
...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
|
|
46619
46803
|
});
|
|
46620
46804
|
});
|
|
46621
46805
|
}
|
|
@@ -46651,26 +46835,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46651
46835
|
const by = b.cy - (b.cy - py) / tb * trimB;
|
|
46652
46836
|
return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
|
|
46653
46837
|
};
|
|
46838
|
+
const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
|
|
46839
|
+
const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
|
|
46840
|
+
const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
|
|
46841
|
+
const routeWidthFor = (v) => {
|
|
46842
|
+
if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
|
|
46843
|
+
const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
|
|
46844
|
+
return W_MIN + t * (W_MAX - W_MIN);
|
|
46845
|
+
};
|
|
46654
46846
|
for (const rt of resolved.routes) {
|
|
46655
|
-
const
|
|
46656
|
-
|
|
46657
|
-
const
|
|
46658
|
-
const b = poiScreen.get(rt.stopIds[i]);
|
|
46847
|
+
for (const leg of rt.legs) {
|
|
46848
|
+
const a = poiScreen.get(leg.fromId);
|
|
46849
|
+
const b = poiScreen.get(leg.toId);
|
|
46659
46850
|
if (!a || !b) continue;
|
|
46851
|
+
const mx = (a.cx + b.cx) / 2;
|
|
46852
|
+
const my = (a.cy + b.cy) / 2;
|
|
46660
46853
|
legs.push({
|
|
46661
|
-
d: legPath(a, b,
|
|
46662
|
-
width:
|
|
46854
|
+
d: legPath(a, b, leg.style === "arc", 0),
|
|
46855
|
+
width: routeWidthFor(Number(leg.value)),
|
|
46663
46856
|
color: mix(palette.text, palette.bg, 72),
|
|
46664
46857
|
arrow: true,
|
|
46665
|
-
lineNumber:
|
|
46858
|
+
lineNumber: leg.lineNumber,
|
|
46859
|
+
...leg.label !== void 0 && {
|
|
46860
|
+
label: leg.label,
|
|
46861
|
+
labelX: mx,
|
|
46862
|
+
labelY: my - 4
|
|
46863
|
+
}
|
|
46666
46864
|
});
|
|
46667
46865
|
}
|
|
46668
46866
|
}
|
|
46669
|
-
const weightVals = resolved.edges.map((e) => Number(e.meta["
|
|
46867
|
+
const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46670
46868
|
const wMin = weightVals.length ? Math.min(...weightVals) : 0;
|
|
46671
46869
|
const wMax = weightVals.length ? Math.max(...weightVals) : 0;
|
|
46672
46870
|
const widthFor = (e) => {
|
|
46673
|
-
const v = Number(e.meta["
|
|
46871
|
+
const v = Number(e.meta["value"]);
|
|
46674
46872
|
if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
|
|
46675
46873
|
const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
|
|
46676
46874
|
return W_MIN + t * (W_MAX - W_MIN);
|
|
@@ -46933,8 +47131,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46933
47131
|
activeGroup,
|
|
46934
47132
|
...hasRamp && {
|
|
46935
47133
|
ramp: {
|
|
46936
|
-
...resolved.directives.
|
|
46937
|
-
metric: resolved.directives.
|
|
47134
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47135
|
+
metric: resolved.directives.regionMetric
|
|
46938
47136
|
},
|
|
46939
47137
|
min: rampMin,
|
|
46940
47138
|
max: rampMax,
|
|
@@ -46954,21 +47152,26 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46954
47152
|
...resolved.caption !== void 0 && { caption: resolved.caption },
|
|
46955
47153
|
regions,
|
|
46956
47154
|
rivers,
|
|
47155
|
+
relief,
|
|
47156
|
+
reliefHatch,
|
|
46957
47157
|
legs,
|
|
46958
47158
|
pois,
|
|
46959
47159
|
labels,
|
|
46960
47160
|
legend,
|
|
46961
47161
|
insets,
|
|
46962
|
-
insetRegions
|
|
47162
|
+
insetRegions,
|
|
47163
|
+
projection,
|
|
47164
|
+
stretch: stretchParams
|
|
46963
47165
|
};
|
|
46964
47166
|
}
|
|
46965
|
-
var import_d3_geo2, import_topojson_client2, 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,
|
|
47167
|
+
var import_d3_geo2, import_topojson_client2, 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;
|
|
46966
47168
|
var init_layout15 = __esm({
|
|
46967
47169
|
"src/map/layout.ts"() {
|
|
46968
47170
|
"use strict";
|
|
46969
47171
|
import_d3_geo2 = require("d3-geo");
|
|
46970
47172
|
import_topojson_client2 = require("topojson-client");
|
|
46971
47173
|
init_color_utils();
|
|
47174
|
+
init_colors();
|
|
46972
47175
|
init_label_layout();
|
|
46973
47176
|
init_legend_constants();
|
|
46974
47177
|
init_title_constants();
|
|
@@ -46981,14 +47184,22 @@ var init_layout15 = __esm({
|
|
|
46981
47184
|
W_MAX = 8;
|
|
46982
47185
|
FONT = 11;
|
|
46983
47186
|
COLO_EPS = 1.5;
|
|
46984
|
-
LAND_TINT_LIGHT =
|
|
46985
|
-
LAND_TINT_DARK =
|
|
47187
|
+
LAND_TINT_LIGHT = 12;
|
|
47188
|
+
LAND_TINT_DARK = 24;
|
|
46986
47189
|
TAG_TINT_LIGHT = 60;
|
|
46987
47190
|
TAG_TINT_DARK = 68;
|
|
46988
|
-
|
|
47191
|
+
WATER_TINT_LIGHT = 13;
|
|
47192
|
+
WATER_TINT_DARK = 14;
|
|
46989
47193
|
RIVER_WIDTH = 1.3;
|
|
47194
|
+
RELIEF_MIN_AREA = 12;
|
|
47195
|
+
RELIEF_MIN_DIM = 2;
|
|
47196
|
+
RELIEF_HATCH_SPACING = 3;
|
|
47197
|
+
RELIEF_HATCH_WIDTH = 0.25;
|
|
47198
|
+
RELIEF_HATCH_STRENGTH = 32;
|
|
46990
47199
|
FOREIGN_TINT_LIGHT = 30;
|
|
46991
47200
|
FOREIGN_TINT_DARK = 62;
|
|
47201
|
+
MUTED_FOREIGN_LIGHT = 28;
|
|
47202
|
+
MUTED_FOREIGN_DARK = 16;
|
|
46992
47203
|
COLO_R = 9;
|
|
46993
47204
|
GOLDEN_ANGLE = 2.399963229728653;
|
|
46994
47205
|
FAN_STEP = 16;
|
|
@@ -47042,7 +47253,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47042
47253
|
const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
|
|
47043
47254
|
if (r.layer !== "base") {
|
|
47044
47255
|
p.classed("dgmo-map-region", true).attr("data-region", r.id);
|
|
47045
|
-
if (r.
|
|
47256
|
+
if (r.value !== void 0) p.attr("data-value", r.value);
|
|
47046
47257
|
if (r.tags) {
|
|
47047
47258
|
for (const [group, value] of Object.entries(r.tags)) {
|
|
47048
47259
|
p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
@@ -47060,6 +47271,20 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47060
47271
|
}
|
|
47061
47272
|
};
|
|
47062
47273
|
for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
|
|
47274
|
+
if (layout.relief.length && layout.reliefHatch) {
|
|
47275
|
+
const h = layout.reliefHatch;
|
|
47276
|
+
const rangeClipId = "dgmo-relief-clip";
|
|
47277
|
+
const landClipId = "dgmo-relief-land";
|
|
47278
|
+
const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
|
|
47279
|
+
for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
|
|
47280
|
+
const landClip = defs.append("clipPath").attr("id", landClipId);
|
|
47281
|
+
for (const r of layout.regions)
|
|
47282
|
+
if (r.id !== "lake") landClip.append("path").attr("d", r.d);
|
|
47283
|
+
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");
|
|
47284
|
+
for (let y = h.spacing; y < height; y += h.spacing) {
|
|
47285
|
+
gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
|
|
47286
|
+
}
|
|
47287
|
+
}
|
|
47063
47288
|
if (layout.rivers.length) {
|
|
47064
47289
|
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none");
|
|
47065
47290
|
for (const r of layout.rivers) {
|
|
@@ -47103,6 +47328,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47103
47328
|
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);
|
|
47104
47329
|
}
|
|
47105
47330
|
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);
|
|
47331
|
+
if (poi.tags) {
|
|
47332
|
+
for (const [group, value] of Object.entries(poi.tags)) {
|
|
47333
|
+
c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
47334
|
+
}
|
|
47335
|
+
}
|
|
47106
47336
|
if (onClickItem) {
|
|
47107
47337
|
c.style("cursor", "pointer").on(
|
|
47108
47338
|
"click",
|
|
@@ -47152,7 +47382,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47152
47382
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
47153
47383
|
const ramp = layout.legend.ramp;
|
|
47154
47384
|
const scoreGroup = ramp ? {
|
|
47155
|
-
name: ramp.metric?.trim() || "
|
|
47385
|
+
name: ramp.metric?.trim() || "Value",
|
|
47156
47386
|
entries: [],
|
|
47157
47387
|
gradient: {
|
|
47158
47388
|
min: ramp.min,
|
|
@@ -47179,7 +47409,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47179
47409
|
}
|
|
47180
47410
|
}
|
|
47181
47411
|
if (layout.title) {
|
|
47182
|
-
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);
|
|
47412
|
+
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);
|
|
47183
47413
|
}
|
|
47184
47414
|
if (layout.subtitle) {
|
|
47185
47415
|
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);
|
|
@@ -47212,6 +47442,121 @@ var init_renderer16 = __esm({
|
|
|
47212
47442
|
}
|
|
47213
47443
|
});
|
|
47214
47444
|
|
|
47445
|
+
// src/map/load-data.ts
|
|
47446
|
+
var load_data_exports = {};
|
|
47447
|
+
__export(load_data_exports, {
|
|
47448
|
+
loadMapData: () => loadMapData
|
|
47449
|
+
});
|
|
47450
|
+
async function loadNodeBuiltins() {
|
|
47451
|
+
const [{ readFile }, { fileURLToPath }, { dirname, resolve }] = await Promise.all([
|
|
47452
|
+
import("fs/promises"),
|
|
47453
|
+
import("url"),
|
|
47454
|
+
import("path")
|
|
47455
|
+
]);
|
|
47456
|
+
return { readFile, fileURLToPath, dirname, resolve };
|
|
47457
|
+
}
|
|
47458
|
+
async function readJson(nb, dir, name) {
|
|
47459
|
+
return JSON.parse(await nb.readFile(nb.resolve(dir, name), "utf8"));
|
|
47460
|
+
}
|
|
47461
|
+
async function firstExistingDir(nb, baseDir) {
|
|
47462
|
+
for (const rel of CANDIDATE_DIRS) {
|
|
47463
|
+
const dir = nb.resolve(baseDir, rel);
|
|
47464
|
+
try {
|
|
47465
|
+
await nb.readFile(nb.resolve(dir, FILES.gazetteer), "utf8");
|
|
47466
|
+
return dir;
|
|
47467
|
+
} catch {
|
|
47468
|
+
}
|
|
47469
|
+
}
|
|
47470
|
+
throw new Error(
|
|
47471
|
+
`map data assets not found near ${baseDir} (looked in ${CANDIDATE_DIRS.join(", ")}). Run \`pnpm build:map-data\` and \`pnpm build\`.`
|
|
47472
|
+
);
|
|
47473
|
+
}
|
|
47474
|
+
function validate(data) {
|
|
47475
|
+
const topoOk = (t) => !!t && t.type === "Topology" && !!t.objects;
|
|
47476
|
+
if (!topoOk(data.worldCoarse) || !topoOk(data.worldDetail) || !topoOk(data.usStates) || !data.gazetteer || !Array.isArray(data.gazetteer.cities) || !data.gazetteer.byName) {
|
|
47477
|
+
throw new Error("map data assets are malformed (failed shape validation)");
|
|
47478
|
+
}
|
|
47479
|
+
return data;
|
|
47480
|
+
}
|
|
47481
|
+
function moduleBaseDir(nb) {
|
|
47482
|
+
try {
|
|
47483
|
+
const url = import_meta.url;
|
|
47484
|
+
if (url) return nb.dirname(nb.fileURLToPath(url));
|
|
47485
|
+
} catch {
|
|
47486
|
+
}
|
|
47487
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
47488
|
+
return process.cwd();
|
|
47489
|
+
}
|
|
47490
|
+
function loadMapData() {
|
|
47491
|
+
cache ??= (async () => {
|
|
47492
|
+
const nb = await loadNodeBuiltins();
|
|
47493
|
+
const dir = await firstExistingDir(nb, moduleBaseDir(nb));
|
|
47494
|
+
const [
|
|
47495
|
+
worldCoarse,
|
|
47496
|
+
worldDetail,
|
|
47497
|
+
usStates,
|
|
47498
|
+
lakes,
|
|
47499
|
+
rivers,
|
|
47500
|
+
mountainRanges,
|
|
47501
|
+
naLand,
|
|
47502
|
+
naLakes,
|
|
47503
|
+
gazetteer
|
|
47504
|
+
] = await Promise.all([
|
|
47505
|
+
readJson(nb, dir, FILES.worldCoarse),
|
|
47506
|
+
readJson(nb, dir, FILES.worldDetail),
|
|
47507
|
+
readJson(nb, dir, FILES.usStates),
|
|
47508
|
+
// Lakes/rivers/mountain/NA assets are optional — older bundles may predate them.
|
|
47509
|
+
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
47510
|
+
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
47511
|
+
readJson(nb, dir, FILES.mountainRanges).catch(
|
|
47512
|
+
() => void 0
|
|
47513
|
+
),
|
|
47514
|
+
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
47515
|
+
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
47516
|
+
readJson(nb, dir, FILES.gazetteer)
|
|
47517
|
+
]);
|
|
47518
|
+
return validate({
|
|
47519
|
+
worldCoarse,
|
|
47520
|
+
worldDetail,
|
|
47521
|
+
usStates,
|
|
47522
|
+
gazetteer,
|
|
47523
|
+
...lakes && { lakes },
|
|
47524
|
+
...rivers && { rivers },
|
|
47525
|
+
...mountainRanges && { mountainRanges },
|
|
47526
|
+
...naLand && { naLand },
|
|
47527
|
+
...naLakes && { naLakes }
|
|
47528
|
+
});
|
|
47529
|
+
})().catch((e) => {
|
|
47530
|
+
cache = void 0;
|
|
47531
|
+
throw e;
|
|
47532
|
+
});
|
|
47533
|
+
return cache;
|
|
47534
|
+
}
|
|
47535
|
+
var import_meta, FILES, CANDIDATE_DIRS, cache;
|
|
47536
|
+
var init_load_data = __esm({
|
|
47537
|
+
"src/map/load-data.ts"() {
|
|
47538
|
+
"use strict";
|
|
47539
|
+
import_meta = {};
|
|
47540
|
+
FILES = {
|
|
47541
|
+
worldCoarse: "world-coarse.json",
|
|
47542
|
+
worldDetail: "world-detail.json",
|
|
47543
|
+
usStates: "us-states.json",
|
|
47544
|
+
lakes: "lakes.json",
|
|
47545
|
+
rivers: "rivers.json",
|
|
47546
|
+
mountainRanges: "mountain-ranges.json",
|
|
47547
|
+
naLand: "na-land.json",
|
|
47548
|
+
naLakes: "na-lakes.json",
|
|
47549
|
+
gazetteer: "gazetteer.json"
|
|
47550
|
+
};
|
|
47551
|
+
CANDIDATE_DIRS = [
|
|
47552
|
+
"./data",
|
|
47553
|
+
"./map-data",
|
|
47554
|
+
"../map-data",
|
|
47555
|
+
"../src/map/data"
|
|
47556
|
+
];
|
|
47557
|
+
}
|
|
47558
|
+
});
|
|
47559
|
+
|
|
47215
47560
|
// src/pyramid/renderer.ts
|
|
47216
47561
|
var renderer_exports17 = {};
|
|
47217
47562
|
__export(renderer_exports17, {
|
|
@@ -55335,15 +55680,17 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
55335
55680
|
if (detectedType === "map") {
|
|
55336
55681
|
const { parseMap: parseMap2 } = await Promise.resolve().then(() => (init_parser12(), parser_exports11));
|
|
55337
55682
|
const { resolveMap: resolveMap2 } = await Promise.resolve().then(() => (init_resolver2(), resolver_exports));
|
|
55338
|
-
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55339
55683
|
const { renderMapForExport: renderMapForExport2 } = await Promise.resolve().then(() => (init_renderer16(), renderer_exports16));
|
|
55340
55684
|
const effectivePalette2 = await resolveExportPalette(theme, palette);
|
|
55341
55685
|
const mapParsed = parseMap2(content);
|
|
55342
|
-
let mapData;
|
|
55343
|
-
|
|
55344
|
-
|
|
55345
|
-
|
|
55346
|
-
|
|
55686
|
+
let mapData = options?.mapData;
|
|
55687
|
+
if (!mapData) {
|
|
55688
|
+
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55689
|
+
try {
|
|
55690
|
+
mapData = await loadMapData2();
|
|
55691
|
+
} catch {
|
|
55692
|
+
return "";
|
|
55693
|
+
}
|
|
55347
55694
|
}
|
|
55348
55695
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
55349
55696
|
const container2 = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|
|
@@ -56396,13 +56743,17 @@ var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
56396
56743
|
// Map (§24B) directives
|
|
56397
56744
|
"region",
|
|
56398
56745
|
"projection",
|
|
56399
|
-
"metric",
|
|
56400
|
-
"
|
|
56746
|
+
"region-metric",
|
|
56747
|
+
"poi-metric",
|
|
56748
|
+
"flow-metric",
|
|
56401
56749
|
"region-labels",
|
|
56402
56750
|
"poi-labels",
|
|
56403
56751
|
"default-country",
|
|
56404
56752
|
"default-state",
|
|
56405
56753
|
"no-legend",
|
|
56754
|
+
"no-insets",
|
|
56755
|
+
"muted",
|
|
56756
|
+
"natural",
|
|
56406
56757
|
"subtitle",
|
|
56407
56758
|
"caption",
|
|
56408
56759
|
"poi",
|
|
@@ -57070,7 +57421,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
57070
57421
|
|
|
57071
57422
|
// src/auto/index.ts
|
|
57072
57423
|
init_safe_href();
|
|
57073
|
-
var VERSION = "0.
|
|
57424
|
+
var VERSION = "0.21.1";
|
|
57074
57425
|
var DEFAULTS = {
|
|
57075
57426
|
theme: "auto",
|
|
57076
57427
|
palette: "nord",
|