@math.gl/geospatial 5.0.0-beta.1 → 5.0.0-beta.2
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/crs/crs-identifier.d.ts +23 -0
- package/dist/crs/crs-identifier.d.ts.map +1 -0
- package/dist/crs/crs-identifier.js +74 -0
- package/dist/crs/crs-identifier.js.map +1 -0
- package/dist/crs/index.cjs +48 -0
- package/dist/crs/index.cjs.map +2 -2
- package/dist/crs/index.d.ts +1 -0
- package/dist/crs/index.d.ts.map +1 -1
- package/dist/crs/index.js +1 -0
- package/dist/crs/index.js.map +1 -1
- package/dist/discontinuous/cap-map.d.ts.map +1 -1
- package/dist/discontinuous/cap-map.js +197 -13
- package/dist/discontinuous/cap-map.js.map +1 -1
- package/dist/discontinuous/elastic/geometry.d.ts +1 -1
- package/dist/discontinuous/elastic/geometry.d.ts.map +1 -1
- package/dist/discontinuous/elastic/geometry.js +7 -7
- package/dist/discontinuous/elastic/geometry.js.map +1 -1
- package/dist/discontinuous/elastic/map.d.ts.map +1 -1
- package/dist/discontinuous/elastic/map.js +263 -23
- package/dist/discontinuous/elastic/map.js.map +1 -1
- package/dist/discontinuous/elastic/source-arc.d.ts +10 -0
- package/dist/discontinuous/elastic/source-arc.d.ts.map +1 -0
- package/dist/discontinuous/elastic/source-arc.js +111 -0
- package/dist/discontinuous/elastic/source-arc.js.map +1 -0
- package/dist/discontinuous/global-polygons.d.ts +1 -1
- package/dist/discontinuous/global-polygons.d.ts.map +1 -1
- package/dist/discontinuous/global-polygons.js +49 -1
- package/dist/discontinuous/global-polygons.js.map +1 -1
- package/dist/discontinuous/map-engine.d.ts +9 -0
- package/dist/discontinuous/map-engine.d.ts.map +1 -1
- package/dist/discontinuous/map-layout.d.ts +21 -0
- package/dist/discontinuous/map-layout.d.ts.map +1 -1
- package/dist/discontinuous/map-layout.js +116 -1
- package/dist/discontinuous/map-layout.js.map +1 -1
- package/dist/discontinuous/map-transition.d.ts.map +1 -1
- package/dist/discontinuous/map-transition.js +66 -3
- package/dist/discontinuous/map-transition.js.map +1 -1
- package/dist/discontinuous/mercator-map.d.ts +2 -2
- package/dist/discontinuous/mercator-map.d.ts.map +1 -1
- package/dist/discontinuous/mercator-map.js +123 -11
- package/dist/discontinuous/mercator-map.js.map +1 -1
- package/dist/discontinuous/polygon-constraints.d.ts +16 -0
- package/dist/discontinuous/polygon-constraints.d.ts.map +1 -0
- package/dist/discontinuous/polygon-constraints.js +157 -0
- package/dist/discontinuous/polygon-constraints.js.map +1 -0
- package/dist/discontinuous/prepare-features.d.ts +27 -0
- package/dist/discontinuous/prepare-features.d.ts.map +1 -1
- package/dist/discontinuous/prepare-features.js +106 -5
- package/dist/discontinuous/prepare-features.js.map +1 -1
- package/dist/discontinuous/rotated-map.d.ts +9 -0
- package/dist/discontinuous/rotated-map.d.ts.map +1 -1
- package/dist/discontinuous/source-arc.d.ts +4 -0
- package/dist/discontinuous/source-arc.d.ts.map +1 -0
- package/dist/discontinuous/source-arc.js +23 -0
- package/dist/discontinuous/source-arc.js.map +1 -0
- package/dist/discontinuous/world-kernels.d.ts +1 -1
- package/dist/discontinuous.cjs +1047 -75
- package/dist/discontinuous.cjs.map +3 -3
- package/dist/index.cjs +48 -0
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/turf.cjs +69 -5
- package/dist/turf.cjs.map +2 -2
- package/dist/turf.d.ts +9 -0
- package/dist/turf.d.ts.map +1 -1
- package/dist/turf.js +67 -0
- package/dist/turf.js.map +1 -1
- package/dist/workers/index.cjs +1075 -79
- package/dist/workers/index.cjs.map +3 -3
- package/dist/workers/operations.cjs +1049 -77
- package/dist/workers/operations.cjs.map +3 -3
- package/package.json +5 -5
- package/src/crs/crs-identifier.ts +86 -0
- package/src/crs/index.ts +1 -0
- package/src/discontinuous/cap-map.ts +248 -19
- package/src/discontinuous/elastic/geometry.ts +18 -7
- package/src/discontinuous/elastic/map.ts +334 -30
- package/src/discontinuous/elastic/source-arc.ts +129 -0
- package/src/discontinuous/global-polygons.ts +56 -2
- package/src/discontinuous/map-layout.ts +165 -2
- package/src/discontinuous/map-transition.ts +67 -3
- package/src/discontinuous/mercator-map.ts +151 -12
- package/src/discontinuous/polygon-constraints.ts +184 -0
- package/src/discontinuous/prepare-features.ts +154 -6
- package/src/discontinuous/source-arc.ts +31 -0
- package/src/index.ts +1 -0
- package/src/turf.ts +86 -0
|
@@ -13546,8 +13546,49 @@ function cutSphericalPolygon(rings, options) {
|
|
|
13546
13546
|
}
|
|
13547
13547
|
function projectSphericalPolygon(map, rings, options) {
|
|
13548
13548
|
const result = [];
|
|
13549
|
+
if (options.polygonEdgeProvenance && (!map.regions || !map.seams))
|
|
13550
|
+
throw new Error("Atlas provenance requires map region and seam metadata");
|
|
13549
13551
|
for (const part of cutSphericalPolygon(rings, options))
|
|
13550
|
-
|
|
13552
|
+
for (const polygon of map.projectPolygon(part.rings, options)) {
|
|
13553
|
+
if (options.polygonEdgeProvenance) {
|
|
13554
|
+
if (!polygon.edgeProvenance)
|
|
13555
|
+
throw new Error("Map backend does not support polygon edge provenance");
|
|
13556
|
+
const region = map.regions.find((r) => r.id === polygon.regionId);
|
|
13557
|
+
polygon.edgeProvenance = polygon.edgeProvenance.map((edges, ring) => edges.map((edge2, i) => {
|
|
13558
|
+
if (edge2.kind !== "source-boundary")
|
|
13559
|
+
return edge2;
|
|
13560
|
+
const parent = part.edges[edge2.ring][edge2.segment];
|
|
13561
|
+
if (parent.kind === "source")
|
|
13562
|
+
return {
|
|
13563
|
+
...edge2,
|
|
13564
|
+
ring: parent.ringIndex,
|
|
13565
|
+
segment: parent.edgeIndex,
|
|
13566
|
+
t0: parent.startFraction + edge2.t0 * (parent.endFraction - parent.startFraction),
|
|
13567
|
+
t1: parent.startFraction + edge2.t1 * (parent.endFraction - parent.startFraction)
|
|
13568
|
+
};
|
|
13569
|
+
const a = geographic(polygon.sourceCoordinates[ring][i]), b = geographic(polygon.sourceCoordinates[ring][i + 1]), kinds = [];
|
|
13570
|
+
region.boundary.forEach((p, j) => {
|
|
13571
|
+
const normal = cross(geographic(p), geographic(region.boundary[(j + 1) % region.boundary.length]));
|
|
13572
|
+
const length = Math.hypot(...normal);
|
|
13573
|
+
if (length < 1e-12)
|
|
13574
|
+
return;
|
|
13575
|
+
if ([a, b].every((v) => Math.abs(dot(normal, v)) / length < 1e-10)) {
|
|
13576
|
+
const seam = map.seams.find((s) => s.regions.some((id, k2) => id === region.id && s.edges[k2] === j));
|
|
13577
|
+
if (seam)
|
|
13578
|
+
kinds.push(seam.kind);
|
|
13579
|
+
}
|
|
13580
|
+
});
|
|
13581
|
+
return {
|
|
13582
|
+
kind: kinds.includes("boundary") ? "coverage-boundary" : kinds.includes("cut") ? "chart-cut" : "continuous-chart-join",
|
|
13583
|
+
ring: 4294967295,
|
|
13584
|
+
segment: 4294967295,
|
|
13585
|
+
t0: 0,
|
|
13586
|
+
t1: 0
|
|
13587
|
+
};
|
|
13588
|
+
}));
|
|
13589
|
+
}
|
|
13590
|
+
result.push(polygon);
|
|
13591
|
+
}
|
|
13551
13592
|
return result;
|
|
13552
13593
|
}
|
|
13553
13594
|
|
|
@@ -13584,33 +13625,13 @@ var lerp = (a, b, t) => [
|
|
|
13584
13625
|
a[0] + (b[0] - a[0]) * t,
|
|
13585
13626
|
a[1] + (b[1] - a[1]) * t
|
|
13586
13627
|
];
|
|
13587
|
-
function clipSegment(a, b, polygons) {
|
|
13588
|
-
const ts = [0, 1], dx = b[0] - a[0], dy = b[1] - a[1];
|
|
13589
|
-
for (const rings of polygons)
|
|
13590
|
-
for (const ring of rings)
|
|
13591
|
-
for (let i = 1; i < ring.length; i++) {
|
|
13592
|
-
const c = ring[i - 1], d = ring[i], ex = d[0] - c[0], ey = d[1] - c[1], det = dx * ey - dy * ex;
|
|
13593
|
-
if (Math.abs(det) < 1e-14)
|
|
13594
|
-
continue;
|
|
13595
|
-
const t = ((c[0] - a[0]) * ey - (c[1] - a[1]) * ex) / det;
|
|
13596
|
-
const u = ((c[0] - a[0]) * dy - (c[1] - a[1]) * dx) / det;
|
|
13597
|
-
if (t > 0 && t < 1 && u >= -1e-10 && u <= 1 + 1e-10)
|
|
13598
|
-
ts.push(t);
|
|
13599
|
-
}
|
|
13600
|
-
ts.sort((a2, b2) => a2 - b2);
|
|
13601
|
-
const result = [];
|
|
13602
|
-
for (let i = 1; i < ts.length; i++)
|
|
13603
|
-
if (ts[i] - ts[i - 1] > 1e-12 && contains(polygons, lerp(a, b, (ts[i] + ts[i - 1]) / 2)))
|
|
13604
|
-
result.push([lerp(a, b, ts[i - 1]), lerp(a, b, ts[i])]);
|
|
13605
|
-
return result;
|
|
13606
|
-
}
|
|
13607
13628
|
function sampling(options) {
|
|
13608
13629
|
const step = options.maxAngularStep ?? 2, tolerance = options.tolerance ?? 1e-4;
|
|
13609
13630
|
if (!Number.isFinite(step) || step <= 0 || step > 90 || !Number.isFinite(tolerance) || tolerance <= 0)
|
|
13610
13631
|
throw new Error("Invalid map sampling options");
|
|
13611
13632
|
return { step, tolerance };
|
|
13612
13633
|
}
|
|
13613
|
-
function sample(line, project, options, cellStep) {
|
|
13634
|
+
function sample(line, project, options, cellStep, interpolate) {
|
|
13614
13635
|
const { step, tolerance } = sampling(options), source = [], xy = [];
|
|
13615
13636
|
const emit = (p, q) => {
|
|
13616
13637
|
if (source.length >= 1e5)
|
|
@@ -13621,23 +13642,23 @@ function sample(line, project, options, cellStep) {
|
|
|
13621
13642
|
const at = (p) => {
|
|
13622
13643
|
const q = project(p);
|
|
13623
13644
|
if (!q)
|
|
13624
|
-
throw new Error(
|
|
13645
|
+
throw new Error(`Elastic grid is undefined inside its coverage at ${p}`);
|
|
13625
13646
|
return q;
|
|
13626
13647
|
};
|
|
13627
|
-
const visit = (a, b, qa, qb, depth) => {
|
|
13628
|
-
const mid = lerp(a, b, 0.5), qm = at(mid), chord2 = lerp(qa, qb, 0.5);
|
|
13648
|
+
const visit = (a, b, qa, qb, depth, segment, t0, t1) => {
|
|
13649
|
+
const tm = (t0 + t1) / 2, mid = interpolate ? interpolate(segment, tm) : lerp(a, b, 0.5), qm = at(mid), chord2 = lerp(qa, qb, 0.5);
|
|
13629
13650
|
if (Math.hypot(b[0] - a[0], b[1] - a[1]) > Math.min(step, cellStep / 2) || Math.hypot(qm[0] - chord2[0], qm[1] - chord2[1]) > tolerance) {
|
|
13630
13651
|
if (depth >= 24)
|
|
13631
13652
|
throw new Error("Elastic sampling limit exceeded");
|
|
13632
|
-
visit(a, mid, qa, qm, depth + 1);
|
|
13633
|
-
visit(mid, b, qm, qb, depth + 1);
|
|
13653
|
+
visit(a, mid, qa, qm, depth + 1, segment, t0, tm);
|
|
13654
|
+
visit(mid, b, qm, qb, depth + 1, segment, tm, t1);
|
|
13634
13655
|
} else
|
|
13635
13656
|
emit(b, qb);
|
|
13636
13657
|
};
|
|
13637
13658
|
if (line.length) {
|
|
13638
13659
|
emit(line[0], at(line[0]));
|
|
13639
13660
|
for (let i = 1; i < line.length; i++)
|
|
13640
|
-
visit(line[i - 1], line[i], at(line[i - 1]), at(line[i]), 0);
|
|
13661
|
+
visit(line[i - 1], line[i], at(line[i - 1]), at(line[i]), 0, i - 1, 0, 1);
|
|
13641
13662
|
}
|
|
13642
13663
|
return { source, xy };
|
|
13643
13664
|
}
|
|
@@ -13674,6 +13695,65 @@ function indexDomain(polygons) {
|
|
|
13674
13695
|
}
|
|
13675
13696
|
|
|
13676
13697
|
// dist/discontinuous/map-transition.js
|
|
13698
|
+
var directWorldProjections = /* @__PURE__ */ new Set([
|
|
13699
|
+
"gilbert",
|
|
13700
|
+
"aitoff",
|
|
13701
|
+
"august",
|
|
13702
|
+
"baker",
|
|
13703
|
+
"boggs",
|
|
13704
|
+
"bromley",
|
|
13705
|
+
"collignon",
|
|
13706
|
+
"craster",
|
|
13707
|
+
"eckert1",
|
|
13708
|
+
"eckert2",
|
|
13709
|
+
"eckert3",
|
|
13710
|
+
"eckert4",
|
|
13711
|
+
"eckert5",
|
|
13712
|
+
"eckert6",
|
|
13713
|
+
"fahey",
|
|
13714
|
+
"foucaut",
|
|
13715
|
+
"ginzburg4",
|
|
13716
|
+
"ginzburg5",
|
|
13717
|
+
"ginzburg6",
|
|
13718
|
+
"ginzburg8",
|
|
13719
|
+
"ginzburg9",
|
|
13720
|
+
"homolosine",
|
|
13721
|
+
"kavrayskiy7",
|
|
13722
|
+
"larrivee",
|
|
13723
|
+
"laskowski",
|
|
13724
|
+
"miller",
|
|
13725
|
+
"mollweide",
|
|
13726
|
+
"mt-flat-polar-parabolic",
|
|
13727
|
+
"mt-flat-polar-quartic",
|
|
13728
|
+
"mt-flat-polar-sinusoidal",
|
|
13729
|
+
"natural-earth2",
|
|
13730
|
+
"nell-hammer",
|
|
13731
|
+
"patterson",
|
|
13732
|
+
"robinson",
|
|
13733
|
+
"sinusoidal",
|
|
13734
|
+
"times",
|
|
13735
|
+
"van-der-grinten",
|
|
13736
|
+
"van-der-grinten2",
|
|
13737
|
+
"van-der-grinten3",
|
|
13738
|
+
"van-der-grinten4",
|
|
13739
|
+
"wagner4",
|
|
13740
|
+
"wagner6",
|
|
13741
|
+
"winkel3",
|
|
13742
|
+
"bonne",
|
|
13743
|
+
"bottomley",
|
|
13744
|
+
"cylindrical-equal-area",
|
|
13745
|
+
"cylindrical-stereographic",
|
|
13746
|
+
"foucaut-sinusoidal",
|
|
13747
|
+
"hammer",
|
|
13748
|
+
"hill",
|
|
13749
|
+
"hufnagel",
|
|
13750
|
+
"hyperelliptical",
|
|
13751
|
+
"lagrange",
|
|
13752
|
+
"loximuthal",
|
|
13753
|
+
"wagner7",
|
|
13754
|
+
"quartic-authalic",
|
|
13755
|
+
"wagner"
|
|
13756
|
+
]);
|
|
13677
13757
|
var MapTransitionGeometry = class {
|
|
13678
13758
|
constructor(parts, strategy, radius2) {
|
|
13679
13759
|
this.strategy = strategy;
|
|
@@ -13905,7 +13985,7 @@ function fullCoverage(map) {
|
|
|
13905
13985
|
const overlaps = domains.some((domain, i) => domains.slice(i + 1).some((other) => import_polygon_clipping2.default.intersection(domain, other).length > 0));
|
|
13906
13986
|
covered = completeSections && !overlaps && import_polygon_clipping2.default.difference(world, ...domains).length === 0;
|
|
13907
13987
|
} else if (d.type === "world") {
|
|
13908
|
-
covered =
|
|
13988
|
+
covered = directWorldProjections.has(d.projection) && Object.keys(d.parameters ?? {}).length === 0;
|
|
13909
13989
|
}
|
|
13910
13990
|
coverageCache.set(map, covered);
|
|
13911
13991
|
return covered;
|
|
@@ -13955,6 +14035,16 @@ function prepareMapFeatures(map, features, options = {}) {
|
|
|
13955
14035
|
throw new Error("Expected a feature array");
|
|
13956
14036
|
if (options.polygonOutlines !== void 0 && typeof options.polygonOutlines !== "boolean")
|
|
13957
14037
|
throw new Error("polygonOutlines must be boolean");
|
|
14038
|
+
const provenance = options.provenance;
|
|
14039
|
+
if (provenance !== void 0 && (!provenance || typeof provenance !== "object" || Array.isArray(provenance)))
|
|
14040
|
+
throw new Error("Unsupported provenance policy");
|
|
14041
|
+
if ((provenance == null ? void 0 : provenance.distances) !== void 0 && (!provenance.distances || typeof provenance.distances !== "object"))
|
|
14042
|
+
throw new Error("Unsupported provenance distance policy");
|
|
14043
|
+
if (provenance && (typeof provenance !== "object" || Object.keys(provenance).some((k2) => !["sourceSegments", "boundaries", "distances", "polygonEdges"].includes(k2)) || [provenance.sourceSegments, provenance.boundaries, provenance.polygonEdges].some((v) => v !== void 0 && typeof v !== "boolean") || provenance.distances && (provenance.distances.metric !== "spherical" || !Number.isFinite(provenance.distances.radius) || provenance.distances.radius <= 0)))
|
|
14044
|
+
throw new Error("Unsupported provenance policy");
|
|
14045
|
+
const edgeKinds = [], edgeRings = [], edgeSegments = [], edgeParameters = [];
|
|
14046
|
+
const lineage = Boolean((provenance == null ? void 0 : provenance.sourceSegments) || (provenance == null ? void 0 : provenance.boundaries) || (provenance == null ? void 0 : provenance.distances));
|
|
14047
|
+
const segments = [], parameters = [], originalVertices = [], distances = [], startReasons = [], endReasons = [];
|
|
13958
14048
|
const regionIds = map.regions.map((r) => r.id), regionIndices = new Map(regionIds.map((id, i) => [id, i]));
|
|
13959
14049
|
const points = vertices(), paths = vertices(), polygons = vertices();
|
|
13960
14050
|
const pointParts = [], pathParts = [], polygonParts = [];
|
|
@@ -13975,7 +14065,27 @@ function prepareMapFeatures(map, features, options = {}) {
|
|
|
13975
14065
|
const isRing = ringIndex !== void 0;
|
|
13976
14066
|
if (isRing && !closed(line))
|
|
13977
14067
|
line.push([...line[0]]);
|
|
13978
|
-
for (const p of map.projectLine(line,
|
|
14068
|
+
for (const p of map.projectLine(line, {
|
|
14069
|
+
...options.sampling,
|
|
14070
|
+
pathProvenance: lineage,
|
|
14071
|
+
pathDistances: Boolean(provenance == null ? void 0 : provenance.distances),
|
|
14072
|
+
pathBoundaries: Boolean(provenance == null ? void 0 : provenance.boundaries)
|
|
14073
|
+
})) {
|
|
14074
|
+
if (lineage) {
|
|
14075
|
+
if (!p.provenance)
|
|
14076
|
+
throw new Error("Map backend does not support path provenance");
|
|
14077
|
+
if (provenance == null ? void 0 : provenance.sourceSegments) {
|
|
14078
|
+
segments.push(...p.provenance.segments);
|
|
14079
|
+
parameters.push(...p.provenance.parameters);
|
|
14080
|
+
originalVertices.push(...p.provenance.vertices);
|
|
14081
|
+
}
|
|
14082
|
+
if (provenance == null ? void 0 : provenance.distances)
|
|
14083
|
+
distances.push(...p.provenance.angularDistances.map((d) => d * provenance.distances.radius));
|
|
14084
|
+
if (provenance == null ? void 0 : provenance.boundaries) {
|
|
14085
|
+
startReasons.push(p.provenance.startReason);
|
|
14086
|
+
endReasons.push(p.provenance.endReason);
|
|
14087
|
+
}
|
|
14088
|
+
}
|
|
13979
14089
|
append(paths, p.coordinates, p.sourceCoordinates);
|
|
13980
14090
|
pathParts.push({
|
|
13981
14091
|
...part(featureIndex, geometryPath, p.regionId),
|
|
@@ -13987,12 +14097,41 @@ function prepareMapFeatures(map, features, options = {}) {
|
|
|
13987
14097
|
}
|
|
13988
14098
|
};
|
|
13989
14099
|
const addPolygon = (input, featureIndex, geometryPath) => {
|
|
14100
|
+
var _a2;
|
|
13990
14101
|
if (!input.length)
|
|
13991
14102
|
return;
|
|
13992
14103
|
const rings = input.map((r) => r.map(position));
|
|
13993
|
-
const parts = options.sphericalCuts ? map.projectGlobalPolygon(rings, {
|
|
14104
|
+
const parts = options.sphericalCuts ? map.projectGlobalPolygon(rings, {
|
|
14105
|
+
...options.sampling,
|
|
14106
|
+
...options.sphericalCuts,
|
|
14107
|
+
polygonEdgeProvenance: provenance == null ? void 0 : provenance.polygonEdges
|
|
14108
|
+
}) : map.projectPolygon(rings, {
|
|
14109
|
+
...options.sampling,
|
|
14110
|
+
polygonEdgeProvenance: provenance == null ? void 0 : provenance.polygonEdges
|
|
14111
|
+
});
|
|
13994
14112
|
for (const p of parts) {
|
|
13995
14113
|
for (let i = 0; i < p.coordinates.length; i++) {
|
|
14114
|
+
if (provenance == null ? void 0 : provenance.polygonEdges) {
|
|
14115
|
+
const edges = (_a2 = p.edgeProvenance) == null ? void 0 : _a2[i];
|
|
14116
|
+
if (!edges)
|
|
14117
|
+
throw new Error("Map backend does not support polygon edge provenance");
|
|
14118
|
+
const kinds = [
|
|
14119
|
+
"source-boundary",
|
|
14120
|
+
"coverage-boundary",
|
|
14121
|
+
"chart-cut",
|
|
14122
|
+
"continuous-chart-join"
|
|
14123
|
+
];
|
|
14124
|
+
for (const edge2 of edges) {
|
|
14125
|
+
edgeKinds.push(kinds.indexOf(edge2.kind) + 1);
|
|
14126
|
+
edgeRings.push(edge2.ring);
|
|
14127
|
+
edgeSegments.push(edge2.segment);
|
|
14128
|
+
edgeParameters.push(edge2.t0, edge2.t1);
|
|
14129
|
+
}
|
|
14130
|
+
edgeKinds.push(0);
|
|
14131
|
+
edgeRings.push(4294967295);
|
|
14132
|
+
edgeSegments.push(4294967295);
|
|
14133
|
+
edgeParameters.push(0, 0);
|
|
14134
|
+
}
|
|
13996
14135
|
append(polygons, p.coordinates[i], p.sourceCoordinates[i]);
|
|
13997
14136
|
ringStarts.push(polygons.positions.length / 2);
|
|
13998
14137
|
}
|
|
@@ -14056,12 +14195,38 @@ function prepareMapFeatures(map, features, options = {}) {
|
|
|
14056
14195
|
featureIds,
|
|
14057
14196
|
regionIds,
|
|
14058
14197
|
points: { ...pack(points), parts: pointParts },
|
|
14059
|
-
paths: {
|
|
14198
|
+
paths: {
|
|
14199
|
+
...pack(paths),
|
|
14200
|
+
parts: pathParts,
|
|
14201
|
+
pathStarts: new Uint32Array(pathStarts),
|
|
14202
|
+
...lineage ? {
|
|
14203
|
+
provenance: {
|
|
14204
|
+
...(provenance == null ? void 0 : provenance.sourceSegments) ? {
|
|
14205
|
+
sourceSegmentIndices: new Uint32Array(segments),
|
|
14206
|
+
sourceSegmentParameters: new Float64Array(parameters),
|
|
14207
|
+
sourceVertexIndices: new Uint32Array(originalVertices)
|
|
14208
|
+
} : {},
|
|
14209
|
+
...(provenance == null ? void 0 : provenance.distances) ? {
|
|
14210
|
+
sourceDistances: new Float64Array(distances),
|
|
14211
|
+
distanceRadius: provenance.distances.radius
|
|
14212
|
+
} : {},
|
|
14213
|
+
...(provenance == null ? void 0 : provenance.boundaries) ? { startReasons, endReasons } : {}
|
|
14214
|
+
}
|
|
14215
|
+
} : {}
|
|
14216
|
+
},
|
|
14060
14217
|
polygons: {
|
|
14061
14218
|
...pack(polygons),
|
|
14062
14219
|
parts: polygonParts,
|
|
14063
14220
|
ringStarts: new Uint32Array(ringStarts),
|
|
14064
|
-
polygonStarts: new Uint32Array(polygonStarts)
|
|
14221
|
+
polygonStarts: new Uint32Array(polygonStarts),
|
|
14222
|
+
...(provenance == null ? void 0 : provenance.polygonEdges) ? {
|
|
14223
|
+
edgeProvenance: {
|
|
14224
|
+
kinds: new Uint8Array(edgeKinds),
|
|
14225
|
+
sourceRingIndices: new Uint32Array(edgeRings),
|
|
14226
|
+
sourceSegmentIndices: new Uint32Array(edgeSegments),
|
|
14227
|
+
sourceParameterRanges: new Float64Array(edgeParameters)
|
|
14228
|
+
}
|
|
14229
|
+
} : {}
|
|
14065
14230
|
}
|
|
14066
14231
|
};
|
|
14067
14232
|
}
|
|
@@ -14069,6 +14234,171 @@ function prepareMapFeatures(map, features, options = {}) {
|
|
|
14069
14234
|
// dist/discontinuous/elastic/map.js
|
|
14070
14235
|
var import_polygon_clipping4 = __toESM(require("polygon-clipping"), 1);
|
|
14071
14236
|
|
|
14237
|
+
// dist/discontinuous/polygon-constraints.js
|
|
14238
|
+
function tracePolygonConstraints(input, output, tolerance = 1e-10, priorities, accept, degenerate) {
|
|
14239
|
+
const constraints = input.flatMap((ring, r) => ring.slice(0, -1).map((a, i) => ({ a, b: ring[i + 1], r, i })));
|
|
14240
|
+
let work = 0;
|
|
14241
|
+
const tick = () => {
|
|
14242
|
+
if (++work > 2e7)
|
|
14243
|
+
throw new Error("Polygon constraint work limit exceeded");
|
|
14244
|
+
};
|
|
14245
|
+
const fraction = (p, a, b) => {
|
|
14246
|
+
const dx = b[0] - a[0], dy = b[1] - a[1], l = dx * dx + dy * dy;
|
|
14247
|
+
return l ? ((p[0] - a[0]) * dx + (p[1] - a[1]) * dy) / l : NaN;
|
|
14248
|
+
};
|
|
14249
|
+
const on = (p, a, b) => {
|
|
14250
|
+
tick();
|
|
14251
|
+
const t = fraction(p, a, b), length = Math.hypot(b[0] - a[0], b[1] - a[1]);
|
|
14252
|
+
return length > 0 && t >= -tolerance && t <= 1 + tolerance && Math.hypot(p[0] - a[0] - t * (b[0] - a[0]), p[1] - a[1] - t * (b[1] - a[1])) <= tolerance * Math.max(1, length);
|
|
14253
|
+
};
|
|
14254
|
+
const boxes = constraints.map((c) => [
|
|
14255
|
+
Math.min(c.a[0], c.b[0]),
|
|
14256
|
+
Math.min(c.a[1], c.b[1]),
|
|
14257
|
+
Math.max(c.a[0], c.b[0]),
|
|
14258
|
+
Math.max(c.a[1], c.b[1])
|
|
14259
|
+
]);
|
|
14260
|
+
const build = (ids) => {
|
|
14261
|
+
const box = [Infinity, Infinity, -Infinity, -Infinity];
|
|
14262
|
+
for (const id of ids) {
|
|
14263
|
+
tick();
|
|
14264
|
+
const b = boxes[id];
|
|
14265
|
+
box[0] = Math.min(box[0], b[0]);
|
|
14266
|
+
box[1] = Math.min(box[1], b[1]);
|
|
14267
|
+
box[2] = Math.max(box[2], b[2]);
|
|
14268
|
+
box[3] = Math.max(box[3], b[3]);
|
|
14269
|
+
}
|
|
14270
|
+
if (ids.length <= 16)
|
|
14271
|
+
return { box, ids };
|
|
14272
|
+
const axis = box[2] - box[0] >= box[3] - box[1] ? 0 : 1;
|
|
14273
|
+
ids.sort((a, b) => {
|
|
14274
|
+
tick();
|
|
14275
|
+
return boxes[a][axis] + boxes[a][axis + 2] - boxes[b][axis] - boxes[b][axis + 2];
|
|
14276
|
+
});
|
|
14277
|
+
const middle = Math.floor(ids.length / 2);
|
|
14278
|
+
return { box, left: build(ids.slice(0, middle)), right: build(ids.slice(middle)) };
|
|
14279
|
+
};
|
|
14280
|
+
const root = build(constraints.map((_, i) => i));
|
|
14281
|
+
const padding = tolerance * Math.max(1, root.box[2] - root.box[0], root.box[3] - root.box[1]);
|
|
14282
|
+
const query = (a, b) => {
|
|
14283
|
+
const box = [
|
|
14284
|
+
Math.min(a[0], b[0]) - padding,
|
|
14285
|
+
Math.min(a[1], b[1]) - padding,
|
|
14286
|
+
Math.max(a[0], b[0]) + padding,
|
|
14287
|
+
Math.max(a[1], b[1]) + padding
|
|
14288
|
+
], ids = [];
|
|
14289
|
+
const overlaps = (b2) => b2[0] <= box[2] && b2[2] >= box[0] && b2[1] <= box[3] && b2[3] >= box[1];
|
|
14290
|
+
const visit = (node) => {
|
|
14291
|
+
tick();
|
|
14292
|
+
if (!overlaps(node.box))
|
|
14293
|
+
return;
|
|
14294
|
+
if (node.ids) {
|
|
14295
|
+
for (const id of node.ids) {
|
|
14296
|
+
tick();
|
|
14297
|
+
if (overlaps(boxes[id]))
|
|
14298
|
+
ids.push(id);
|
|
14299
|
+
}
|
|
14300
|
+
} else {
|
|
14301
|
+
visit(node.left);
|
|
14302
|
+
visit(node.right);
|
|
14303
|
+
}
|
|
14304
|
+
};
|
|
14305
|
+
visit(root);
|
|
14306
|
+
return ids.map((id) => constraints[id]);
|
|
14307
|
+
};
|
|
14308
|
+
const rings = [], owners = [];
|
|
14309
|
+
for (const ring of output) {
|
|
14310
|
+
const points = [];
|
|
14311
|
+
for (let i = 1; i < ring.length; i++) {
|
|
14312
|
+
const a = ring[i - 1], b = ring[i];
|
|
14313
|
+
if (a.every((v, k2) => v === b[k2]))
|
|
14314
|
+
continue;
|
|
14315
|
+
const breaks = [{ t: 0, p: a }];
|
|
14316
|
+
for (const c of query(a, b))
|
|
14317
|
+
if (on(c.a, a, b) && (!accept || accept(c.a))) {
|
|
14318
|
+
const t = fraction(c.a, a, b);
|
|
14319
|
+
if (t > 1e-12 && t < 1 - 1e-12)
|
|
14320
|
+
breaks.push({ t, p: c.a });
|
|
14321
|
+
}
|
|
14322
|
+
breaks.sort((a2, b2) => a2.t - b2.t);
|
|
14323
|
+
for (const item of breaks)
|
|
14324
|
+
if (!points.length || Math.hypot(...points[points.length - 1].map((v, k2) => v - item.p[k2])) > 1e-14)
|
|
14325
|
+
points.push([...item.p]);
|
|
14326
|
+
}
|
|
14327
|
+
if (points.length < 3)
|
|
14328
|
+
continue;
|
|
14329
|
+
points.push([...points[0]]);
|
|
14330
|
+
const tags = [];
|
|
14331
|
+
for (let i = 1; i < points.length; i++) {
|
|
14332
|
+
const a = points[i - 1], b = points[i];
|
|
14333
|
+
if (degenerate == null ? void 0 : degenerate(a, b)) {
|
|
14334
|
+
tags.push(null);
|
|
14335
|
+
continue;
|
|
14336
|
+
}
|
|
14337
|
+
let candidates = query(a, b).filter((c) => on(a, c.a, c.b) && on(b, c.a, c.b));
|
|
14338
|
+
const same = (p, q) => Math.hypot(...p.map((v, k2) => v - q[k2])) <= 64 * Number.EPSILON * Math.max(1, ...p.map(Math.abs), ...q.map(Math.abs));
|
|
14339
|
+
const exact = candidates.filter((c) => same(a, c.a) && same(b, c.b) || same(a, c.b) && same(b, c.a));
|
|
14340
|
+
if (exact.length)
|
|
14341
|
+
candidates = exact;
|
|
14342
|
+
if (candidates.some((c) => {
|
|
14343
|
+
var _a2, _b;
|
|
14344
|
+
return ((_b = (_a2 = priorities == null ? void 0 : priorities[c.r]) == null ? void 0 : _a2[c.i]) == null ? void 0 : _b.kind) === "source-boundary";
|
|
14345
|
+
}))
|
|
14346
|
+
candidates = candidates.filter((c) => {
|
|
14347
|
+
var _a2, _b;
|
|
14348
|
+
return ((_b = (_a2 = priorities == null ? void 0 : priorities[c.r]) == null ? void 0 : _a2[c.i]) == null ? void 0 : _b.kind) === "source-boundary";
|
|
14349
|
+
});
|
|
14350
|
+
if (candidates.length > 1) {
|
|
14351
|
+
const score = (c) => Math.max(...[a, b].map((p) => {
|
|
14352
|
+
const t = Math.min(1, Math.max(0, fraction(p, c.a, c.b)));
|
|
14353
|
+
return Math.hypot(p[0] - c.a[0] - t * (c.b[0] - c.a[0]), p[1] - c.a[1] - t * (c.b[1] - c.a[1]));
|
|
14354
|
+
}));
|
|
14355
|
+
candidates.sort((a2, b2) => score(a2) - score(b2));
|
|
14356
|
+
const epsilon7 = 64 * Number.EPSILON * Math.max(1, ...a.map(Math.abs), ...b.map(Math.abs));
|
|
14357
|
+
if (score(candidates[1]) - score(candidates[0]) > epsilon7)
|
|
14358
|
+
candidates = [candidates[0]];
|
|
14359
|
+
else if (Math.hypot(a[0] - b[0], a[1] - b[1]) <= 2 * epsilon7)
|
|
14360
|
+
candidates = [];
|
|
14361
|
+
else
|
|
14362
|
+
throw new Error("Ambiguous polygon clipping constraint ancestry");
|
|
14363
|
+
}
|
|
14364
|
+
tags.push(candidates.length ? [candidates[0].r, candidates[0].i] : null);
|
|
14365
|
+
}
|
|
14366
|
+
rings.push(points);
|
|
14367
|
+
owners.push(tags);
|
|
14368
|
+
}
|
|
14369
|
+
return { rings, owners };
|
|
14370
|
+
}
|
|
14371
|
+
function composePolygonEdge(parent, a, b, start, end) {
|
|
14372
|
+
if (parent.kind !== "source-boundary")
|
|
14373
|
+
return { ...parent };
|
|
14374
|
+
const v = geographic(a), length = angle(v, geographic(b));
|
|
14375
|
+
const parameter = (p) => length ? Math.min(1, angle(v, geographic(p)) / length) : 0;
|
|
14376
|
+
return {
|
|
14377
|
+
...parent,
|
|
14378
|
+
t0: parent.t0 + parameter(start) * (parent.t1 - parent.t0),
|
|
14379
|
+
t1: parent.t0 + parameter(end) * (parent.t1 - parent.t0)
|
|
14380
|
+
};
|
|
14381
|
+
}
|
|
14382
|
+
|
|
14383
|
+
// dist/discontinuous/source-arc.js
|
|
14384
|
+
function sourceArc(a, b) {
|
|
14385
|
+
const va = geographic(a), vb = geographic(b), length = angle(va, vb);
|
|
14386
|
+
const poleA = Math.abs(a[1]) === 90, poleB = Math.abs(b[1]) === 90;
|
|
14387
|
+
const start = poleA && !poleB ? [b[0], a[1]] : [...a], end = poleB && !poleA ? [a[0], b[1]] : [...b];
|
|
14388
|
+
return (t) => {
|
|
14389
|
+
if (t === 0)
|
|
14390
|
+
return [...start];
|
|
14391
|
+
if (t === 1)
|
|
14392
|
+
return [...end];
|
|
14393
|
+
if (length < 1e-14)
|
|
14394
|
+
return [a[0] + t * (b[0] - a[0]), a[1] + t * (b[1] - a[1])];
|
|
14395
|
+
const p = coordinates(unit(va.map((v, k2) => (Math.sin((1 - t) * length) * v + Math.sin(t * length) * vb[k2]) / Math.sin(length))));
|
|
14396
|
+
const reference = start[0] + t * (end[0] - start[0]);
|
|
14397
|
+
p[0] += 360 * Math.round((reference - p[0]) / 360);
|
|
14398
|
+
return p;
|
|
14399
|
+
};
|
|
14400
|
+
}
|
|
14401
|
+
|
|
14072
14402
|
// dist/discontinuous/map-layout.js
|
|
14073
14403
|
var import_polygon_clipping3 = __toESM(require("polygon-clipping"), 1);
|
|
14074
14404
|
var EPS = 1e-10;
|
|
@@ -14218,6 +14548,10 @@ var DiscontinuousMap = class {
|
|
|
14218
14548
|
for (let i = 1; i < points.length; i++)
|
|
14219
14549
|
validateArc(points[i - 1], points[i]);
|
|
14220
14550
|
const results = [];
|
|
14551
|
+
const cumulative = options.pathDistances ? [0] : void 0;
|
|
14552
|
+
if (cumulative)
|
|
14553
|
+
for (let i = 1; i < points.length; i++)
|
|
14554
|
+
cumulative.push(cumulative[i - 1] + angle(points[i - 1], points[i]));
|
|
14221
14555
|
for (const r of this.compiled) {
|
|
14222
14556
|
let current = null;
|
|
14223
14557
|
for (let i = 1; i < points.length; i++) {
|
|
@@ -14226,18 +14560,42 @@ var DiscontinuousMap = class {
|
|
|
14226
14560
|
current = null;
|
|
14227
14561
|
continue;
|
|
14228
14562
|
}
|
|
14563
|
+
const reason = (p, endpoint, isEndpoint) => {
|
|
14564
|
+
if (isEndpoint && angle(p, endpoint) < 1e-12)
|
|
14565
|
+
return "source-endpoint";
|
|
14566
|
+
const kinds = r.normals.map((normal, edge2) => {
|
|
14567
|
+
var _a2;
|
|
14568
|
+
return Math.abs(dot(normal, p)) < 1e-9 ? (_a2 = this.seams.find((s) => s.regions.some((id, i2) => id === r.definition.id && s.edges[i2] === edge2))) == null ? void 0 : _a2.kind : void 0;
|
|
14569
|
+
}).filter(Boolean);
|
|
14570
|
+
return kinds.includes("boundary") ? "coverage-boundary" : kinds.includes("cut") ? "chart-cut" : kinds.includes("join") ? "continuous-chart-join" : "coverage-boundary";
|
|
14571
|
+
};
|
|
14229
14572
|
const sampled = this.sample(r, clipped[0], clipped[1], settings);
|
|
14230
14573
|
if (sampled.length < 2)
|
|
14231
14574
|
continue;
|
|
14232
14575
|
if (!current || angle(geographic(current.sourceCoordinates[current.sourceCoordinates.length - 1]), clipped[0]) > EPS || !this.sameProjectedPoint(current.coordinates[current.coordinates.length - 1], this.project(r, sampled[0]))) {
|
|
14233
14576
|
current = { regionId: r.definition.id, coordinates: [], sourceCoordinates: [] };
|
|
14577
|
+
if (options.pathProvenance)
|
|
14578
|
+
current.provenance = { segments: [], parameters: [], vertices: [], angularDistances: [] };
|
|
14579
|
+
if (current.provenance && options.pathBoundaries)
|
|
14580
|
+
current.provenance.startReason = reason(clipped[0], points[0], i === 1);
|
|
14234
14581
|
results.push(current);
|
|
14235
14582
|
} else
|
|
14236
14583
|
sampled.shift();
|
|
14237
14584
|
for (const p of sampled) {
|
|
14238
14585
|
current.coordinates.push(this.project(r, p));
|
|
14239
14586
|
current.sourceCoordinates.push(coordinates(p));
|
|
14587
|
+
if (current.provenance) {
|
|
14588
|
+
const length = angle(points[i - 1], points[i]);
|
|
14589
|
+
const t = length ? Math.min(1, Math.max(0, angle(points[i - 1], p) / length)) : 0;
|
|
14590
|
+
current.provenance.segments.push(i - 1);
|
|
14591
|
+
current.provenance.parameters.push(t);
|
|
14592
|
+
current.provenance.vertices.push(angle(points[i - 1], p) < 1e-12 ? i - 1 : angle(points[i], p) < 1e-12 ? i : 4294967295);
|
|
14593
|
+
if (cumulative)
|
|
14594
|
+
current.provenance.angularDistances.push(cumulative[i - 1] + t * length);
|
|
14595
|
+
}
|
|
14240
14596
|
}
|
|
14597
|
+
if (current.provenance && options.pathBoundaries)
|
|
14598
|
+
current.provenance.endReason = reason(clipped[1], points[points.length - 1], i === points.length - 1);
|
|
14241
14599
|
if (!this.contains(r, points[i]))
|
|
14242
14600
|
current = null;
|
|
14243
14601
|
}
|
|
@@ -14334,26 +14692,91 @@ var DiscontinuousMap = class {
|
|
|
14334
14692
|
coordinates: [],
|
|
14335
14693
|
sourceCoordinates: []
|
|
14336
14694
|
};
|
|
14695
|
+
if (options.polygonEdgeProvenance)
|
|
14696
|
+
output.edgeProvenance = [];
|
|
14337
14697
|
polygon.forEach((ring, index) => {
|
|
14338
14698
|
const sphere = ring.map((p) => unit(add(center3, add(scale(x, p[0]), scale(y, p[1])))));
|
|
14339
14699
|
const points = [];
|
|
14700
|
+
const edges = [];
|
|
14701
|
+
const classify = (a, b) => {
|
|
14702
|
+
if (angle(a, b) < 64 * Number.EPSILON)
|
|
14703
|
+
return {
|
|
14704
|
+
kind: "continuous-chart-join",
|
|
14705
|
+
ring: 4294967295,
|
|
14706
|
+
segment: 4294967295,
|
|
14707
|
+
t0: 0,
|
|
14708
|
+
t1: 0
|
|
14709
|
+
};
|
|
14710
|
+
const candidates = [];
|
|
14711
|
+
vectors.forEach((source, ring2) => source.forEach((u, segment) => {
|
|
14712
|
+
const v = source[(segment + 1) % source.length], length = angle(u, v);
|
|
14713
|
+
if (length > 1e-12 && [a, b].every((p) => Math.abs(dot(unit(cross(u, v)), p)) < 1e-12 && Math.abs(angle(u, p) + angle(p, v) - length) < 1e-10))
|
|
14714
|
+
candidates.push({ ring: ring2, segment });
|
|
14715
|
+
}));
|
|
14716
|
+
if (candidates.length > 1)
|
|
14717
|
+
throw new Error("Ambiguous polygon boundary provenance");
|
|
14718
|
+
if (candidates.length) {
|
|
14719
|
+
const { ring: ring2, segment } = candidates[0], source = vectors[ring2], u = source[segment], length = angle(u, source[(segment + 1) % source.length]);
|
|
14720
|
+
return {
|
|
14721
|
+
kind: "source-boundary",
|
|
14722
|
+
ring: ring2,
|
|
14723
|
+
segment,
|
|
14724
|
+
t0: Math.min(1, angle(u, a) / length),
|
|
14725
|
+
t1: Math.min(1, angle(u, b) / length)
|
|
14726
|
+
};
|
|
14727
|
+
}
|
|
14728
|
+
const kinds = r.normals.map((n, edge2) => {
|
|
14729
|
+
var _a2;
|
|
14730
|
+
return [a, b].every((p) => Math.abs(dot(n, p)) < 1e-9) ? (_a2 = this.seams.find((s) => s.regions.some((id, i) => id === r.definition.id && s.edges[i] === edge2))) == null ? void 0 : _a2.kind : void 0;
|
|
14731
|
+
}).filter(Boolean);
|
|
14732
|
+
if (!kinds.length)
|
|
14733
|
+
throw new Error("Unknown polygon clipping constraint");
|
|
14734
|
+
return {
|
|
14735
|
+
kind: kinds.includes("boundary") ? "coverage-boundary" : kinds.includes("cut") ? "chart-cut" : "continuous-chart-join",
|
|
14736
|
+
ring: 4294967295,
|
|
14737
|
+
segment: 4294967295,
|
|
14738
|
+
t0: 0,
|
|
14739
|
+
t1: 0
|
|
14740
|
+
};
|
|
14741
|
+
};
|
|
14340
14742
|
for (let i = 1; i < sphere.length; i++) {
|
|
14743
|
+
const origin2 = options.polygonEdgeProvenance && !sphere[i - 1].every((value2, k2) => value2 === sphere[i][k2]) ? classify(sphere[i - 1], sphere[i]) : void 0;
|
|
14341
14744
|
const sampled = this.sample(r, sphere[i - 1], sphere[i], settings);
|
|
14342
14745
|
for (const point of sampled) {
|
|
14343
14746
|
const previous = points[points.length - 1];
|
|
14344
|
-
if (!previous || !point.every((value2, k2) => value2 === previous[k2]))
|
|
14747
|
+
if (!previous || !point.every((value2, k2) => value2 === previous[k2])) {
|
|
14748
|
+
if (previous && origin2) {
|
|
14749
|
+
const edge2 = { ...origin2 };
|
|
14750
|
+
if (edge2.kind === "source-boundary") {
|
|
14751
|
+
const source = vectors[edge2.ring], u = source[edge2.segment], length = angle(u, source[(edge2.segment + 1) % source.length]);
|
|
14752
|
+
edge2.t0 = Math.min(1, angle(u, previous) / length);
|
|
14753
|
+
edge2.t1 = Math.min(1, angle(u, point) / length);
|
|
14754
|
+
}
|
|
14755
|
+
edges.push(edge2);
|
|
14756
|
+
}
|
|
14345
14757
|
points.push(point);
|
|
14758
|
+
}
|
|
14346
14759
|
}
|
|
14347
14760
|
}
|
|
14348
14761
|
if (points.length < 3)
|
|
14349
14762
|
return;
|
|
14350
14763
|
if (points[points.length - 1].every((value2, k2) => value2 === points[0][k2]))
|
|
14351
14764
|
points.pop();
|
|
14765
|
+
if (options.polygonEdgeProvenance && edges.length < points.length)
|
|
14766
|
+
edges.push(classify(points[points.length - 1], points[0]));
|
|
14352
14767
|
points.push(points[0]);
|
|
14353
14768
|
const xy = points.map((p) => this.project(r, p));
|
|
14354
14769
|
if (ringOrientation(xy) > 0 !== (index === 0)) {
|
|
14355
14770
|
xy.reverse();
|
|
14356
14771
|
points.reverse();
|
|
14772
|
+
edges.reverse();
|
|
14773
|
+
for (const e of edges)
|
|
14774
|
+
[e.t0, e.t1] = [e.t1, e.t0];
|
|
14775
|
+
}
|
|
14776
|
+
if (output.edgeProvenance) {
|
|
14777
|
+
if (edges.length !== points.length - 1)
|
|
14778
|
+
throw new Error("Mismatched polygon edge provenance");
|
|
14779
|
+
output.edgeProvenance.push(edges);
|
|
14357
14780
|
}
|
|
14358
14781
|
output.coordinates.push(xy);
|
|
14359
14782
|
output.sourceCoordinates.push(points.map(coordinates));
|
|
@@ -14551,10 +14974,11 @@ var CapMap = class extends DiscontinuousMap {
|
|
|
14551
14974
|
unprojectPoint(p, id) {
|
|
14552
14975
|
return super.unprojectPoint(p, id).filter((q) => this.visible(q.position));
|
|
14553
14976
|
}
|
|
14554
|
-
clip(rings, polygon, options, regionId) {
|
|
14977
|
+
clip(rings, polygon, options, regionId, segmentIndices) {
|
|
14555
14978
|
const output = [];
|
|
14556
14979
|
const originals = /* @__PURE__ */ new Map();
|
|
14557
|
-
let ring = [];
|
|
14980
|
+
let ring = [], indices = [], activeSegment = 0;
|
|
14981
|
+
let previousInput, currentInput;
|
|
14558
14982
|
const precision = Math.min((options == null ? void 0 : options.maxAngularStep) ?? 2, Math.sqrt(((options == null ? void 0 : options.tolerance) ?? 1e-4) / this.radius) / RAD / 4) * RAD;
|
|
14559
14983
|
if (!Number.isFinite(precision) || 2 * Math.PI / precision > 1e6)
|
|
14560
14984
|
throw new Error("Projection sampling limit exceeded; relax tolerance");
|
|
@@ -14609,14 +15033,49 @@ var CapMap = class extends DiscontinuousMap {
|
|
|
14609
15033
|
point: (x, y) => {
|
|
14610
15034
|
if (++emitted > 1e6)
|
|
14611
15035
|
throw new Error("Projection sampling limit exceeded; relax tolerance");
|
|
14612
|
-
|
|
15036
|
+
let source = originals.get(`${x},${y}`);
|
|
15037
|
+
if (!source && !polygon && this.nonlinear && previousInput && currentInput) {
|
|
15038
|
+
const a = geographic(previousInput), b = geographic(currentInput), length = angle(a, b);
|
|
15039
|
+
const at = (t) => length < 1e-14 ? [...currentInput] : coordinates(unit(a.map((v, k2) => (Math.sin((1 - t) * length) * v + Math.sin(t * length) * b[k2]) / Math.sin(length))));
|
|
15040
|
+
const value2 = (t) => geographic(local(at(t)))[0] - Math.cos(this.cap);
|
|
15041
|
+
const approximate = this.source([x / RAD, y / RAD]);
|
|
15042
|
+
const reference = length ? Math.min(1, angle(a, geographic(approximate)) / length) : 0;
|
|
15043
|
+
const roots = [];
|
|
15044
|
+
for (let j = 0; j < 32; j++) {
|
|
15045
|
+
let lo = j / 32, hi = (j + 1) / 32, f = value2(lo), g = value2(hi);
|
|
15046
|
+
if (Math.abs(f) < 1e-14)
|
|
15047
|
+
roots.push(lo);
|
|
15048
|
+
if (f * g >= 0)
|
|
15049
|
+
continue;
|
|
15050
|
+
for (let k2 = 0; k2 < 52; k2++) {
|
|
15051
|
+
const mid = (lo + hi) / 2;
|
|
15052
|
+
if (value2(mid) >= 0 === f >= 0)
|
|
15053
|
+
lo = mid;
|
|
15054
|
+
else
|
|
15055
|
+
hi = mid;
|
|
15056
|
+
}
|
|
15057
|
+
roots.push((lo + hi) / 2);
|
|
15058
|
+
}
|
|
15059
|
+
if (Math.abs(value2(1)) < 1e-14)
|
|
15060
|
+
roots.push(1);
|
|
15061
|
+
if (!roots.length)
|
|
15062
|
+
throw new Error("Unresolved nonlinear cap source intersection");
|
|
15063
|
+
roots.sort((a2, b2) => Math.abs(a2 - reference) - Math.abs(b2 - reference));
|
|
15064
|
+
source = at(roots[0]);
|
|
15065
|
+
}
|
|
15066
|
+
ring.push(source ?? this.source([x / RAD, y / RAD]));
|
|
15067
|
+
if (segmentIndices)
|
|
15068
|
+
indices.push(activeSegment);
|
|
14613
15069
|
},
|
|
14614
15070
|
lineStart: () => {
|
|
14615
15071
|
ring = [];
|
|
15072
|
+
indices = [];
|
|
14616
15073
|
},
|
|
14617
15074
|
lineEnd: () => {
|
|
14618
|
-
if (ring.length > 1)
|
|
15075
|
+
if (ring.length > 1) {
|
|
14619
15076
|
output.push(ring);
|
|
15077
|
+
segmentIndices == null ? void 0 : segmentIndices.push(indices);
|
|
15078
|
+
}
|
|
14620
15079
|
},
|
|
14621
15080
|
polygonStart: () => {
|
|
14622
15081
|
},
|
|
@@ -14633,7 +15092,9 @@ var CapMap = class extends DiscontinuousMap {
|
|
|
14633
15092
|
}
|
|
14634
15093
|
const x = q[0] * RAD, y = q[1] * RAD;
|
|
14635
15094
|
originals.set(`${x},${y}`, [...p]);
|
|
15095
|
+
currentInput = p;
|
|
14636
15096
|
stream.point(x, y);
|
|
15097
|
+
previousInput = p;
|
|
14637
15098
|
};
|
|
14638
15099
|
const subdivide = (a, b, depth = 0) => {
|
|
14639
15100
|
if (this.nonlinear && depth < 20) {
|
|
@@ -14650,11 +15111,14 @@ var CapMap = class extends DiscontinuousMap {
|
|
|
14650
15111
|
emit(b);
|
|
14651
15112
|
};
|
|
14652
15113
|
for (const points of rings) {
|
|
15114
|
+
previousInput = void 0;
|
|
14653
15115
|
stream.lineStart();
|
|
14654
15116
|
if (points.length)
|
|
14655
15117
|
emit(points[0]);
|
|
14656
|
-
for (let i = 1; i < points.length; i++)
|
|
15118
|
+
for (let i = 1; i < points.length; i++) {
|
|
15119
|
+
activeSegment = i - 1;
|
|
14657
15120
|
subdivide(points[i - 1], points[i]);
|
|
15121
|
+
}
|
|
14658
15122
|
if (polygon && points.length)
|
|
14659
15123
|
subdivide(points[points.length - 1], points[0]);
|
|
14660
15124
|
stream.lineEnd();
|
|
@@ -14666,7 +15130,41 @@ var CapMap = class extends DiscontinuousMap {
|
|
|
14666
15130
|
projectLine(line, options) {
|
|
14667
15131
|
if (this.cap === Math.PI / 2 && !this.nonlinear)
|
|
14668
15132
|
return super.projectLine(line, options);
|
|
14669
|
-
return super.projectLine(line, options).flatMap((part) =>
|
|
15133
|
+
return super.projectLine(line, options).flatMap((part) => {
|
|
15134
|
+
const indices = part.provenance ? [] : void 0;
|
|
15135
|
+
const clipped = this.clip([part.sourceCoordinates], false, options, part.regionId, indices);
|
|
15136
|
+
return clipped.flatMap((points, piece) => super.projectLine(points, options).filter((q) => q.regionId === part.regionId).map((q) => {
|
|
15137
|
+
const parent = part.provenance, child2 = q.provenance;
|
|
15138
|
+
if (!parent || !child2)
|
|
15139
|
+
return q;
|
|
15140
|
+
const provenance = {
|
|
15141
|
+
segments: [],
|
|
15142
|
+
parameters: [],
|
|
15143
|
+
vertices: [],
|
|
15144
|
+
angularDistances: []
|
|
15145
|
+
};
|
|
15146
|
+
for (let j = 0; j < q.sourceCoordinates.length; j++) {
|
|
15147
|
+
const k2 = child2.segments[j];
|
|
15148
|
+
const edge2 = indices[piece][k2 + 1];
|
|
15149
|
+
const a = geographic(part.sourceCoordinates[edge2]), b = geographic(part.sourceCoordinates[edge2 + 1]), p = geographic(q.sourceCoordinates[j]);
|
|
15150
|
+
const length = angle(a, b), t = length ? Math.min(1, angle(a, p) / length) : 0;
|
|
15151
|
+
const endpoint = t < 1e-12 ? edge2 : t > 1 - 1e-12 ? edge2 + 1 : -1;
|
|
15152
|
+
const segment = parent.segments[edge2 + 1];
|
|
15153
|
+
const from = parent.segments[edge2] === segment ? parent.parameters[edge2] : 0;
|
|
15154
|
+
provenance.segments.push(endpoint >= 0 ? parent.segments[endpoint] : segment);
|
|
15155
|
+
provenance.parameters.push(endpoint >= 0 ? parent.parameters[endpoint] : from + t * (parent.parameters[edge2 + 1] - from));
|
|
15156
|
+
provenance.vertices.push(endpoint >= 0 ? parent.vertices[endpoint] : 4294967295);
|
|
15157
|
+
if (options == null ? void 0 : options.pathDistances)
|
|
15158
|
+
provenance.angularDistances.push(parent.angularDistances[edge2] + t * (parent.angularDistances[edge2 + 1] - parent.angularDistances[edge2]));
|
|
15159
|
+
}
|
|
15160
|
+
if (options == null ? void 0 : options.pathBoundaries) {
|
|
15161
|
+
const same = (a, b) => angle(geographic(a), geographic(b)) < 1e-12;
|
|
15162
|
+
provenance.startReason = same(q.sourceCoordinates[0], part.sourceCoordinates[0]) ? parent.startReason : "coverage-boundary";
|
|
15163
|
+
provenance.endReason = same(q.sourceCoordinates[q.sourceCoordinates.length - 1], part.sourceCoordinates[part.sourceCoordinates.length - 1]) ? parent.endReason : "coverage-boundary";
|
|
15164
|
+
}
|
|
15165
|
+
return { ...q, provenance };
|
|
15166
|
+
}));
|
|
15167
|
+
});
|
|
14670
15168
|
}
|
|
14671
15169
|
projectPolygon(rings, options) {
|
|
14672
15170
|
if (this.cap === Math.PI / 2 && !this.nonlinear)
|
|
@@ -14739,15 +15237,95 @@ var CapMap = class extends DiscontinuousMap {
|
|
|
14739
15237
|
};
|
|
14740
15238
|
for (const ring of outer) {
|
|
14741
15239
|
const plane = ring.map(planar), sources = [ring, ...holes.filter((h2) => contains2(plane, planar(h2[0])))];
|
|
15240
|
+
const parentPlane = part.sourceCoordinates.map((r) => r.map(planar));
|
|
15241
|
+
const fromPlane = (p) => coordinates(unit(center3.map((v, k2) => v + x[k2] * p[0] + y[k2] * p[1])));
|
|
15242
|
+
const traced = tracePolygonConstraints(parentPlane, sources.map((r) => r.map(planar)), this.nonlinear ? 2e-6 : 1e-10, part.edgeProvenance, (p) => this.visible(fromPlane(p)));
|
|
15243
|
+
const resolved2 = traced.rings.map((r) => r.map(fromPlane));
|
|
15244
|
+
traced.owners.forEach((owners, r) => owners.forEach((owner, i) => {
|
|
15245
|
+
if (!owner)
|
|
15246
|
+
return;
|
|
15247
|
+
const [pr, pe] = owner, a = part.sourceCoordinates[pr][pe], b = part.sourceCoordinates[pr][pe + 1], at = sourceArc(a, b);
|
|
15248
|
+
for (const j of [i, i + 1]) {
|
|
15249
|
+
const point = resolved2[r][j], distance3 = angle(geographic(a), geographic(b)), fraction = distance3 ? angle(geographic(a), geographic(point)) / distance3 : 0;
|
|
15250
|
+
if (fraction < 1e-10)
|
|
15251
|
+
resolved2[r][j] = [...a];
|
|
15252
|
+
else if (fraction > 1 - 1e-10)
|
|
15253
|
+
resolved2[r][j] = [...b];
|
|
15254
|
+
else if (Math.hypot(...cross(geographic(a), geographic(b))) > 1e-14 && Math.abs(dot(unit(cross(geographic(a), geographic(b))), geographic(point))) < 1e-12) {
|
|
15255
|
+
resolved2[r][j] = at(Math.min(1, Math.max(0, fraction)));
|
|
15256
|
+
} else {
|
|
15257
|
+
const value2 = (t) => geographic(this.local(at(t)))[0] - Math.cos(this.cap), roots = [];
|
|
15258
|
+
for (let k2 = 0; k2 < 32; k2++) {
|
|
15259
|
+
let lo = k2 / 32, hi = (k2 + 1) / 32, f = value2(lo), g = value2(hi);
|
|
15260
|
+
if (Math.abs(f) < 1e-13)
|
|
15261
|
+
roots.push(lo);
|
|
15262
|
+
if (f * g >= 0)
|
|
15263
|
+
continue;
|
|
15264
|
+
for (let n = 0; n < 52; n++) {
|
|
15265
|
+
const mid = (lo + hi) / 2;
|
|
15266
|
+
if (value2(mid) >= 0 === f >= 0)
|
|
15267
|
+
lo = mid;
|
|
15268
|
+
else
|
|
15269
|
+
hi = mid;
|
|
15270
|
+
}
|
|
15271
|
+
roots.push((lo + hi) / 2);
|
|
15272
|
+
}
|
|
15273
|
+
if (Math.abs(value2(1)) < 1e-13)
|
|
15274
|
+
roots.push(1);
|
|
15275
|
+
if (!roots.length)
|
|
15276
|
+
throw new Error("Unresolved cap polygon source intersection");
|
|
15277
|
+
roots.sort((a2, b2) => Math.abs(a2 - fraction) - Math.abs(b2 - fraction));
|
|
15278
|
+
resolved2[r][j] = at(roots[0]);
|
|
15279
|
+
}
|
|
15280
|
+
}
|
|
15281
|
+
}));
|
|
15282
|
+
for (const ring2 of resolved2)
|
|
15283
|
+
ring2[ring2.length - 1] = [...ring2[0]];
|
|
14742
15284
|
result.push({
|
|
14743
15285
|
regionId: part.regionId,
|
|
14744
|
-
sourceCoordinates:
|
|
14745
|
-
coordinates:
|
|
15286
|
+
sourceCoordinates: resolved2,
|
|
15287
|
+
coordinates: resolved2.map((r) => r.map((p) => {
|
|
14746
15288
|
const q = super.projectPoint(p, part.regionId);
|
|
14747
15289
|
if (!q)
|
|
14748
|
-
throw new Error(
|
|
15290
|
+
throw new Error("Cap polygon source constraint left its owning chart");
|
|
14749
15291
|
return q.position;
|
|
14750
|
-
}))
|
|
15292
|
+
})),
|
|
15293
|
+
...(options == null ? void 0 : options.polygonEdgeProvenance) ? {
|
|
15294
|
+
edgeProvenance: traced.owners.map((owners, r) => owners.map((owner, i) => {
|
|
15295
|
+
const a = resolved2[r][i], b = resolved2[r][i + 1];
|
|
15296
|
+
if (owner) {
|
|
15297
|
+
const [pr, pe] = owner;
|
|
15298
|
+
return composePolygonEdge(part.edgeProvenance[pr][pe], part.sourceCoordinates[pr][pe], part.sourceCoordinates[pr][pe + 1], a, b);
|
|
15299
|
+
}
|
|
15300
|
+
if (angle(geographic(a), geographic(b)) < 64 * Number.EPSILON)
|
|
15301
|
+
return {
|
|
15302
|
+
kind: "continuous-chart-join",
|
|
15303
|
+
ring: 4294967295,
|
|
15304
|
+
segment: 4294967295,
|
|
15305
|
+
t0: 0,
|
|
15306
|
+
t1: 0
|
|
15307
|
+
};
|
|
15308
|
+
const kinds = [];
|
|
15309
|
+
region.boundary.forEach((p, j) => {
|
|
15310
|
+
const n = cross(geographic(p), geographic(region.boundary[(j + 1) % region.boundary.length])), length = Math.hypot(...n);
|
|
15311
|
+
if (length && [a, b].every((p2) => Math.abs(dot(n, geographic(p2))) / length < 1e-9)) {
|
|
15312
|
+
const seam = this.seams.find((s) => s.regions.some((id, k2) => id === region.id && s.edges[k2] === j));
|
|
15313
|
+
if (seam)
|
|
15314
|
+
kinds.push(seam.kind);
|
|
15315
|
+
}
|
|
15316
|
+
});
|
|
15317
|
+
const horizon = [a, b].every((p) => Math.abs(geographic(this.local(p))[0] - Math.cos(this.cap)) < 1e-7);
|
|
15318
|
+
if (!horizon && !kinds.length)
|
|
15319
|
+
throw new Error("Unknown cap polygon clipping constraint");
|
|
15320
|
+
return {
|
|
15321
|
+
kind: horizon ? "coverage-boundary" : kinds.includes("boundary") ? "coverage-boundary" : kinds.includes("cut") ? "chart-cut" : "continuous-chart-join",
|
|
15322
|
+
ring: 4294967295,
|
|
15323
|
+
segment: 4294967295,
|
|
15324
|
+
t0: 0,
|
|
15325
|
+
t1: 0
|
|
15326
|
+
};
|
|
15327
|
+
}))
|
|
15328
|
+
} : {}
|
|
14751
15329
|
});
|
|
14752
15330
|
}
|
|
14753
15331
|
}
|
|
@@ -16572,6 +17150,94 @@ function invertCell(p, target) {
|
|
|
16572
17150
|
return output;
|
|
16573
17151
|
}
|
|
16574
17152
|
|
|
17153
|
+
// dist/discontinuous/elastic/source-arc.js
|
|
17154
|
+
function clipSourceArc(a, b, polygons) {
|
|
17155
|
+
const at = sourceArc(a, b), va = geographic(a), vb = geographic(b), omega = angle(va, vb), ts = [0, 1];
|
|
17156
|
+
let work = 0;
|
|
17157
|
+
const tick = () => {
|
|
17158
|
+
if (++work > 1e6)
|
|
17159
|
+
throw new Error("Elastic source clipping limit exceeded");
|
|
17160
|
+
};
|
|
17161
|
+
const linear = omega < 1e-14 || Math.abs(a[1]) < 1e-12 && Math.abs(b[1]) < 1e-12 || Math.abs(at(0)[0] - at(1)[0]) < 1e-12;
|
|
17162
|
+
const tangent = omega > 1e-14 ? va.map((v, k2) => (vb[k2] - v * Math.cos(omega)) / Math.sin(omega)) : [0, 0, 0];
|
|
17163
|
+
const momentum = Math.abs(omega * (va[0] * tangent[1] - va[1] * tangent[0])) + 64 * Number.EPSILON * omega;
|
|
17164
|
+
const vector = (t) => va.map((v, k2) => v * Math.cos(omega * t) + tangent[k2] * Math.sin(omega * t));
|
|
17165
|
+
const derivative = (t) => va.map((v, k2) => omega * (-v * Math.sin(omega * t) + tangent[k2] * Math.cos(omega * t)));
|
|
17166
|
+
for (const rings of polygons)
|
|
17167
|
+
for (const ring of rings)
|
|
17168
|
+
for (let edge2 = 1; edge2 < ring.length; edge2++) {
|
|
17169
|
+
const c = ring[edge2 - 1], d = ring[edge2], dx = d[0] - c[0], dy = d[1] - c[1], length = Math.hypot(dx, dy);
|
|
17170
|
+
if (!length)
|
|
17171
|
+
continue;
|
|
17172
|
+
const angular = omega / RAD, latitude = Math.min(90, Math.max(Math.abs(a[1]), Math.abs(b[1])) + angular), cosine2 = Math.cos(latitude * RAD), longitude3 = cosine2 > 1e-10 ? angular / cosine2 : 360;
|
|
17173
|
+
if (Math.max(c[1], d[1]) < Math.min(a[1], b[1]) - angular - 1e-10 || Math.min(c[1], d[1]) > Math.max(a[1], b[1]) + angular + 1e-10 || Math.max(c[0], d[0]) < Math.min(a[0], b[0]) - longitude3 - 1e-10 || Math.min(c[0], d[0]) > Math.max(a[0], b[0]) + longitude3 + 1e-10)
|
|
17174
|
+
continue;
|
|
17175
|
+
const value2 = (t) => {
|
|
17176
|
+
tick();
|
|
17177
|
+
const p = at(t);
|
|
17178
|
+
return ((p[0] - c[0]) * dy - (p[1] - c[1]) * dx) / length;
|
|
17179
|
+
};
|
|
17180
|
+
const put = (t) => {
|
|
17181
|
+
const p = at(t), u = ((p[0] - c[0]) * dx + (p[1] - c[1]) * dy) / (length * length);
|
|
17182
|
+
if (u >= -1e-10 && u <= 1 + 1e-10)
|
|
17183
|
+
ts.push(t);
|
|
17184
|
+
};
|
|
17185
|
+
const bisect = (lo, hi, f) => {
|
|
17186
|
+
for (let k2 = 0; k2 < 52; k2++) {
|
|
17187
|
+
const mid = (lo + hi) / 2;
|
|
17188
|
+
if (value2(mid) >= 0 === f >= 0)
|
|
17189
|
+
lo = mid;
|
|
17190
|
+
else
|
|
17191
|
+
hi = mid;
|
|
17192
|
+
}
|
|
17193
|
+
put((lo + hi) / 2);
|
|
17194
|
+
};
|
|
17195
|
+
const visit = (lo, hi, depth) => {
|
|
17196
|
+
tick();
|
|
17197
|
+
const f = value2(lo), g = value2(hi), mid = (lo + hi) / 2, h2 = (hi - lo) / 2;
|
|
17198
|
+
if (Math.abs(f) < 1e-12)
|
|
17199
|
+
put(lo);
|
|
17200
|
+
if (Math.abs(g) < 1e-12)
|
|
17201
|
+
put(hi);
|
|
17202
|
+
if (linear) {
|
|
17203
|
+
if (f * g < 0)
|
|
17204
|
+
bisect(lo, hi, f);
|
|
17205
|
+
return;
|
|
17206
|
+
}
|
|
17207
|
+
const v = vector(mid), dv = derivative(mid), r2 = v[0] * v[0] + v[1] * v[1];
|
|
17208
|
+
const df = ((v[0] * dv[1] - v[1] * dv[0]) / r2 * dy - dv[2] / Math.sqrt(r2) * dx) / (RAD * length);
|
|
17209
|
+
let z = Math.max(Math.abs(vector(lo)[2]), Math.abs(vector(hi)[2]));
|
|
17210
|
+
const phase = Math.atan2(tangent[2], va[2]);
|
|
17211
|
+
for (let k2 = -2; k2 <= 2; k2++) {
|
|
17212
|
+
const theta = phase + k2 * Math.PI;
|
|
17213
|
+
if (theta >= omega * lo && theta <= omega * hi)
|
|
17214
|
+
z = Math.max(z, Math.hypot(va[2], tangent[2]));
|
|
17215
|
+
}
|
|
17216
|
+
const r = Math.sqrt(Math.max(0, 1 - Math.min(1, z) ** 2));
|
|
17217
|
+
const second = r ? (2 * momentum * omega * Math.abs(dy) / r ** 4 + omega ** 2 * Math.abs(dx) * (1 / r + 1 / r ** 3)) / (RAD * length) : Infinity;
|
|
17218
|
+
if (Number.isFinite(df) && Math.abs(df) > second * h2 + 1e-12) {
|
|
17219
|
+
if (f * g < 0)
|
|
17220
|
+
bisect(lo, hi, f);
|
|
17221
|
+
return;
|
|
17222
|
+
}
|
|
17223
|
+
const speed = r ? (momentum * Math.abs(dy) / r ** 2 + omega * Math.abs(dx)) / (RAD * length) : Infinity;
|
|
17224
|
+
if (Math.abs(value2(mid)) > speed * h2 + 1e-12)
|
|
17225
|
+
return;
|
|
17226
|
+
if (depth >= 24)
|
|
17227
|
+
throw new Error("Unresolved Elastic source clipping tangent or pole");
|
|
17228
|
+
visit(lo, mid, depth + 1);
|
|
17229
|
+
visit(mid, hi, depth + 1);
|
|
17230
|
+
};
|
|
17231
|
+
visit(0, 1, 0);
|
|
17232
|
+
}
|
|
17233
|
+
ts.sort((a2, b2) => a2 - b2);
|
|
17234
|
+
const result = [];
|
|
17235
|
+
for (let i = 1; i < ts.length; i++)
|
|
17236
|
+
if (ts[i] - ts[i - 1] > 1e-12 && contains(polygons, at((ts[i] + ts[i - 1]) / 2)))
|
|
17237
|
+
result.push({ a: at(ts[i - 1]), b: at(ts[i]) });
|
|
17238
|
+
return result;
|
|
17239
|
+
}
|
|
17240
|
+
|
|
16575
17241
|
// dist/discontinuous/elastic/map.js
|
|
16576
17242
|
var kernel = Object.assign((x, y) => [x, y], {
|
|
16577
17243
|
invert: (x, y) => [x, y]
|
|
@@ -16703,7 +17369,7 @@ var ElasticMap = class {
|
|
|
16703
17369
|
}
|
|
16704
17370
|
sourceOptions(options) {
|
|
16705
17371
|
const { step } = sampling(options);
|
|
16706
|
-
return { maxAngularStep: Math.min(step, 1), tolerance: 1e-5 };
|
|
17372
|
+
return { ...options, maxAngularStep: Math.min(step, 1), tolerance: 1e-5 };
|
|
16707
17373
|
}
|
|
16708
17374
|
sampled(c, line, options) {
|
|
16709
17375
|
return sample(line, (p) => c.grid.project(p), options, Math.min(180 / (c.grid.section.rows - 1), 360 / (c.grid.section.columns - 1)));
|
|
@@ -16712,23 +17378,70 @@ var ElasticMap = class {
|
|
|
16712
17378
|
const out = [];
|
|
16713
17379
|
for (const part of splitter.projectLine(line, this.sourceOptions(options)))
|
|
16714
17380
|
for (const c of this.charts.filter((c2) => c2.baseId === part.regionId)) {
|
|
16715
|
-
let current
|
|
16716
|
-
const
|
|
16717
|
-
if (
|
|
16718
|
-
|
|
16719
|
-
|
|
16720
|
-
|
|
16721
|
-
|
|
17381
|
+
let current;
|
|
17382
|
+
const boundary = (point, vertex) => {
|
|
17383
|
+
if (vertex === 0 || vertex === line.length - 1)
|
|
17384
|
+
return "source-endpoint";
|
|
17385
|
+
let edge2 = 0;
|
|
17386
|
+
const kinds = [];
|
|
17387
|
+
for (const polygon of c.domain)
|
|
17388
|
+
for (const ring of polygon)
|
|
17389
|
+
for (let i = 1; i < ring.length; i++, edge2++)
|
|
17390
|
+
if (onSegment(point, ring[i - 1], ring[i])) {
|
|
17391
|
+
const seam = this.seams.find((s) => s.regions.some((id, j) => id === c.region.id && s.edges[j] === edge2));
|
|
17392
|
+
kinds.push((seam == null ? void 0 : seam.kind) ?? "boundary");
|
|
17393
|
+
}
|
|
17394
|
+
return kinds.includes("boundary") ? "coverage-boundary" : kinds.includes("cut") ? "chart-cut" : kinds.includes("join") ? "continuous-chart-join" : "coverage-boundary";
|
|
16722
17395
|
};
|
|
16723
|
-
for (let i = 1; i < part.
|
|
16724
|
-
|
|
16725
|
-
|
|
16726
|
-
|
|
16727
|
-
|
|
16728
|
-
|
|
16729
|
-
|
|
17396
|
+
for (let i = 1; i < part.sourceCoordinates.length; i++) {
|
|
17397
|
+
const a = part.coordinates[i - 1], b = part.coordinates[i];
|
|
17398
|
+
const intervals = clipSourceArc(a, b, c.domain);
|
|
17399
|
+
if (!intervals.length) {
|
|
17400
|
+
current = void 0;
|
|
17401
|
+
continue;
|
|
17402
|
+
}
|
|
17403
|
+
if (Math.hypot(intervals[0].a[0] - a[0], intervals[0].a[1] - a[1]) > 1e-8)
|
|
17404
|
+
current = void 0;
|
|
17405
|
+
for (const clipped of intervals) {
|
|
17406
|
+
const arc = sourceArc(clipped.a, clipped.b);
|
|
17407
|
+
const samples = sample([clipped.a, clipped.b], (p) => c.grid.project(p), options, Math.min(180 / (c.grid.section.rows - 1), 360 / (c.grid.section.columns - 1)), (_, t) => arc(t));
|
|
17408
|
+
const first = samples.source[0], last = samples.source[samples.source.length - 1];
|
|
17409
|
+
const joined = current && Math.hypot(...current.sourceCoordinates[current.sourceCoordinates.length - 1].map((v, k2) => v - first[k2])) < 1e-8;
|
|
17410
|
+
if (!joined) {
|
|
17411
|
+
current = { regionId: c.region.id, coordinates: [], sourceCoordinates: [] };
|
|
17412
|
+
if (part.provenance)
|
|
17413
|
+
current.provenance = {
|
|
17414
|
+
segments: [],
|
|
17415
|
+
parameters: [],
|
|
17416
|
+
vertices: [],
|
|
17417
|
+
angularDistances: []
|
|
17418
|
+
};
|
|
17419
|
+
out.push(current);
|
|
17420
|
+
}
|
|
17421
|
+
for (let j = joined ? 1 : 0; j < samples.source.length; j++) {
|
|
17422
|
+
const p = samples.source[j];
|
|
17423
|
+
current.sourceCoordinates.push(p);
|
|
17424
|
+
current.coordinates.push(samples.xy[j]);
|
|
17425
|
+
const parent = part.provenance, target = current.provenance;
|
|
17426
|
+
if (parent && target) {
|
|
17427
|
+
const length = angle(geographic(a), geographic(b)), t = length ? Math.min(1, angle(geographic(a), geographic(p)) / length) : 0;
|
|
17428
|
+
const endpoint = t < 1e-12 ? i - 1 : t > 1 - 1e-12 ? i : -1, segment = parent.segments[i], from = parent.segments[i - 1] === segment ? parent.parameters[i - 1] : 0;
|
|
17429
|
+
target.segments.push(endpoint >= 0 ? parent.segments[endpoint] : segment);
|
|
17430
|
+
target.parameters.push(endpoint >= 0 ? parent.parameters[endpoint] : from + t * (parent.parameters[i] - from));
|
|
17431
|
+
target.vertices.push(endpoint >= 0 ? parent.vertices[endpoint] : 4294967295);
|
|
17432
|
+
if (options.pathDistances)
|
|
17433
|
+
target.angularDistances.push(parent.angularDistances[i - 1] + t * (parent.angularDistances[i] - parent.angularDistances[i - 1]));
|
|
17434
|
+
if (options.pathBoundaries) {
|
|
17435
|
+
if (target.vertices.length === 1)
|
|
17436
|
+
target.startReason = boundary(p, target.vertices[0]);
|
|
17437
|
+
target.endReason = boundary(p, target.vertices[target.vertices.length - 1]);
|
|
17438
|
+
}
|
|
17439
|
+
}
|
|
17440
|
+
}
|
|
17441
|
+
if (Math.hypot(last[0] - b[0], last[1] - b[1]) > 1e-8)
|
|
17442
|
+
current = void 0;
|
|
16730
17443
|
}
|
|
16731
|
-
|
|
17444
|
+
}
|
|
16732
17445
|
}
|
|
16733
17446
|
return out;
|
|
16734
17447
|
}
|
|
@@ -16736,13 +17449,175 @@ var ElasticMap = class {
|
|
|
16736
17449
|
const out = [];
|
|
16737
17450
|
for (const part of splitter.projectPolygon(rings, this.sourceOptions(options)))
|
|
16738
17451
|
for (const c of this.charts.filter((c2) => c2.baseId === part.regionId)) {
|
|
16739
|
-
const
|
|
17452
|
+
const prepared = [], preparedEdges = [];
|
|
17453
|
+
part.coordinates.forEach((ring, r) => {
|
|
17454
|
+
const points = [], edges = [];
|
|
17455
|
+
for (let i = 1; i < ring.length; i++) {
|
|
17456
|
+
const a = ring[i - 1], b = ring[i], arc = sourceArc(a, b), length = angle(geographic(a), geographic(b)), fractions = [0, 1];
|
|
17457
|
+
for (const interval of clipSourceArc(a, b, c.domain))
|
|
17458
|
+
for (const p of [interval.a, interval.b]) {
|
|
17459
|
+
const t = length > 1e-14 ? angle(geographic(a), geographic(p)) / length : Math.abs(b[0] - a[0]) > 1e-14 ? (p[0] - a[0]) / (b[0] - a[0]) : 0;
|
|
17460
|
+
if (t > 1e-12 && t < 1 - 1e-12)
|
|
17461
|
+
fractions.push(t);
|
|
17462
|
+
}
|
|
17463
|
+
fractions.sort((a2, b2) => a2 - b2);
|
|
17464
|
+
const split = fractions.filter((t, i2) => !i2 || t - fractions[i2 - 1] > 1e-12);
|
|
17465
|
+
const append2 = (point) => {
|
|
17466
|
+
if (points.length >= 1e5)
|
|
17467
|
+
throw new Error("Elastic polygon constraint vertex limit exceeded");
|
|
17468
|
+
if (points.length) {
|
|
17469
|
+
const previous = points[points.length - 1];
|
|
17470
|
+
if (options.polygonEdgeProvenance)
|
|
17471
|
+
edges.push(composePolygonEdge(part.edgeProvenance[r][i - 1], a, b, previous, point));
|
|
17472
|
+
}
|
|
17473
|
+
points.push(point);
|
|
17474
|
+
};
|
|
17475
|
+
const first = arc(0);
|
|
17476
|
+
if (!points.length)
|
|
17477
|
+
points.push(first);
|
|
17478
|
+
else if (points[points.length - 1].some((v, k2) => v !== first[k2])) {
|
|
17479
|
+
if (angle(geographic(points[points.length - 1]), geographic(first)) > 1e-10)
|
|
17480
|
+
throw new Error("Discontinuous Elastic input source constraint");
|
|
17481
|
+
if (options.polygonEdgeProvenance)
|
|
17482
|
+
edges.push({
|
|
17483
|
+
kind: "continuous-chart-join",
|
|
17484
|
+
ring: 4294967295,
|
|
17485
|
+
segment: 4294967295,
|
|
17486
|
+
t0: 0,
|
|
17487
|
+
t1: 0
|
|
17488
|
+
});
|
|
17489
|
+
points.push(first);
|
|
17490
|
+
}
|
|
17491
|
+
for (let j = 1; j < split.length; j++) {
|
|
17492
|
+
append2(arc((split[j - 1] + split[j]) / 2));
|
|
17493
|
+
append2(arc(split[j]));
|
|
17494
|
+
}
|
|
17495
|
+
}
|
|
17496
|
+
if (points[points.length - 1].some((v, k2) => v !== points[0][k2])) {
|
|
17497
|
+
if (angle(geographic(points[points.length - 1]), geographic(points[0])) > 1e-10)
|
|
17498
|
+
throw new Error("Unclosed Elastic input source constraint");
|
|
17499
|
+
if (options.polygonEdgeProvenance)
|
|
17500
|
+
edges.push({
|
|
17501
|
+
kind: "continuous-chart-join",
|
|
17502
|
+
ring: 4294967295,
|
|
17503
|
+
segment: 4294967295,
|
|
17504
|
+
t0: 0,
|
|
17505
|
+
t1: 0
|
|
17506
|
+
});
|
|
17507
|
+
points.push([...points[0]]);
|
|
17508
|
+
}
|
|
17509
|
+
prepared.push(points);
|
|
17510
|
+
preparedEdges.push(edges);
|
|
17511
|
+
});
|
|
17512
|
+
const clipped = import_polygon_clipping4.default.intersection(snapPolygon(prepared), c.domain.map(snapPolygon));
|
|
16740
17513
|
for (const polygon of clipped) {
|
|
16741
|
-
const
|
|
17514
|
+
const input = snapPolygon(prepared), traced = tracePolygonConstraints(input, polygon, 1e-9, options.polygonEdgeProvenance ? preparedEdges : void 0, void 0, (a, b) => angle(geographic(a), geographic(b)) < 64 * Number.EPSILON), resolved2 = traced.rings.map((r) => r.map((p) => [...p]));
|
|
17515
|
+
traced.owners.forEach((owners, r) => owners.forEach((owner, i) => {
|
|
17516
|
+
if (!owner)
|
|
17517
|
+
return;
|
|
17518
|
+
const [pr, pe] = owner, a = prepared[pr][pe], b = prepared[pr][pe + 1], length = angle(geographic(a), geographic(b)), arc = sourceArc(a, b);
|
|
17519
|
+
for (const j of [i, i + 1]) {
|
|
17520
|
+
const q = traced.rings[r][j], start = input[pr][pe], end = input[pr][pe + 1];
|
|
17521
|
+
if (Math.hypot(q[0] - start[0], q[1] - start[1]) < 1e-8)
|
|
17522
|
+
resolved2[r][j] = [...a];
|
|
17523
|
+
else if (Math.hypot(q[0] - end[0], q[1] - end[1]) < 1e-8)
|
|
17524
|
+
resolved2[r][j] = [...b];
|
|
17525
|
+
else {
|
|
17526
|
+
const candidates = clipSourceArc(a, b, c.domain).flatMap((interval) => [
|
|
17527
|
+
interval.a,
|
|
17528
|
+
interval.b
|
|
17529
|
+
]);
|
|
17530
|
+
if (!candidates.length)
|
|
17531
|
+
throw new Error("Unresolved Elastic polygon source intersection");
|
|
17532
|
+
const reference = length ? angle(geographic(a), geographic(q)) / length : 0;
|
|
17533
|
+
candidates.sort((x, y) => Math.abs((length ? angle(geographic(a), geographic(x)) / length : 0) - reference) - Math.abs((length ? angle(geographic(a), geographic(y)) / length : 0) - reference));
|
|
17534
|
+
const fraction = length ? angle(geographic(a), geographic(candidates[0])) / length : 0;
|
|
17535
|
+
resolved2[r][j] = arc(Math.min(1, Math.max(0, fraction)));
|
|
17536
|
+
}
|
|
17537
|
+
}
|
|
17538
|
+
}));
|
|
17539
|
+
for (const ring of resolved2)
|
|
17540
|
+
ring[ring.length - 1] = [...ring[0]];
|
|
17541
|
+
const generated = (a, b) => {
|
|
17542
|
+
if (angle(geographic(a), geographic(b)) < 64 * Number.EPSILON)
|
|
17543
|
+
return "continuous-chart-join";
|
|
17544
|
+
let edge2 = 0;
|
|
17545
|
+
const kinds = [];
|
|
17546
|
+
for (const polygon2 of c.domain)
|
|
17547
|
+
for (const ring of polygon2)
|
|
17548
|
+
for (let j = 1; j < ring.length; j++, edge2++)
|
|
17549
|
+
if (onSegment(a, ring[j - 1], ring[j]) && onSegment(b, ring[j - 1], ring[j])) {
|
|
17550
|
+
const seam = this.seams.find((s) => s.regions.some((id, k2) => id === c.region.id && s.edges[k2] === edge2));
|
|
17551
|
+
kinds.push((seam == null ? void 0 : seam.kind) ?? "boundary");
|
|
17552
|
+
}
|
|
17553
|
+
if (!kinds.length)
|
|
17554
|
+
throw new Error("Unknown Elastic polygon clipping constraint");
|
|
17555
|
+
return kinds.includes("boundary") ? "coverage-boundary" : kinds.includes("cut") ? "chart-cut" : "continuous-chart-join";
|
|
17556
|
+
};
|
|
17557
|
+
const coordinates2 = [], sourceCoordinates = [], edgeProvenance = [];
|
|
17558
|
+
resolved2.forEach((ring, r) => {
|
|
17559
|
+
const source = [], xy = [], edges = [];
|
|
17560
|
+
for (let i = 1; i < ring.length; i++) {
|
|
17561
|
+
const owner = traced.owners[r][i - 1], arc = owner ? sourceArc(ring[i - 1], ring[i]) : void 0;
|
|
17562
|
+
const samples = sample(arc ? [arc(0), arc(1)] : [ring[i - 1], ring[i]], (p) => c.grid.project(p), options, Math.min(180 / (c.grid.section.rows - 1), 360 / (c.grid.section.columns - 1)), arc ? (_, t) => arc(t) : void 0);
|
|
17563
|
+
if (!source.length) {
|
|
17564
|
+
source.push(samples.source[0]);
|
|
17565
|
+
xy.push(samples.xy[0]);
|
|
17566
|
+
} else if (source[source.length - 1].some((v, k2) => Math.abs(v - samples.source[0][k2]) > 1e-10)) {
|
|
17567
|
+
if (angle(geographic(source[source.length - 1]), geographic(samples.source[0])) > 1e-10)
|
|
17568
|
+
throw new Error("Discontinuous Elastic polygon source constraint");
|
|
17569
|
+
if (options.polygonEdgeProvenance)
|
|
17570
|
+
edges.push({
|
|
17571
|
+
kind: "continuous-chart-join",
|
|
17572
|
+
ring: 4294967295,
|
|
17573
|
+
segment: 4294967295,
|
|
17574
|
+
t0: 0,
|
|
17575
|
+
t1: 0
|
|
17576
|
+
});
|
|
17577
|
+
source.push(samples.source[0]);
|
|
17578
|
+
xy.push(samples.xy[0]);
|
|
17579
|
+
}
|
|
17580
|
+
for (let j = 1; j < samples.source.length; j++) {
|
|
17581
|
+
if (options.polygonEdgeProvenance) {
|
|
17582
|
+
if (owner) {
|
|
17583
|
+
const [pr, pe] = owner;
|
|
17584
|
+
edges.push(composePolygonEdge(preparedEdges[pr][pe], prepared[pr][pe], prepared[pr][pe + 1], source[source.length - 1], samples.source[j]));
|
|
17585
|
+
} else
|
|
17586
|
+
edges.push({
|
|
17587
|
+
kind: generated(ring[i - 1], ring[i]),
|
|
17588
|
+
ring: 4294967295,
|
|
17589
|
+
segment: 4294967295,
|
|
17590
|
+
t0: 0,
|
|
17591
|
+
t1: 0
|
|
17592
|
+
});
|
|
17593
|
+
}
|
|
17594
|
+
source.push(samples.source[j]);
|
|
17595
|
+
xy.push(samples.xy[j]);
|
|
17596
|
+
}
|
|
17597
|
+
}
|
|
17598
|
+
if (source.length && source[source.length - 1].some((v, k2) => v !== source[0][k2])) {
|
|
17599
|
+
if (angle(geographic(source[source.length - 1]), geographic(source[0])) > 1e-10)
|
|
17600
|
+
throw new Error("Unclosed Elastic polygon source constraint");
|
|
17601
|
+
if (options.polygonEdgeProvenance)
|
|
17602
|
+
edges.push({
|
|
17603
|
+
kind: "continuous-chart-join",
|
|
17604
|
+
ring: 4294967295,
|
|
17605
|
+
segment: 4294967295,
|
|
17606
|
+
t0: 0,
|
|
17607
|
+
t1: 0
|
|
17608
|
+
});
|
|
17609
|
+
source.push([...source[0]]);
|
|
17610
|
+
xy.push([...xy[0]]);
|
|
17611
|
+
}
|
|
17612
|
+
coordinates2.push(xy);
|
|
17613
|
+
sourceCoordinates.push(source);
|
|
17614
|
+
edgeProvenance.push(edges);
|
|
17615
|
+
});
|
|
16742
17616
|
out.push({
|
|
16743
17617
|
regionId: c.region.id,
|
|
16744
|
-
coordinates:
|
|
16745
|
-
sourceCoordinates
|
|
17618
|
+
coordinates: coordinates2,
|
|
17619
|
+
sourceCoordinates,
|
|
17620
|
+
...options.polygonEdgeProvenance ? { edgeProvenance } : {}
|
|
16746
17621
|
});
|
|
16747
17622
|
}
|
|
16748
17623
|
}
|
|
@@ -16796,7 +17671,7 @@ function wrap2(lon) {
|
|
|
16796
17671
|
return x > 180 ? x - 360 : x < -180 ? x + 360 : x;
|
|
16797
17672
|
}
|
|
16798
17673
|
function snapPolygon(rings) {
|
|
16799
|
-
return rings.map((
|
|
17674
|
+
return rings.map((r) => r.map((p) => p.map((v) => Math.round(v * 1e10) / 1e10)));
|
|
16800
17675
|
}
|
|
16801
17676
|
|
|
16802
17677
|
// dist/discontinuous/layout.js
|
|
@@ -19055,7 +19930,7 @@ function createGraticule(columns) {
|
|
|
19055
19930
|
|
|
19056
19931
|
// dist/discontinuous/myriahedral/unfold.js
|
|
19057
19932
|
var import_core2 = require("@math.gl/core");
|
|
19058
|
-
var
|
|
19933
|
+
var import_geometry4 = require("@math.gl/geometry");
|
|
19059
19934
|
|
|
19060
19935
|
// dist/discontinuous/myriahedral/mesh.js
|
|
19061
19936
|
var subtract3 = (a, b) => [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
|
|
@@ -19298,7 +20173,7 @@ function restoreLayout(data) {
|
|
|
19298
20173
|
const { mesh, panels, targetAngles } = data;
|
|
19299
20174
|
if (panels.length !== mesh.faces.length || targetAngles.length !== panels.length || !targetAngles.every(Number.isFinite) || data.rootTransform.length !== 16 || !data.rootTransform.every(Number.isFinite))
|
|
19300
20175
|
throw new Error("Invalid prepared hinge layout");
|
|
19301
|
-
const tree = new
|
|
20176
|
+
const tree = new import_geometry4.HingeTree(panels);
|
|
19302
20177
|
const rootTransform = new import_core2.Matrix4(data.rootTransform);
|
|
19303
20178
|
const poses = new Float64Array(panels.length * 16), angles = new Float64Array(panels.length);
|
|
19304
20179
|
const evaluate2 = (amount) => {
|
|
@@ -19600,17 +20475,65 @@ var MercatorMap = class extends DiscontinuousMap {
|
|
|
19600
20475
|
continue;
|
|
19601
20476
|
}
|
|
19602
20477
|
const at = (t) => [a[0] + (b[0] - a[0]) * t, a[1] + dy * t];
|
|
19603
|
-
const
|
|
20478
|
+
const endpoint = (t) => {
|
|
20479
|
+
if (t === 0 || t === 1)
|
|
20480
|
+
return { xy: at(t), source: part.sourceCoordinates[i - 1 + t], t };
|
|
20481
|
+
const va = geographic(part.sourceCoordinates[i - 1]), vb = geographic(part.sourceCoordinates[i]), arc = angle(va, vb);
|
|
20482
|
+
const sourceAt = (t2) => {
|
|
20483
|
+
if (!arc)
|
|
20484
|
+
return part.sourceCoordinates[i - 1];
|
|
20485
|
+
const a2 = Math.sin((1 - t2) * arc) / Math.sin(arc), b2 = Math.sin(t2 * arc) / Math.sin(arc);
|
|
20486
|
+
return coordinates(unit(va.map((v, k2) => a2 * v + b2 * vb[k2])));
|
|
20487
|
+
};
|
|
20488
|
+
const latitude = Math.sign(at(t)[1]) * this.limit;
|
|
20489
|
+
let lo = 0, hi = 1;
|
|
20490
|
+
for (let j = 0; j < 52; j++) {
|
|
20491
|
+
const mid = (lo + hi) / 2;
|
|
20492
|
+
if (sourceAt(mid)[1] < latitude === part.sourceCoordinates[i - 1][1] < latitude)
|
|
20493
|
+
lo = mid;
|
|
20494
|
+
else
|
|
20495
|
+
hi = mid;
|
|
20496
|
+
}
|
|
20497
|
+
const f = (lo + hi) / 2, source = sourceAt(f);
|
|
20498
|
+
const xy = super.projectPoint(source, part.regionId).position;
|
|
20499
|
+
return { xy, source, t: f };
|
|
20500
|
+
};
|
|
20501
|
+
const start = endpoint(t0), end = endpoint(t1);
|
|
20502
|
+
const append2 = (point, index) => {
|
|
20503
|
+
current.coordinates.push(point.xy);
|
|
20504
|
+
current.sourceCoordinates.push(point.source);
|
|
20505
|
+
const source = part.provenance, target = current.provenance;
|
|
20506
|
+
if (!source || !target)
|
|
20507
|
+
return;
|
|
20508
|
+
const segment = source.segments[i];
|
|
20509
|
+
const from = source.segments[i - 1] === segment ? source.parameters[i - 1] : 0;
|
|
20510
|
+
target.segments.push(point.t === 0 || point.t === 1 ? source.segments[index] : segment);
|
|
20511
|
+
target.parameters.push(point.t === 0 || point.t === 1 ? source.parameters[index] : from + point.t * (source.parameters[i] - from));
|
|
20512
|
+
target.vertices.push(point.t === 0 || point.t === 1 ? source.vertices[index] : 4294967295);
|
|
20513
|
+
if (options == null ? void 0 : options.pathDistances)
|
|
20514
|
+
target.angularDistances.push(source.angularDistances[i - 1] + point.t * (source.angularDistances[i] - source.angularDistances[i - 1]));
|
|
20515
|
+
};
|
|
19604
20516
|
if (!current || t0 > 0) {
|
|
19605
20517
|
current = {
|
|
19606
20518
|
regionId: part.regionId,
|
|
19607
|
-
coordinates: [
|
|
19608
|
-
sourceCoordinates: [
|
|
20519
|
+
coordinates: [],
|
|
20520
|
+
sourceCoordinates: [],
|
|
20521
|
+
...part.provenance ? {
|
|
20522
|
+
provenance: {
|
|
20523
|
+
segments: [],
|
|
20524
|
+
parameters: [],
|
|
20525
|
+
vertices: [],
|
|
20526
|
+
angularDistances: [],
|
|
20527
|
+
...(options == null ? void 0 : options.pathBoundaries) ? { startReason: t0 > 0 ? "coverage-boundary" : part.provenance.startReason } : {}
|
|
20528
|
+
}
|
|
20529
|
+
} : {}
|
|
19609
20530
|
};
|
|
19610
20531
|
result.push(current);
|
|
20532
|
+
append2(start, i - 1);
|
|
19611
20533
|
}
|
|
19612
|
-
|
|
19613
|
-
current.
|
|
20534
|
+
append2(end, i);
|
|
20535
|
+
if (current.provenance && (options == null ? void 0 : options.pathBoundaries))
|
|
20536
|
+
current.provenance.endReason = t1 < 1 ? "coverage-boundary" : part.provenance.endReason;
|
|
19614
20537
|
if (t1 < 1)
|
|
19615
20538
|
current = void 0;
|
|
19616
20539
|
}
|
|
@@ -19628,11 +20551,60 @@ var MercatorMap = class extends DiscontinuousMap {
|
|
|
19628
20551
|
[-x, -y]
|
|
19629
20552
|
]
|
|
19630
20553
|
];
|
|
19631
|
-
return super.projectPolygon(rings, options).flatMap((part) => import_polygon_clipping5.default.intersection(part.coordinates, box).map((
|
|
19632
|
-
|
|
19633
|
-
|
|
19634
|
-
|
|
19635
|
-
|
|
20554
|
+
return super.projectPolygon(rings, options).flatMap((part) => import_polygon_clipping5.default.intersection(part.coordinates, box).map((polygon) => {
|
|
20555
|
+
const traced = tracePolygonConstraints(part.coordinates, polygon, 1e-10, part.edgeProvenance);
|
|
20556
|
+
const sources = traced.rings.map((r) => r.map((p) => this.source(p)));
|
|
20557
|
+
traced.owners.forEach((owners, r) => owners.forEach((owner, i) => {
|
|
20558
|
+
if (!owner)
|
|
20559
|
+
return;
|
|
20560
|
+
const [parentRing, parentEdge] = owner, a = part.sourceCoordinates[parentRing][parentEdge], b = part.sourceCoordinates[parentRing][parentEdge + 1], at = sourceArc(a, b);
|
|
20561
|
+
for (const j of [i, i + 1]) {
|
|
20562
|
+
const q = traced.rings[r][j], first = part.coordinates[parentRing][parentEdge], last = part.coordinates[parentRing][parentEdge + 1];
|
|
20563
|
+
if (Math.hypot(q[0] - first[0], q[1] - first[1]) < 1e-10 * this.radius)
|
|
20564
|
+
sources[r][j] = [...a];
|
|
20565
|
+
else if (Math.hypot(q[0] - last[0], q[1] - last[1]) < 1e-10 * this.radius)
|
|
20566
|
+
sources[r][j] = [...b];
|
|
20567
|
+
else {
|
|
20568
|
+
const latitude = Math.sign(q[1]) * this.limit;
|
|
20569
|
+
let lo = 0, hi = 1;
|
|
20570
|
+
if (a[1] < latitude === b[1] < latitude)
|
|
20571
|
+
throw new Error("Unresolved Mercator source constraint intersection");
|
|
20572
|
+
for (let k2 = 0; k2 < 52; k2++) {
|
|
20573
|
+
const mid = (lo + hi) / 2;
|
|
20574
|
+
if (at(mid)[1] < latitude === a[1] < latitude)
|
|
20575
|
+
lo = mid;
|
|
20576
|
+
else
|
|
20577
|
+
hi = mid;
|
|
20578
|
+
}
|
|
20579
|
+
sources[r][j] = at((lo + hi) / 2);
|
|
20580
|
+
}
|
|
20581
|
+
}
|
|
20582
|
+
}));
|
|
20583
|
+
for (const r of sources)
|
|
20584
|
+
r[r.length - 1] = [...r[0]];
|
|
20585
|
+
return {
|
|
20586
|
+
regionId: part.regionId,
|
|
20587
|
+
sourceCoordinates: sources,
|
|
20588
|
+
coordinates: sources.map((r) => r.map((p) => super.projectPoint(p, part.regionId).position)),
|
|
20589
|
+
...(options == null ? void 0 : options.polygonEdgeProvenance) ? {
|
|
20590
|
+
edgeProvenance: traced.owners.map((owners, r) => owners.map((owner, i) => {
|
|
20591
|
+
if (owner) {
|
|
20592
|
+
const [pr, pe] = owner;
|
|
20593
|
+
return composePolygonEdge(part.edgeProvenance[pr][pe], part.sourceCoordinates[pr][pe], part.sourceCoordinates[pr][pe + 1], sources[r][i], sources[r][i + 1]);
|
|
20594
|
+
}
|
|
20595
|
+
if (!sources[r].slice(i, i + 2).every((p) => Math.abs(Math.abs(p[1]) - this.limit) < 1e-7))
|
|
20596
|
+
throw new Error("Unknown Mercator clipping constraint");
|
|
20597
|
+
return {
|
|
20598
|
+
kind: "coverage-boundary",
|
|
20599
|
+
ring: 4294967295,
|
|
20600
|
+
segment: 4294967295,
|
|
20601
|
+
t0: 0,
|
|
20602
|
+
t1: 0
|
|
20603
|
+
};
|
|
20604
|
+
}))
|
|
20605
|
+
} : {}
|
|
20606
|
+
};
|
|
20607
|
+
}));
|
|
19636
20608
|
}
|
|
19637
20609
|
};
|
|
19638
20610
|
|