@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/index.cjs
CHANGED
|
@@ -835,13 +835,9 @@ var init_reserved_key_registry = __esm({
|
|
|
835
835
|
"icon"
|
|
836
836
|
]);
|
|
837
837
|
MAP_REGISTRY = staticRegistry([
|
|
838
|
-
"
|
|
838
|
+
"value",
|
|
839
839
|
"label",
|
|
840
|
-
"
|
|
841
|
-
"description",
|
|
842
|
-
"weight",
|
|
843
|
-
"style",
|
|
844
|
-
"date"
|
|
840
|
+
"style"
|
|
845
841
|
]);
|
|
846
842
|
ORG_REGISTRY = staticRegistry([
|
|
847
843
|
"color",
|
|
@@ -15854,7 +15850,8 @@ function parseMap(content) {
|
|
|
15854
15850
|
continue;
|
|
15855
15851
|
}
|
|
15856
15852
|
if (open.route && indent > open.route.indent) {
|
|
15857
|
-
open.route.route.
|
|
15853
|
+
const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
|
|
15854
|
+
open.route.route.legs.push(leg);
|
|
15858
15855
|
continue;
|
|
15859
15856
|
}
|
|
15860
15857
|
if (open.poi && indent > open.poi.indent) {
|
|
@@ -15885,6 +15882,10 @@ function parseMap(content) {
|
|
|
15885
15882
|
handleTag(trimmed, lineNumber);
|
|
15886
15883
|
continue;
|
|
15887
15884
|
}
|
|
15885
|
+
if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
|
|
15886
|
+
handleDirective(firstWord, "", lineNumber);
|
|
15887
|
+
continue;
|
|
15888
|
+
}
|
|
15888
15889
|
if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
|
|
15889
15890
|
handleDirective(
|
|
15890
15891
|
firstWord,
|
|
@@ -15949,13 +15950,20 @@ function parseMap(content) {
|
|
|
15949
15950
|
);
|
|
15950
15951
|
d.projection = value;
|
|
15951
15952
|
break;
|
|
15952
|
-
case "metric":
|
|
15953
|
-
dup(d.
|
|
15954
|
-
|
|
15953
|
+
case "region-metric": {
|
|
15954
|
+
dup(d.regionMetric);
|
|
15955
|
+
const { label: rmLabel, colorName: rmColor } = peelTrailingColorName(value);
|
|
15956
|
+
d.regionMetric = rmLabel;
|
|
15957
|
+
if (rmColor) d.regionMetricColor = rmColor;
|
|
15958
|
+
break;
|
|
15959
|
+
}
|
|
15960
|
+
case "poi-metric":
|
|
15961
|
+
dup(d.poiMetric);
|
|
15962
|
+
d.poiMetric = value;
|
|
15955
15963
|
break;
|
|
15956
|
-
case "
|
|
15957
|
-
dup(d.
|
|
15958
|
-
d.
|
|
15964
|
+
case "flow-metric":
|
|
15965
|
+
dup(d.flowMetric);
|
|
15966
|
+
d.flowMetric = value;
|
|
15959
15967
|
break;
|
|
15960
15968
|
case "scale":
|
|
15961
15969
|
dup(d.scale);
|
|
@@ -15997,6 +16005,21 @@ function parseMap(content) {
|
|
|
15997
16005
|
case "no-legend":
|
|
15998
16006
|
d.noLegend = true;
|
|
15999
16007
|
break;
|
|
16008
|
+
case "no-insets":
|
|
16009
|
+
d.noInsets = true;
|
|
16010
|
+
break;
|
|
16011
|
+
case "relief":
|
|
16012
|
+
d.relief = true;
|
|
16013
|
+
break;
|
|
16014
|
+
case "muted":
|
|
16015
|
+
case "natural":
|
|
16016
|
+
if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
|
|
16017
|
+
pushWarning(
|
|
16018
|
+
line12,
|
|
16019
|
+
`Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
|
|
16020
|
+
);
|
|
16021
|
+
d.basemapStyle = key;
|
|
16022
|
+
break;
|
|
16000
16023
|
case "subtitle":
|
|
16001
16024
|
dup(d.subtitle);
|
|
16002
16025
|
d.subtitle = value;
|
|
@@ -16074,14 +16097,14 @@ function parseMap(content) {
|
|
|
16074
16097
|
line12
|
|
16075
16098
|
);
|
|
16076
16099
|
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16077
|
-
let
|
|
16078
|
-
const
|
|
16079
|
-
if (
|
|
16080
|
-
delete meta["
|
|
16081
|
-
|
|
16082
|
-
if (!Number.isFinite(
|
|
16083
|
-
pushError(line12, `
|
|
16084
|
-
|
|
16100
|
+
let valueNum;
|
|
16101
|
+
const value = meta["value"];
|
|
16102
|
+
if (value !== void 0) {
|
|
16103
|
+
delete meta["value"];
|
|
16104
|
+
valueNum = Number(value);
|
|
16105
|
+
if (!Number.isFinite(valueNum)) {
|
|
16106
|
+
pushError(line12, `value must be a number (got "${value}").`);
|
|
16107
|
+
valueNum = void 0;
|
|
16085
16108
|
}
|
|
16086
16109
|
}
|
|
16087
16110
|
let regionName = split.name;
|
|
@@ -16099,7 +16122,8 @@ function parseMap(content) {
|
|
|
16099
16122
|
lineNumber: line12
|
|
16100
16123
|
};
|
|
16101
16124
|
if (regionScope !== void 0) region.scope = regionScope;
|
|
16102
|
-
if (
|
|
16125
|
+
if (valueNum !== void 0) region.value = valueNum;
|
|
16126
|
+
if (split.color) region.color = split.color;
|
|
16103
16127
|
regions.push(region);
|
|
16104
16128
|
}
|
|
16105
16129
|
function handlePoi(rest, line12, indent) {
|
|
@@ -16124,28 +16148,81 @@ function parseMap(content) {
|
|
|
16124
16148
|
const poi = { pos, tags, meta, lineNumber: line12 };
|
|
16125
16149
|
if (split.alias) poi.alias = split.alias;
|
|
16126
16150
|
if (label !== void 0) poi.label = label;
|
|
16151
|
+
if (split.color) poi.color = split.color;
|
|
16127
16152
|
pois.push(poi);
|
|
16128
16153
|
open.poi = { poi, indent };
|
|
16129
16154
|
}
|
|
16130
16155
|
function handleRoute(rest, line12, indent) {
|
|
16131
|
-
const
|
|
16132
|
-
|
|
16156
|
+
const split = rest ? splitNameAndMeta(
|
|
16157
|
+
rest,
|
|
16158
|
+
registry(),
|
|
16159
|
+
aliasMap,
|
|
16160
|
+
void 0,
|
|
16161
|
+
diagnostics,
|
|
16162
|
+
line12
|
|
16163
|
+
) : { name: "", meta: {}, alias: void 0 };
|
|
16164
|
+
const pos = parsePos(split.name, line12);
|
|
16165
|
+
if (!pos || pos.kind === "name" && !pos.name) {
|
|
16166
|
+
pushError(
|
|
16167
|
+
line12,
|
|
16168
|
+
"route requires an origin: `route <origin> [style: arc]`."
|
|
16169
|
+
);
|
|
16170
|
+
return;
|
|
16171
|
+
}
|
|
16172
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16173
|
+
const originLabel = meta["label"];
|
|
16174
|
+
const originValue = meta["value"];
|
|
16175
|
+
const style = meta["style"] === "arc" ? "arc" : "straight";
|
|
16176
|
+
const route = {
|
|
16177
|
+
origin: pos,
|
|
16178
|
+
...split.alias !== void 0 && { originAlias: split.alias },
|
|
16179
|
+
...originLabel !== void 0 && { originLabel },
|
|
16180
|
+
...originValue !== void 0 && { originValue },
|
|
16181
|
+
originTags: tags,
|
|
16182
|
+
style,
|
|
16183
|
+
legs: [],
|
|
16184
|
+
lineNumber: line12
|
|
16185
|
+
};
|
|
16133
16186
|
routes.push(route);
|
|
16134
16187
|
open.route = { route, indent };
|
|
16135
16188
|
}
|
|
16136
|
-
function
|
|
16137
|
-
|
|
16138
|
-
|
|
16189
|
+
function parseLeg(trimmed, line12, headerStyle) {
|
|
16190
|
+
let arrowStyle = "straight";
|
|
16191
|
+
let label;
|
|
16192
|
+
let rest = trimmed;
|
|
16193
|
+
const m = trimmed.match(LEG_ARROW_RE);
|
|
16194
|
+
if (m) {
|
|
16195
|
+
const arr = classifyArrow(m[1], line12);
|
|
16196
|
+
arrowStyle = arr.style;
|
|
16197
|
+
label = arr.label;
|
|
16198
|
+
rest = m[2];
|
|
16199
|
+
}
|
|
16200
|
+
const split = splitNameAndMeta(
|
|
16201
|
+
rest,
|
|
16202
|
+
registry(),
|
|
16203
|
+
aliasMap,
|
|
16204
|
+
void 0,
|
|
16205
|
+
diagnostics,
|
|
16206
|
+
line12
|
|
16207
|
+
);
|
|
16208
|
+
const pos = parsePos(split.name, line12) ?? {
|
|
16139
16209
|
kind: "name",
|
|
16140
16210
|
name: split.name
|
|
16141
16211
|
};
|
|
16142
|
-
const
|
|
16143
|
-
|
|
16144
|
-
|
|
16212
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16213
|
+
const value = meta["value"];
|
|
16214
|
+
const destLabel = meta["label"];
|
|
16215
|
+
const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
|
|
16216
|
+
return {
|
|
16217
|
+
...label !== void 0 && { label },
|
|
16218
|
+
style,
|
|
16219
|
+
...value !== void 0 && { value },
|
|
16220
|
+
dest: pos,
|
|
16221
|
+
...split.alias !== void 0 && { destAlias: split.alias },
|
|
16222
|
+
...destLabel !== void 0 && { destLabel },
|
|
16223
|
+
destTags: tags,
|
|
16145
16224
|
lineNumber: line12
|
|
16146
16225
|
};
|
|
16147
|
-
if (split.alias) stop.alias = split.alias;
|
|
16148
|
-
return stop;
|
|
16149
16226
|
}
|
|
16150
16227
|
function handleEdges(trimmed, line12) {
|
|
16151
16228
|
const parts = trimmed.split(ARROW_SPLIT);
|
|
@@ -16247,7 +16324,7 @@ function partitionMeta(meta, tagGroupNames) {
|
|
|
16247
16324
|
function poiName(pos) {
|
|
16248
16325
|
return pos.kind === "name" ? pos.name : void 0;
|
|
16249
16326
|
}
|
|
16250
|
-
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
|
|
16327
|
+
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
|
|
16251
16328
|
var init_parser12 = __esm({
|
|
16252
16329
|
"src/map/parser.ts"() {
|
|
16253
16330
|
"use strict";
|
|
@@ -16261,12 +16338,14 @@ var init_parser12 = __esm({
|
|
|
16261
16338
|
SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
|
|
16262
16339
|
ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
|
|
16263
16340
|
HUB_RE = /^(->|~>)\s+(.+)$/;
|
|
16341
|
+
LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
|
|
16264
16342
|
AT_RE = /(^|[\s,])at\s*:/i;
|
|
16265
16343
|
DIRECTIVE_SET = /* @__PURE__ */ new Set([
|
|
16266
16344
|
"region",
|
|
16267
16345
|
"projection",
|
|
16268
|
-
"metric",
|
|
16269
|
-
"
|
|
16346
|
+
"region-metric",
|
|
16347
|
+
"poi-metric",
|
|
16348
|
+
"flow-metric",
|
|
16270
16349
|
"scale",
|
|
16271
16350
|
"region-labels",
|
|
16272
16351
|
"poi-labels",
|
|
@@ -16274,6 +16353,8 @@ var init_parser12 = __esm({
|
|
|
16274
16353
|
"default-state",
|
|
16275
16354
|
"active-tag",
|
|
16276
16355
|
"no-legend",
|
|
16356
|
+
"no-insets",
|
|
16357
|
+
"relief",
|
|
16277
16358
|
"subtitle",
|
|
16278
16359
|
"caption"
|
|
16279
16360
|
]);
|
|
@@ -45498,6 +45579,74 @@ function featureBbox(topo, geomId) {
|
|
|
45498
45579
|
[b[1][0], b[1][1]]
|
|
45499
45580
|
];
|
|
45500
45581
|
}
|
|
45582
|
+
function explodePolygons(gj) {
|
|
45583
|
+
const g = gj.geometry ?? gj;
|
|
45584
|
+
const t = g.type;
|
|
45585
|
+
const coords = g.coordinates;
|
|
45586
|
+
if (t === "Polygon") {
|
|
45587
|
+
return [
|
|
45588
|
+
{ type: "Feature", geometry: { type: "Polygon", coordinates: coords } }
|
|
45589
|
+
];
|
|
45590
|
+
}
|
|
45591
|
+
if (t === "MultiPolygon") {
|
|
45592
|
+
return coords.map((rings) => ({
|
|
45593
|
+
type: "Feature",
|
|
45594
|
+
geometry: { type: "Polygon", coordinates: rings }
|
|
45595
|
+
}));
|
|
45596
|
+
}
|
|
45597
|
+
return [];
|
|
45598
|
+
}
|
|
45599
|
+
function bboxGap(a, b) {
|
|
45600
|
+
const lonGap = Math.max(0, a[0][0] - b[1][0], b[0][0] - a[1][0]);
|
|
45601
|
+
const latGap = Math.max(0, a[0][1] - b[1][1], b[0][1] - a[1][1]);
|
|
45602
|
+
return Math.max(lonGap, latGap);
|
|
45603
|
+
}
|
|
45604
|
+
function featureBboxPrimary(topo, geomId) {
|
|
45605
|
+
const geom = geomObject(topo).geometries.find((g) => g.id === geomId);
|
|
45606
|
+
if (!geom) return null;
|
|
45607
|
+
const gj = (0, import_topojson_client.feature)(topo, geom);
|
|
45608
|
+
const parts = explodePolygons(gj);
|
|
45609
|
+
if (parts.length <= 1) return featureBbox(topo, geomId);
|
|
45610
|
+
const polys = parts.map((p) => {
|
|
45611
|
+
const b = (0, import_d3_geo.geoBounds)(p);
|
|
45612
|
+
if (!b || !Number.isFinite(b[0][0])) return null;
|
|
45613
|
+
const wraps = b[1][0] < b[0][0];
|
|
45614
|
+
const bbox = [
|
|
45615
|
+
[b[0][0], b[0][1]],
|
|
45616
|
+
[b[1][0], b[1][1]]
|
|
45617
|
+
];
|
|
45618
|
+
return { bbox, area: (0, import_d3_geo.geoArea)(p), wraps };
|
|
45619
|
+
}).filter(
|
|
45620
|
+
(p) => p !== null
|
|
45621
|
+
);
|
|
45622
|
+
if (polys.length <= 1 || polys.some((p) => p.wraps))
|
|
45623
|
+
return featureBbox(topo, geomId);
|
|
45624
|
+
const maxArea = Math.max(...polys.map((p) => p.area));
|
|
45625
|
+
const anchor = polys.find((p) => p.area === maxArea);
|
|
45626
|
+
const cluster = [
|
|
45627
|
+
[anchor.bbox[0][0], anchor.bbox[0][1]],
|
|
45628
|
+
[anchor.bbox[1][0], anchor.bbox[1][1]]
|
|
45629
|
+
];
|
|
45630
|
+
const remaining = polys.filter((p) => p !== anchor);
|
|
45631
|
+
let added = true;
|
|
45632
|
+
while (added) {
|
|
45633
|
+
added = false;
|
|
45634
|
+
for (let i = remaining.length - 1; i >= 0; i--) {
|
|
45635
|
+
const p = remaining[i];
|
|
45636
|
+
const near = bboxGap(p.bbox, cluster) <= DETACH_GAP_DEG;
|
|
45637
|
+
const large = p.area >= DETACH_AREA_FRAC * maxArea;
|
|
45638
|
+
if (near || large) {
|
|
45639
|
+
cluster[0][0] = Math.min(cluster[0][0], p.bbox[0][0]);
|
|
45640
|
+
cluster[0][1] = Math.min(cluster[0][1], p.bbox[0][1]);
|
|
45641
|
+
cluster[1][0] = Math.max(cluster[1][0], p.bbox[1][0]);
|
|
45642
|
+
cluster[1][1] = Math.max(cluster[1][1], p.bbox[1][1]);
|
|
45643
|
+
remaining.splice(i, 1);
|
|
45644
|
+
added = true;
|
|
45645
|
+
}
|
|
45646
|
+
}
|
|
45647
|
+
}
|
|
45648
|
+
return cluster;
|
|
45649
|
+
}
|
|
45501
45650
|
function unionExtent(boxes, points) {
|
|
45502
45651
|
const lats = [];
|
|
45503
45652
|
const lons = [];
|
|
@@ -45536,13 +45685,15 @@ function unionLongitudes(lons) {
|
|
|
45536
45685
|
}
|
|
45537
45686
|
return { west: pts[gapIdx], east: pts[gapIdx - 1] + 360 };
|
|
45538
45687
|
}
|
|
45539
|
-
var import_topojson_client, import_d3_geo, fold;
|
|
45688
|
+
var import_topojson_client, import_d3_geo, fold, DETACH_GAP_DEG, DETACH_AREA_FRAC;
|
|
45540
45689
|
var init_geo = __esm({
|
|
45541
45690
|
"src/map/geo.ts"() {
|
|
45542
45691
|
"use strict";
|
|
45543
45692
|
import_topojson_client = require("topojson-client");
|
|
45544
45693
|
import_d3_geo = require("d3-geo");
|
|
45545
45694
|
fold = (s) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim();
|
|
45695
|
+
DETACH_GAP_DEG = 10;
|
|
45696
|
+
DETACH_AREA_FRAC = 0.25;
|
|
45546
45697
|
}
|
|
45547
45698
|
});
|
|
45548
45699
|
|
|
@@ -45551,6 +45702,11 @@ var resolver_exports = {};
|
|
|
45551
45702
|
__export(resolver_exports, {
|
|
45552
45703
|
resolveMap: () => resolveMap
|
|
45553
45704
|
});
|
|
45705
|
+
function usStateFromBareScope(scope) {
|
|
45706
|
+
if (!scope) return null;
|
|
45707
|
+
const up = scope.toUpperCase();
|
|
45708
|
+
return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
|
|
45709
|
+
}
|
|
45554
45710
|
function looksUS(lat, lon) {
|
|
45555
45711
|
if (lat < 15 || lat > 72) return false;
|
|
45556
45712
|
return lon >= -180 && lon <= -64 || lon >= 172;
|
|
@@ -45600,9 +45756,9 @@ function resolveMap(parsed, data) {
|
|
|
45600
45756
|
const f = fold(r.name);
|
|
45601
45757
|
return usStateIndex.has(f) && !countryIndex.has(f);
|
|
45602
45758
|
}) || parsed.regions.some(
|
|
45603
|
-
(r) => r.scope === "US" || r.scope?.startsWith("US-")
|
|
45759
|
+
(r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
|
|
45604
45760
|
) || parsed.pois.some(
|
|
45605
|
-
(p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
|
|
45761
|
+
(p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
|
|
45606
45762
|
);
|
|
45607
45763
|
const regions = [];
|
|
45608
45764
|
const seenRegion = /* @__PURE__ */ new Map();
|
|
@@ -45641,12 +45797,12 @@ function resolveMap(parsed, data) {
|
|
|
45641
45797
|
chosen = { ...inState, layer: "us-state" };
|
|
45642
45798
|
} else {
|
|
45643
45799
|
chosen = { ...inCountry, layer: "country" };
|
|
45800
|
+
warn(
|
|
45801
|
+
r.lineNumber,
|
|
45802
|
+
`"${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}").`,
|
|
45803
|
+
"W_MAP_REGION_AMBIGUOUS"
|
|
45804
|
+
);
|
|
45644
45805
|
}
|
|
45645
|
-
warn(
|
|
45646
|
-
r.lineNumber,
|
|
45647
|
-
`"${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}").`,
|
|
45648
|
-
"W_MAP_REGION_AMBIGUOUS"
|
|
45649
|
-
);
|
|
45650
45806
|
} else if (inState) {
|
|
45651
45807
|
chosen = { ...inState, layer: "us-state" };
|
|
45652
45808
|
} else if (inCountry) {
|
|
@@ -45669,7 +45825,8 @@ function resolveMap(parsed, data) {
|
|
|
45669
45825
|
iso: chosen.id,
|
|
45670
45826
|
name: chosen.name,
|
|
45671
45827
|
layer: chosen.layer,
|
|
45672
|
-
...r.
|
|
45828
|
+
...r.value !== void 0 && { value: r.value },
|
|
45829
|
+
...r.color !== void 0 && { color: r.color },
|
|
45673
45830
|
tags: r.tags,
|
|
45674
45831
|
meta: r.meta,
|
|
45675
45832
|
lineNumber: r.lineNumber
|
|
@@ -45727,9 +45884,10 @@ function resolveMap(parsed, data) {
|
|
|
45727
45884
|
let cands = idxs.map((i) => data.gazetteer.cities[i]);
|
|
45728
45885
|
const scopeUse = scope ?? scopeHint;
|
|
45729
45886
|
if (scopeUse) {
|
|
45730
|
-
const
|
|
45887
|
+
const bareState = usStateFromBareScope(scopeUse);
|
|
45888
|
+
const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
|
|
45731
45889
|
const filtered = cands.filter(
|
|
45732
|
-
(c2) =>
|
|
45890
|
+
(c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
|
|
45733
45891
|
);
|
|
45734
45892
|
if (filtered.length) cands = filtered;
|
|
45735
45893
|
else if (scope) {
|
|
@@ -45810,6 +45968,7 @@ function resolveMap(parsed, data) {
|
|
|
45810
45968
|
lat,
|
|
45811
45969
|
lon,
|
|
45812
45970
|
...p.label !== void 0 && { label: p.label },
|
|
45971
|
+
...p.color !== void 0 && { color: p.color },
|
|
45813
45972
|
tags: p.tags,
|
|
45814
45973
|
meta: p.meta,
|
|
45815
45974
|
lineNumber: p.lineNumber
|
|
@@ -45858,33 +46017,89 @@ function resolveMap(parsed, data) {
|
|
|
45858
46017
|
lineNumber: e.lineNumber
|
|
45859
46018
|
});
|
|
45860
46019
|
}
|
|
45861
|
-
const
|
|
45862
|
-
|
|
45863
|
-
|
|
45864
|
-
|
|
45865
|
-
|
|
45866
|
-
if (
|
|
45867
|
-
|
|
45868
|
-
|
|
45869
|
-
|
|
45870
|
-
const poi = {
|
|
46020
|
+
const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
|
|
46021
|
+
const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
|
|
46022
|
+
if (pos.kind === "coords") {
|
|
46023
|
+
const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
|
|
46024
|
+
if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
|
|
46025
|
+
if (!registry.has(id)) {
|
|
46026
|
+
registerPoi(
|
|
46027
|
+
id,
|
|
46028
|
+
{
|
|
45871
46029
|
id,
|
|
45872
|
-
...
|
|
45873
|
-
lat:
|
|
45874
|
-
lon:
|
|
45875
|
-
|
|
45876
|
-
|
|
45877
|
-
|
|
45878
|
-
|
|
45879
|
-
}
|
|
45880
|
-
|
|
45881
|
-
|
|
45882
|
-
} else {
|
|
45883
|
-
id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
|
|
46030
|
+
...alias !== void 0 && { name: alias },
|
|
46031
|
+
lat: pos.lat,
|
|
46032
|
+
lon: pos.lon,
|
|
46033
|
+
...label !== void 0 && { label },
|
|
46034
|
+
tags,
|
|
46035
|
+
meta,
|
|
46036
|
+
lineNumber: line12
|
|
46037
|
+
},
|
|
46038
|
+
line12
|
|
46039
|
+
);
|
|
45884
46040
|
}
|
|
45885
|
-
|
|
46041
|
+
return id;
|
|
45886
46042
|
}
|
|
45887
|
-
|
|
46043
|
+
const f = fold(pos.name);
|
|
46044
|
+
if (registry.has(f)) return f;
|
|
46045
|
+
const aliased = declaredByName.get(f);
|
|
46046
|
+
if (aliased) return aliased;
|
|
46047
|
+
const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
|
|
46048
|
+
if (got.kind !== "ok") return null;
|
|
46049
|
+
noteCountry(got.iso);
|
|
46050
|
+
registerPoi(
|
|
46051
|
+
f,
|
|
46052
|
+
{
|
|
46053
|
+
id: f,
|
|
46054
|
+
name: pos.name,
|
|
46055
|
+
lat: got.lat,
|
|
46056
|
+
lon: got.lon,
|
|
46057
|
+
...label !== void 0 && { label },
|
|
46058
|
+
tags,
|
|
46059
|
+
meta,
|
|
46060
|
+
lineNumber: line12
|
|
46061
|
+
},
|
|
46062
|
+
line12
|
|
46063
|
+
);
|
|
46064
|
+
return f;
|
|
46065
|
+
};
|
|
46066
|
+
const routes = [];
|
|
46067
|
+
for (const rt of parsed.routes) {
|
|
46068
|
+
const originId = resolveStop(
|
|
46069
|
+
rt.origin,
|
|
46070
|
+
rt.originAlias,
|
|
46071
|
+
rt.originLabel,
|
|
46072
|
+
rt.originTags,
|
|
46073
|
+
rt.originValue,
|
|
46074
|
+
rt.lineNumber
|
|
46075
|
+
);
|
|
46076
|
+
if (!originId) continue;
|
|
46077
|
+
const stopIds = [originId];
|
|
46078
|
+
const legs = [];
|
|
46079
|
+
let prevId = originId;
|
|
46080
|
+
for (const leg of rt.legs) {
|
|
46081
|
+
const destId = resolveStop(
|
|
46082
|
+
leg.dest,
|
|
46083
|
+
leg.destAlias,
|
|
46084
|
+
leg.destLabel,
|
|
46085
|
+
leg.destTags,
|
|
46086
|
+
void 0,
|
|
46087
|
+
// a leg's `value:` is leg thickness, not the dest's size
|
|
46088
|
+
leg.lineNumber
|
|
46089
|
+
);
|
|
46090
|
+
if (!destId) continue;
|
|
46091
|
+
legs.push({
|
|
46092
|
+
fromId: prevId,
|
|
46093
|
+
toId: destId,
|
|
46094
|
+
...leg.label !== void 0 && { label: leg.label },
|
|
46095
|
+
style: leg.style,
|
|
46096
|
+
...leg.value !== void 0 && { value: leg.value },
|
|
46097
|
+
lineNumber: leg.lineNumber
|
|
46098
|
+
});
|
|
46099
|
+
if (!stopIds.includes(destId)) stopIds.push(destId);
|
|
46100
|
+
prevId = destId;
|
|
46101
|
+
}
|
|
46102
|
+
routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
|
|
45888
46103
|
}
|
|
45889
46104
|
const subdivisions = [];
|
|
45890
46105
|
if (usSubdivisionReferenced || parsed.directives.region === "us-states")
|
|
@@ -45896,7 +46111,7 @@ function resolveMap(parsed, data) {
|
|
|
45896
46111
|
}
|
|
45897
46112
|
for (const r of regions) {
|
|
45898
46113
|
if (r.layer === "country") {
|
|
45899
|
-
const bb =
|
|
46114
|
+
const bb = featureBboxPrimary(data.worldCoarse, r.iso);
|
|
45900
46115
|
if (bb) regionBoxes.push(bb);
|
|
45901
46116
|
}
|
|
45902
46117
|
}
|
|
@@ -45910,6 +46125,7 @@ function resolveMap(parsed, data) {
|
|
|
45910
46125
|
const lonSpan = extent2[1][0] - extent2[0][0];
|
|
45911
46126
|
const latSpan = extent2[1][1] - extent2[0][1];
|
|
45912
46127
|
const span = Math.max(lonSpan, latSpan);
|
|
46128
|
+
const maxAbsLat = Math.max(Math.abs(extent2[0][1]), Math.abs(extent2[1][1]));
|
|
45913
46129
|
const usDominant = (subdivisions.includes("us-states") || regions.some((r) => r.layer === "us-state")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
|
|
45914
46130
|
let projection;
|
|
45915
46131
|
const override = parsed.directives.projection;
|
|
@@ -45917,12 +46133,10 @@ function resolveMap(parsed, data) {
|
|
|
45917
46133
|
projection = override;
|
|
45918
46134
|
} else if (usDominant) {
|
|
45919
46135
|
projection = "albers-usa";
|
|
45920
|
-
} else if (span > WORLD_SPAN) {
|
|
46136
|
+
} else if (span > WORLD_SPAN || maxAbsLat > MERCATOR_MAX_LAT) {
|
|
45921
46137
|
projection = "equirectangular";
|
|
45922
|
-
} else if (span < MERCATOR_MAX_SPAN) {
|
|
45923
|
-
projection = "mercator";
|
|
45924
46138
|
} else {
|
|
45925
|
-
projection = "
|
|
46139
|
+
projection = "mercator";
|
|
45926
46140
|
}
|
|
45927
46141
|
if (lonSpan >= 180) {
|
|
45928
46142
|
extent2 = [
|
|
@@ -45976,14 +46190,14 @@ function firstError(diags) {
|
|
|
45976
46190
|
const e = diags.find((d) => d.severity === "error");
|
|
45977
46191
|
return e ? formatDgmoError(e) : null;
|
|
45978
46192
|
}
|
|
45979
|
-
var WORLD_SPAN,
|
|
46193
|
+
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
|
|
45980
46194
|
var init_resolver2 = __esm({
|
|
45981
46195
|
"src/map/resolver.ts"() {
|
|
45982
46196
|
"use strict";
|
|
45983
46197
|
init_diagnostics();
|
|
45984
46198
|
init_geo();
|
|
45985
46199
|
WORLD_SPAN = 90;
|
|
45986
|
-
|
|
46200
|
+
MERCATOR_MAX_LAT = 80;
|
|
45987
46201
|
PAD_FRACTION = 0.05;
|
|
45988
46202
|
WORLD_LAT_SOUTH = -58;
|
|
45989
46203
|
WORLD_LAT_NORTH = 78;
|
|
@@ -46008,115 +46222,59 @@ var init_resolver2 = __esm({
|
|
|
46008
46222
|
"north macedonia": "macedonia",
|
|
46009
46223
|
"czech republic": "czechia"
|
|
46010
46224
|
};
|
|
46011
|
-
|
|
46012
|
-
|
|
46013
|
-
|
|
46014
|
-
|
|
46015
|
-
|
|
46016
|
-
|
|
46017
|
-
|
|
46018
|
-
|
|
46019
|
-
|
|
46020
|
-
|
|
46021
|
-
|
|
46022
|
-
|
|
46023
|
-
|
|
46024
|
-
|
|
46025
|
-
|
|
46026
|
-
|
|
46027
|
-
|
|
46028
|
-
|
|
46029
|
-
|
|
46030
|
-
|
|
46031
|
-
|
|
46032
|
-
|
|
46033
|
-
|
|
46034
|
-
|
|
46035
|
-
|
|
46036
|
-
|
|
46037
|
-
|
|
46038
|
-
|
|
46039
|
-
|
|
46040
|
-
|
|
46041
|
-
|
|
46042
|
-
|
|
46043
|
-
|
|
46044
|
-
|
|
46045
|
-
|
|
46046
|
-
|
|
46047
|
-
|
|
46048
|
-
|
|
46049
|
-
|
|
46050
|
-
|
|
46051
|
-
|
|
46052
|
-
|
|
46053
|
-
|
|
46054
|
-
|
|
46055
|
-
|
|
46056
|
-
|
|
46057
|
-
|
|
46058
|
-
|
|
46059
|
-
|
|
46060
|
-
|
|
46061
|
-
|
|
46062
|
-
|
|
46063
|
-
const [
|
|
46064
|
-
worldCoarse,
|
|
46065
|
-
worldDetail,
|
|
46066
|
-
usStates,
|
|
46067
|
-
lakes,
|
|
46068
|
-
rivers,
|
|
46069
|
-
naLand,
|
|
46070
|
-
naLakes,
|
|
46071
|
-
gazetteer
|
|
46072
|
-
] = await Promise.all([
|
|
46073
|
-
readJson(nb, dir, FILES.worldCoarse),
|
|
46074
|
-
readJson(nb, dir, FILES.worldDetail),
|
|
46075
|
-
readJson(nb, dir, FILES.usStates),
|
|
46076
|
-
// Lakes/rivers/NA assets are optional — older bundles may predate them.
|
|
46077
|
-
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
46078
|
-
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
46079
|
-
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
46080
|
-
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
46081
|
-
readJson(nb, dir, FILES.gazetteer)
|
|
46225
|
+
US_STATE_POSTAL = /* @__PURE__ */ new Set([
|
|
46226
|
+
"AL",
|
|
46227
|
+
"AK",
|
|
46228
|
+
"AZ",
|
|
46229
|
+
"AR",
|
|
46230
|
+
"CA",
|
|
46231
|
+
"CO",
|
|
46232
|
+
"CT",
|
|
46233
|
+
"DE",
|
|
46234
|
+
"FL",
|
|
46235
|
+
"GA",
|
|
46236
|
+
"HI",
|
|
46237
|
+
"ID",
|
|
46238
|
+
"IL",
|
|
46239
|
+
"IN",
|
|
46240
|
+
"IA",
|
|
46241
|
+
"KS",
|
|
46242
|
+
"KY",
|
|
46243
|
+
"LA",
|
|
46244
|
+
"ME",
|
|
46245
|
+
"MD",
|
|
46246
|
+
"MA",
|
|
46247
|
+
"MI",
|
|
46248
|
+
"MN",
|
|
46249
|
+
"MS",
|
|
46250
|
+
"MO",
|
|
46251
|
+
"MT",
|
|
46252
|
+
"NE",
|
|
46253
|
+
"NV",
|
|
46254
|
+
"NH",
|
|
46255
|
+
"NJ",
|
|
46256
|
+
"NM",
|
|
46257
|
+
"NY",
|
|
46258
|
+
"NC",
|
|
46259
|
+
"ND",
|
|
46260
|
+
"OH",
|
|
46261
|
+
"OK",
|
|
46262
|
+
"OR",
|
|
46263
|
+
"PA",
|
|
46264
|
+
"RI",
|
|
46265
|
+
"SC",
|
|
46266
|
+
"SD",
|
|
46267
|
+
"TN",
|
|
46268
|
+
"TX",
|
|
46269
|
+
"UT",
|
|
46270
|
+
"VT",
|
|
46271
|
+
"VA",
|
|
46272
|
+
"WA",
|
|
46273
|
+
"WV",
|
|
46274
|
+
"WI",
|
|
46275
|
+
"WY",
|
|
46276
|
+
"DC"
|
|
46082
46277
|
]);
|
|
46083
|
-
return validate({
|
|
46084
|
-
worldCoarse,
|
|
46085
|
-
worldDetail,
|
|
46086
|
-
usStates,
|
|
46087
|
-
gazetteer,
|
|
46088
|
-
...lakes && { lakes },
|
|
46089
|
-
...rivers && { rivers },
|
|
46090
|
-
...naLand && { naLand },
|
|
46091
|
-
...naLakes && { naLakes }
|
|
46092
|
-
});
|
|
46093
|
-
})().catch((e) => {
|
|
46094
|
-
cache = void 0;
|
|
46095
|
-
throw e;
|
|
46096
|
-
});
|
|
46097
|
-
return cache;
|
|
46098
|
-
}
|
|
46099
|
-
var import_meta, FILES, CANDIDATE_DIRS, cache;
|
|
46100
|
-
var init_load_data = __esm({
|
|
46101
|
-
"src/map/load-data.ts"() {
|
|
46102
|
-
"use strict";
|
|
46103
|
-
import_meta = {};
|
|
46104
|
-
FILES = {
|
|
46105
|
-
worldCoarse: "world-coarse.json",
|
|
46106
|
-
worldDetail: "world-detail.json",
|
|
46107
|
-
usStates: "us-states.json",
|
|
46108
|
-
lakes: "lakes.json",
|
|
46109
|
-
rivers: "rivers.json",
|
|
46110
|
-
naLand: "na-land.json",
|
|
46111
|
-
naLakes: "na-lakes.json",
|
|
46112
|
-
gazetteer: "gazetteer.json"
|
|
46113
|
-
};
|
|
46114
|
-
CANDIDATE_DIRS = [
|
|
46115
|
-
"./data",
|
|
46116
|
-
"./map-data",
|
|
46117
|
-
"../map-data",
|
|
46118
|
-
"../src/map/data"
|
|
46119
|
-
];
|
|
46120
46278
|
}
|
|
46121
46279
|
});
|
|
46122
46280
|
|
|
@@ -46146,8 +46304,19 @@ function projectionFor(family) {
|
|
|
46146
46304
|
return (0, import_d3_geo2.geoEquirectangular)();
|
|
46147
46305
|
}
|
|
46148
46306
|
}
|
|
46149
|
-
function mapBackgroundColor(palette) {
|
|
46150
|
-
return mix(
|
|
46307
|
+
function mapBackgroundColor(palette, isDark = false, _dataActive = false) {
|
|
46308
|
+
return mix(
|
|
46309
|
+
palette.colors.blue,
|
|
46310
|
+
palette.bg,
|
|
46311
|
+
isDark ? WATER_TINT_DARK : WATER_TINT_LIGHT
|
|
46312
|
+
);
|
|
46313
|
+
}
|
|
46314
|
+
function mapNeutralLandColor(palette, isDark, _dataActive = false) {
|
|
46315
|
+
return mix(
|
|
46316
|
+
palette.colors.green,
|
|
46317
|
+
palette.bg,
|
|
46318
|
+
isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
|
|
46319
|
+
);
|
|
46151
46320
|
}
|
|
46152
46321
|
function layoutMap(resolved, data, size, opts) {
|
|
46153
46322
|
const { palette, isDark } = opts;
|
|
@@ -46168,28 +46337,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46168
46337
|
}
|
|
46169
46338
|
}
|
|
46170
46339
|
const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
|
|
46171
|
-
const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
|
|
46172
|
-
const neutralFill = mix(palette.colors.green, palette.bg, landTint);
|
|
46173
|
-
const water = mapBackgroundColor(palette);
|
|
46174
46340
|
const usContext = usLayer !== null;
|
|
46175
|
-
const foreignFill = mix(
|
|
46176
|
-
palette.colors.gray,
|
|
46177
|
-
palette.bg,
|
|
46178
|
-
isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46179
|
-
);
|
|
46180
46341
|
const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
|
|
46181
|
-
const
|
|
46342
|
+
const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
|
|
46182
46343
|
const scaleOverride = resolved.directives.scale;
|
|
46183
|
-
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...
|
|
46184
|
-
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...
|
|
46185
|
-
const rampHue = palette.colors.red;
|
|
46186
|
-
const hasRamp =
|
|
46187
|
-
const
|
|
46344
|
+
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
|
|
46345
|
+
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
|
|
46346
|
+
const rampHue = resolveColor(resolved.directives.regionMetricColor ?? "", palette) ?? palette.colors.red;
|
|
46347
|
+
const hasRamp = values.length > 0;
|
|
46348
|
+
const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
|
|
46188
46349
|
const matchColorGroup = (v) => {
|
|
46189
46350
|
const lv = v.trim().toLowerCase();
|
|
46190
46351
|
if (lv === "none") return null;
|
|
46191
|
-
if (
|
|
46192
|
-
return SCORE_NAME;
|
|
46352
|
+
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
46193
46353
|
const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
46194
46354
|
return tg ? tg.name : v;
|
|
46195
46355
|
};
|
|
@@ -46200,11 +46360,20 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46200
46360
|
} else if (resolved.directives.activeTag !== void 0) {
|
|
46201
46361
|
activeGroup = matchColorGroup(resolved.directives.activeTag);
|
|
46202
46362
|
} else {
|
|
46203
|
-
activeGroup =
|
|
46363
|
+
activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
|
|
46204
46364
|
}
|
|
46205
|
-
const activeIsScore =
|
|
46365
|
+
const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
|
|
46366
|
+
const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
|
|
46367
|
+
const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
|
|
46368
|
+
const water = mapBackgroundColor(palette, isDark, mutedBasemap);
|
|
46369
|
+
const lakeStroke = mix(regionStroke, water, 45);
|
|
46370
|
+
const foreignFill = mix(
|
|
46371
|
+
palette.colors.gray,
|
|
46372
|
+
palette.bg,
|
|
46373
|
+
mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46374
|
+
);
|
|
46206
46375
|
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
46207
|
-
const
|
|
46376
|
+
const fillForValue = (s) => {
|
|
46208
46377
|
const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
|
|
46209
46378
|
const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
|
|
46210
46379
|
return mix(rampHue, rampBase, pct);
|
|
@@ -46227,9 +46396,16 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46227
46396
|
isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT
|
|
46228
46397
|
);
|
|
46229
46398
|
};
|
|
46399
|
+
const directFill = (name) => {
|
|
46400
|
+
const hex = name ? resolveColor(name, palette) : null;
|
|
46401
|
+
if (!hex) return null;
|
|
46402
|
+
return mix(hex, palette.bg, isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT);
|
|
46403
|
+
};
|
|
46230
46404
|
const regionFill = (r) => {
|
|
46405
|
+
const direct = directFill(r.color);
|
|
46406
|
+
if (direct) return direct;
|
|
46231
46407
|
if (activeIsScore) {
|
|
46232
|
-
return r.
|
|
46408
|
+
return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
|
|
46233
46409
|
}
|
|
46234
46410
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
46235
46411
|
};
|
|
@@ -46281,6 +46457,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46281
46457
|
const fitIsGlobal = fitGB[1][0] - fitGB[0][0] >= 270 || fitGB[1][1] - fitGB[0][1] >= 130;
|
|
46282
46458
|
let path;
|
|
46283
46459
|
let project;
|
|
46460
|
+
let stretchParams = null;
|
|
46284
46461
|
if (fitIsGlobal) {
|
|
46285
46462
|
const cb = (0, import_d3_geo2.geoPath)(projection).bounds(fitTarget);
|
|
46286
46463
|
const bx0 = cb[0][0];
|
|
@@ -46291,6 +46468,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46291
46468
|
const oy = fitBox[0][1];
|
|
46292
46469
|
const sx = cw > 0 ? (fitBox[1][0] - ox) / cw : 1;
|
|
46293
46470
|
const sy = ch > 0 ? (fitBox[1][1] - oy) / ch : 1;
|
|
46471
|
+
stretchParams = { sx, sy, ox, oy, bx0, by0 };
|
|
46294
46472
|
const stretch = (x, y) => [
|
|
46295
46473
|
ox + (x - bx0) * sx,
|
|
46296
46474
|
oy + (y - by0) * sy
|
|
@@ -46322,7 +46500,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46322
46500
|
const insets = [];
|
|
46323
46501
|
const insetRegions = [];
|
|
46324
46502
|
const insetLabelSeeds = [];
|
|
46325
|
-
if (resolved.projection === "albers-usa" && usLayer) {
|
|
46503
|
+
if (resolved.projection === "albers-usa" && usLayer && !resolved.directives.noInsets) {
|
|
46326
46504
|
const PAD = 8;
|
|
46327
46505
|
const GAP = 12;
|
|
46328
46506
|
const yB = height - FIT_PAD;
|
|
@@ -46353,38 +46531,14 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46353
46531
|
}
|
|
46354
46532
|
return y;
|
|
46355
46533
|
};
|
|
46356
|
-
const
|
|
46534
|
+
const coastFloor = (x0, xr) => {
|
|
46357
46535
|
const n = 24;
|
|
46358
|
-
const pts = [];
|
|
46359
46536
|
let maxY = -Infinity;
|
|
46360
46537
|
for (let i = 0; i <= n; i++) {
|
|
46361
|
-
const
|
|
46362
|
-
|
|
46363
|
-
|
|
46364
|
-
|
|
46365
|
-
if (y > maxY) maxY = y;
|
|
46366
|
-
}
|
|
46367
|
-
}
|
|
46368
|
-
if (pts.length === 0) return () => yB - height * 0.42;
|
|
46369
|
-
let m = 0;
|
|
46370
|
-
if (pts.length >= 2) {
|
|
46371
|
-
let sx = 0, sy = 0, sxx = 0, sxy = 0;
|
|
46372
|
-
for (const [x, y] of pts) {
|
|
46373
|
-
sx += x;
|
|
46374
|
-
sy += y;
|
|
46375
|
-
sxx += x * x;
|
|
46376
|
-
sxy += x * y;
|
|
46377
|
-
}
|
|
46378
|
-
const den = pts.length * sxx - sx * sx;
|
|
46379
|
-
if (den !== 0) m = (pts.length * sxy - sx * sy) / den;
|
|
46380
|
-
}
|
|
46381
|
-
m = Math.max(-0.35, Math.min(0.35, m));
|
|
46382
|
-
let c = -Infinity;
|
|
46383
|
-
for (const [x, y] of pts) {
|
|
46384
|
-
const need = y - m * x + GAP;
|
|
46385
|
-
if (need > c) c = need;
|
|
46386
|
-
}
|
|
46387
|
-
return (x) => m * x + c;
|
|
46538
|
+
const y = at(x0 + (xr - x0) * i / n);
|
|
46539
|
+
if (y > maxY) maxY = y;
|
|
46540
|
+
}
|
|
46541
|
+
return maxY;
|
|
46388
46542
|
};
|
|
46389
46543
|
const placeInset = (iso, proj, boxX, iwReq) => {
|
|
46390
46544
|
const f = usLayer.get(iso);
|
|
@@ -46393,19 +46547,15 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46393
46547
|
const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD);
|
|
46394
46548
|
if (iw < 24) return boxX;
|
|
46395
46549
|
const xr = x0 + iw + 2 * PAD;
|
|
46396
|
-
const
|
|
46397
|
-
const
|
|
46398
|
-
const yR = top(xr);
|
|
46550
|
+
const floor = coastFloor(x0, xr);
|
|
46551
|
+
const topGuess = floor > -Infinity ? floor + GAP : yB - height * 0.42;
|
|
46399
46552
|
proj.fitWidth(iw, f);
|
|
46400
46553
|
const bb = (0, import_d3_geo2.geoPath)(proj).bounds(f);
|
|
46401
46554
|
const sh = Number.isFinite(bb[0][0]) ? bb[1][1] - bb[0][1] : iw;
|
|
46402
46555
|
const needH = sh + 2 * PAD;
|
|
46403
|
-
let topFit =
|
|
46556
|
+
let topFit = topGuess;
|
|
46404
46557
|
const bottom = Math.min(topFit + needH, yB);
|
|
46405
46558
|
if (bottom - topFit < needH) topFit = bottom - needH;
|
|
46406
|
-
const lift = topFit - Math.max(yL, yR);
|
|
46407
|
-
const topL = yL + lift;
|
|
46408
|
-
const topR = yR + lift;
|
|
46409
46559
|
proj.fitExtent(
|
|
46410
46560
|
[
|
|
46411
46561
|
[x0 + PAD, topFit + PAD],
|
|
@@ -46424,15 +46574,18 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46424
46574
|
}
|
|
46425
46575
|
insets.push({
|
|
46426
46576
|
x: x0,
|
|
46427
|
-
y:
|
|
46577
|
+
y: topFit,
|
|
46428
46578
|
w: xr - x0,
|
|
46429
|
-
h: bottom -
|
|
46579
|
+
h: bottom - topFit,
|
|
46430
46580
|
points: [
|
|
46431
|
-
[x0,
|
|
46432
|
-
[xr,
|
|
46581
|
+
[x0, topFit],
|
|
46582
|
+
[xr, topFit],
|
|
46433
46583
|
[xr, bottom],
|
|
46434
46584
|
[x0, bottom]
|
|
46435
|
-
]
|
|
46585
|
+
],
|
|
46586
|
+
// The FITTED inset projection (just fit to this box) — captured so the
|
|
46587
|
+
// geo-query can invert pixels inside the frame back to AK/HI coords.
|
|
46588
|
+
projection: proj
|
|
46436
46589
|
});
|
|
46437
46590
|
insetRegions.push({
|
|
46438
46591
|
id: iso,
|
|
@@ -46441,7 +46594,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46441
46594
|
stroke: regionStroke,
|
|
46442
46595
|
lineNumber,
|
|
46443
46596
|
layer: "us-state",
|
|
46444
|
-
...r?.
|
|
46597
|
+
...r?.value !== void 0 && { value: r.value },
|
|
46445
46598
|
...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46446
46599
|
});
|
|
46447
46600
|
const ctr = (0, import_d3_geo2.geoPath)(proj).centroid(f);
|
|
@@ -46584,7 +46737,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46584
46737
|
lineNumber,
|
|
46585
46738
|
layer,
|
|
46586
46739
|
...label !== void 0 && { label },
|
|
46587
|
-
...isThisLayer && r.
|
|
46740
|
+
...isThisLayer && r.value !== void 0 && { value: r.value },
|
|
46588
46741
|
...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46589
46742
|
});
|
|
46590
46743
|
}
|
|
@@ -46602,13 +46755,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46602
46755
|
id: "lake",
|
|
46603
46756
|
d,
|
|
46604
46757
|
fill: water,
|
|
46605
|
-
stroke:
|
|
46758
|
+
stroke: lakeStroke,
|
|
46606
46759
|
lineNumber: -1,
|
|
46607
46760
|
layer: "base"
|
|
46608
46761
|
});
|
|
46609
46762
|
}
|
|
46610
46763
|
}
|
|
46611
|
-
const
|
|
46764
|
+
const relief = [];
|
|
46765
|
+
let reliefHatch = null;
|
|
46766
|
+
if (resolved.directives.relief === true && data.mountainRanges) {
|
|
46767
|
+
for (const [, f] of decodeLayer(data.mountainRanges)) {
|
|
46768
|
+
const viewF = isGlobalView ? dropFrameFillers(f) : cullFeatureToView(f);
|
|
46769
|
+
if (!viewF) continue;
|
|
46770
|
+
const area2 = path.area(viewF);
|
|
46771
|
+
if (!Number.isFinite(area2) || area2 < RELIEF_MIN_AREA) continue;
|
|
46772
|
+
const box = path.bounds(viewF);
|
|
46773
|
+
if (box[1][0] - box[0][0] < RELIEF_MIN_DIM || box[1][1] - box[0][1] < RELIEF_MIN_DIM)
|
|
46774
|
+
continue;
|
|
46775
|
+
const d = path(viewF) ?? "";
|
|
46776
|
+
if (!d) continue;
|
|
46777
|
+
relief.push({ d });
|
|
46778
|
+
}
|
|
46779
|
+
if (relief.length) {
|
|
46780
|
+
const darkTone = isDark ? palette.bg : palette.text;
|
|
46781
|
+
const lightTone = isDark ? palette.text : palette.bg;
|
|
46782
|
+
const landLum = relativeLuminance(neutralFill);
|
|
46783
|
+
const tone = Math.abs(landLum - relativeLuminance(darkTone)) > 0.04 ? darkTone : lightTone;
|
|
46784
|
+
reliefHatch = {
|
|
46785
|
+
color: mix(tone, neutralFill, RELIEF_HATCH_STRENGTH),
|
|
46786
|
+
spacing: RELIEF_HATCH_SPACING,
|
|
46787
|
+
width: RELIEF_HATCH_WIDTH
|
|
46788
|
+
};
|
|
46789
|
+
}
|
|
46790
|
+
}
|
|
46791
|
+
const riverColor = mix(water, regionStroke, 16);
|
|
46612
46792
|
const rivers = [];
|
|
46613
46793
|
if (data.rivers) {
|
|
46614
46794
|
for (const [, f] of decodeLayer(data.rivers)) {
|
|
@@ -46619,16 +46799,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46619
46799
|
rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
|
|
46620
46800
|
}
|
|
46621
46801
|
}
|
|
46622
|
-
const sizeVals = resolved.pois.map((p) => Number(p.meta["
|
|
46802
|
+
const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46623
46803
|
const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
|
|
46624
46804
|
const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
|
|
46625
46805
|
const radiusFor = (p) => {
|
|
46626
|
-
const v = Number(p.meta["
|
|
46806
|
+
const v = Number(p.meta["value"]);
|
|
46627
46807
|
if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
|
|
46628
46808
|
const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
|
|
46629
46809
|
return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
|
|
46630
46810
|
};
|
|
46631
46811
|
const poiFill = (p) => {
|
|
46812
|
+
const directHex = p.color ? resolveColor(p.color, palette) : null;
|
|
46813
|
+
if (directHex)
|
|
46814
|
+
return { fill: directHex, stroke: mix(directHex, palette.text, 18) };
|
|
46632
46815
|
for (const group of resolved.tagGroups) {
|
|
46633
46816
|
const val = p.tags[group.name.toLowerCase()];
|
|
46634
46817
|
if (!val) continue;
|
|
@@ -46690,7 +46873,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46690
46873
|
lineNumber: e.p.lineNumber,
|
|
46691
46874
|
implicit: !!e.p.implicit,
|
|
46692
46875
|
isOrigin: originIds.has(e.p.id),
|
|
46693
|
-
...num !== void 0 && { routeNumber: num }
|
|
46876
|
+
...num !== void 0 && { routeNumber: num },
|
|
46877
|
+
...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
|
|
46694
46878
|
});
|
|
46695
46879
|
});
|
|
46696
46880
|
}
|
|
@@ -46726,26 +46910,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46726
46910
|
const by = b.cy - (b.cy - py) / tb * trimB;
|
|
46727
46911
|
return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
|
|
46728
46912
|
};
|
|
46913
|
+
const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
|
|
46914
|
+
const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
|
|
46915
|
+
const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
|
|
46916
|
+
const routeWidthFor = (v) => {
|
|
46917
|
+
if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
|
|
46918
|
+
const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
|
|
46919
|
+
return W_MIN + t * (W_MAX - W_MIN);
|
|
46920
|
+
};
|
|
46729
46921
|
for (const rt of resolved.routes) {
|
|
46730
|
-
const
|
|
46731
|
-
|
|
46732
|
-
const
|
|
46733
|
-
const b = poiScreen.get(rt.stopIds[i]);
|
|
46922
|
+
for (const leg of rt.legs) {
|
|
46923
|
+
const a = poiScreen.get(leg.fromId);
|
|
46924
|
+
const b = poiScreen.get(leg.toId);
|
|
46734
46925
|
if (!a || !b) continue;
|
|
46926
|
+
const mx = (a.cx + b.cx) / 2;
|
|
46927
|
+
const my = (a.cy + b.cy) / 2;
|
|
46735
46928
|
legs.push({
|
|
46736
|
-
d: legPath(a, b,
|
|
46737
|
-
width:
|
|
46929
|
+
d: legPath(a, b, leg.style === "arc", 0),
|
|
46930
|
+
width: routeWidthFor(Number(leg.value)),
|
|
46738
46931
|
color: mix(palette.text, palette.bg, 72),
|
|
46739
46932
|
arrow: true,
|
|
46740
|
-
lineNumber:
|
|
46933
|
+
lineNumber: leg.lineNumber,
|
|
46934
|
+
...leg.label !== void 0 && {
|
|
46935
|
+
label: leg.label,
|
|
46936
|
+
labelX: mx,
|
|
46937
|
+
labelY: my - 4
|
|
46938
|
+
}
|
|
46741
46939
|
});
|
|
46742
46940
|
}
|
|
46743
46941
|
}
|
|
46744
|
-
const weightVals = resolved.edges.map((e) => Number(e.meta["
|
|
46942
|
+
const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46745
46943
|
const wMin = weightVals.length ? Math.min(...weightVals) : 0;
|
|
46746
46944
|
const wMax = weightVals.length ? Math.max(...weightVals) : 0;
|
|
46747
46945
|
const widthFor = (e) => {
|
|
46748
|
-
const v = Number(e.meta["
|
|
46946
|
+
const v = Number(e.meta["value"]);
|
|
46749
46947
|
if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
|
|
46750
46948
|
const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
|
|
46751
46949
|
return W_MIN + t * (W_MAX - W_MIN);
|
|
@@ -47008,8 +47206,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47008
47206
|
activeGroup,
|
|
47009
47207
|
...hasRamp && {
|
|
47010
47208
|
ramp: {
|
|
47011
|
-
...resolved.directives.
|
|
47012
|
-
metric: resolved.directives.
|
|
47209
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47210
|
+
metric: resolved.directives.regionMetric
|
|
47013
47211
|
},
|
|
47014
47212
|
min: rampMin,
|
|
47015
47213
|
max: rampMax,
|
|
@@ -47029,21 +47227,26 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47029
47227
|
...resolved.caption !== void 0 && { caption: resolved.caption },
|
|
47030
47228
|
regions,
|
|
47031
47229
|
rivers,
|
|
47230
|
+
relief,
|
|
47231
|
+
reliefHatch,
|
|
47032
47232
|
legs,
|
|
47033
47233
|
pois,
|
|
47034
47234
|
labels,
|
|
47035
47235
|
legend,
|
|
47036
47236
|
insets,
|
|
47037
|
-
insetRegions
|
|
47237
|
+
insetRegions,
|
|
47238
|
+
projection,
|
|
47239
|
+
stretch: stretchParams
|
|
47038
47240
|
};
|
|
47039
47241
|
}
|
|
47040
|
-
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,
|
|
47242
|
+
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;
|
|
47041
47243
|
var init_layout15 = __esm({
|
|
47042
47244
|
"src/map/layout.ts"() {
|
|
47043
47245
|
"use strict";
|
|
47044
47246
|
import_d3_geo2 = require("d3-geo");
|
|
47045
47247
|
import_topojson_client2 = require("topojson-client");
|
|
47046
47248
|
init_color_utils();
|
|
47249
|
+
init_colors();
|
|
47047
47250
|
init_label_layout();
|
|
47048
47251
|
init_legend_constants();
|
|
47049
47252
|
init_title_constants();
|
|
@@ -47056,14 +47259,22 @@ var init_layout15 = __esm({
|
|
|
47056
47259
|
W_MAX = 8;
|
|
47057
47260
|
FONT = 11;
|
|
47058
47261
|
COLO_EPS = 1.5;
|
|
47059
|
-
LAND_TINT_LIGHT =
|
|
47060
|
-
LAND_TINT_DARK =
|
|
47262
|
+
LAND_TINT_LIGHT = 12;
|
|
47263
|
+
LAND_TINT_DARK = 24;
|
|
47061
47264
|
TAG_TINT_LIGHT = 60;
|
|
47062
47265
|
TAG_TINT_DARK = 68;
|
|
47063
|
-
|
|
47266
|
+
WATER_TINT_LIGHT = 13;
|
|
47267
|
+
WATER_TINT_DARK = 14;
|
|
47064
47268
|
RIVER_WIDTH = 1.3;
|
|
47269
|
+
RELIEF_MIN_AREA = 12;
|
|
47270
|
+
RELIEF_MIN_DIM = 2;
|
|
47271
|
+
RELIEF_HATCH_SPACING = 3;
|
|
47272
|
+
RELIEF_HATCH_WIDTH = 0.25;
|
|
47273
|
+
RELIEF_HATCH_STRENGTH = 32;
|
|
47065
47274
|
FOREIGN_TINT_LIGHT = 30;
|
|
47066
47275
|
FOREIGN_TINT_DARK = 62;
|
|
47276
|
+
MUTED_FOREIGN_LIGHT = 28;
|
|
47277
|
+
MUTED_FOREIGN_DARK = 16;
|
|
47067
47278
|
COLO_R = 9;
|
|
47068
47279
|
GOLDEN_ANGLE = 2.399963229728653;
|
|
47069
47280
|
FAN_STEP = 16;
|
|
@@ -47117,7 +47328,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47117
47328
|
const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
|
|
47118
47329
|
if (r.layer !== "base") {
|
|
47119
47330
|
p.classed("dgmo-map-region", true).attr("data-region", r.id);
|
|
47120
|
-
if (r.
|
|
47331
|
+
if (r.value !== void 0) p.attr("data-value", r.value);
|
|
47121
47332
|
if (r.tags) {
|
|
47122
47333
|
for (const [group, value] of Object.entries(r.tags)) {
|
|
47123
47334
|
p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
@@ -47135,6 +47346,20 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47135
47346
|
}
|
|
47136
47347
|
};
|
|
47137
47348
|
for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
|
|
47349
|
+
if (layout.relief.length && layout.reliefHatch) {
|
|
47350
|
+
const h = layout.reliefHatch;
|
|
47351
|
+
const rangeClipId = "dgmo-relief-clip";
|
|
47352
|
+
const landClipId = "dgmo-relief-land";
|
|
47353
|
+
const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
|
|
47354
|
+
for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
|
|
47355
|
+
const landClip = defs.append("clipPath").attr("id", landClipId);
|
|
47356
|
+
for (const r of layout.regions)
|
|
47357
|
+
if (r.id !== "lake") landClip.append("path").attr("d", r.d);
|
|
47358
|
+
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");
|
|
47359
|
+
for (let y = h.spacing; y < height; y += h.spacing) {
|
|
47360
|
+
gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
|
|
47361
|
+
}
|
|
47362
|
+
}
|
|
47138
47363
|
if (layout.rivers.length) {
|
|
47139
47364
|
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none");
|
|
47140
47365
|
for (const r of layout.rivers) {
|
|
@@ -47178,6 +47403,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47178
47403
|
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);
|
|
47179
47404
|
}
|
|
47180
47405
|
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);
|
|
47406
|
+
if (poi.tags) {
|
|
47407
|
+
for (const [group, value] of Object.entries(poi.tags)) {
|
|
47408
|
+
c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
47409
|
+
}
|
|
47410
|
+
}
|
|
47181
47411
|
if (onClickItem) {
|
|
47182
47412
|
c.style("cursor", "pointer").on(
|
|
47183
47413
|
"click",
|
|
@@ -47227,7 +47457,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47227
47457
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
47228
47458
|
const ramp = layout.legend.ramp;
|
|
47229
47459
|
const scoreGroup = ramp ? {
|
|
47230
|
-
name: ramp.metric?.trim() || "
|
|
47460
|
+
name: ramp.metric?.trim() || "Value",
|
|
47231
47461
|
entries: [],
|
|
47232
47462
|
gradient: {
|
|
47233
47463
|
min: ramp.min,
|
|
@@ -47254,7 +47484,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47254
47484
|
}
|
|
47255
47485
|
}
|
|
47256
47486
|
if (layout.title) {
|
|
47257
|
-
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);
|
|
47487
|
+
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);
|
|
47258
47488
|
}
|
|
47259
47489
|
if (layout.subtitle) {
|
|
47260
47490
|
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);
|
|
@@ -47287,6 +47517,121 @@ var init_renderer16 = __esm({
|
|
|
47287
47517
|
}
|
|
47288
47518
|
});
|
|
47289
47519
|
|
|
47520
|
+
// src/map/load-data.ts
|
|
47521
|
+
var load_data_exports = {};
|
|
47522
|
+
__export(load_data_exports, {
|
|
47523
|
+
loadMapData: () => loadMapData
|
|
47524
|
+
});
|
|
47525
|
+
async function loadNodeBuiltins() {
|
|
47526
|
+
const [{ readFile }, { fileURLToPath }, { dirname, resolve }] = await Promise.all([
|
|
47527
|
+
import("fs/promises"),
|
|
47528
|
+
import("url"),
|
|
47529
|
+
import("path")
|
|
47530
|
+
]);
|
|
47531
|
+
return { readFile, fileURLToPath, dirname, resolve };
|
|
47532
|
+
}
|
|
47533
|
+
async function readJson(nb, dir, name) {
|
|
47534
|
+
return JSON.parse(await nb.readFile(nb.resolve(dir, name), "utf8"));
|
|
47535
|
+
}
|
|
47536
|
+
async function firstExistingDir(nb, baseDir) {
|
|
47537
|
+
for (const rel of CANDIDATE_DIRS) {
|
|
47538
|
+
const dir = nb.resolve(baseDir, rel);
|
|
47539
|
+
try {
|
|
47540
|
+
await nb.readFile(nb.resolve(dir, FILES.gazetteer), "utf8");
|
|
47541
|
+
return dir;
|
|
47542
|
+
} catch {
|
|
47543
|
+
}
|
|
47544
|
+
}
|
|
47545
|
+
throw new Error(
|
|
47546
|
+
`map data assets not found near ${baseDir} (looked in ${CANDIDATE_DIRS.join(", ")}). Run \`pnpm build:map-data\` and \`pnpm build\`.`
|
|
47547
|
+
);
|
|
47548
|
+
}
|
|
47549
|
+
function validate(data) {
|
|
47550
|
+
const topoOk = (t) => !!t && t.type === "Topology" && !!t.objects;
|
|
47551
|
+
if (!topoOk(data.worldCoarse) || !topoOk(data.worldDetail) || !topoOk(data.usStates) || !data.gazetteer || !Array.isArray(data.gazetteer.cities) || !data.gazetteer.byName) {
|
|
47552
|
+
throw new Error("map data assets are malformed (failed shape validation)");
|
|
47553
|
+
}
|
|
47554
|
+
return data;
|
|
47555
|
+
}
|
|
47556
|
+
function moduleBaseDir(nb) {
|
|
47557
|
+
try {
|
|
47558
|
+
const url = import_meta.url;
|
|
47559
|
+
if (url) return nb.dirname(nb.fileURLToPath(url));
|
|
47560
|
+
} catch {
|
|
47561
|
+
}
|
|
47562
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
47563
|
+
return process.cwd();
|
|
47564
|
+
}
|
|
47565
|
+
function loadMapData() {
|
|
47566
|
+
cache ??= (async () => {
|
|
47567
|
+
const nb = await loadNodeBuiltins();
|
|
47568
|
+
const dir = await firstExistingDir(nb, moduleBaseDir(nb));
|
|
47569
|
+
const [
|
|
47570
|
+
worldCoarse,
|
|
47571
|
+
worldDetail,
|
|
47572
|
+
usStates,
|
|
47573
|
+
lakes,
|
|
47574
|
+
rivers,
|
|
47575
|
+
mountainRanges,
|
|
47576
|
+
naLand,
|
|
47577
|
+
naLakes,
|
|
47578
|
+
gazetteer
|
|
47579
|
+
] = await Promise.all([
|
|
47580
|
+
readJson(nb, dir, FILES.worldCoarse),
|
|
47581
|
+
readJson(nb, dir, FILES.worldDetail),
|
|
47582
|
+
readJson(nb, dir, FILES.usStates),
|
|
47583
|
+
// Lakes/rivers/mountain/NA assets are optional — older bundles may predate them.
|
|
47584
|
+
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
47585
|
+
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
47586
|
+
readJson(nb, dir, FILES.mountainRanges).catch(
|
|
47587
|
+
() => void 0
|
|
47588
|
+
),
|
|
47589
|
+
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
47590
|
+
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
47591
|
+
readJson(nb, dir, FILES.gazetteer)
|
|
47592
|
+
]);
|
|
47593
|
+
return validate({
|
|
47594
|
+
worldCoarse,
|
|
47595
|
+
worldDetail,
|
|
47596
|
+
usStates,
|
|
47597
|
+
gazetteer,
|
|
47598
|
+
...lakes && { lakes },
|
|
47599
|
+
...rivers && { rivers },
|
|
47600
|
+
...mountainRanges && { mountainRanges },
|
|
47601
|
+
...naLand && { naLand },
|
|
47602
|
+
...naLakes && { naLakes }
|
|
47603
|
+
});
|
|
47604
|
+
})().catch((e) => {
|
|
47605
|
+
cache = void 0;
|
|
47606
|
+
throw e;
|
|
47607
|
+
});
|
|
47608
|
+
return cache;
|
|
47609
|
+
}
|
|
47610
|
+
var import_meta, FILES, CANDIDATE_DIRS, cache;
|
|
47611
|
+
var init_load_data = __esm({
|
|
47612
|
+
"src/map/load-data.ts"() {
|
|
47613
|
+
"use strict";
|
|
47614
|
+
import_meta = {};
|
|
47615
|
+
FILES = {
|
|
47616
|
+
worldCoarse: "world-coarse.json",
|
|
47617
|
+
worldDetail: "world-detail.json",
|
|
47618
|
+
usStates: "us-states.json",
|
|
47619
|
+
lakes: "lakes.json",
|
|
47620
|
+
rivers: "rivers.json",
|
|
47621
|
+
mountainRanges: "mountain-ranges.json",
|
|
47622
|
+
naLand: "na-land.json",
|
|
47623
|
+
naLakes: "na-lakes.json",
|
|
47624
|
+
gazetteer: "gazetteer.json"
|
|
47625
|
+
};
|
|
47626
|
+
CANDIDATE_DIRS = [
|
|
47627
|
+
"./data",
|
|
47628
|
+
"./map-data",
|
|
47629
|
+
"../map-data",
|
|
47630
|
+
"../src/map/data"
|
|
47631
|
+
];
|
|
47632
|
+
}
|
|
47633
|
+
});
|
|
47634
|
+
|
|
47290
47635
|
// src/pyramid/renderer.ts
|
|
47291
47636
|
var renderer_exports17 = {};
|
|
47292
47637
|
__export(renderer_exports17, {
|
|
@@ -55410,15 +55755,17 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
55410
55755
|
if (detectedType === "map") {
|
|
55411
55756
|
const { parseMap: parseMap2 } = await Promise.resolve().then(() => (init_parser12(), parser_exports11));
|
|
55412
55757
|
const { resolveMap: resolveMap2 } = await Promise.resolve().then(() => (init_resolver2(), resolver_exports));
|
|
55413
|
-
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55414
55758
|
const { renderMapForExport: renderMapForExport2 } = await Promise.resolve().then(() => (init_renderer16(), renderer_exports16));
|
|
55415
55759
|
const effectivePalette2 = await resolveExportPalette(theme, palette);
|
|
55416
55760
|
const mapParsed = parseMap2(content);
|
|
55417
|
-
let mapData;
|
|
55418
|
-
|
|
55419
|
-
|
|
55420
|
-
|
|
55421
|
-
|
|
55761
|
+
let mapData = options?.mapData;
|
|
55762
|
+
if (!mapData) {
|
|
55763
|
+
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55764
|
+
try {
|
|
55765
|
+
mapData = await loadMapData2();
|
|
55766
|
+
} catch {
|
|
55767
|
+
return "";
|
|
55768
|
+
}
|
|
55422
55769
|
}
|
|
55423
55770
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
55424
55771
|
const container2 = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|