@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.js
CHANGED
|
@@ -833,13 +833,9 @@ var init_reserved_key_registry = __esm({
|
|
|
833
833
|
"icon"
|
|
834
834
|
]);
|
|
835
835
|
MAP_REGISTRY = staticRegistry([
|
|
836
|
-
"
|
|
836
|
+
"value",
|
|
837
837
|
"label",
|
|
838
|
-
"
|
|
839
|
-
"description",
|
|
840
|
-
"weight",
|
|
841
|
-
"style",
|
|
842
|
-
"date"
|
|
838
|
+
"style"
|
|
843
839
|
]);
|
|
844
840
|
ORG_REGISTRY = staticRegistry([
|
|
845
841
|
"color",
|
|
@@ -15870,7 +15866,8 @@ function parseMap(content) {
|
|
|
15870
15866
|
continue;
|
|
15871
15867
|
}
|
|
15872
15868
|
if (open.route && indent > open.route.indent) {
|
|
15873
|
-
open.route.route.
|
|
15869
|
+
const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
|
|
15870
|
+
open.route.route.legs.push(leg);
|
|
15874
15871
|
continue;
|
|
15875
15872
|
}
|
|
15876
15873
|
if (open.poi && indent > open.poi.indent) {
|
|
@@ -15901,6 +15898,10 @@ function parseMap(content) {
|
|
|
15901
15898
|
handleTag(trimmed, lineNumber);
|
|
15902
15899
|
continue;
|
|
15903
15900
|
}
|
|
15901
|
+
if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
|
|
15902
|
+
handleDirective(firstWord, "", lineNumber);
|
|
15903
|
+
continue;
|
|
15904
|
+
}
|
|
15904
15905
|
if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
|
|
15905
15906
|
handleDirective(
|
|
15906
15907
|
firstWord,
|
|
@@ -15965,13 +15966,20 @@ function parseMap(content) {
|
|
|
15965
15966
|
);
|
|
15966
15967
|
d.projection = value;
|
|
15967
15968
|
break;
|
|
15968
|
-
case "metric":
|
|
15969
|
-
dup(d.
|
|
15970
|
-
|
|
15969
|
+
case "region-metric": {
|
|
15970
|
+
dup(d.regionMetric);
|
|
15971
|
+
const { label: rmLabel, colorName: rmColor } = peelTrailingColorName(value);
|
|
15972
|
+
d.regionMetric = rmLabel;
|
|
15973
|
+
if (rmColor) d.regionMetricColor = rmColor;
|
|
15974
|
+
break;
|
|
15975
|
+
}
|
|
15976
|
+
case "poi-metric":
|
|
15977
|
+
dup(d.poiMetric);
|
|
15978
|
+
d.poiMetric = value;
|
|
15971
15979
|
break;
|
|
15972
|
-
case "
|
|
15973
|
-
dup(d.
|
|
15974
|
-
d.
|
|
15980
|
+
case "flow-metric":
|
|
15981
|
+
dup(d.flowMetric);
|
|
15982
|
+
d.flowMetric = value;
|
|
15975
15983
|
break;
|
|
15976
15984
|
case "scale":
|
|
15977
15985
|
dup(d.scale);
|
|
@@ -16013,6 +16021,21 @@ function parseMap(content) {
|
|
|
16013
16021
|
case "no-legend":
|
|
16014
16022
|
d.noLegend = true;
|
|
16015
16023
|
break;
|
|
16024
|
+
case "no-insets":
|
|
16025
|
+
d.noInsets = true;
|
|
16026
|
+
break;
|
|
16027
|
+
case "relief":
|
|
16028
|
+
d.relief = true;
|
|
16029
|
+
break;
|
|
16030
|
+
case "muted":
|
|
16031
|
+
case "natural":
|
|
16032
|
+
if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
|
|
16033
|
+
pushWarning(
|
|
16034
|
+
line12,
|
|
16035
|
+
`Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
|
|
16036
|
+
);
|
|
16037
|
+
d.basemapStyle = key;
|
|
16038
|
+
break;
|
|
16016
16039
|
case "subtitle":
|
|
16017
16040
|
dup(d.subtitle);
|
|
16018
16041
|
d.subtitle = value;
|
|
@@ -16090,14 +16113,14 @@ function parseMap(content) {
|
|
|
16090
16113
|
line12
|
|
16091
16114
|
);
|
|
16092
16115
|
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16093
|
-
let
|
|
16094
|
-
const
|
|
16095
|
-
if (
|
|
16096
|
-
delete meta["
|
|
16097
|
-
|
|
16098
|
-
if (!Number.isFinite(
|
|
16099
|
-
pushError(line12, `
|
|
16100
|
-
|
|
16116
|
+
let valueNum;
|
|
16117
|
+
const value = meta["value"];
|
|
16118
|
+
if (value !== void 0) {
|
|
16119
|
+
delete meta["value"];
|
|
16120
|
+
valueNum = Number(value);
|
|
16121
|
+
if (!Number.isFinite(valueNum)) {
|
|
16122
|
+
pushError(line12, `value must be a number (got "${value}").`);
|
|
16123
|
+
valueNum = void 0;
|
|
16101
16124
|
}
|
|
16102
16125
|
}
|
|
16103
16126
|
let regionName = split.name;
|
|
@@ -16115,7 +16138,8 @@ function parseMap(content) {
|
|
|
16115
16138
|
lineNumber: line12
|
|
16116
16139
|
};
|
|
16117
16140
|
if (regionScope !== void 0) region.scope = regionScope;
|
|
16118
|
-
if (
|
|
16141
|
+
if (valueNum !== void 0) region.value = valueNum;
|
|
16142
|
+
if (split.color) region.color = split.color;
|
|
16119
16143
|
regions.push(region);
|
|
16120
16144
|
}
|
|
16121
16145
|
function handlePoi(rest, line12, indent) {
|
|
@@ -16140,28 +16164,81 @@ function parseMap(content) {
|
|
|
16140
16164
|
const poi = { pos, tags, meta, lineNumber: line12 };
|
|
16141
16165
|
if (split.alias) poi.alias = split.alias;
|
|
16142
16166
|
if (label !== void 0) poi.label = label;
|
|
16167
|
+
if (split.color) poi.color = split.color;
|
|
16143
16168
|
pois.push(poi);
|
|
16144
16169
|
open.poi = { poi, indent };
|
|
16145
16170
|
}
|
|
16146
16171
|
function handleRoute(rest, line12, indent) {
|
|
16147
|
-
const
|
|
16148
|
-
|
|
16172
|
+
const split = rest ? splitNameAndMeta(
|
|
16173
|
+
rest,
|
|
16174
|
+
registry(),
|
|
16175
|
+
aliasMap,
|
|
16176
|
+
void 0,
|
|
16177
|
+
diagnostics,
|
|
16178
|
+
line12
|
|
16179
|
+
) : { name: "", meta: {}, alias: void 0 };
|
|
16180
|
+
const pos = parsePos(split.name, line12);
|
|
16181
|
+
if (!pos || pos.kind === "name" && !pos.name) {
|
|
16182
|
+
pushError(
|
|
16183
|
+
line12,
|
|
16184
|
+
"route requires an origin: `route <origin> [style: arc]`."
|
|
16185
|
+
);
|
|
16186
|
+
return;
|
|
16187
|
+
}
|
|
16188
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16189
|
+
const originLabel = meta["label"];
|
|
16190
|
+
const originValue = meta["value"];
|
|
16191
|
+
const style = meta["style"] === "arc" ? "arc" : "straight";
|
|
16192
|
+
const route = {
|
|
16193
|
+
origin: pos,
|
|
16194
|
+
...split.alias !== void 0 && { originAlias: split.alias },
|
|
16195
|
+
...originLabel !== void 0 && { originLabel },
|
|
16196
|
+
...originValue !== void 0 && { originValue },
|
|
16197
|
+
originTags: tags,
|
|
16198
|
+
style,
|
|
16199
|
+
legs: [],
|
|
16200
|
+
lineNumber: line12
|
|
16201
|
+
};
|
|
16149
16202
|
routes.push(route);
|
|
16150
16203
|
open.route = { route, indent };
|
|
16151
16204
|
}
|
|
16152
|
-
function
|
|
16153
|
-
|
|
16154
|
-
|
|
16205
|
+
function parseLeg(trimmed, line12, headerStyle) {
|
|
16206
|
+
let arrowStyle = "straight";
|
|
16207
|
+
let label;
|
|
16208
|
+
let rest = trimmed;
|
|
16209
|
+
const m = trimmed.match(LEG_ARROW_RE);
|
|
16210
|
+
if (m) {
|
|
16211
|
+
const arr = classifyArrow(m[1], line12);
|
|
16212
|
+
arrowStyle = arr.style;
|
|
16213
|
+
label = arr.label;
|
|
16214
|
+
rest = m[2];
|
|
16215
|
+
}
|
|
16216
|
+
const split = splitNameAndMeta(
|
|
16217
|
+
rest,
|
|
16218
|
+
registry(),
|
|
16219
|
+
aliasMap,
|
|
16220
|
+
void 0,
|
|
16221
|
+
diagnostics,
|
|
16222
|
+
line12
|
|
16223
|
+
);
|
|
16224
|
+
const pos = parsePos(split.name, line12) ?? {
|
|
16155
16225
|
kind: "name",
|
|
16156
16226
|
name: split.name
|
|
16157
16227
|
};
|
|
16158
|
-
const
|
|
16159
|
-
|
|
16160
|
-
|
|
16228
|
+
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
16229
|
+
const value = meta["value"];
|
|
16230
|
+
const destLabel = meta["label"];
|
|
16231
|
+
const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
|
|
16232
|
+
return {
|
|
16233
|
+
...label !== void 0 && { label },
|
|
16234
|
+
style,
|
|
16235
|
+
...value !== void 0 && { value },
|
|
16236
|
+
dest: pos,
|
|
16237
|
+
...split.alias !== void 0 && { destAlias: split.alias },
|
|
16238
|
+
...destLabel !== void 0 && { destLabel },
|
|
16239
|
+
destTags: tags,
|
|
16161
16240
|
lineNumber: line12
|
|
16162
16241
|
};
|
|
16163
|
-
if (split.alias) stop.alias = split.alias;
|
|
16164
|
-
return stop;
|
|
16165
16242
|
}
|
|
16166
16243
|
function handleEdges(trimmed, line12) {
|
|
16167
16244
|
const parts = trimmed.split(ARROW_SPLIT);
|
|
@@ -16263,7 +16340,7 @@ function partitionMeta(meta, tagGroupNames) {
|
|
|
16263
16340
|
function poiName(pos) {
|
|
16264
16341
|
return pos.kind === "name" ? pos.name : void 0;
|
|
16265
16342
|
}
|
|
16266
|
-
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
|
|
16343
|
+
var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
|
|
16267
16344
|
var init_parser12 = __esm({
|
|
16268
16345
|
"src/map/parser.ts"() {
|
|
16269
16346
|
"use strict";
|
|
@@ -16277,12 +16354,14 @@ var init_parser12 = __esm({
|
|
|
16277
16354
|
SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
|
|
16278
16355
|
ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
|
|
16279
16356
|
HUB_RE = /^(->|~>)\s+(.+)$/;
|
|
16357
|
+
LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
|
|
16280
16358
|
AT_RE = /(^|[\s,])at\s*:/i;
|
|
16281
16359
|
DIRECTIVE_SET = /* @__PURE__ */ new Set([
|
|
16282
16360
|
"region",
|
|
16283
16361
|
"projection",
|
|
16284
|
-
"metric",
|
|
16285
|
-
"
|
|
16362
|
+
"region-metric",
|
|
16363
|
+
"poi-metric",
|
|
16364
|
+
"flow-metric",
|
|
16286
16365
|
"scale",
|
|
16287
16366
|
"region-labels",
|
|
16288
16367
|
"poi-labels",
|
|
@@ -16290,6 +16369,8 @@ var init_parser12 = __esm({
|
|
|
16290
16369
|
"default-state",
|
|
16291
16370
|
"active-tag",
|
|
16292
16371
|
"no-legend",
|
|
16372
|
+
"no-insets",
|
|
16373
|
+
"relief",
|
|
16293
16374
|
"subtitle",
|
|
16294
16375
|
"caption"
|
|
16295
16376
|
]);
|
|
@@ -45488,7 +45569,7 @@ var init_renderer15 = __esm({
|
|
|
45488
45569
|
|
|
45489
45570
|
// src/map/geo.ts
|
|
45490
45571
|
import { feature } from "topojson-client";
|
|
45491
|
-
import { geoBounds } from "d3-geo";
|
|
45572
|
+
import { geoBounds, geoArea } from "d3-geo";
|
|
45492
45573
|
function geomObject(topo) {
|
|
45493
45574
|
const key = Object.keys(topo.objects)[0];
|
|
45494
45575
|
return topo.objects[key];
|
|
@@ -45516,6 +45597,74 @@ function featureBbox(topo, geomId) {
|
|
|
45516
45597
|
[b[1][0], b[1][1]]
|
|
45517
45598
|
];
|
|
45518
45599
|
}
|
|
45600
|
+
function explodePolygons(gj) {
|
|
45601
|
+
const g = gj.geometry ?? gj;
|
|
45602
|
+
const t = g.type;
|
|
45603
|
+
const coords = g.coordinates;
|
|
45604
|
+
if (t === "Polygon") {
|
|
45605
|
+
return [
|
|
45606
|
+
{ type: "Feature", geometry: { type: "Polygon", coordinates: coords } }
|
|
45607
|
+
];
|
|
45608
|
+
}
|
|
45609
|
+
if (t === "MultiPolygon") {
|
|
45610
|
+
return coords.map((rings) => ({
|
|
45611
|
+
type: "Feature",
|
|
45612
|
+
geometry: { type: "Polygon", coordinates: rings }
|
|
45613
|
+
}));
|
|
45614
|
+
}
|
|
45615
|
+
return [];
|
|
45616
|
+
}
|
|
45617
|
+
function bboxGap(a, b) {
|
|
45618
|
+
const lonGap = Math.max(0, a[0][0] - b[1][0], b[0][0] - a[1][0]);
|
|
45619
|
+
const latGap = Math.max(0, a[0][1] - b[1][1], b[0][1] - a[1][1]);
|
|
45620
|
+
return Math.max(lonGap, latGap);
|
|
45621
|
+
}
|
|
45622
|
+
function featureBboxPrimary(topo, geomId) {
|
|
45623
|
+
const geom = geomObject(topo).geometries.find((g) => g.id === geomId);
|
|
45624
|
+
if (!geom) return null;
|
|
45625
|
+
const gj = feature(topo, geom);
|
|
45626
|
+
const parts = explodePolygons(gj);
|
|
45627
|
+
if (parts.length <= 1) return featureBbox(topo, geomId);
|
|
45628
|
+
const polys = parts.map((p) => {
|
|
45629
|
+
const b = geoBounds(p);
|
|
45630
|
+
if (!b || !Number.isFinite(b[0][0])) return null;
|
|
45631
|
+
const wraps = b[1][0] < b[0][0];
|
|
45632
|
+
const bbox = [
|
|
45633
|
+
[b[0][0], b[0][1]],
|
|
45634
|
+
[b[1][0], b[1][1]]
|
|
45635
|
+
];
|
|
45636
|
+
return { bbox, area: geoArea(p), wraps };
|
|
45637
|
+
}).filter(
|
|
45638
|
+
(p) => p !== null
|
|
45639
|
+
);
|
|
45640
|
+
if (polys.length <= 1 || polys.some((p) => p.wraps))
|
|
45641
|
+
return featureBbox(topo, geomId);
|
|
45642
|
+
const maxArea = Math.max(...polys.map((p) => p.area));
|
|
45643
|
+
const anchor = polys.find((p) => p.area === maxArea);
|
|
45644
|
+
const cluster = [
|
|
45645
|
+
[anchor.bbox[0][0], anchor.bbox[0][1]],
|
|
45646
|
+
[anchor.bbox[1][0], anchor.bbox[1][1]]
|
|
45647
|
+
];
|
|
45648
|
+
const remaining = polys.filter((p) => p !== anchor);
|
|
45649
|
+
let added = true;
|
|
45650
|
+
while (added) {
|
|
45651
|
+
added = false;
|
|
45652
|
+
for (let i = remaining.length - 1; i >= 0; i--) {
|
|
45653
|
+
const p = remaining[i];
|
|
45654
|
+
const near = bboxGap(p.bbox, cluster) <= DETACH_GAP_DEG;
|
|
45655
|
+
const large = p.area >= DETACH_AREA_FRAC * maxArea;
|
|
45656
|
+
if (near || large) {
|
|
45657
|
+
cluster[0][0] = Math.min(cluster[0][0], p.bbox[0][0]);
|
|
45658
|
+
cluster[0][1] = Math.min(cluster[0][1], p.bbox[0][1]);
|
|
45659
|
+
cluster[1][0] = Math.max(cluster[1][0], p.bbox[1][0]);
|
|
45660
|
+
cluster[1][1] = Math.max(cluster[1][1], p.bbox[1][1]);
|
|
45661
|
+
remaining.splice(i, 1);
|
|
45662
|
+
added = true;
|
|
45663
|
+
}
|
|
45664
|
+
}
|
|
45665
|
+
}
|
|
45666
|
+
return cluster;
|
|
45667
|
+
}
|
|
45519
45668
|
function unionExtent(boxes, points) {
|
|
45520
45669
|
const lats = [];
|
|
45521
45670
|
const lons = [];
|
|
@@ -45554,11 +45703,13 @@ function unionLongitudes(lons) {
|
|
|
45554
45703
|
}
|
|
45555
45704
|
return { west: pts[gapIdx], east: pts[gapIdx - 1] + 360 };
|
|
45556
45705
|
}
|
|
45557
|
-
var fold;
|
|
45706
|
+
var fold, DETACH_GAP_DEG, DETACH_AREA_FRAC;
|
|
45558
45707
|
var init_geo = __esm({
|
|
45559
45708
|
"src/map/geo.ts"() {
|
|
45560
45709
|
"use strict";
|
|
45561
45710
|
fold = (s) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim();
|
|
45711
|
+
DETACH_GAP_DEG = 10;
|
|
45712
|
+
DETACH_AREA_FRAC = 0.25;
|
|
45562
45713
|
}
|
|
45563
45714
|
});
|
|
45564
45715
|
|
|
@@ -45567,6 +45718,11 @@ var resolver_exports = {};
|
|
|
45567
45718
|
__export(resolver_exports, {
|
|
45568
45719
|
resolveMap: () => resolveMap
|
|
45569
45720
|
});
|
|
45721
|
+
function usStateFromBareScope(scope) {
|
|
45722
|
+
if (!scope) return null;
|
|
45723
|
+
const up = scope.toUpperCase();
|
|
45724
|
+
return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
|
|
45725
|
+
}
|
|
45570
45726
|
function looksUS(lat, lon) {
|
|
45571
45727
|
if (lat < 15 || lat > 72) return false;
|
|
45572
45728
|
return lon >= -180 && lon <= -64 || lon >= 172;
|
|
@@ -45616,9 +45772,9 @@ function resolveMap(parsed, data) {
|
|
|
45616
45772
|
const f = fold(r.name);
|
|
45617
45773
|
return usStateIndex.has(f) && !countryIndex.has(f);
|
|
45618
45774
|
}) || parsed.regions.some(
|
|
45619
|
-
(r) => r.scope === "US" || r.scope?.startsWith("US-")
|
|
45775
|
+
(r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
|
|
45620
45776
|
) || parsed.pois.some(
|
|
45621
|
-
(p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
|
|
45777
|
+
(p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
|
|
45622
45778
|
);
|
|
45623
45779
|
const regions = [];
|
|
45624
45780
|
const seenRegion = /* @__PURE__ */ new Map();
|
|
@@ -45657,12 +45813,12 @@ function resolveMap(parsed, data) {
|
|
|
45657
45813
|
chosen = { ...inState, layer: "us-state" };
|
|
45658
45814
|
} else {
|
|
45659
45815
|
chosen = { ...inCountry, layer: "country" };
|
|
45816
|
+
warn(
|
|
45817
|
+
r.lineNumber,
|
|
45818
|
+
`"${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}").`,
|
|
45819
|
+
"W_MAP_REGION_AMBIGUOUS"
|
|
45820
|
+
);
|
|
45660
45821
|
}
|
|
45661
|
-
warn(
|
|
45662
|
-
r.lineNumber,
|
|
45663
|
-
`"${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}").`,
|
|
45664
|
-
"W_MAP_REGION_AMBIGUOUS"
|
|
45665
|
-
);
|
|
45666
45822
|
} else if (inState) {
|
|
45667
45823
|
chosen = { ...inState, layer: "us-state" };
|
|
45668
45824
|
} else if (inCountry) {
|
|
@@ -45685,7 +45841,8 @@ function resolveMap(parsed, data) {
|
|
|
45685
45841
|
iso: chosen.id,
|
|
45686
45842
|
name: chosen.name,
|
|
45687
45843
|
layer: chosen.layer,
|
|
45688
|
-
...r.
|
|
45844
|
+
...r.value !== void 0 && { value: r.value },
|
|
45845
|
+
...r.color !== void 0 && { color: r.color },
|
|
45689
45846
|
tags: r.tags,
|
|
45690
45847
|
meta: r.meta,
|
|
45691
45848
|
lineNumber: r.lineNumber
|
|
@@ -45743,9 +45900,10 @@ function resolveMap(parsed, data) {
|
|
|
45743
45900
|
let cands = idxs.map((i) => data.gazetteer.cities[i]);
|
|
45744
45901
|
const scopeUse = scope ?? scopeHint;
|
|
45745
45902
|
if (scopeUse) {
|
|
45746
|
-
const
|
|
45903
|
+
const bareState = usStateFromBareScope(scopeUse);
|
|
45904
|
+
const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
|
|
45747
45905
|
const filtered = cands.filter(
|
|
45748
|
-
(c2) =>
|
|
45906
|
+
(c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
|
|
45749
45907
|
);
|
|
45750
45908
|
if (filtered.length) cands = filtered;
|
|
45751
45909
|
else if (scope) {
|
|
@@ -45826,6 +45984,7 @@ function resolveMap(parsed, data) {
|
|
|
45826
45984
|
lat,
|
|
45827
45985
|
lon,
|
|
45828
45986
|
...p.label !== void 0 && { label: p.label },
|
|
45987
|
+
...p.color !== void 0 && { color: p.color },
|
|
45829
45988
|
tags: p.tags,
|
|
45830
45989
|
meta: p.meta,
|
|
45831
45990
|
lineNumber: p.lineNumber
|
|
@@ -45874,33 +46033,89 @@ function resolveMap(parsed, data) {
|
|
|
45874
46033
|
lineNumber: e.lineNumber
|
|
45875
46034
|
});
|
|
45876
46035
|
}
|
|
45877
|
-
const
|
|
45878
|
-
|
|
45879
|
-
|
|
45880
|
-
|
|
45881
|
-
|
|
45882
|
-
if (
|
|
45883
|
-
|
|
45884
|
-
|
|
45885
|
-
|
|
45886
|
-
const poi = {
|
|
46036
|
+
const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
|
|
46037
|
+
const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
|
|
46038
|
+
if (pos.kind === "coords") {
|
|
46039
|
+
const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
|
|
46040
|
+
if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
|
|
46041
|
+
if (!registry.has(id)) {
|
|
46042
|
+
registerPoi(
|
|
46043
|
+
id,
|
|
46044
|
+
{
|
|
45887
46045
|
id,
|
|
45888
|
-
...
|
|
45889
|
-
lat:
|
|
45890
|
-
lon:
|
|
45891
|
-
|
|
45892
|
-
|
|
45893
|
-
|
|
45894
|
-
|
|
45895
|
-
}
|
|
45896
|
-
|
|
45897
|
-
|
|
45898
|
-
} else {
|
|
45899
|
-
id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
|
|
46046
|
+
...alias !== void 0 && { name: alias },
|
|
46047
|
+
lat: pos.lat,
|
|
46048
|
+
lon: pos.lon,
|
|
46049
|
+
...label !== void 0 && { label },
|
|
46050
|
+
tags,
|
|
46051
|
+
meta,
|
|
46052
|
+
lineNumber: line12
|
|
46053
|
+
},
|
|
46054
|
+
line12
|
|
46055
|
+
);
|
|
45900
46056
|
}
|
|
45901
|
-
|
|
46057
|
+
return id;
|
|
46058
|
+
}
|
|
46059
|
+
const f = fold(pos.name);
|
|
46060
|
+
if (registry.has(f)) return f;
|
|
46061
|
+
const aliased = declaredByName.get(f);
|
|
46062
|
+
if (aliased) return aliased;
|
|
46063
|
+
const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
|
|
46064
|
+
if (got.kind !== "ok") return null;
|
|
46065
|
+
noteCountry(got.iso);
|
|
46066
|
+
registerPoi(
|
|
46067
|
+
f,
|
|
46068
|
+
{
|
|
46069
|
+
id: f,
|
|
46070
|
+
name: pos.name,
|
|
46071
|
+
lat: got.lat,
|
|
46072
|
+
lon: got.lon,
|
|
46073
|
+
...label !== void 0 && { label },
|
|
46074
|
+
tags,
|
|
46075
|
+
meta,
|
|
46076
|
+
lineNumber: line12
|
|
46077
|
+
},
|
|
46078
|
+
line12
|
|
46079
|
+
);
|
|
46080
|
+
return f;
|
|
46081
|
+
};
|
|
46082
|
+
const routes = [];
|
|
46083
|
+
for (const rt of parsed.routes) {
|
|
46084
|
+
const originId = resolveStop(
|
|
46085
|
+
rt.origin,
|
|
46086
|
+
rt.originAlias,
|
|
46087
|
+
rt.originLabel,
|
|
46088
|
+
rt.originTags,
|
|
46089
|
+
rt.originValue,
|
|
46090
|
+
rt.lineNumber
|
|
46091
|
+
);
|
|
46092
|
+
if (!originId) continue;
|
|
46093
|
+
const stopIds = [originId];
|
|
46094
|
+
const legs = [];
|
|
46095
|
+
let prevId = originId;
|
|
46096
|
+
for (const leg of rt.legs) {
|
|
46097
|
+
const destId = resolveStop(
|
|
46098
|
+
leg.dest,
|
|
46099
|
+
leg.destAlias,
|
|
46100
|
+
leg.destLabel,
|
|
46101
|
+
leg.destTags,
|
|
46102
|
+
void 0,
|
|
46103
|
+
// a leg's `value:` is leg thickness, not the dest's size
|
|
46104
|
+
leg.lineNumber
|
|
46105
|
+
);
|
|
46106
|
+
if (!destId) continue;
|
|
46107
|
+
legs.push({
|
|
46108
|
+
fromId: prevId,
|
|
46109
|
+
toId: destId,
|
|
46110
|
+
...leg.label !== void 0 && { label: leg.label },
|
|
46111
|
+
style: leg.style,
|
|
46112
|
+
...leg.value !== void 0 && { value: leg.value },
|
|
46113
|
+
lineNumber: leg.lineNumber
|
|
46114
|
+
});
|
|
46115
|
+
if (!stopIds.includes(destId)) stopIds.push(destId);
|
|
46116
|
+
prevId = destId;
|
|
45902
46117
|
}
|
|
45903
|
-
routes.push({ stopIds,
|
|
46118
|
+
routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
|
|
45904
46119
|
}
|
|
45905
46120
|
const subdivisions = [];
|
|
45906
46121
|
if (usSubdivisionReferenced || parsed.directives.region === "us-states")
|
|
@@ -45912,7 +46127,7 @@ function resolveMap(parsed, data) {
|
|
|
45912
46127
|
}
|
|
45913
46128
|
for (const r of regions) {
|
|
45914
46129
|
if (r.layer === "country") {
|
|
45915
|
-
const bb =
|
|
46130
|
+
const bb = featureBboxPrimary(data.worldCoarse, r.iso);
|
|
45916
46131
|
if (bb) regionBoxes.push(bb);
|
|
45917
46132
|
}
|
|
45918
46133
|
}
|
|
@@ -45926,6 +46141,7 @@ function resolveMap(parsed, data) {
|
|
|
45926
46141
|
const lonSpan = extent2[1][0] - extent2[0][0];
|
|
45927
46142
|
const latSpan = extent2[1][1] - extent2[0][1];
|
|
45928
46143
|
const span = Math.max(lonSpan, latSpan);
|
|
46144
|
+
const maxAbsLat = Math.max(Math.abs(extent2[0][1]), Math.abs(extent2[1][1]));
|
|
45929
46145
|
const usDominant = (subdivisions.includes("us-states") || regions.some((r) => r.layer === "us-state")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
|
|
45930
46146
|
let projection;
|
|
45931
46147
|
const override = parsed.directives.projection;
|
|
@@ -45933,12 +46149,10 @@ function resolveMap(parsed, data) {
|
|
|
45933
46149
|
projection = override;
|
|
45934
46150
|
} else if (usDominant) {
|
|
45935
46151
|
projection = "albers-usa";
|
|
45936
|
-
} else if (span > WORLD_SPAN) {
|
|
46152
|
+
} else if (span > WORLD_SPAN || maxAbsLat > MERCATOR_MAX_LAT) {
|
|
45937
46153
|
projection = "equirectangular";
|
|
45938
|
-
} else if (span < MERCATOR_MAX_SPAN) {
|
|
45939
|
-
projection = "mercator";
|
|
45940
46154
|
} else {
|
|
45941
|
-
projection = "
|
|
46155
|
+
projection = "mercator";
|
|
45942
46156
|
}
|
|
45943
46157
|
if (lonSpan >= 180) {
|
|
45944
46158
|
extent2 = [
|
|
@@ -45992,14 +46206,14 @@ function firstError(diags) {
|
|
|
45992
46206
|
const e = diags.find((d) => d.severity === "error");
|
|
45993
46207
|
return e ? formatDgmoError(e) : null;
|
|
45994
46208
|
}
|
|
45995
|
-
var WORLD_SPAN,
|
|
46209
|
+
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
|
|
45996
46210
|
var init_resolver2 = __esm({
|
|
45997
46211
|
"src/map/resolver.ts"() {
|
|
45998
46212
|
"use strict";
|
|
45999
46213
|
init_diagnostics();
|
|
46000
46214
|
init_geo();
|
|
46001
46215
|
WORLD_SPAN = 90;
|
|
46002
|
-
|
|
46216
|
+
MERCATOR_MAX_LAT = 80;
|
|
46003
46217
|
PAD_FRACTION = 0.05;
|
|
46004
46218
|
WORLD_LAT_SOUTH = -58;
|
|
46005
46219
|
WORLD_LAT_NORTH = 78;
|
|
@@ -46024,114 +46238,59 @@ var init_resolver2 = __esm({
|
|
|
46024
46238
|
"north macedonia": "macedonia",
|
|
46025
46239
|
"czech republic": "czechia"
|
|
46026
46240
|
};
|
|
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
|
-
|
|
46064
|
-
|
|
46065
|
-
|
|
46066
|
-
|
|
46067
|
-
|
|
46068
|
-
|
|
46069
|
-
|
|
46070
|
-
|
|
46071
|
-
|
|
46072
|
-
|
|
46073
|
-
|
|
46074
|
-
|
|
46075
|
-
|
|
46076
|
-
|
|
46077
|
-
|
|
46078
|
-
|
|
46079
|
-
const [
|
|
46080
|
-
worldCoarse,
|
|
46081
|
-
worldDetail,
|
|
46082
|
-
usStates,
|
|
46083
|
-
lakes,
|
|
46084
|
-
rivers,
|
|
46085
|
-
naLand,
|
|
46086
|
-
naLakes,
|
|
46087
|
-
gazetteer
|
|
46088
|
-
] = await Promise.all([
|
|
46089
|
-
readJson(nb, dir, FILES.worldCoarse),
|
|
46090
|
-
readJson(nb, dir, FILES.worldDetail),
|
|
46091
|
-
readJson(nb, dir, FILES.usStates),
|
|
46092
|
-
// Lakes/rivers/NA assets are optional — older bundles may predate them.
|
|
46093
|
-
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
46094
|
-
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
46095
|
-
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
46096
|
-
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
46097
|
-
readJson(nb, dir, FILES.gazetteer)
|
|
46241
|
+
US_STATE_POSTAL = /* @__PURE__ */ new Set([
|
|
46242
|
+
"AL",
|
|
46243
|
+
"AK",
|
|
46244
|
+
"AZ",
|
|
46245
|
+
"AR",
|
|
46246
|
+
"CA",
|
|
46247
|
+
"CO",
|
|
46248
|
+
"CT",
|
|
46249
|
+
"DE",
|
|
46250
|
+
"FL",
|
|
46251
|
+
"GA",
|
|
46252
|
+
"HI",
|
|
46253
|
+
"ID",
|
|
46254
|
+
"IL",
|
|
46255
|
+
"IN",
|
|
46256
|
+
"IA",
|
|
46257
|
+
"KS",
|
|
46258
|
+
"KY",
|
|
46259
|
+
"LA",
|
|
46260
|
+
"ME",
|
|
46261
|
+
"MD",
|
|
46262
|
+
"MA",
|
|
46263
|
+
"MI",
|
|
46264
|
+
"MN",
|
|
46265
|
+
"MS",
|
|
46266
|
+
"MO",
|
|
46267
|
+
"MT",
|
|
46268
|
+
"NE",
|
|
46269
|
+
"NV",
|
|
46270
|
+
"NH",
|
|
46271
|
+
"NJ",
|
|
46272
|
+
"NM",
|
|
46273
|
+
"NY",
|
|
46274
|
+
"NC",
|
|
46275
|
+
"ND",
|
|
46276
|
+
"OH",
|
|
46277
|
+
"OK",
|
|
46278
|
+
"OR",
|
|
46279
|
+
"PA",
|
|
46280
|
+
"RI",
|
|
46281
|
+
"SC",
|
|
46282
|
+
"SD",
|
|
46283
|
+
"TN",
|
|
46284
|
+
"TX",
|
|
46285
|
+
"UT",
|
|
46286
|
+
"VT",
|
|
46287
|
+
"VA",
|
|
46288
|
+
"WA",
|
|
46289
|
+
"WV",
|
|
46290
|
+
"WI",
|
|
46291
|
+
"WY",
|
|
46292
|
+
"DC"
|
|
46098
46293
|
]);
|
|
46099
|
-
return validate({
|
|
46100
|
-
worldCoarse,
|
|
46101
|
-
worldDetail,
|
|
46102
|
-
usStates,
|
|
46103
|
-
gazetteer,
|
|
46104
|
-
...lakes && { lakes },
|
|
46105
|
-
...rivers && { rivers },
|
|
46106
|
-
...naLand && { naLand },
|
|
46107
|
-
...naLakes && { naLakes }
|
|
46108
|
-
});
|
|
46109
|
-
})().catch((e) => {
|
|
46110
|
-
cache = void 0;
|
|
46111
|
-
throw e;
|
|
46112
|
-
});
|
|
46113
|
-
return cache;
|
|
46114
|
-
}
|
|
46115
|
-
var FILES, CANDIDATE_DIRS, cache;
|
|
46116
|
-
var init_load_data = __esm({
|
|
46117
|
-
"src/map/load-data.ts"() {
|
|
46118
|
-
"use strict";
|
|
46119
|
-
FILES = {
|
|
46120
|
-
worldCoarse: "world-coarse.json",
|
|
46121
|
-
worldDetail: "world-detail.json",
|
|
46122
|
-
usStates: "us-states.json",
|
|
46123
|
-
lakes: "lakes.json",
|
|
46124
|
-
rivers: "rivers.json",
|
|
46125
|
-
naLand: "na-land.json",
|
|
46126
|
-
naLakes: "na-lakes.json",
|
|
46127
|
-
gazetteer: "gazetteer.json"
|
|
46128
|
-
};
|
|
46129
|
-
CANDIDATE_DIRS = [
|
|
46130
|
-
"./data",
|
|
46131
|
-
"./map-data",
|
|
46132
|
-
"../map-data",
|
|
46133
|
-
"../src/map/data"
|
|
46134
|
-
];
|
|
46135
46294
|
}
|
|
46136
46295
|
});
|
|
46137
46296
|
|
|
@@ -46171,8 +46330,19 @@ function projectionFor(family) {
|
|
|
46171
46330
|
return geoEquirectangular();
|
|
46172
46331
|
}
|
|
46173
46332
|
}
|
|
46174
|
-
function mapBackgroundColor(palette) {
|
|
46175
|
-
return mix(
|
|
46333
|
+
function mapBackgroundColor(palette, isDark = false, _dataActive = false) {
|
|
46334
|
+
return mix(
|
|
46335
|
+
palette.colors.blue,
|
|
46336
|
+
palette.bg,
|
|
46337
|
+
isDark ? WATER_TINT_DARK : WATER_TINT_LIGHT
|
|
46338
|
+
);
|
|
46339
|
+
}
|
|
46340
|
+
function mapNeutralLandColor(palette, isDark, _dataActive = false) {
|
|
46341
|
+
return mix(
|
|
46342
|
+
palette.colors.green,
|
|
46343
|
+
palette.bg,
|
|
46344
|
+
isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
|
|
46345
|
+
);
|
|
46176
46346
|
}
|
|
46177
46347
|
function layoutMap(resolved, data, size, opts) {
|
|
46178
46348
|
const { palette, isDark } = opts;
|
|
@@ -46193,28 +46363,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46193
46363
|
}
|
|
46194
46364
|
}
|
|
46195
46365
|
const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
|
|
46196
|
-
const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
|
|
46197
|
-
const neutralFill = mix(palette.colors.green, palette.bg, landTint);
|
|
46198
|
-
const water = mapBackgroundColor(palette);
|
|
46199
46366
|
const usContext = usLayer !== null;
|
|
46200
|
-
const foreignFill = mix(
|
|
46201
|
-
palette.colors.gray,
|
|
46202
|
-
palette.bg,
|
|
46203
|
-
isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46204
|
-
);
|
|
46205
46367
|
const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
|
|
46206
|
-
const
|
|
46368
|
+
const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
|
|
46207
46369
|
const scaleOverride = resolved.directives.scale;
|
|
46208
|
-
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...
|
|
46209
|
-
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...
|
|
46210
|
-
const rampHue = palette.colors.red;
|
|
46211
|
-
const hasRamp =
|
|
46212
|
-
const
|
|
46370
|
+
const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
|
|
46371
|
+
const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
|
|
46372
|
+
const rampHue = resolveColor(resolved.directives.regionMetricColor ?? "", palette) ?? palette.colors.red;
|
|
46373
|
+
const hasRamp = values.length > 0;
|
|
46374
|
+
const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
|
|
46213
46375
|
const matchColorGroup = (v) => {
|
|
46214
46376
|
const lv = v.trim().toLowerCase();
|
|
46215
46377
|
if (lv === "none") return null;
|
|
46216
|
-
if (
|
|
46217
|
-
return SCORE_NAME;
|
|
46378
|
+
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
46218
46379
|
const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
46219
46380
|
return tg ? tg.name : v;
|
|
46220
46381
|
};
|
|
@@ -46225,11 +46386,20 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46225
46386
|
} else if (resolved.directives.activeTag !== void 0) {
|
|
46226
46387
|
activeGroup = matchColorGroup(resolved.directives.activeTag);
|
|
46227
46388
|
} else {
|
|
46228
|
-
activeGroup =
|
|
46389
|
+
activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
|
|
46229
46390
|
}
|
|
46230
|
-
const activeIsScore =
|
|
46391
|
+
const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
|
|
46392
|
+
const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
|
|
46393
|
+
const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
|
|
46394
|
+
const water = mapBackgroundColor(palette, isDark, mutedBasemap);
|
|
46395
|
+
const lakeStroke = mix(regionStroke, water, 45);
|
|
46396
|
+
const foreignFill = mix(
|
|
46397
|
+
palette.colors.gray,
|
|
46398
|
+
palette.bg,
|
|
46399
|
+
mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
|
|
46400
|
+
);
|
|
46231
46401
|
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
46232
|
-
const
|
|
46402
|
+
const fillForValue = (s) => {
|
|
46233
46403
|
const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
|
|
46234
46404
|
const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
|
|
46235
46405
|
return mix(rampHue, rampBase, pct);
|
|
@@ -46252,9 +46422,16 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46252
46422
|
isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT
|
|
46253
46423
|
);
|
|
46254
46424
|
};
|
|
46425
|
+
const directFill = (name) => {
|
|
46426
|
+
const hex = name ? resolveColor(name, palette) : null;
|
|
46427
|
+
if (!hex) return null;
|
|
46428
|
+
return mix(hex, palette.bg, isDark ? TAG_TINT_DARK : TAG_TINT_LIGHT);
|
|
46429
|
+
};
|
|
46255
46430
|
const regionFill = (r) => {
|
|
46431
|
+
const direct = directFill(r.color);
|
|
46432
|
+
if (direct) return direct;
|
|
46256
46433
|
if (activeIsScore) {
|
|
46257
|
-
return r.
|
|
46434
|
+
return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
|
|
46258
46435
|
}
|
|
46259
46436
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
46260
46437
|
};
|
|
@@ -46306,6 +46483,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46306
46483
|
const fitIsGlobal = fitGB[1][0] - fitGB[0][0] >= 270 || fitGB[1][1] - fitGB[0][1] >= 130;
|
|
46307
46484
|
let path;
|
|
46308
46485
|
let project;
|
|
46486
|
+
let stretchParams = null;
|
|
46309
46487
|
if (fitIsGlobal) {
|
|
46310
46488
|
const cb = geoPath(projection).bounds(fitTarget);
|
|
46311
46489
|
const bx0 = cb[0][0];
|
|
@@ -46316,6 +46494,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46316
46494
|
const oy = fitBox[0][1];
|
|
46317
46495
|
const sx = cw > 0 ? (fitBox[1][0] - ox) / cw : 1;
|
|
46318
46496
|
const sy = ch > 0 ? (fitBox[1][1] - oy) / ch : 1;
|
|
46497
|
+
stretchParams = { sx, sy, ox, oy, bx0, by0 };
|
|
46319
46498
|
const stretch = (x, y) => [
|
|
46320
46499
|
ox + (x - bx0) * sx,
|
|
46321
46500
|
oy + (y - by0) * sy
|
|
@@ -46347,7 +46526,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46347
46526
|
const insets = [];
|
|
46348
46527
|
const insetRegions = [];
|
|
46349
46528
|
const insetLabelSeeds = [];
|
|
46350
|
-
if (resolved.projection === "albers-usa" && usLayer) {
|
|
46529
|
+
if (resolved.projection === "albers-usa" && usLayer && !resolved.directives.noInsets) {
|
|
46351
46530
|
const PAD = 8;
|
|
46352
46531
|
const GAP = 12;
|
|
46353
46532
|
const yB = height - FIT_PAD;
|
|
@@ -46378,38 +46557,14 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46378
46557
|
}
|
|
46379
46558
|
return y;
|
|
46380
46559
|
};
|
|
46381
|
-
const
|
|
46560
|
+
const coastFloor = (x0, xr) => {
|
|
46382
46561
|
const n = 24;
|
|
46383
|
-
const pts = [];
|
|
46384
46562
|
let maxY = -Infinity;
|
|
46385
46563
|
for (let i = 0; i <= n; i++) {
|
|
46386
|
-
const
|
|
46387
|
-
|
|
46388
|
-
|
|
46389
|
-
|
|
46390
|
-
if (y > maxY) maxY = y;
|
|
46391
|
-
}
|
|
46392
|
-
}
|
|
46393
|
-
if (pts.length === 0) return () => yB - height * 0.42;
|
|
46394
|
-
let m = 0;
|
|
46395
|
-
if (pts.length >= 2) {
|
|
46396
|
-
let sx = 0, sy = 0, sxx = 0, sxy = 0;
|
|
46397
|
-
for (const [x, y] of pts) {
|
|
46398
|
-
sx += x;
|
|
46399
|
-
sy += y;
|
|
46400
|
-
sxx += x * x;
|
|
46401
|
-
sxy += x * y;
|
|
46402
|
-
}
|
|
46403
|
-
const den = pts.length * sxx - sx * sx;
|
|
46404
|
-
if (den !== 0) m = (pts.length * sxy - sx * sy) / den;
|
|
46405
|
-
}
|
|
46406
|
-
m = Math.max(-0.35, Math.min(0.35, m));
|
|
46407
|
-
let c = -Infinity;
|
|
46408
|
-
for (const [x, y] of pts) {
|
|
46409
|
-
const need = y - m * x + GAP;
|
|
46410
|
-
if (need > c) c = need;
|
|
46411
|
-
}
|
|
46412
|
-
return (x) => m * x + c;
|
|
46564
|
+
const y = at(x0 + (xr - x0) * i / n);
|
|
46565
|
+
if (y > maxY) maxY = y;
|
|
46566
|
+
}
|
|
46567
|
+
return maxY;
|
|
46413
46568
|
};
|
|
46414
46569
|
const placeInset = (iso, proj, boxX, iwReq) => {
|
|
46415
46570
|
const f = usLayer.get(iso);
|
|
@@ -46418,19 +46573,15 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46418
46573
|
const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD);
|
|
46419
46574
|
if (iw < 24) return boxX;
|
|
46420
46575
|
const xr = x0 + iw + 2 * PAD;
|
|
46421
|
-
const
|
|
46422
|
-
const
|
|
46423
|
-
const yR = top(xr);
|
|
46576
|
+
const floor = coastFloor(x0, xr);
|
|
46577
|
+
const topGuess = floor > -Infinity ? floor + GAP : yB - height * 0.42;
|
|
46424
46578
|
proj.fitWidth(iw, f);
|
|
46425
46579
|
const bb = geoPath(proj).bounds(f);
|
|
46426
46580
|
const sh = Number.isFinite(bb[0][0]) ? bb[1][1] - bb[0][1] : iw;
|
|
46427
46581
|
const needH = sh + 2 * PAD;
|
|
46428
|
-
let topFit =
|
|
46582
|
+
let topFit = topGuess;
|
|
46429
46583
|
const bottom = Math.min(topFit + needH, yB);
|
|
46430
46584
|
if (bottom - topFit < needH) topFit = bottom - needH;
|
|
46431
|
-
const lift = topFit - Math.max(yL, yR);
|
|
46432
|
-
const topL = yL + lift;
|
|
46433
|
-
const topR = yR + lift;
|
|
46434
46585
|
proj.fitExtent(
|
|
46435
46586
|
[
|
|
46436
46587
|
[x0 + PAD, topFit + PAD],
|
|
@@ -46449,15 +46600,18 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46449
46600
|
}
|
|
46450
46601
|
insets.push({
|
|
46451
46602
|
x: x0,
|
|
46452
|
-
y:
|
|
46603
|
+
y: topFit,
|
|
46453
46604
|
w: xr - x0,
|
|
46454
|
-
h: bottom -
|
|
46605
|
+
h: bottom - topFit,
|
|
46455
46606
|
points: [
|
|
46456
|
-
[x0,
|
|
46457
|
-
[xr,
|
|
46607
|
+
[x0, topFit],
|
|
46608
|
+
[xr, topFit],
|
|
46458
46609
|
[xr, bottom],
|
|
46459
46610
|
[x0, bottom]
|
|
46460
|
-
]
|
|
46611
|
+
],
|
|
46612
|
+
// The FITTED inset projection (just fit to this box) — captured so the
|
|
46613
|
+
// geo-query can invert pixels inside the frame back to AK/HI coords.
|
|
46614
|
+
projection: proj
|
|
46461
46615
|
});
|
|
46462
46616
|
insetRegions.push({
|
|
46463
46617
|
id: iso,
|
|
@@ -46466,7 +46620,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46466
46620
|
stroke: regionStroke,
|
|
46467
46621
|
lineNumber,
|
|
46468
46622
|
layer: "us-state",
|
|
46469
|
-
...r?.
|
|
46623
|
+
...r?.value !== void 0 && { value: r.value },
|
|
46470
46624
|
...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46471
46625
|
});
|
|
46472
46626
|
const ctr = geoPath(proj).centroid(f);
|
|
@@ -46609,7 +46763,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46609
46763
|
lineNumber,
|
|
46610
46764
|
layer,
|
|
46611
46765
|
...label !== void 0 && { label },
|
|
46612
|
-
...isThisLayer && r.
|
|
46766
|
+
...isThisLayer && r.value !== void 0 && { value: r.value },
|
|
46613
46767
|
...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
46614
46768
|
});
|
|
46615
46769
|
}
|
|
@@ -46627,13 +46781,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46627
46781
|
id: "lake",
|
|
46628
46782
|
d,
|
|
46629
46783
|
fill: water,
|
|
46630
|
-
stroke:
|
|
46784
|
+
stroke: lakeStroke,
|
|
46631
46785
|
lineNumber: -1,
|
|
46632
46786
|
layer: "base"
|
|
46633
46787
|
});
|
|
46634
46788
|
}
|
|
46635
46789
|
}
|
|
46636
|
-
const
|
|
46790
|
+
const relief = [];
|
|
46791
|
+
let reliefHatch = null;
|
|
46792
|
+
if (resolved.directives.relief === true && data.mountainRanges) {
|
|
46793
|
+
for (const [, f] of decodeLayer(data.mountainRanges)) {
|
|
46794
|
+
const viewF = isGlobalView ? dropFrameFillers(f) : cullFeatureToView(f);
|
|
46795
|
+
if (!viewF) continue;
|
|
46796
|
+
const area2 = path.area(viewF);
|
|
46797
|
+
if (!Number.isFinite(area2) || area2 < RELIEF_MIN_AREA) continue;
|
|
46798
|
+
const box = path.bounds(viewF);
|
|
46799
|
+
if (box[1][0] - box[0][0] < RELIEF_MIN_DIM || box[1][1] - box[0][1] < RELIEF_MIN_DIM)
|
|
46800
|
+
continue;
|
|
46801
|
+
const d = path(viewF) ?? "";
|
|
46802
|
+
if (!d) continue;
|
|
46803
|
+
relief.push({ d });
|
|
46804
|
+
}
|
|
46805
|
+
if (relief.length) {
|
|
46806
|
+
const darkTone = isDark ? palette.bg : palette.text;
|
|
46807
|
+
const lightTone = isDark ? palette.text : palette.bg;
|
|
46808
|
+
const landLum = relativeLuminance(neutralFill);
|
|
46809
|
+
const tone = Math.abs(landLum - relativeLuminance(darkTone)) > 0.04 ? darkTone : lightTone;
|
|
46810
|
+
reliefHatch = {
|
|
46811
|
+
color: mix(tone, neutralFill, RELIEF_HATCH_STRENGTH),
|
|
46812
|
+
spacing: RELIEF_HATCH_SPACING,
|
|
46813
|
+
width: RELIEF_HATCH_WIDTH
|
|
46814
|
+
};
|
|
46815
|
+
}
|
|
46816
|
+
}
|
|
46817
|
+
const riverColor = mix(water, regionStroke, 16);
|
|
46637
46818
|
const rivers = [];
|
|
46638
46819
|
if (data.rivers) {
|
|
46639
46820
|
for (const [, f] of decodeLayer(data.rivers)) {
|
|
@@ -46644,16 +46825,19 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46644
46825
|
rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
|
|
46645
46826
|
}
|
|
46646
46827
|
}
|
|
46647
|
-
const sizeVals = resolved.pois.map((p) => Number(p.meta["
|
|
46828
|
+
const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46648
46829
|
const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
|
|
46649
46830
|
const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
|
|
46650
46831
|
const radiusFor = (p) => {
|
|
46651
|
-
const v = Number(p.meta["
|
|
46832
|
+
const v = Number(p.meta["value"]);
|
|
46652
46833
|
if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
|
|
46653
46834
|
const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
|
|
46654
46835
|
return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
|
|
46655
46836
|
};
|
|
46656
46837
|
const poiFill = (p) => {
|
|
46838
|
+
const directHex = p.color ? resolveColor(p.color, palette) : null;
|
|
46839
|
+
if (directHex)
|
|
46840
|
+
return { fill: directHex, stroke: mix(directHex, palette.text, 18) };
|
|
46657
46841
|
for (const group of resolved.tagGroups) {
|
|
46658
46842
|
const val = p.tags[group.name.toLowerCase()];
|
|
46659
46843
|
if (!val) continue;
|
|
@@ -46715,7 +46899,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46715
46899
|
lineNumber: e.p.lineNumber,
|
|
46716
46900
|
implicit: !!e.p.implicit,
|
|
46717
46901
|
isOrigin: originIds.has(e.p.id),
|
|
46718
|
-
...num !== void 0 && { routeNumber: num }
|
|
46902
|
+
...num !== void 0 && { routeNumber: num },
|
|
46903
|
+
...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
|
|
46719
46904
|
});
|
|
46720
46905
|
});
|
|
46721
46906
|
}
|
|
@@ -46751,26 +46936,40 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
46751
46936
|
const by = b.cy - (b.cy - py) / tb * trimB;
|
|
46752
46937
|
return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
|
|
46753
46938
|
};
|
|
46939
|
+
const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
|
|
46940
|
+
const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
|
|
46941
|
+
const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
|
|
46942
|
+
const routeWidthFor = (v) => {
|
|
46943
|
+
if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
|
|
46944
|
+
const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
|
|
46945
|
+
return W_MIN + t * (W_MAX - W_MIN);
|
|
46946
|
+
};
|
|
46754
46947
|
for (const rt of resolved.routes) {
|
|
46755
|
-
const
|
|
46756
|
-
|
|
46757
|
-
const
|
|
46758
|
-
const b = poiScreen.get(rt.stopIds[i]);
|
|
46948
|
+
for (const leg of rt.legs) {
|
|
46949
|
+
const a = poiScreen.get(leg.fromId);
|
|
46950
|
+
const b = poiScreen.get(leg.toId);
|
|
46759
46951
|
if (!a || !b) continue;
|
|
46952
|
+
const mx = (a.cx + b.cx) / 2;
|
|
46953
|
+
const my = (a.cy + b.cy) / 2;
|
|
46760
46954
|
legs.push({
|
|
46761
|
-
d: legPath(a, b,
|
|
46762
|
-
width:
|
|
46955
|
+
d: legPath(a, b, leg.style === "arc", 0),
|
|
46956
|
+
width: routeWidthFor(Number(leg.value)),
|
|
46763
46957
|
color: mix(palette.text, palette.bg, 72),
|
|
46764
46958
|
arrow: true,
|
|
46765
|
-
lineNumber:
|
|
46959
|
+
lineNumber: leg.lineNumber,
|
|
46960
|
+
...leg.label !== void 0 && {
|
|
46961
|
+
label: leg.label,
|
|
46962
|
+
labelX: mx,
|
|
46963
|
+
labelY: my - 4
|
|
46964
|
+
}
|
|
46766
46965
|
});
|
|
46767
46966
|
}
|
|
46768
46967
|
}
|
|
46769
|
-
const weightVals = resolved.edges.map((e) => Number(e.meta["
|
|
46968
|
+
const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
|
|
46770
46969
|
const wMin = weightVals.length ? Math.min(...weightVals) : 0;
|
|
46771
46970
|
const wMax = weightVals.length ? Math.max(...weightVals) : 0;
|
|
46772
46971
|
const widthFor = (e) => {
|
|
46773
|
-
const v = Number(e.meta["
|
|
46972
|
+
const v = Number(e.meta["value"]);
|
|
46774
46973
|
if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
|
|
46775
46974
|
const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
|
|
46776
46975
|
return W_MIN + t * (W_MAX - W_MIN);
|
|
@@ -47033,8 +47232,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47033
47232
|
activeGroup,
|
|
47034
47233
|
...hasRamp && {
|
|
47035
47234
|
ramp: {
|
|
47036
|
-
...resolved.directives.
|
|
47037
|
-
metric: resolved.directives.
|
|
47235
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47236
|
+
metric: resolved.directives.regionMetric
|
|
47038
47237
|
},
|
|
47039
47238
|
min: rampMin,
|
|
47040
47239
|
max: rampMax,
|
|
@@ -47054,19 +47253,24 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47054
47253
|
...resolved.caption !== void 0 && { caption: resolved.caption },
|
|
47055
47254
|
regions,
|
|
47056
47255
|
rivers,
|
|
47256
|
+
relief,
|
|
47257
|
+
reliefHatch,
|
|
47057
47258
|
legs,
|
|
47058
47259
|
pois,
|
|
47059
47260
|
labels,
|
|
47060
47261
|
legend,
|
|
47061
47262
|
insets,
|
|
47062
|
-
insetRegions
|
|
47263
|
+
insetRegions,
|
|
47264
|
+
projection,
|
|
47265
|
+
stretch: stretchParams
|
|
47063
47266
|
};
|
|
47064
47267
|
}
|
|
47065
|
-
var FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK,
|
|
47268
|
+
var FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT_LIGHT, WATER_TINT_DARK, RIVER_WIDTH, RELIEF_MIN_AREA, RELIEF_MIN_DIM, RELIEF_HATCH_SPACING, RELIEF_HATCH_WIDTH, RELIEF_HATCH_STRENGTH, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, MUTED_FOREIGN_LIGHT, MUTED_FOREIGN_DARK, COLO_R, GOLDEN_ANGLE, FAN_STEP, ARC_CURVE_FRAC, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, US_NON_CONUS;
|
|
47066
47269
|
var init_layout15 = __esm({
|
|
47067
47270
|
"src/map/layout.ts"() {
|
|
47068
47271
|
"use strict";
|
|
47069
47272
|
init_color_utils();
|
|
47273
|
+
init_colors();
|
|
47070
47274
|
init_label_layout();
|
|
47071
47275
|
init_legend_constants();
|
|
47072
47276
|
init_title_constants();
|
|
@@ -47079,14 +47283,22 @@ var init_layout15 = __esm({
|
|
|
47079
47283
|
W_MAX = 8;
|
|
47080
47284
|
FONT = 11;
|
|
47081
47285
|
COLO_EPS = 1.5;
|
|
47082
|
-
LAND_TINT_LIGHT =
|
|
47083
|
-
LAND_TINT_DARK =
|
|
47286
|
+
LAND_TINT_LIGHT = 12;
|
|
47287
|
+
LAND_TINT_DARK = 24;
|
|
47084
47288
|
TAG_TINT_LIGHT = 60;
|
|
47085
47289
|
TAG_TINT_DARK = 68;
|
|
47086
|
-
|
|
47290
|
+
WATER_TINT_LIGHT = 13;
|
|
47291
|
+
WATER_TINT_DARK = 14;
|
|
47087
47292
|
RIVER_WIDTH = 1.3;
|
|
47293
|
+
RELIEF_MIN_AREA = 12;
|
|
47294
|
+
RELIEF_MIN_DIM = 2;
|
|
47295
|
+
RELIEF_HATCH_SPACING = 3;
|
|
47296
|
+
RELIEF_HATCH_WIDTH = 0.25;
|
|
47297
|
+
RELIEF_HATCH_STRENGTH = 32;
|
|
47088
47298
|
FOREIGN_TINT_LIGHT = 30;
|
|
47089
47299
|
FOREIGN_TINT_DARK = 62;
|
|
47300
|
+
MUTED_FOREIGN_LIGHT = 28;
|
|
47301
|
+
MUTED_FOREIGN_DARK = 16;
|
|
47090
47302
|
COLO_R = 9;
|
|
47091
47303
|
GOLDEN_ANGLE = 2.399963229728653;
|
|
47092
47304
|
FAN_STEP = 16;
|
|
@@ -47141,7 +47353,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47141
47353
|
const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
|
|
47142
47354
|
if (r.layer !== "base") {
|
|
47143
47355
|
p.classed("dgmo-map-region", true).attr("data-region", r.id);
|
|
47144
|
-
if (r.
|
|
47356
|
+
if (r.value !== void 0) p.attr("data-value", r.value);
|
|
47145
47357
|
if (r.tags) {
|
|
47146
47358
|
for (const [group, value] of Object.entries(r.tags)) {
|
|
47147
47359
|
p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
@@ -47159,6 +47371,20 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47159
47371
|
}
|
|
47160
47372
|
};
|
|
47161
47373
|
for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
|
|
47374
|
+
if (layout.relief.length && layout.reliefHatch) {
|
|
47375
|
+
const h = layout.reliefHatch;
|
|
47376
|
+
const rangeClipId = "dgmo-relief-clip";
|
|
47377
|
+
const landClipId = "dgmo-relief-land";
|
|
47378
|
+
const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
|
|
47379
|
+
for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
|
|
47380
|
+
const landClip = defs.append("clipPath").attr("id", landClipId);
|
|
47381
|
+
for (const r of layout.regions)
|
|
47382
|
+
if (r.id !== "lake") landClip.append("path").attr("d", r.d);
|
|
47383
|
+
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");
|
|
47384
|
+
for (let y = h.spacing; y < height; y += h.spacing) {
|
|
47385
|
+
gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
|
|
47386
|
+
}
|
|
47387
|
+
}
|
|
47162
47388
|
if (layout.rivers.length) {
|
|
47163
47389
|
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none");
|
|
47164
47390
|
for (const r of layout.rivers) {
|
|
@@ -47202,6 +47428,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47202
47428
|
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);
|
|
47203
47429
|
}
|
|
47204
47430
|
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);
|
|
47431
|
+
if (poi.tags) {
|
|
47432
|
+
for (const [group, value] of Object.entries(poi.tags)) {
|
|
47433
|
+
c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
|
|
47434
|
+
}
|
|
47435
|
+
}
|
|
47205
47436
|
if (onClickItem) {
|
|
47206
47437
|
c.style("cursor", "pointer").on(
|
|
47207
47438
|
"click",
|
|
@@ -47251,7 +47482,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47251
47482
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
47252
47483
|
const ramp = layout.legend.ramp;
|
|
47253
47484
|
const scoreGroup = ramp ? {
|
|
47254
|
-
name: ramp.metric?.trim() || "
|
|
47485
|
+
name: ramp.metric?.trim() || "Value",
|
|
47255
47486
|
entries: [],
|
|
47256
47487
|
gradient: {
|
|
47257
47488
|
min: ramp.min,
|
|
@@ -47278,7 +47509,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
47278
47509
|
}
|
|
47279
47510
|
}
|
|
47280
47511
|
if (layout.title) {
|
|
47281
|
-
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);
|
|
47512
|
+
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);
|
|
47282
47513
|
}
|
|
47283
47514
|
if (layout.subtitle) {
|
|
47284
47515
|
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);
|
|
@@ -47310,6 +47541,120 @@ var init_renderer16 = __esm({
|
|
|
47310
47541
|
}
|
|
47311
47542
|
});
|
|
47312
47543
|
|
|
47544
|
+
// src/map/load-data.ts
|
|
47545
|
+
var load_data_exports = {};
|
|
47546
|
+
__export(load_data_exports, {
|
|
47547
|
+
loadMapData: () => loadMapData
|
|
47548
|
+
});
|
|
47549
|
+
async function loadNodeBuiltins() {
|
|
47550
|
+
const [{ readFile }, { fileURLToPath }, { dirname, resolve }] = await Promise.all([
|
|
47551
|
+
import("fs/promises"),
|
|
47552
|
+
import("url"),
|
|
47553
|
+
import("path")
|
|
47554
|
+
]);
|
|
47555
|
+
return { readFile, fileURLToPath, dirname, resolve };
|
|
47556
|
+
}
|
|
47557
|
+
async function readJson(nb, dir, name) {
|
|
47558
|
+
return JSON.parse(await nb.readFile(nb.resolve(dir, name), "utf8"));
|
|
47559
|
+
}
|
|
47560
|
+
async function firstExistingDir(nb, baseDir) {
|
|
47561
|
+
for (const rel of CANDIDATE_DIRS) {
|
|
47562
|
+
const dir = nb.resolve(baseDir, rel);
|
|
47563
|
+
try {
|
|
47564
|
+
await nb.readFile(nb.resolve(dir, FILES.gazetteer), "utf8");
|
|
47565
|
+
return dir;
|
|
47566
|
+
} catch {
|
|
47567
|
+
}
|
|
47568
|
+
}
|
|
47569
|
+
throw new Error(
|
|
47570
|
+
`map data assets not found near ${baseDir} (looked in ${CANDIDATE_DIRS.join(", ")}). Run \`pnpm build:map-data\` and \`pnpm build\`.`
|
|
47571
|
+
);
|
|
47572
|
+
}
|
|
47573
|
+
function validate(data) {
|
|
47574
|
+
const topoOk = (t) => !!t && t.type === "Topology" && !!t.objects;
|
|
47575
|
+
if (!topoOk(data.worldCoarse) || !topoOk(data.worldDetail) || !topoOk(data.usStates) || !data.gazetteer || !Array.isArray(data.gazetteer.cities) || !data.gazetteer.byName) {
|
|
47576
|
+
throw new Error("map data assets are malformed (failed shape validation)");
|
|
47577
|
+
}
|
|
47578
|
+
return data;
|
|
47579
|
+
}
|
|
47580
|
+
function moduleBaseDir(nb) {
|
|
47581
|
+
try {
|
|
47582
|
+
const url = import.meta.url;
|
|
47583
|
+
if (url) return nb.dirname(nb.fileURLToPath(url));
|
|
47584
|
+
} catch {
|
|
47585
|
+
}
|
|
47586
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
47587
|
+
return process.cwd();
|
|
47588
|
+
}
|
|
47589
|
+
function loadMapData() {
|
|
47590
|
+
cache ??= (async () => {
|
|
47591
|
+
const nb = await loadNodeBuiltins();
|
|
47592
|
+
const dir = await firstExistingDir(nb, moduleBaseDir(nb));
|
|
47593
|
+
const [
|
|
47594
|
+
worldCoarse,
|
|
47595
|
+
worldDetail,
|
|
47596
|
+
usStates,
|
|
47597
|
+
lakes,
|
|
47598
|
+
rivers,
|
|
47599
|
+
mountainRanges,
|
|
47600
|
+
naLand,
|
|
47601
|
+
naLakes,
|
|
47602
|
+
gazetteer
|
|
47603
|
+
] = await Promise.all([
|
|
47604
|
+
readJson(nb, dir, FILES.worldCoarse),
|
|
47605
|
+
readJson(nb, dir, FILES.worldDetail),
|
|
47606
|
+
readJson(nb, dir, FILES.usStates),
|
|
47607
|
+
// Lakes/rivers/mountain/NA assets are optional — older bundles may predate them.
|
|
47608
|
+
readJson(nb, dir, FILES.lakes).catch(() => void 0),
|
|
47609
|
+
readJson(nb, dir, FILES.rivers).catch(() => void 0),
|
|
47610
|
+
readJson(nb, dir, FILES.mountainRanges).catch(
|
|
47611
|
+
() => void 0
|
|
47612
|
+
),
|
|
47613
|
+
readJson(nb, dir, FILES.naLand).catch(() => void 0),
|
|
47614
|
+
readJson(nb, dir, FILES.naLakes).catch(() => void 0),
|
|
47615
|
+
readJson(nb, dir, FILES.gazetteer)
|
|
47616
|
+
]);
|
|
47617
|
+
return validate({
|
|
47618
|
+
worldCoarse,
|
|
47619
|
+
worldDetail,
|
|
47620
|
+
usStates,
|
|
47621
|
+
gazetteer,
|
|
47622
|
+
...lakes && { lakes },
|
|
47623
|
+
...rivers && { rivers },
|
|
47624
|
+
...mountainRanges && { mountainRanges },
|
|
47625
|
+
...naLand && { naLand },
|
|
47626
|
+
...naLakes && { naLakes }
|
|
47627
|
+
});
|
|
47628
|
+
})().catch((e) => {
|
|
47629
|
+
cache = void 0;
|
|
47630
|
+
throw e;
|
|
47631
|
+
});
|
|
47632
|
+
return cache;
|
|
47633
|
+
}
|
|
47634
|
+
var FILES, CANDIDATE_DIRS, cache;
|
|
47635
|
+
var init_load_data = __esm({
|
|
47636
|
+
"src/map/load-data.ts"() {
|
|
47637
|
+
"use strict";
|
|
47638
|
+
FILES = {
|
|
47639
|
+
worldCoarse: "world-coarse.json",
|
|
47640
|
+
worldDetail: "world-detail.json",
|
|
47641
|
+
usStates: "us-states.json",
|
|
47642
|
+
lakes: "lakes.json",
|
|
47643
|
+
rivers: "rivers.json",
|
|
47644
|
+
mountainRanges: "mountain-ranges.json",
|
|
47645
|
+
naLand: "na-land.json",
|
|
47646
|
+
naLakes: "na-lakes.json",
|
|
47647
|
+
gazetteer: "gazetteer.json"
|
|
47648
|
+
};
|
|
47649
|
+
CANDIDATE_DIRS = [
|
|
47650
|
+
"./data",
|
|
47651
|
+
"./map-data",
|
|
47652
|
+
"../map-data",
|
|
47653
|
+
"../src/map/data"
|
|
47654
|
+
];
|
|
47655
|
+
}
|
|
47656
|
+
});
|
|
47657
|
+
|
|
47313
47658
|
// src/pyramid/renderer.ts
|
|
47314
47659
|
var renderer_exports17 = {};
|
|
47315
47660
|
__export(renderer_exports17, {
|
|
@@ -55438,15 +55783,17 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
55438
55783
|
if (detectedType === "map") {
|
|
55439
55784
|
const { parseMap: parseMap2 } = await Promise.resolve().then(() => (init_parser12(), parser_exports11));
|
|
55440
55785
|
const { resolveMap: resolveMap2 } = await Promise.resolve().then(() => (init_resolver2(), resolver_exports));
|
|
55441
|
-
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55442
55786
|
const { renderMapForExport: renderMapForExport2 } = await Promise.resolve().then(() => (init_renderer16(), renderer_exports16));
|
|
55443
55787
|
const effectivePalette2 = await resolveExportPalette(theme, palette);
|
|
55444
55788
|
const mapParsed = parseMap2(content);
|
|
55445
|
-
let mapData;
|
|
55446
|
-
|
|
55447
|
-
|
|
55448
|
-
|
|
55449
|
-
|
|
55789
|
+
let mapData = options?.mapData;
|
|
55790
|
+
if (!mapData) {
|
|
55791
|
+
const { loadMapData: loadMapData2 } = await Promise.resolve().then(() => (init_load_data(), load_data_exports));
|
|
55792
|
+
try {
|
|
55793
|
+
mapData = await loadMapData2();
|
|
55794
|
+
} catch {
|
|
55795
|
+
return "";
|
|
55796
|
+
}
|
|
55450
55797
|
}
|
|
55451
55798
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
55452
55799
|
const container2 = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|