@tileflow/core 0.1.0-alpha.33 → 0.1.0-alpha.34
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/README.md +3 -0
- package/dist/browser.d.ts +478 -150
- package/dist/browser.js +6810 -4170
- package/dist/build.d.ts +12 -4
- package/dist/build.js +609 -222
- package/dist/config-reference.json +2413 -829
- package/dist/{icon-composition-CSnN2-Xt.d.ts → icon-composition-DqoZWQuz.d.ts} +189 -2
- package/dist/index.d.ts +76 -5
- package/dist/index.js +945 -250
- package/dist/{manifest-types-E7m23eXL.d.ts → manifest-types-hmzy2bBX.d.ts} +20 -1
- package/dist/manifest.d.ts +2 -2
- package/dist/runtime.d.ts +1 -1
- package/docs/application-tile-reading.md +3 -0
- package/docs/authoring-model.md +2 -1
- package/docs/buildings-3d.md +66 -62
- package/docs/street-lights.md +32 -5
- package/docs/trees-3d.md +211 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -261,16 +261,16 @@ var init_expression_operators = __esm({
|
|
|
261
261
|
function fixed(value, options) {
|
|
262
262
|
const reason = options.reason.trim();
|
|
263
263
|
if (!reason) throw new Error("Tileflow fixed values require a non-empty reason.");
|
|
264
|
-
|
|
264
|
+
cloneJson2(value);
|
|
265
265
|
return { kind: "theme-fixed", reason, value };
|
|
266
266
|
}
|
|
267
267
|
function expression(value) {
|
|
268
268
|
validateExpressionArray(value, "expression");
|
|
269
|
-
return { kind: "expression", value:
|
|
269
|
+
return { kind: "expression", value: cloneJson2(value) };
|
|
270
270
|
}
|
|
271
271
|
function toMapLibreStyleValue(value) {
|
|
272
272
|
if (isTileflowExpression(value)) {
|
|
273
|
-
return
|
|
273
|
+
return cloneJson2(value.value);
|
|
274
274
|
}
|
|
275
275
|
if (isTileflowZoomValue(value)) {
|
|
276
276
|
if (value.interpolation === "step") {
|
|
@@ -278,8 +278,8 @@ function toMapLibreStyleValue(value) {
|
|
|
278
278
|
return [
|
|
279
279
|
"step",
|
|
280
280
|
["zoom"],
|
|
281
|
-
|
|
282
|
-
...rest.flatMap(([stop, stopValue]) => [stop,
|
|
281
|
+
cloneJson2(firstValue),
|
|
282
|
+
...rest.flatMap(([stop, stopValue]) => [stop, cloneJson2(stopValue)])
|
|
283
283
|
];
|
|
284
284
|
}
|
|
285
285
|
const interpolation = value.interpolation === "exponential" ? ["exponential", value.base] : [value.interpolation];
|
|
@@ -287,13 +287,13 @@ function toMapLibreStyleValue(value) {
|
|
|
287
287
|
"interpolate",
|
|
288
288
|
interpolation,
|
|
289
289
|
["zoom"],
|
|
290
|
-
...value.stops.flatMap(([stop, stopValue]) => [stop,
|
|
290
|
+
...value.stops.flatMap(([stop, stopValue]) => [stop, cloneJson2(stopValue)])
|
|
291
291
|
];
|
|
292
292
|
}
|
|
293
293
|
if (isTileflowThemeValueNode(value)) {
|
|
294
294
|
throw new Error("Tileflow theme values must be resolved before MapLibre style compilation.");
|
|
295
295
|
}
|
|
296
|
-
return
|
|
296
|
+
return cloneJson2(value);
|
|
297
297
|
}
|
|
298
298
|
function isTileflowExpression(value) {
|
|
299
299
|
return isRecord(value) && value.kind === "expression" && Array.isArray(value.value);
|
|
@@ -330,7 +330,7 @@ function createZoomValue(interpolation, stops, base) {
|
|
|
330
330
|
throw new Error("Tileflow zoom stops must be strictly increasing.");
|
|
331
331
|
}
|
|
332
332
|
previous = stop;
|
|
333
|
-
return [stop,
|
|
333
|
+
return [stop, cloneJson2(value)];
|
|
334
334
|
});
|
|
335
335
|
return {
|
|
336
336
|
kind: "zoom",
|
|
@@ -359,9 +359,9 @@ function validateExpressionArray(value, name) {
|
|
|
359
359
|
if (!isMapLibreExpressionOperator(value[0])) {
|
|
360
360
|
throw new Error(`Unknown MapLibre expression operator: ${value[0]}`);
|
|
361
361
|
}
|
|
362
|
-
|
|
362
|
+
cloneJson2(value);
|
|
363
363
|
}
|
|
364
|
-
function
|
|
364
|
+
function cloneJson2(value) {
|
|
365
365
|
const serialized = JSON.stringify(value);
|
|
366
366
|
if (serialized === void 0) {
|
|
367
367
|
throw new Error("Tileflow style values must be JSON-serializable.");
|
|
@@ -403,9 +403,9 @@ var init_values = __esm({
|
|
|
403
403
|
color = {
|
|
404
404
|
alpha(value, opacity) {
|
|
405
405
|
return {
|
|
406
|
-
color:
|
|
406
|
+
color: cloneJson2(value),
|
|
407
407
|
kind: "theme-color",
|
|
408
|
-
opacity:
|
|
408
|
+
opacity: cloneJson2(opacity),
|
|
409
409
|
operation: "alpha"
|
|
410
410
|
};
|
|
411
411
|
},
|
|
@@ -414,12 +414,12 @@ var init_values = __esm({
|
|
|
414
414
|
throw new Error("Tileflow color mixing supports only the deterministic OKLCH color space.");
|
|
415
415
|
}
|
|
416
416
|
return {
|
|
417
|
-
amount:
|
|
418
|
-
from:
|
|
417
|
+
amount: cloneJson2(options.amount),
|
|
418
|
+
from: cloneJson2(from),
|
|
419
419
|
kind: "theme-color",
|
|
420
420
|
operation: "mix",
|
|
421
421
|
space: "oklch",
|
|
422
|
-
to:
|
|
422
|
+
to: cloneJson2(to)
|
|
423
423
|
};
|
|
424
424
|
}
|
|
425
425
|
};
|
|
@@ -662,9 +662,9 @@ function tileflowSunMetadata(preset) {
|
|
|
662
662
|
return Object.freeze({ version: 1, ...preset });
|
|
663
663
|
}
|
|
664
664
|
function readTileflowSunPreset(metadata) {
|
|
665
|
-
if (!
|
|
665
|
+
if (!isRecord6(metadata)) return void 0;
|
|
666
666
|
const value = metadata[tileflowSunMetadataKey];
|
|
667
|
-
if (!
|
|
667
|
+
if (!isRecord6(value) || value.version !== 1 || !isRecord6(value.ambient)) return void 0;
|
|
668
668
|
const { azimuth, altitude, color: color3, intensity, shadowIntensity } = value;
|
|
669
669
|
const ambient = value.ambient;
|
|
670
670
|
if (!isFiniteNumber(azimuth) || !isFiniteNumber(altitude) || !isUnit(intensity) || !isUnit(shadowIntensity) || !isUnit(ambient.intensity) || !isColour(color3) || !isColour(ambient.color))
|
|
@@ -681,7 +681,7 @@ function readTileflowSunPreset(metadata) {
|
|
|
681
681
|
function tileflowStyleSunPreset(style) {
|
|
682
682
|
const published = readTileflowSunPreset(style?.metadata);
|
|
683
683
|
if (published) return published;
|
|
684
|
-
const light =
|
|
684
|
+
const light = isRecord6(style?.light) ? style.light : void 0;
|
|
685
685
|
const position = light?.position;
|
|
686
686
|
if (!position) return tileflowDefaultSunPreset;
|
|
687
687
|
return Object.freeze({
|
|
@@ -719,7 +719,7 @@ function smoothstep2(from, to, value) {
|
|
|
719
719
|
function clamp01(value) {
|
|
720
720
|
return Math.min(1, Math.max(0, Number.isFinite(value) ? value : 0));
|
|
721
721
|
}
|
|
722
|
-
function
|
|
722
|
+
function isRecord6(value) {
|
|
723
723
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
724
724
|
}
|
|
725
725
|
function isFiniteNumber(value) {
|
|
@@ -963,7 +963,7 @@ function auditTileflowThemeValues(value, path = "value", context = inferAuditCon
|
|
|
963
963
|
return diagnostics.sort(compareAuditDiagnostics);
|
|
964
964
|
}
|
|
965
965
|
function auditTileflowMapThemeValues(map) {
|
|
966
|
-
const modules =
|
|
966
|
+
const modules = isRecord7(map.modules) ? map.modules : void 0;
|
|
967
967
|
const moduleDiagnostics = modules ? Object.keys(modules).sort(compareCodeUnits2).flatMap(
|
|
968
968
|
(owner) => auditTileflowThemeValues(modules[owner], `modules.${owner}`, {
|
|
969
969
|
owner,
|
|
@@ -1070,7 +1070,7 @@ function isThemePrimitiveForCategory(value, category) {
|
|
|
1070
1070
|
return category === "number" ? typeof value === "number" && Number.isFinite(value) || Array.isArray(value) && value.every((entry) => typeof entry === "number" && Number.isFinite(entry)) : typeof value === "string" && value.length > 0;
|
|
1071
1071
|
}
|
|
1072
1072
|
function isThemeValueCandidate(value) {
|
|
1073
|
-
return
|
|
1073
|
+
return isRecord7(value) && (value.kind === "theme-token" || value.kind === "theme-fixed" || value.kind === "theme-color");
|
|
1074
1074
|
}
|
|
1075
1075
|
function visitAuditableValue(value, path, category, state, intentRequired = false) {
|
|
1076
1076
|
if (isThemeStructuralPath(path)) category = void 0;
|
|
@@ -1086,7 +1086,7 @@ function visitAuditableValue(value, path, category, state, intentRequired = fals
|
|
|
1086
1086
|
visitAuditableArray(value, path, category, state, false, intentRequired);
|
|
1087
1087
|
return;
|
|
1088
1088
|
}
|
|
1089
|
-
if (!
|
|
1089
|
+
if (!isRecord7(value)) return;
|
|
1090
1090
|
if (value.kind === "expression" && Array.isArray(value.value)) {
|
|
1091
1091
|
visitAuditableArray(value.value, `${path}.value`, category, state, true, intentRequired);
|
|
1092
1092
|
return;
|
|
@@ -1469,7 +1469,7 @@ function assertThemeLighting(value, path) {
|
|
|
1469
1469
|
}
|
|
1470
1470
|
}
|
|
1471
1471
|
function assertThemeCategoryValue(value, expectedCategory, path) {
|
|
1472
|
-
if (!
|
|
1472
|
+
if (!isRecord7(value)) {
|
|
1473
1473
|
assertTokenPrimitive(expectedCategory, value, path);
|
|
1474
1474
|
return;
|
|
1475
1475
|
}
|
|
@@ -1830,11 +1830,11 @@ function cloneJson14(value) {
|
|
|
1830
1830
|
if (serialized === void 0) throw new Error("Tileflow themes must be JSON-serializable.");
|
|
1831
1831
|
return JSON.parse(serialized);
|
|
1832
1832
|
}
|
|
1833
|
-
function
|
|
1833
|
+
function isRecord7(value) {
|
|
1834
1834
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1835
1835
|
}
|
|
1836
1836
|
function isPlainRecord(value) {
|
|
1837
|
-
if (!
|
|
1837
|
+
if (!isRecord7(value)) return false;
|
|
1838
1838
|
const prototype = Object.getPrototypeOf(value);
|
|
1839
1839
|
return prototype === Object.prototype || prototype === null;
|
|
1840
1840
|
}
|
|
@@ -1947,7 +1947,7 @@ var init_model = __esm({
|
|
|
1947
1947
|
if (Array.isArray(value)) {
|
|
1948
1948
|
return value.map((entry, index) => this.resolveTree(entry, `${path}[${index}]`, category));
|
|
1949
1949
|
}
|
|
1950
|
-
if (!
|
|
1950
|
+
if (!isRecord7(value)) return value;
|
|
1951
1951
|
if (value.kind === "expression" && Array.isArray(value.value)) {
|
|
1952
1952
|
return {
|
|
1953
1953
|
...value,
|
|
@@ -2956,7 +2956,7 @@ var defaults = {
|
|
|
2956
2956
|
function resolveTileflowAtmosphere(value) {
|
|
2957
2957
|
if (!value) return void 0;
|
|
2958
2958
|
const options = { ...defaults, ...value === true ? {} : value };
|
|
2959
|
-
const
|
|
2959
|
+
const normalize2 = (input) => {
|
|
2960
2960
|
const color3 = typeof input === "string" ? Color.parse(input) : void 0;
|
|
2961
2961
|
if (!color3 || color3.a !== 1)
|
|
2962
2962
|
throw new Error("Atmosphere colors must resolve to opaque colors.");
|
|
@@ -2966,10 +2966,10 @@ function resolveTileflowAtmosphere(value) {
|
|
|
2966
2966
|
};
|
|
2967
2967
|
return {
|
|
2968
2968
|
...options,
|
|
2969
|
-
skyColor:
|
|
2970
|
-
horizonColor:
|
|
2971
|
-
fogColor:
|
|
2972
|
-
spaceColor:
|
|
2969
|
+
skyColor: normalize2(options.skyColor),
|
|
2970
|
+
horizonColor: normalize2(options.horizonColor),
|
|
2971
|
+
fogColor: normalize2(options.fogColor),
|
|
2972
|
+
spaceColor: normalize2(options.spaceColor)
|
|
2973
2973
|
};
|
|
2974
2974
|
}
|
|
2975
2975
|
function compileTileflowSky(options) {
|
|
@@ -3480,10 +3480,10 @@ function isCanonicalOpenMapTilesSchema(schema) {
|
|
|
3480
3480
|
([key, value]) => schema.fields[key] === value
|
|
3481
3481
|
);
|
|
3482
3482
|
}
|
|
3483
|
-
function dataIdentity(kind, schema,
|
|
3483
|
+
function dataIdentity(kind, schema, version2, url) {
|
|
3484
3484
|
return {
|
|
3485
|
-
...
|
|
3486
|
-
..."worldSelection" in
|
|
3485
|
+
...version2.generation ? { generation: version2.generation } : {},
|
|
3486
|
+
..."worldSelection" in version2 && version2.worldSelection ? { worldSelection: version2.worldSelection } : {},
|
|
3487
3487
|
...kind === "vector-tiles" ? {
|
|
3488
3488
|
bindings: {
|
|
3489
3489
|
fields: { ...schema.fields },
|
|
@@ -3498,7 +3498,7 @@ function dataIdentity(kind, schema, version, url) {
|
|
|
3498
3498
|
}
|
|
3499
3499
|
} : {},
|
|
3500
3500
|
kind,
|
|
3501
|
-
...
|
|
3501
|
+
...version2.revision ? { revision: version2.revision } : {},
|
|
3502
3502
|
schema: schema.type,
|
|
3503
3503
|
schemaVersion: schema.contractVersion,
|
|
3504
3504
|
semantics: { ...schema.semantics },
|
|
@@ -4090,98 +4090,6 @@ function cloneJson(value) {
|
|
|
4090
4090
|
return JSON.parse(JSON.stringify(value));
|
|
4091
4091
|
}
|
|
4092
4092
|
|
|
4093
|
-
// src/cartography/contributions.ts
|
|
4094
|
-
var tileflowLayerSlots = [
|
|
4095
|
-
"background",
|
|
4096
|
-
"land",
|
|
4097
|
-
"terrain",
|
|
4098
|
-
"hydro",
|
|
4099
|
-
"building-areas",
|
|
4100
|
-
"transport-areas",
|
|
4101
|
-
"transport-tunnel-shadow",
|
|
4102
|
-
"transport-tunnel-casing",
|
|
4103
|
-
"transport-tunnel-fill",
|
|
4104
|
-
"transport-pedestrian-areas",
|
|
4105
|
-
"aeroways",
|
|
4106
|
-
"transport-surface-shadow",
|
|
4107
|
-
"transport-surface-casing",
|
|
4108
|
-
"transport-surface-fill",
|
|
4109
|
-
"transport-bridge-shadow",
|
|
4110
|
-
"transport-bridge-casing",
|
|
4111
|
-
"transport-bridge-fill",
|
|
4112
|
-
"transport-symbols",
|
|
4113
|
-
"boundaries",
|
|
4114
|
-
"buildings",
|
|
4115
|
-
"vegetation",
|
|
4116
|
-
"symbols"
|
|
4117
|
-
];
|
|
4118
|
-
var tileflowLayerBands = [
|
|
4119
|
-
"land",
|
|
4120
|
-
"relief",
|
|
4121
|
-
"water",
|
|
4122
|
-
"roads",
|
|
4123
|
-
"boundaries",
|
|
4124
|
-
"buildings",
|
|
4125
|
-
"vegetation",
|
|
4126
|
-
"labels"
|
|
4127
|
-
];
|
|
4128
|
-
var bandSlots = {
|
|
4129
|
-
land: ["background", "land"],
|
|
4130
|
-
relief: ["terrain", "terrain"],
|
|
4131
|
-
water: ["hydro", "hydro"],
|
|
4132
|
-
roads: ["transport-areas", "transport-symbols"],
|
|
4133
|
-
boundaries: ["boundaries", "boundaries"],
|
|
4134
|
-
buildings: ["buildings", "buildings"],
|
|
4135
|
-
vegetation: ["vegetation", "vegetation"],
|
|
4136
|
-
labels: ["symbols", "symbols"]
|
|
4137
|
-
};
|
|
4138
|
-
var tileflowBandPlacements = tileflowLayerBands.flatMap(
|
|
4139
|
-
(band) => [`below-${band}`, `above-${band}`]
|
|
4140
|
-
);
|
|
4141
|
-
function tileflowBandPlacementSlot(placement) {
|
|
4142
|
-
const [side, band] = splitBandPlacement(placement);
|
|
4143
|
-
return bandSlots[band][side === "below" ? 0 : 1];
|
|
4144
|
-
}
|
|
4145
|
-
function tileflowBandPlacementIndex(slotRanks, placement) {
|
|
4146
|
-
const [side, band] = splitBandPlacement(placement);
|
|
4147
|
-
const [first, last] = bandSlots[band];
|
|
4148
|
-
const threshold = side === "below" ? tileflowLayerSlots.indexOf(first) : tileflowLayerSlots.indexOf(last) + 1;
|
|
4149
|
-
const index = slotRanks.findIndex((rank) => rank !== void 0 && rank >= threshold);
|
|
4150
|
-
return index < 0 ? slotRanks.length : index;
|
|
4151
|
-
}
|
|
4152
|
-
function splitBandPlacement(placement) {
|
|
4153
|
-
const separator = placement.indexOf("-");
|
|
4154
|
-
return [
|
|
4155
|
-
placement.slice(0, separator),
|
|
4156
|
-
placement.slice(separator + 1)
|
|
4157
|
-
];
|
|
4158
|
-
}
|
|
4159
|
-
var tileflowSemanticTargetPattern = /^[a-z][a-z0-9-]*(?:\.[A-Za-z0-9_-]+)*$/u;
|
|
4160
|
-
var tileflowRenderStackOperationNamePattern = /^[a-z][A-Za-z0-9_-]*$/u;
|
|
4161
|
-
var tileflowCompilerMetadataKeys = Object.freeze({
|
|
4162
|
-
owner: "tileflow:compiler-owner",
|
|
4163
|
-
slot: "tileflow:compiler-slot",
|
|
4164
|
-
target: "tileflow:compiler-target"
|
|
4165
|
-
});
|
|
4166
|
-
|
|
4167
|
-
// src/modules/addresses/index.ts
|
|
4168
|
-
function addresses(options = {}) {
|
|
4169
|
-
return { type: "addresses", ...cloneJson2(options) };
|
|
4170
|
-
}
|
|
4171
|
-
function cloneJson2(value) {
|
|
4172
|
-
return JSON.parse(JSON.stringify(value));
|
|
4173
|
-
}
|
|
4174
|
-
|
|
4175
|
-
// src/cartography/context.ts
|
|
4176
|
-
function typographyTextStyle(typography) {
|
|
4177
|
-
return {
|
|
4178
|
-
font: typography.font,
|
|
4179
|
-
...typography.fallbacks ? { fallbacks: typography.fallbacks } : {},
|
|
4180
|
-
...typography.letterSpacing === void 0 ? {} : { letterSpacing: typography.letterSpacing },
|
|
4181
|
-
...typography.transform === void 0 ? {} : { transform: typography.transform }
|
|
4182
|
-
};
|
|
4183
|
-
}
|
|
4184
|
-
|
|
4185
4093
|
// src/cartography/layer-style.ts
|
|
4186
4094
|
import { Color as Color2 } from "@maplibre/maplibre-gl-style-spec";
|
|
4187
4095
|
|
|
@@ -4815,30 +4723,30 @@ function asRecord2(value) {
|
|
|
4815
4723
|
// src/cartography/merge.ts
|
|
4816
4724
|
init_values();
|
|
4817
4725
|
function mergeTileflowDesign(base, ...overlays) {
|
|
4818
|
-
let resolved =
|
|
4726
|
+
let resolved = cloneJson3(base);
|
|
4819
4727
|
for (const overlay of overlays) {
|
|
4820
4728
|
resolved = mergeValue(resolved, overlay);
|
|
4821
4729
|
}
|
|
4822
4730
|
return resolved;
|
|
4823
4731
|
}
|
|
4824
4732
|
function mergeValue(base, overlay) {
|
|
4825
|
-
if (overlay === void 0) return
|
|
4733
|
+
if (overlay === void 0) return cloneJson3(base);
|
|
4826
4734
|
if (Array.isArray(overlay) || isTileflowExpression(overlay) || isTileflowThemeValueNode(overlay) || isTileflowZoomValue(overlay) || !isRecord2(overlay)) {
|
|
4827
|
-
return
|
|
4735
|
+
return cloneJson3(overlay);
|
|
4828
4736
|
}
|
|
4829
4737
|
const baseRecord = isRecord2(base) ? base : {};
|
|
4830
4738
|
const result = {};
|
|
4831
4739
|
for (const key of /* @__PURE__ */ new Set([...Object.keys(baseRecord), ...Object.keys(overlay)])) {
|
|
4832
4740
|
const overlayValue = overlay[key];
|
|
4833
4741
|
if (overlayValue === void 0) {
|
|
4834
|
-
if (key in baseRecord) result[key] =
|
|
4742
|
+
if (key in baseRecord) result[key] = cloneJson3(baseRecord[key]);
|
|
4835
4743
|
continue;
|
|
4836
4744
|
}
|
|
4837
4745
|
result[key] = mergeValue(baseRecord[key], overlayValue);
|
|
4838
4746
|
}
|
|
4839
4747
|
return result;
|
|
4840
4748
|
}
|
|
4841
|
-
function
|
|
4749
|
+
function cloneJson3(value) {
|
|
4842
4750
|
if (value === void 0) return value;
|
|
4843
4751
|
return JSON.parse(JSON.stringify(value));
|
|
4844
4752
|
}
|
|
@@ -4846,6 +4754,558 @@ function isRecord2(value) {
|
|
|
4846
4754
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
4847
4755
|
}
|
|
4848
4756
|
|
|
4757
|
+
// src/modules/vegetation/compiler.ts
|
|
4758
|
+
init_values();
|
|
4759
|
+
|
|
4760
|
+
// src/trees-3d.ts
|
|
4761
|
+
var tileflowTreeForms = ["round", "open", "tall", "conifer", "columnar", "palm"];
|
|
4762
|
+
var tileflowTreeFinishes = ["faceted", "smooth", "toon"];
|
|
4763
|
+
var tileflowWorldTreeFields = Object.freeze({
|
|
4764
|
+
height: "height",
|
|
4765
|
+
diameterCrown: "diameter_crown",
|
|
4766
|
+
circumference: "circumference",
|
|
4767
|
+
genus: "genus",
|
|
4768
|
+
species: "species",
|
|
4769
|
+
leafType: "leaf_type",
|
|
4770
|
+
taxon: "taxon",
|
|
4771
|
+
canopyRank: "rank",
|
|
4772
|
+
canopyClearance: "clearance_px_z15",
|
|
4773
|
+
canopyCover: "cover_pct",
|
|
4774
|
+
canopyHeight: "height_m"
|
|
4775
|
+
});
|
|
4776
|
+
var tileflowDefaultUnknownTreeForms = Object.freeze({
|
|
4777
|
+
round: 1,
|
|
4778
|
+
open: 1,
|
|
4779
|
+
tall: 1
|
|
4780
|
+
});
|
|
4781
|
+
var broadleaves = Object.freeze({
|
|
4782
|
+
...Object.fromEntries(
|
|
4783
|
+
[
|
|
4784
|
+
"acacia",
|
|
4785
|
+
"albizia",
|
|
4786
|
+
"arbutus",
|
|
4787
|
+
"bursera",
|
|
4788
|
+
"ceratonia",
|
|
4789
|
+
"delonix",
|
|
4790
|
+
"ficus",
|
|
4791
|
+
"gleditsia",
|
|
4792
|
+
"jacaranda",
|
|
4793
|
+
"olea",
|
|
4794
|
+
"quercus",
|
|
4795
|
+
"robinia",
|
|
4796
|
+
"schinus",
|
|
4797
|
+
"sophora",
|
|
4798
|
+
"styphnolobium",
|
|
4799
|
+
"tamarix"
|
|
4800
|
+
].map((genus) => [genus, "open"])
|
|
4801
|
+
),
|
|
4802
|
+
...Object.fromEntries(
|
|
4803
|
+
[
|
|
4804
|
+
"betula",
|
|
4805
|
+
"celtis",
|
|
4806
|
+
"fraxinus",
|
|
4807
|
+
"ginkgo",
|
|
4808
|
+
"liquidambar",
|
|
4809
|
+
"liriodendron",
|
|
4810
|
+
"magnolia",
|
|
4811
|
+
"platanus",
|
|
4812
|
+
"populus",
|
|
4813
|
+
"pyrus",
|
|
4814
|
+
"ulmus",
|
|
4815
|
+
"zelkova"
|
|
4816
|
+
].map((genus) => [genus, "tall"])
|
|
4817
|
+
),
|
|
4818
|
+
...Object.fromEntries(
|
|
4819
|
+
[
|
|
4820
|
+
"acer",
|
|
4821
|
+
"aesculus",
|
|
4822
|
+
"carpinus",
|
|
4823
|
+
"castanea",
|
|
4824
|
+
"catalpa",
|
|
4825
|
+
"cercis",
|
|
4826
|
+
"citrus",
|
|
4827
|
+
"fagus",
|
|
4828
|
+
"lagerstroemia",
|
|
4829
|
+
"malus",
|
|
4830
|
+
"melia",
|
|
4831
|
+
"morus",
|
|
4832
|
+
"prunus",
|
|
4833
|
+
"sorbus",
|
|
4834
|
+
"tilia"
|
|
4835
|
+
].map((genus) => [genus, "round"])
|
|
4836
|
+
)
|
|
4837
|
+
});
|
|
4838
|
+
function tileflowTreeFormMixProblem(mix2) {
|
|
4839
|
+
if (typeof mix2 !== "object" || mix2 === null || Array.isArray(mix2))
|
|
4840
|
+
return "a mix of forms is an object of weights, such as {round: 1, palm: 2}";
|
|
4841
|
+
let total = 0;
|
|
4842
|
+
for (const [form, weight] of Object.entries(mix2)) {
|
|
4843
|
+
if (!tileflowTreeForms.includes(form))
|
|
4844
|
+
return `"${form}" is not a tree form; forms are ${tileflowTreeForms.join(", ")}`;
|
|
4845
|
+
if (typeof weight !== "number" || !Number.isFinite(weight) || weight < 0)
|
|
4846
|
+
return `the weight of "${form}" must be a number of 0 or more`;
|
|
4847
|
+
total += weight;
|
|
4848
|
+
}
|
|
4849
|
+
return total > 0 ? void 0 : "a mix of forms needs at least one weight above 0";
|
|
4850
|
+
}
|
|
4851
|
+
var tileflowTreeModelIdPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
4852
|
+
var tileflowVegetationMetadataKey = "tileflow:vegetation";
|
|
4853
|
+
function tileflowVegetationMetadata(vegetation2) {
|
|
4854
|
+
return { version: 1, ...vegetation2 };
|
|
4855
|
+
}
|
|
4856
|
+
function readTileflowVegetation3D(metadata) {
|
|
4857
|
+
if (!isRecord3(metadata)) return void 0;
|
|
4858
|
+
const value = metadata[tileflowVegetationMetadataKey];
|
|
4859
|
+
if (!isRecord3(value) || value.version !== 1) return void 0;
|
|
4860
|
+
const { source, layers, fields, colors, heightScale, crownScale, unknownForms, regions: regions2 } = value;
|
|
4861
|
+
if (typeof source !== "string" || !isRecord3(layers) || typeof layers.tree !== "string")
|
|
4862
|
+
return void 0;
|
|
4863
|
+
if (!isRecord3(fields) || !isRecord3(colors) || typeof colors.bark !== "string") return void 0;
|
|
4864
|
+
const palette = (list) => Array.isArray(list) && list.length > 0 && list.every((entry) => typeof entry === "string") ? list : void 0;
|
|
4865
|
+
const broadleaf = palette(colors.broadleaf);
|
|
4866
|
+
const conifer = palette(colors.conifer);
|
|
4867
|
+
const palm = palette(colors.palm) ?? broadleaf;
|
|
4868
|
+
if (!broadleaf || !conifer || !palm) return void 0;
|
|
4869
|
+
const scale = (number) => typeof number === "number" && number > 0 && number <= 10 ? number : 1;
|
|
4870
|
+
const mix2 = tileflowTreeFormMixProblem(unknownForms) === void 0 ? unknownForms : void 0;
|
|
4871
|
+
const models = Object.fromEntries(
|
|
4872
|
+
Object.entries(isRecord3(value.models) ? value.models : {}).filter(
|
|
4873
|
+
([id2, model]) => tileflowTreeModelIdPattern.test(id2) && isRecord3(model) && typeof model.near === "string" && (model.far === void 0 || typeof model.far === "string")
|
|
4874
|
+
).slice(0, 16).map(([id2, model]) => {
|
|
4875
|
+
const { near, far } = model;
|
|
4876
|
+
return [id2, far === void 0 ? { near } : { near, far }];
|
|
4877
|
+
})
|
|
4878
|
+
);
|
|
4879
|
+
const ownScales = isRecord3(value.forms) ? value.forms : {};
|
|
4880
|
+
const forms = Object.fromEntries(
|
|
4881
|
+
tileflowTreeForms.flatMap((form) => {
|
|
4882
|
+
const own = ownScales[form];
|
|
4883
|
+
if (!isRecord3(own)) return [];
|
|
4884
|
+
const drawn = Array.isArray(own.models) ? [...new Set(own.models)].filter((id2) => typeof id2 === "string" && id2 in models).slice(0, 4) : [];
|
|
4885
|
+
return [
|
|
4886
|
+
[
|
|
4887
|
+
form,
|
|
4888
|
+
{
|
|
4889
|
+
heightScale: scale(own.heightScale),
|
|
4890
|
+
crownScale: scale(own.crownScale),
|
|
4891
|
+
...drawn.length > 0 ? { models: drawn } : {}
|
|
4892
|
+
}
|
|
4893
|
+
]
|
|
4894
|
+
];
|
|
4895
|
+
})
|
|
4896
|
+
);
|
|
4897
|
+
const finish = tileflowTreeFinishes.find((name) => name === value.finish) ?? "faceted";
|
|
4898
|
+
const edges = typeof value.edges === "number" && value.edges >= 0 && value.edges <= 1 ? value.edges : 0;
|
|
4899
|
+
const zones = Array.isArray(regions2) ? regions2.filter(
|
|
4900
|
+
(region) => isRecord3(region) && tileflowTreeRegionProblem(region) === void 0
|
|
4901
|
+
) : [];
|
|
4902
|
+
const named = Object.fromEntries(
|
|
4903
|
+
Object.entries(tileflowWorldTreeFields).map(([key, fallback]) => [
|
|
4904
|
+
key,
|
|
4905
|
+
typeof fields[key] === "string" ? fields[key] : fallback
|
|
4906
|
+
])
|
|
4907
|
+
);
|
|
4908
|
+
return {
|
|
4909
|
+
source,
|
|
4910
|
+
layers: {
|
|
4911
|
+
tree: layers.tree,
|
|
4912
|
+
...typeof layers.canopy === "string" ? { canopy: layers.canopy } : {}
|
|
4913
|
+
},
|
|
4914
|
+
fields: named,
|
|
4915
|
+
colors: { bark: colors.bark, broadleaf, conifer, palm },
|
|
4916
|
+
heightScale: scale(heightScale),
|
|
4917
|
+
crownScale: scale(crownScale),
|
|
4918
|
+
forms,
|
|
4919
|
+
models,
|
|
4920
|
+
finish,
|
|
4921
|
+
edges,
|
|
4922
|
+
...typeof value.edgeColor === "string" ? { edgeColor: value.edgeColor } : {},
|
|
4923
|
+
unknownForms: mix2 ?? tileflowDefaultUnknownTreeForms,
|
|
4924
|
+
regions: zones,
|
|
4925
|
+
flatLayers: Array.isArray(value.flatLayers) ? value.flatLayers.filter((id2) => typeof id2 === "string") : []
|
|
4926
|
+
};
|
|
4927
|
+
}
|
|
4928
|
+
function tileflowTreeRegionProblem(region) {
|
|
4929
|
+
if (!isRecord3(region)) return "a region is an object with bounds and unknownForms";
|
|
4930
|
+
const bounds = region.bounds;
|
|
4931
|
+
if (!Array.isArray(bounds) || bounds.length !== 4 || !bounds.every((value) => typeof value === "number" && Number.isFinite(value)))
|
|
4932
|
+
return "bounds are [west, south, east, north] in degrees";
|
|
4933
|
+
const [west, south, east, north] = bounds;
|
|
4934
|
+
if (Math.abs(west) > 180 || Math.abs(east) > 180 || Math.abs(south) > 90 || Math.abs(north) > 90)
|
|
4935
|
+
return "bounds are [west, south, east, north] in degrees, longitudes within \xB1180 and latitudes within \xB190";
|
|
4936
|
+
if (south > north) return "a region\u2019s south lies below its north";
|
|
4937
|
+
const mix2 = tileflowTreeFormMixProblem(region.unknownForms);
|
|
4938
|
+
return mix2 ? `unknownForms: ${mix2}` : void 0;
|
|
4939
|
+
}
|
|
4940
|
+
function isRecord3(value) {
|
|
4941
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4942
|
+
}
|
|
4943
|
+
|
|
4944
|
+
// src/modules/vegetation/compiler.ts
|
|
4945
|
+
function compileVegetation(request, context) {
|
|
4946
|
+
const minZoom = request?.flat?.minZoom ?? 16;
|
|
4947
|
+
const mode = request?.mode ?? "3d";
|
|
4948
|
+
const config = mergeTileflowDesign(
|
|
4949
|
+
{
|
|
4950
|
+
type: "vegetation",
|
|
4951
|
+
enabled: true,
|
|
4952
|
+
flat: {
|
|
4953
|
+
color: context.colors.landcover.wood,
|
|
4954
|
+
minZoom,
|
|
4955
|
+
opacity: mode === "3d" ? 0.82 : 0.9,
|
|
4956
|
+
pitchAlignment: "map",
|
|
4957
|
+
pitchScale: "map",
|
|
4958
|
+
radius: minZoom < 24 ? zoom.linear([
|
|
4959
|
+
[minZoom, 2.2],
|
|
4960
|
+
[minZoom < 20 ? 20 : 24, 8]
|
|
4961
|
+
]) : 2.2,
|
|
4962
|
+
strokeColor: context.colors.park,
|
|
4963
|
+
strokeOpacity: 0.55,
|
|
4964
|
+
strokeWidth: 0.8
|
|
4965
|
+
},
|
|
4966
|
+
mode,
|
|
4967
|
+
threeDimensional: {
|
|
4968
|
+
barkColor: context.colors.vegetation.tree.bark,
|
|
4969
|
+
broadleafColors: context.colors.vegetation.tree.broadleaf,
|
|
4970
|
+
coniferColors: context.colors.vegetation.tree.conifer,
|
|
4971
|
+
palmColors: context.colors.vegetation.tree.palm,
|
|
4972
|
+
crownScale: 1,
|
|
4973
|
+
heightScale: 1
|
|
4974
|
+
}
|
|
4975
|
+
},
|
|
4976
|
+
request
|
|
4977
|
+
);
|
|
4978
|
+
if (config.enabled === false || !context.data.schema.layers.tree) return [];
|
|
4979
|
+
const resolvedMode = config.mode ?? "3d";
|
|
4980
|
+
return [
|
|
4981
|
+
{
|
|
4982
|
+
kind: "layer",
|
|
4983
|
+
layer: applyCircleStyle(
|
|
4984
|
+
{
|
|
4985
|
+
id: "tileflow-vegetation-trees",
|
|
4986
|
+
type: "circle",
|
|
4987
|
+
source: context.data.sourceId,
|
|
4988
|
+
"source-layer": context.data.schema.layers.tree,
|
|
4989
|
+
// The layer also holds rows of trees as lines; a circle on each vertex would misdraw them.
|
|
4990
|
+
filter: ["==", ["geometry-type"], "Point"],
|
|
4991
|
+
metadata: {
|
|
4992
|
+
"tileflow:vegetation-mode": resolvedMode,
|
|
4993
|
+
...resolvedMode === "3d" ? { "tileflow:vegetation-fallback": "flat-circle" } : {}
|
|
4994
|
+
}
|
|
4995
|
+
},
|
|
4996
|
+
config.flat ?? {}
|
|
4997
|
+
),
|
|
4998
|
+
localOrder: 1,
|
|
4999
|
+
owner: "vegetation",
|
|
5000
|
+
slot: "vegetation",
|
|
5001
|
+
target: "vegetation.trees"
|
|
5002
|
+
}
|
|
5003
|
+
];
|
|
5004
|
+
}
|
|
5005
|
+
function tileflowVegetationDescription(request, context) {
|
|
5006
|
+
const { schema } = context.data;
|
|
5007
|
+
if (request?.enabled === false || (request?.mode ?? "3d") !== "3d" || !schema.layers.tree)
|
|
5008
|
+
return void 0;
|
|
5009
|
+
const tree = context.colors.vegetation.tree;
|
|
5010
|
+
const style = request?.threeDimensional ?? {};
|
|
5011
|
+
const colours = (value, fallback) => Array.isArray(value) && value.length > 0 && value.every((entry) => typeof entry === "string") ? value : [...fallback];
|
|
5012
|
+
const number = (value) => {
|
|
5013
|
+
const resolved = value === void 0 ? void 0 : toMapLibreStyleValue(value);
|
|
5014
|
+
return typeof resolved === "number" && resolved > 0 ? resolved : 1;
|
|
5015
|
+
};
|
|
5016
|
+
const field2 = (name, fallback) => schema.fields[name] ?? fallback;
|
|
5017
|
+
return {
|
|
5018
|
+
source: context.data.sourceId,
|
|
5019
|
+
layers: {
|
|
5020
|
+
tree: schema.layers.tree,
|
|
5021
|
+
...schema.layers.canopy ? { canopy: schema.layers.canopy } : {}
|
|
5022
|
+
},
|
|
5023
|
+
fields: {
|
|
5024
|
+
...tileflowWorldTreeFields,
|
|
5025
|
+
height: field2("height", tileflowWorldTreeFields.height),
|
|
5026
|
+
diameterCrown: field2("diameterCrown", tileflowWorldTreeFields.diameterCrown),
|
|
5027
|
+
genus: field2("genus", tileflowWorldTreeFields.genus),
|
|
5028
|
+
species: field2("species", tileflowWorldTreeFields.species),
|
|
5029
|
+
leafType: field2("leafType", tileflowWorldTreeFields.leafType),
|
|
5030
|
+
canopyRank: field2("canopyRank", tileflowWorldTreeFields.canopyRank),
|
|
5031
|
+
canopyClearance: field2("canopyClearanceAtZoom15", tileflowWorldTreeFields.canopyClearance),
|
|
5032
|
+
canopyCover: field2("canopyCoverPercent", tileflowWorldTreeFields.canopyCover)
|
|
5033
|
+
},
|
|
5034
|
+
colors: {
|
|
5035
|
+
bark: typeof style.barkColor === "string" ? style.barkColor : tree.bark,
|
|
5036
|
+
broadleaf: colours(style.broadleafColors, tree.broadleaf),
|
|
5037
|
+
conifer: colours(style.coniferColors, tree.conifer),
|
|
5038
|
+
palm: colours(style.palmColors, tree.palm)
|
|
5039
|
+
},
|
|
5040
|
+
heightScale: number(style.heightScale),
|
|
5041
|
+
crownScale: number(style.crownScale),
|
|
5042
|
+
forms: Object.fromEntries(
|
|
5043
|
+
Object.entries(style.forms ?? {}).map(([form, own]) => [
|
|
5044
|
+
form,
|
|
5045
|
+
{
|
|
5046
|
+
heightScale: number(own?.heightScale),
|
|
5047
|
+
crownScale: number(own?.crownScale),
|
|
5048
|
+
...own?.models?.length ? { models: [...own.models] } : {}
|
|
5049
|
+
}
|
|
5050
|
+
])
|
|
5051
|
+
),
|
|
5052
|
+
// Filled by the compiler from the map's prepared models.
|
|
5053
|
+
models: {},
|
|
5054
|
+
finish: style.finish ?? "faceted",
|
|
5055
|
+
edges: (() => {
|
|
5056
|
+
const edges = toMapLibreStyleValue(style.edges ?? 0);
|
|
5057
|
+
return typeof edges === "number" ? edges : 0;
|
|
5058
|
+
})(),
|
|
5059
|
+
...(() => {
|
|
5060
|
+
const edgeColor = style.edgeColor === void 0 ? void 0 : toMapLibreStyleValue(style.edgeColor);
|
|
5061
|
+
return typeof edgeColor === "string" ? { edgeColor } : {};
|
|
5062
|
+
})(),
|
|
5063
|
+
unknownForms: style.unknownForms ?? tileflowDefaultUnknownTreeForms,
|
|
5064
|
+
regions: style.regions ?? [],
|
|
5065
|
+
// Filled by the compiler once the style's layers are final.
|
|
5066
|
+
flatLayers: []
|
|
5067
|
+
};
|
|
5068
|
+
}
|
|
5069
|
+
|
|
5070
|
+
// src/buildings-3d-design.ts
|
|
5071
|
+
var tileflowBuildingsMetadataKey = "tileflow:buildings";
|
|
5072
|
+
var tileflowDefaultBuildings3DDesign = Object.freeze({
|
|
5073
|
+
source: "tileflow",
|
|
5074
|
+
layers: Object.freeze({ building: "building", places: "poi" }),
|
|
5075
|
+
color: "#d8d0c0",
|
|
5076
|
+
edges: 1,
|
|
5077
|
+
nightLight: 1,
|
|
5078
|
+
windows: false,
|
|
5079
|
+
shadows: true,
|
|
5080
|
+
occlusion: true
|
|
5081
|
+
});
|
|
5082
|
+
function tileflowBuildingsMetadata(design) {
|
|
5083
|
+
return { version: 1, ...design };
|
|
5084
|
+
}
|
|
5085
|
+
function readTileflowBuildings3D(metadata) {
|
|
5086
|
+
if (!isRecord4(metadata)) return void 0;
|
|
5087
|
+
const value = metadata[tileflowBuildingsMetadataKey];
|
|
5088
|
+
if (!isRecord4(value) || value.version !== 1) return void 0;
|
|
5089
|
+
const { source, layers, color: color3 } = value;
|
|
5090
|
+
if (typeof source !== "string" || !isRecord4(layers) || typeof layers.building !== "string")
|
|
5091
|
+
return void 0;
|
|
5092
|
+
if (typeof color3 !== "string" && !Array.isArray(color3)) return void 0;
|
|
5093
|
+
const within = (number, high, fallback) => typeof number === "number" && number >= 0 && number <= high ? number : fallback;
|
|
5094
|
+
return {
|
|
5095
|
+
source,
|
|
5096
|
+
layers: {
|
|
5097
|
+
building: layers.building,
|
|
5098
|
+
...typeof layers.places === "string" ? { places: layers.places } : {}
|
|
5099
|
+
},
|
|
5100
|
+
color: color3,
|
|
5101
|
+
edges: within(value.edges, 1, 1),
|
|
5102
|
+
...typeof value.edgeColor === "string" ? { edgeColor: value.edgeColor } : {},
|
|
5103
|
+
nightLight: within(value.nightLight, 2, 1),
|
|
5104
|
+
windows: value.windows === true,
|
|
5105
|
+
shadows: value.shadows !== false,
|
|
5106
|
+
occlusion: value.occlusion !== false
|
|
5107
|
+
};
|
|
5108
|
+
}
|
|
5109
|
+
function isRecord4(value) {
|
|
5110
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5111
|
+
}
|
|
5112
|
+
|
|
5113
|
+
// src/street-lights.ts
|
|
5114
|
+
init_theme_blend();
|
|
5115
|
+
var tileflowStreetLightsMetadataKey = "tileflow:street-lights";
|
|
5116
|
+
var tileflowDefaultStreetLightsDesign = Object.freeze({
|
|
5117
|
+
source: "tileflow",
|
|
5118
|
+
layers: Object.freeze({
|
|
5119
|
+
streetFurniture: "street_furniture",
|
|
5120
|
+
transportation: "transportation",
|
|
5121
|
+
sidewalk: "sidewalk"
|
|
5122
|
+
}),
|
|
5123
|
+
estimate: "lit",
|
|
5124
|
+
color: "#ffcf8f",
|
|
5125
|
+
intensity: 1
|
|
5126
|
+
});
|
|
5127
|
+
function tileflowStreetLightsMetadata(design) {
|
|
5128
|
+
return { version: 1, ...design };
|
|
5129
|
+
}
|
|
5130
|
+
function readTileflowStreetLights(metadata) {
|
|
5131
|
+
if (typeof metadata !== "object" || metadata === null || Array.isArray(metadata))
|
|
5132
|
+
return void 0;
|
|
5133
|
+
const value = metadata[tileflowStreetLightsMetadataKey];
|
|
5134
|
+
if (typeof value !== "object" || value === null || value.version !== 1) return void 0;
|
|
5135
|
+
const layers = value.layers;
|
|
5136
|
+
if (typeof value.source !== "string" || typeof layers?.streetFurniture !== "string" || typeof layers.transportation !== "string")
|
|
5137
|
+
return void 0;
|
|
5138
|
+
const estimate = ["lit", "streets", "none"].find((name) => name === value.estimate);
|
|
5139
|
+
const intensity = typeof value.intensity === "number" && value.intensity >= 0 && value.intensity <= 2 ? value.intensity : 1;
|
|
5140
|
+
return {
|
|
5141
|
+
source: value.source,
|
|
5142
|
+
layers: {
|
|
5143
|
+
streetFurniture: layers.streetFurniture,
|
|
5144
|
+
transportation: layers.transportation,
|
|
5145
|
+
...typeof layers.sidewalk === "string" ? { sidewalk: layers.sidewalk } : {}
|
|
5146
|
+
},
|
|
5147
|
+
estimate: estimate ?? "lit",
|
|
5148
|
+
color: typeof value.color === "string" && tileflowColourChannels(value.color) ? value.color : tileflowDefaultStreetLightsDesign.color,
|
|
5149
|
+
intensity
|
|
5150
|
+
};
|
|
5151
|
+
}
|
|
5152
|
+
|
|
5153
|
+
// src/cartography/scene-3d-metadata.ts
|
|
5154
|
+
init_values();
|
|
5155
|
+
var colourSources = [
|
|
5156
|
+
["tileflow-buildings-render-extrusion", "fill-extrusion-color"],
|
|
5157
|
+
["tileflow-buildings-3d", "fill-extrusion-color"],
|
|
5158
|
+
["tileflow-buildings-fill", "fill-color"]
|
|
5159
|
+
];
|
|
5160
|
+
function tileflowBuildings3DDesignOf(module, context, layers) {
|
|
5161
|
+
const config = isRecord5(module) ? module : {};
|
|
5162
|
+
if (config.enabled === false) return void 0;
|
|
5163
|
+
const style = config.threeDimensional ?? {};
|
|
5164
|
+
let color3;
|
|
5165
|
+
for (const [id2, property] of colourSources) {
|
|
5166
|
+
const value = layers.find((layer) => layer.id === id2)?.paint?.[property];
|
|
5167
|
+
if (typeof value === "string" || Array.isArray(value)) {
|
|
5168
|
+
color3 = value;
|
|
5169
|
+
break;
|
|
5170
|
+
}
|
|
5171
|
+
}
|
|
5172
|
+
const number = (value, fallback) => {
|
|
5173
|
+
const resolved = value === void 0 ? void 0 : toMapLibreStyleValue(value);
|
|
5174
|
+
return typeof resolved === "number" ? resolved : fallback;
|
|
5175
|
+
};
|
|
5176
|
+
const edgeColor = style.edgeColor === void 0 ? void 0 : toMapLibreStyleValue(style.edgeColor);
|
|
5177
|
+
return {
|
|
5178
|
+
source: context.data.sourceId,
|
|
5179
|
+
layers: {
|
|
5180
|
+
building: context.data.schema.layers.building,
|
|
5181
|
+
...context.data.schema.layers.poi ? { places: context.data.schema.layers.poi } : {}
|
|
5182
|
+
},
|
|
5183
|
+
color: color3 ?? context.colors.buildings.generic,
|
|
5184
|
+
edges: number(style.edges, 1),
|
|
5185
|
+
...typeof edgeColor === "string" ? { edgeColor } : {},
|
|
5186
|
+
nightLight: number(style.nightLight, 1),
|
|
5187
|
+
windows: style.windows === true,
|
|
5188
|
+
shadows: style.shadows !== false,
|
|
5189
|
+
occlusion: style.occlusion !== false
|
|
5190
|
+
};
|
|
5191
|
+
}
|
|
5192
|
+
function tileflowStreetLightsDesignOf(module, context) {
|
|
5193
|
+
const config = isRecord5(module) ? module : {};
|
|
5194
|
+
const layers = context.data.schema.layers;
|
|
5195
|
+
const style = config.streetLights ?? {};
|
|
5196
|
+
if (config.enabled === false || style.enabled === false || !layers.streetFurniture)
|
|
5197
|
+
return void 0;
|
|
5198
|
+
const color3 = style.color === void 0 ? void 0 : toMapLibreStyleValue(style.color);
|
|
5199
|
+
const intensity = style.intensity === void 0 ? void 0 : toMapLibreStyleValue(style.intensity);
|
|
5200
|
+
const estimate = style.estimate;
|
|
5201
|
+
return {
|
|
5202
|
+
source: context.data.sourceId,
|
|
5203
|
+
layers: {
|
|
5204
|
+
streetFurniture: layers.streetFurniture,
|
|
5205
|
+
transportation: layers.road,
|
|
5206
|
+
...layers.sidewalk ? { sidewalk: layers.sidewalk } : {}
|
|
5207
|
+
},
|
|
5208
|
+
estimate: estimate === "streets" || estimate === "none" || estimate === "lit" ? estimate : "lit",
|
|
5209
|
+
color: typeof color3 === "string" ? color3 : tileflowDefaultStreetLightsDesign.color,
|
|
5210
|
+
intensity: typeof intensity === "number" ? intensity : 1
|
|
5211
|
+
};
|
|
5212
|
+
}
|
|
5213
|
+
function isRecord5(value) {
|
|
5214
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5215
|
+
}
|
|
5216
|
+
|
|
5217
|
+
// src/cartography/contributions.ts
|
|
5218
|
+
var tileflowLayerSlots = [
|
|
5219
|
+
"background",
|
|
5220
|
+
"land",
|
|
5221
|
+
"terrain",
|
|
5222
|
+
"hydro",
|
|
5223
|
+
"building-areas",
|
|
5224
|
+
"transport-areas",
|
|
5225
|
+
"transport-tunnel-shadow",
|
|
5226
|
+
"transport-tunnel-casing",
|
|
5227
|
+
"transport-tunnel-fill",
|
|
5228
|
+
"transport-pedestrian-areas",
|
|
5229
|
+
"aeroways",
|
|
5230
|
+
"transport-surface-shadow",
|
|
5231
|
+
"transport-surface-casing",
|
|
5232
|
+
"transport-surface-fill",
|
|
5233
|
+
"transport-bridge-shadow",
|
|
5234
|
+
"transport-bridge-casing",
|
|
5235
|
+
"transport-bridge-fill",
|
|
5236
|
+
"transport-symbols",
|
|
5237
|
+
"boundaries",
|
|
5238
|
+
"buildings",
|
|
5239
|
+
"vegetation",
|
|
5240
|
+
"symbols"
|
|
5241
|
+
];
|
|
5242
|
+
var tileflowLayerBands = [
|
|
5243
|
+
"land",
|
|
5244
|
+
"relief",
|
|
5245
|
+
"water",
|
|
5246
|
+
"roads",
|
|
5247
|
+
"boundaries",
|
|
5248
|
+
"buildings",
|
|
5249
|
+
"vegetation",
|
|
5250
|
+
"labels"
|
|
5251
|
+
];
|
|
5252
|
+
var bandSlots = {
|
|
5253
|
+
land: ["background", "land"],
|
|
5254
|
+
relief: ["terrain", "terrain"],
|
|
5255
|
+
water: ["hydro", "hydro"],
|
|
5256
|
+
roads: ["transport-areas", "transport-symbols"],
|
|
5257
|
+
boundaries: ["boundaries", "boundaries"],
|
|
5258
|
+
buildings: ["buildings", "buildings"],
|
|
5259
|
+
vegetation: ["vegetation", "vegetation"],
|
|
5260
|
+
labels: ["symbols", "symbols"]
|
|
5261
|
+
};
|
|
5262
|
+
var tileflowBandPlacements = tileflowLayerBands.flatMap(
|
|
5263
|
+
(band) => [`below-${band}`, `above-${band}`]
|
|
5264
|
+
);
|
|
5265
|
+
function tileflowBandPlacementSlot(placement) {
|
|
5266
|
+
const [side, band] = splitBandPlacement(placement);
|
|
5267
|
+
return bandSlots[band][side === "below" ? 0 : 1];
|
|
5268
|
+
}
|
|
5269
|
+
function tileflowBandPlacementIndex(slotRanks, placement) {
|
|
5270
|
+
const [side, band] = splitBandPlacement(placement);
|
|
5271
|
+
const [first, last] = bandSlots[band];
|
|
5272
|
+
const threshold = side === "below" ? tileflowLayerSlots.indexOf(first) : tileflowLayerSlots.indexOf(last) + 1;
|
|
5273
|
+
const index = slotRanks.findIndex((rank) => rank !== void 0 && rank >= threshold);
|
|
5274
|
+
return index < 0 ? slotRanks.length : index;
|
|
5275
|
+
}
|
|
5276
|
+
function splitBandPlacement(placement) {
|
|
5277
|
+
const separator = placement.indexOf("-");
|
|
5278
|
+
return [
|
|
5279
|
+
placement.slice(0, separator),
|
|
5280
|
+
placement.slice(separator + 1)
|
|
5281
|
+
];
|
|
5282
|
+
}
|
|
5283
|
+
var tileflowSemanticTargetPattern = /^[a-z][a-z0-9-]*(?:\.[A-Za-z0-9_-]+)*$/u;
|
|
5284
|
+
var tileflowRenderStackOperationNamePattern = /^[a-z][A-Za-z0-9_-]*$/u;
|
|
5285
|
+
var tileflowCompilerMetadataKeys = Object.freeze({
|
|
5286
|
+
owner: "tileflow:compiler-owner",
|
|
5287
|
+
slot: "tileflow:compiler-slot",
|
|
5288
|
+
target: "tileflow:compiler-target"
|
|
5289
|
+
});
|
|
5290
|
+
|
|
5291
|
+
// src/modules/addresses/index.ts
|
|
5292
|
+
function addresses(options = {}) {
|
|
5293
|
+
return { type: "addresses", ...cloneJson4(options) };
|
|
5294
|
+
}
|
|
5295
|
+
function cloneJson4(value) {
|
|
5296
|
+
return JSON.parse(JSON.stringify(value));
|
|
5297
|
+
}
|
|
5298
|
+
|
|
5299
|
+
// src/cartography/context.ts
|
|
5300
|
+
function typographyTextStyle(typography) {
|
|
5301
|
+
return {
|
|
5302
|
+
font: typography.font,
|
|
5303
|
+
...typography.fallbacks ? { fallbacks: typography.fallbacks } : {},
|
|
5304
|
+
...typography.letterSpacing === void 0 ? {} : { letterSpacing: typography.letterSpacing },
|
|
5305
|
+
...typography.transform === void 0 ? {} : { transform: typography.transform }
|
|
5306
|
+
};
|
|
5307
|
+
}
|
|
5308
|
+
|
|
4849
5309
|
// src/modules/addresses/compiler.ts
|
|
4850
5310
|
init_values();
|
|
4851
5311
|
function compileAddresses(request, context) {
|
|
@@ -7645,7 +8105,8 @@ function resolveColors(overrides = {}, defaults4 = defaultColors, moduleOverride
|
|
|
7645
8105
|
resolved.landcover.grass,
|
|
7646
8106
|
resolved.landcover.meadow
|
|
7647
8107
|
],
|
|
7648
|
-
conifer: [resolved.landcover.protected, resolved.landcover.scrub, resolved.landcover.wood]
|
|
8108
|
+
conifer: [resolved.landcover.protected, resolved.landcover.scrub, resolved.landcover.wood],
|
|
8109
|
+
palm: [resolved.landcover.urbanPark, resolved.landcover.grass, resolved.landcover.meadow]
|
|
7649
8110
|
}
|
|
7650
8111
|
}
|
|
7651
8112
|
};
|
|
@@ -7812,6 +8273,11 @@ function resolveThemeColors(theme) {
|
|
|
7812
8273
|
optionalColor("vegetation.tree.conifer.a", colors.vegetation.tree.conifer[0]),
|
|
7813
8274
|
optionalColor("vegetation.tree.conifer.b", colors.vegetation.tree.conifer[1]),
|
|
7814
8275
|
optionalColor("vegetation.tree.conifer.c", colors.vegetation.tree.conifer[2])
|
|
8276
|
+
],
|
|
8277
|
+
palm: [
|
|
8278
|
+
optionalColor("vegetation.tree.palm.a", colors.vegetation.tree.palm[0]),
|
|
8279
|
+
optionalColor("vegetation.tree.palm.b", colors.vegetation.tree.palm[1]),
|
|
8280
|
+
optionalColor("vegetation.tree.palm.c", colors.vegetation.tree.palm[2])
|
|
7815
8281
|
]
|
|
7816
8282
|
}
|
|
7817
8283
|
}
|
|
@@ -9161,77 +9627,6 @@ function cloneJson16(value) {
|
|
|
9161
9627
|
return JSON.parse(JSON.stringify(value));
|
|
9162
9628
|
}
|
|
9163
9629
|
|
|
9164
|
-
// src/modules/vegetation/compiler.ts
|
|
9165
|
-
init_values();
|
|
9166
|
-
function compileVegetation(request, context) {
|
|
9167
|
-
const minZoom = request?.flat?.minZoom ?? 16;
|
|
9168
|
-
const mode = request?.mode ?? "3d";
|
|
9169
|
-
const config = mergeTileflowDesign(
|
|
9170
|
-
{
|
|
9171
|
-
type: "vegetation",
|
|
9172
|
-
enabled: true,
|
|
9173
|
-
flat: {
|
|
9174
|
-
color: context.colors.landcover.wood,
|
|
9175
|
-
minZoom,
|
|
9176
|
-
opacity: mode === "3d" ? 0.82 : 0.9,
|
|
9177
|
-
pitchAlignment: "map",
|
|
9178
|
-
pitchScale: "map",
|
|
9179
|
-
radius: minZoom < 24 ? zoom.linear([
|
|
9180
|
-
[minZoom, 2.2],
|
|
9181
|
-
[minZoom < 20 ? 20 : 24, 8]
|
|
9182
|
-
]) : 2.2,
|
|
9183
|
-
strokeColor: context.colors.park,
|
|
9184
|
-
strokeOpacity: 0.55,
|
|
9185
|
-
strokeWidth: 0.8
|
|
9186
|
-
},
|
|
9187
|
-
mode,
|
|
9188
|
-
threeDimensional: {
|
|
9189
|
-
barkColor: context.colors.vegetation.tree.bark,
|
|
9190
|
-
broadleafColors: context.colors.vegetation.tree.broadleaf,
|
|
9191
|
-
coniferColors: context.colors.vegetation.tree.conifer,
|
|
9192
|
-
crownScale: 1,
|
|
9193
|
-
heightScale: 1
|
|
9194
|
-
}
|
|
9195
|
-
},
|
|
9196
|
-
request
|
|
9197
|
-
);
|
|
9198
|
-
if (config.enabled === false || !context.data.schema.layers.tree) return [];
|
|
9199
|
-
const resolvedMode = config.mode ?? "3d";
|
|
9200
|
-
const threeDimensional = config.threeDimensional;
|
|
9201
|
-
return [
|
|
9202
|
-
{
|
|
9203
|
-
kind: "layer",
|
|
9204
|
-
layer: applyCircleStyle(
|
|
9205
|
-
{
|
|
9206
|
-
id: "tileflow-vegetation-trees",
|
|
9207
|
-
type: "circle",
|
|
9208
|
-
source: context.data.sourceId,
|
|
9209
|
-
"source-layer": context.data.schema.layers.tree,
|
|
9210
|
-
metadata: {
|
|
9211
|
-
"tileflow:vegetation-mode": resolvedMode,
|
|
9212
|
-
...resolvedMode === "3d" ? { "tileflow:vegetation-fallback": "flat-circle" } : {},
|
|
9213
|
-
"tileflow:tree-bark-color": threeDimensional.barkColor,
|
|
9214
|
-
"tileflow:tree-broadleaf-colors": threeDimensional.broadleafColors,
|
|
9215
|
-
"tileflow:tree-conifer-colors": threeDimensional.coniferColors,
|
|
9216
|
-
"tileflow:tree-crown-field": context.data.schema.fields.diameterCrown,
|
|
9217
|
-
"tileflow:tree-crown-scale": threeDimensional.crownScale,
|
|
9218
|
-
"tileflow:tree-genus-field": context.data.schema.fields.genus,
|
|
9219
|
-
"tileflow:tree-height-field": context.data.schema.fields.height,
|
|
9220
|
-
"tileflow:tree-height-scale": threeDimensional.heightScale,
|
|
9221
|
-
"tileflow:tree-leaf-type-field": context.data.schema.fields.leafType,
|
|
9222
|
-
"tileflow:tree-species-field": context.data.schema.fields.species
|
|
9223
|
-
}
|
|
9224
|
-
},
|
|
9225
|
-
config.flat ?? {}
|
|
9226
|
-
),
|
|
9227
|
-
localOrder: 1,
|
|
9228
|
-
owner: "vegetation",
|
|
9229
|
-
slot: "vegetation",
|
|
9230
|
-
target: "vegetation.trees"
|
|
9231
|
-
}
|
|
9232
|
-
];
|
|
9233
|
-
}
|
|
9234
|
-
|
|
9235
9630
|
// src/modules/water/index.ts
|
|
9236
9631
|
function water(options = {}) {
|
|
9237
9632
|
return { type: "water", ...cloneJson17(options) };
|
|
@@ -10933,21 +11328,21 @@ function bindSemanticValue(value, schema, sourceId) {
|
|
|
10933
11328
|
}
|
|
10934
11329
|
if (isDataSourceReference(value)) return sourceId;
|
|
10935
11330
|
if (Array.isArray(value)) return value.map((item) => bindSemanticValue(item, schema, sourceId));
|
|
10936
|
-
if (!
|
|
11331
|
+
if (!isRecord8(value)) return value;
|
|
10937
11332
|
return Object.fromEntries(
|
|
10938
11333
|
Object.entries(value).map(([key, item]) => [key, bindSemanticValue(item, schema, sourceId)])
|
|
10939
11334
|
);
|
|
10940
11335
|
}
|
|
10941
11336
|
function isDataFieldReference2(value) {
|
|
10942
|
-
return
|
|
11337
|
+
return isRecord8(value) && value.kind === "tileflow-data-field" && typeof value.name === "string";
|
|
10943
11338
|
}
|
|
10944
11339
|
function isDataLayerReference(value) {
|
|
10945
|
-
return
|
|
11340
|
+
return isRecord8(value) && value.kind === "tileflow-data-layer" && typeof value.name === "string";
|
|
10946
11341
|
}
|
|
10947
11342
|
function isDataSourceReference(value) {
|
|
10948
|
-
return
|
|
11343
|
+
return isRecord8(value) && value.kind === "tileflow-data-source" && value.name === "primary";
|
|
10949
11344
|
}
|
|
10950
|
-
function
|
|
11345
|
+
function isRecord8(value) {
|
|
10951
11346
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
10952
11347
|
}
|
|
10953
11348
|
function compareCodeUnits5(left, right) {
|
|
@@ -11051,8 +11446,8 @@ function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
|
11051
11446
|
renderer: type,
|
|
11052
11447
|
...filter === void 0 ? {} : { selector: cloneJson20(filter) },
|
|
11053
11448
|
style: Object.freeze({
|
|
11054
|
-
...
|
|
11055
|
-
...
|
|
11449
|
+
...isRecord9(layout) ? { placement: Object.freeze(cloneJson20(layout)) } : {},
|
|
11450
|
+
...isRecord9(paint) ? { appearance: Object.freeze(cloneJson20(paint)) } : {}
|
|
11056
11451
|
})
|
|
11057
11452
|
});
|
|
11058
11453
|
}
|
|
@@ -11292,21 +11687,21 @@ function visitReferences(value, counts, visited = /* @__PURE__ */ new WeakSet())
|
|
|
11292
11687
|
}
|
|
11293
11688
|
}
|
|
11294
11689
|
function isSemanticFieldReference(value) {
|
|
11295
|
-
return
|
|
11690
|
+
return isRecord9(value) && value.kind === "tileflow-data-field";
|
|
11296
11691
|
}
|
|
11297
11692
|
function isSemanticLayerReference(value) {
|
|
11298
|
-
return
|
|
11693
|
+
return isRecord9(value) && value.kind === "tileflow-data-layer";
|
|
11299
11694
|
}
|
|
11300
11695
|
function isSemanticSourceReference(value) {
|
|
11301
|
-
return
|
|
11696
|
+
return isRecord9(value) && value.kind === "tileflow-data-source";
|
|
11302
11697
|
}
|
|
11303
11698
|
function cloneJson20(value) {
|
|
11304
11699
|
return JSON.parse(JSON.stringify(value));
|
|
11305
11700
|
}
|
|
11306
11701
|
function asRecord4(value) {
|
|
11307
|
-
return
|
|
11702
|
+
return isRecord9(value) ? value : {};
|
|
11308
11703
|
}
|
|
11309
|
-
function
|
|
11704
|
+
function isRecord9(value) {
|
|
11310
11705
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
11311
11706
|
}
|
|
11312
11707
|
|
|
@@ -11370,7 +11765,7 @@ function validateTileflowRenderSelectorConstraints(input) {
|
|
|
11370
11765
|
};
|
|
11371
11766
|
while (pending.length > 0) {
|
|
11372
11767
|
const current = pending.pop();
|
|
11373
|
-
if (!
|
|
11768
|
+
if (!isRecord10(current.selector) || typeof current.selector.kind !== "string") {
|
|
11374
11769
|
addIssue(
|
|
11375
11770
|
"invalid-selector",
|
|
11376
11771
|
"a render selector must be a semantic selector node",
|
|
@@ -11431,7 +11826,7 @@ function validateTileflowRenderSelectorConstraints(input) {
|
|
|
11431
11826
|
}
|
|
11432
11827
|
for (const [index, branch] of current.selector.branches.entries()) {
|
|
11433
11828
|
const branchPath = [...branchesPath, index];
|
|
11434
|
-
if (!
|
|
11829
|
+
if (!isRecord10(branch)) {
|
|
11435
11830
|
addIssue("invalid-selector", "match selector branch must be an object", branchPath);
|
|
11436
11831
|
continue;
|
|
11437
11832
|
}
|
|
@@ -11462,14 +11857,14 @@ function validateTileflowRenderSelectorConstraints(input) {
|
|
|
11462
11857
|
for (let index = current.selector.stops.length - 1; index >= 0; index -= 1) {
|
|
11463
11858
|
const stop = current.selector.stops[index];
|
|
11464
11859
|
const stopPath = [...stopsPath, index];
|
|
11465
|
-
if (!
|
|
11860
|
+
if (!isRecord10(stop)) {
|
|
11466
11861
|
addIssue("invalid-selector", "step selector stop must be an object", stopPath);
|
|
11467
11862
|
continue;
|
|
11468
11863
|
}
|
|
11469
11864
|
pushChild(stop.selector, current.depth + 1, [...stopPath, "selector"]);
|
|
11470
11865
|
}
|
|
11471
11866
|
for (const [index, stop] of current.selector.stops.entries()) {
|
|
11472
|
-
if (!
|
|
11867
|
+
if (!isRecord10(stop)) continue;
|
|
11473
11868
|
const zoom3 = stop.zoom;
|
|
11474
11869
|
const zoomPath = [...stopsPath, index, "zoom"];
|
|
11475
11870
|
if (typeof zoom3 !== "number" || !Number.isFinite(zoom3) || zoom3 < 0 || zoom3 > 24) {
|
|
@@ -11852,7 +12247,7 @@ function applyRendererStyle(layer, renderer, style) {
|
|
|
11852
12247
|
};
|
|
11853
12248
|
}
|
|
11854
12249
|
function lowerSelector(selector, data) {
|
|
11855
|
-
if (!
|
|
12250
|
+
if (!isRecord10(selector) || typeof selector.kind !== "string") {
|
|
11856
12251
|
throw renderStackError(
|
|
11857
12252
|
"invalid-selector",
|
|
11858
12253
|
"A render selector must be a semantic selector node."
|
|
@@ -12055,7 +12450,7 @@ function requireRenderer(value) {
|
|
|
12055
12450
|
function requirePlacement(value) {
|
|
12056
12451
|
if (typeof value === "string") {
|
|
12057
12452
|
if (tileflowBandPlacements.includes(value)) return;
|
|
12058
|
-
} else if (
|
|
12453
|
+
} else if (isRecord10(value)) {
|
|
12059
12454
|
const keys = Object.keys(value);
|
|
12060
12455
|
if (keys.length === 1 && (keys[0] === "above" || keys[0] === "below")) {
|
|
12061
12456
|
requirePortableTarget(value[keys[0]], "render placement target");
|
|
@@ -12082,7 +12477,7 @@ function validateRefinementShape(operation) {
|
|
|
12082
12477
|
validateStyle(operation.renderer, operation.style);
|
|
12083
12478
|
}
|
|
12084
12479
|
function validateStyle(renderer, style) {
|
|
12085
|
-
if (!
|
|
12480
|
+
if (!isRecord10(style)) {
|
|
12086
12481
|
throw renderStackError(
|
|
12087
12482
|
"invalid-style",
|
|
12088
12483
|
`A ${renderer} render operation requires a style object.`
|
|
@@ -12184,7 +12579,7 @@ function normalizeRequirements(requirements) {
|
|
|
12184
12579
|
return [...requirements];
|
|
12185
12580
|
}
|
|
12186
12581
|
function requireRenderStackEntries(stack) {
|
|
12187
|
-
if (!
|
|
12582
|
+
if (!isRecord10(stack)) {
|
|
12188
12583
|
throw renderStackError("invalid-stack", "A render stack must be a named operation record.");
|
|
12189
12584
|
}
|
|
12190
12585
|
const entries = Object.entries(stack);
|
|
@@ -12331,9 +12726,9 @@ function cloneJson21(value) {
|
|
|
12331
12726
|
return JSON.parse(JSON.stringify(value));
|
|
12332
12727
|
}
|
|
12333
12728
|
function asRecord5(value) {
|
|
12334
|
-
return
|
|
12729
|
+
return isRecord10(value) ? value : {};
|
|
12335
12730
|
}
|
|
12336
|
-
function
|
|
12731
|
+
function isRecord10(value) {
|
|
12337
12732
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
12338
12733
|
}
|
|
12339
12734
|
|
|
@@ -13372,6 +13767,17 @@ var waterModuleSchema = z7.object({
|
|
|
13372
13767
|
stream: lineStyleSchema.optional()
|
|
13373
13768
|
}).strict().optional()
|
|
13374
13769
|
}).strict();
|
|
13770
|
+
function boundedThemeNumberSchema(min, max) {
|
|
13771
|
+
return z7.union([
|
|
13772
|
+
z7.number().finite().min(min).max(max),
|
|
13773
|
+
themeNumberReferenceSchema,
|
|
13774
|
+
z7.object({
|
|
13775
|
+
kind: z7.literal("theme-fixed"),
|
|
13776
|
+
reason: z7.string().trim().min(1),
|
|
13777
|
+
value: z7.number().finite().min(min).max(max)
|
|
13778
|
+
}).strict()
|
|
13779
|
+
]);
|
|
13780
|
+
}
|
|
13375
13781
|
var buildingsModuleSchema = z7.object({
|
|
13376
13782
|
type: z7.literal("buildings"),
|
|
13377
13783
|
businessCorridor: areaStyleSchema.optional(),
|
|
@@ -13379,7 +13785,15 @@ var buildingsModuleSchema = z7.object({
|
|
|
13379
13785
|
extrusion: extrusionStyleSchema.optional(),
|
|
13380
13786
|
flat: areaStyleSchema.optional(),
|
|
13381
13787
|
mode: z7.enum(["3d", "flat"]).optional(),
|
|
13382
|
-
renderStack: renderStackSchema.optional()
|
|
13788
|
+
renderStack: renderStackSchema.optional(),
|
|
13789
|
+
threeDimensional: z7.object({
|
|
13790
|
+
edges: boundedThemeNumberSchema(0, 1).optional(),
|
|
13791
|
+
edgeColor: themeColorValueSchema.optional(),
|
|
13792
|
+
nightLight: boundedThemeNumberSchema(0, 2).optional(),
|
|
13793
|
+
occlusion: z7.boolean().optional(),
|
|
13794
|
+
shadows: z7.boolean().optional(),
|
|
13795
|
+
windows: z7.boolean().optional()
|
|
13796
|
+
}).strict().optional()
|
|
13383
13797
|
}).strict();
|
|
13384
13798
|
var addressesModuleSchema = z7.object({
|
|
13385
13799
|
type: z7.literal("addresses"),
|
|
@@ -13492,6 +13906,12 @@ var roadsModuleSchema = z7.object({
|
|
|
13492
13906
|
pattern: fillStyleSchema.optional(),
|
|
13493
13907
|
surface: fillStyleSchema.optional()
|
|
13494
13908
|
}).strict().optional(),
|
|
13909
|
+
streetLights: z7.object({
|
|
13910
|
+
color: themeColorValueSchema.optional(),
|
|
13911
|
+
enabled: z7.boolean().optional(),
|
|
13912
|
+
estimate: z7.enum(["lit", "streets", "none"]).optional(),
|
|
13913
|
+
intensity: boundedThemeNumberSchema(0, 2).optional()
|
|
13914
|
+
}).strict().optional(),
|
|
13495
13915
|
structures: roadStructureMapSchema.optional(),
|
|
13496
13916
|
weight: z7.enum(["thin", "regular", "bold"]).optional(),
|
|
13497
13917
|
widthScale: z7.partialRecord(roadClassSchema, themeNumberValueSchema).optional()
|
|
@@ -13580,6 +14000,16 @@ var nauticalModuleSchema = z7.object({
|
|
|
13580
14000
|
wreckAreas: areaStyleSchema.optional(),
|
|
13581
14001
|
wrecks: markerSymbolStyleSchema.optional()
|
|
13582
14002
|
}).strict();
|
|
14003
|
+
var treeFormMixSchema = z7.object({
|
|
14004
|
+
round: z7.number().finite().min(0).optional(),
|
|
14005
|
+
open: z7.number().finite().min(0).optional(),
|
|
14006
|
+
tall: z7.number().finite().min(0).optional(),
|
|
14007
|
+
conifer: z7.number().finite().min(0).optional(),
|
|
14008
|
+
columnar: z7.number().finite().min(0).optional(),
|
|
14009
|
+
palm: z7.number().finite().min(0).optional()
|
|
14010
|
+
}).strict().refine((mix2) => Object.values(mix2).some((weight) => (weight ?? 0) > 0), {
|
|
14011
|
+
message: "Expected at least one tree form with a weight above 0"
|
|
14012
|
+
});
|
|
13583
14013
|
var modulesSchema = z7.object({
|
|
13584
14014
|
addresses: addressesModuleSchema.optional(),
|
|
13585
14015
|
aeroways: aerowaysModuleSchema.optional(),
|
|
@@ -13602,6 +14032,39 @@ var modulesSchema = z7.object({
|
|
|
13602
14032
|
barkColor: themeColorValueSchema.optional(),
|
|
13603
14033
|
broadleafColors: z7.array(themeColorValueSchema).min(1).max(8).optional(),
|
|
13604
14034
|
coniferColors: z7.array(themeColorValueSchema).min(1).max(8).optional(),
|
|
14035
|
+
palmColors: z7.array(themeColorValueSchema).min(1).max(8).optional(),
|
|
14036
|
+
finish: z7.enum(["faceted", "smooth", "toon"]).optional(),
|
|
14037
|
+
edges: boundedThemeNumberSchema(0, 1).optional(),
|
|
14038
|
+
edgeColor: themeColorValueSchema.optional(),
|
|
14039
|
+
forms: z7.partialRecord(
|
|
14040
|
+
z7.enum(["round", "open", "tall", "conifer", "columnar", "palm"]),
|
|
14041
|
+
z7.object({
|
|
14042
|
+
crownScale: boundedThemeNumberSchema(0.1, 10).optional(),
|
|
14043
|
+
heightScale: boundedThemeNumberSchema(0.1, 10).optional(),
|
|
14044
|
+
models: z7.array(
|
|
14045
|
+
z7.string().max(64).regex(
|
|
14046
|
+
tileflowTreeModelIdPattern,
|
|
14047
|
+
"Expected a model id: its .glb file name in lowercase letters, digits and hyphens"
|
|
14048
|
+
)
|
|
14049
|
+
).min(1).max(4).refine((ids) => new Set(ids).size === ids.length, {
|
|
14050
|
+
message: "Expected each model once"
|
|
14051
|
+
}).optional()
|
|
14052
|
+
}).strict()
|
|
14053
|
+
).optional(),
|
|
14054
|
+
unknownForms: treeFormMixSchema.optional(),
|
|
14055
|
+
regions: z7.array(
|
|
14056
|
+
z7.object({
|
|
14057
|
+
bounds: z7.tuple([
|
|
14058
|
+
z7.number().finite().min(-180).max(180),
|
|
14059
|
+
z7.number().finite().min(-90).max(90),
|
|
14060
|
+
z7.number().finite().min(-180).max(180),
|
|
14061
|
+
z7.number().finite().min(-90).max(90)
|
|
14062
|
+
]).refine(([, south, , north]) => south <= north, {
|
|
14063
|
+
message: "Expected bounds as [west, south, east, north] with south below north"
|
|
14064
|
+
}),
|
|
14065
|
+
unknownForms: treeFormMixSchema
|
|
14066
|
+
}).strict()
|
|
14067
|
+
).max(16).optional(),
|
|
13605
14068
|
crownScale: z7.union([
|
|
13606
14069
|
z7.number().finite().positive().max(10),
|
|
13607
14070
|
themeNumberReferenceSchema,
|
|
@@ -13934,6 +14397,7 @@ var iconDirectoriesSchema = z7.array(
|
|
|
13934
14397
|
}
|
|
13935
14398
|
});
|
|
13936
14399
|
var fontDirectoriesSchema = z7.array(assetDirectorySchema).max(16);
|
|
14400
|
+
var modelDirectoriesSchema = z7.array(assetDirectorySchema).max(16);
|
|
13937
14401
|
var fontStacksSchema = z7.array(
|
|
13938
14402
|
z7.string().min(1).max(200).refine(
|
|
13939
14403
|
(value) => value === value.trim() && value === value.normalize("NFC") && !/[\p{Cc}\\/]/u.test(value),
|
|
@@ -14155,6 +14619,7 @@ var resolvedTileflowMapSchema = z7.object({
|
|
|
14155
14619
|
icons: iconDirectoriesSchema.optional(),
|
|
14156
14620
|
id: tileflowMapIdSchema,
|
|
14157
14621
|
marine: marineSchema.optional(),
|
|
14622
|
+
models: modelDirectoriesSchema.optional(),
|
|
14158
14623
|
modules: modulesSchema.optional(),
|
|
14159
14624
|
name: z7.string().trim().min(1),
|
|
14160
14625
|
overlays: overlaysSchema.optional(),
|
|
@@ -15097,11 +15562,11 @@ function isTileflowPoiCategory(value) {
|
|
|
15097
15562
|
return typeof value === "string" && tileflowPoiCategories.includes(value);
|
|
15098
15563
|
}
|
|
15099
15564
|
function semanticTarget(layer) {
|
|
15100
|
-
if (!
|
|
15565
|
+
if (!isRecord11(layer.metadata)) return void 0;
|
|
15101
15566
|
const value = layer.metadata[tileflowCompilerMetadataKeys.target];
|
|
15102
15567
|
return typeof value === "string" ? value : void 0;
|
|
15103
15568
|
}
|
|
15104
|
-
function
|
|
15569
|
+
function isRecord11(value) {
|
|
15105
15570
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
15106
15571
|
}
|
|
15107
15572
|
function isSafeArtifactName(value) {
|
|
@@ -16145,8 +16610,19 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
16145
16610
|
"domains",
|
|
16146
16611
|
() => compileSemanticDomains(modules, context)
|
|
16147
16612
|
);
|
|
16613
|
+
const vegetation3D = runCompilationPhase(
|
|
16614
|
+
"domains",
|
|
16615
|
+
() => withPreparedTreeModels(
|
|
16616
|
+
tileflowVegetationDescription(
|
|
16617
|
+
modules.vegetation,
|
|
16618
|
+
context
|
|
16619
|
+
),
|
|
16620
|
+
config,
|
|
16621
|
+
options.preparedAssets
|
|
16622
|
+
)
|
|
16623
|
+
);
|
|
16148
16624
|
const renderStackModules = Object.values(modules).filter(
|
|
16149
|
-
(module) =>
|
|
16625
|
+
(module) => isRecord12(module) && module.enabled !== false && "renderStack" in module && isRecord12(module.renderStack)
|
|
16150
16626
|
);
|
|
16151
16627
|
const renderOperations = runCompilationPhase(
|
|
16152
16628
|
"render-stack",
|
|
@@ -16306,6 +16782,15 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
16306
16782
|
() => createTileflowOverlayPlacementManifest(plannedLayers)
|
|
16307
16783
|
);
|
|
16308
16784
|
const layers = runCompilationPhase("finalization", () => finalizeTileflowLayers(plannedLayers));
|
|
16785
|
+
const buildings3D = tileflowBuildings3DDesignOf(
|
|
16786
|
+
modules.buildings,
|
|
16787
|
+
context,
|
|
16788
|
+
layers
|
|
16789
|
+
);
|
|
16790
|
+
const streetLights = tileflowStreetLightsDesignOf(
|
|
16791
|
+
modules.roads,
|
|
16792
|
+
context
|
|
16793
|
+
);
|
|
16309
16794
|
runCompilationPhase(
|
|
16310
16795
|
"finalization",
|
|
16311
16796
|
() => assertTileflowInteractionManifestLayers(interactionManifest, layers)
|
|
@@ -16378,13 +16863,33 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
16378
16863
|
"tileflow:colorScheme": resolvedTheme.colorScheme,
|
|
16379
16864
|
[tileflowRouteMetadataKey]: tileflowRouteMetadata(resolveTileflowRouteInks(resolvedTheme)),
|
|
16380
16865
|
...resolvedTheme.sun ? { [tileflowSunMetadataKey]: tileflowSunMetadata(resolvedTheme.sun) } : {},
|
|
16866
|
+
...buildings3D ? {
|
|
16867
|
+
[tileflowBuildingsMetadataKey]: tileflowBuildingsMetadata(
|
|
16868
|
+
bindSemanticReferences(buildings3D, semanticData)
|
|
16869
|
+
)
|
|
16870
|
+
} : {},
|
|
16871
|
+
...streetLights ? {
|
|
16872
|
+
[tileflowStreetLightsMetadataKey]: tileflowStreetLightsMetadata(
|
|
16873
|
+
bindSemanticReferences(streetLights, semanticData)
|
|
16874
|
+
)
|
|
16875
|
+
} : {},
|
|
16876
|
+
...vegetation3D ? {
|
|
16877
|
+
[tileflowVegetationMetadataKey]: tileflowVegetationMetadata({
|
|
16878
|
+
...bindSemanticReferences(vegetation3D, semanticData),
|
|
16879
|
+
// The layers that draw the trees flat: the module's own and its render passes.
|
|
16880
|
+
flatLayers: layers.filter((layer) => {
|
|
16881
|
+
const metadata = layer.metadata;
|
|
16882
|
+
return metadata?.["tileflow:vegetation-mode"] !== void 0 || metadata?.["tileflow:domain"] === "vegetation";
|
|
16883
|
+
}).map((layer) => String(layer.id))
|
|
16884
|
+
})
|
|
16885
|
+
} : {},
|
|
16381
16886
|
"tileflow:data": data.identity,
|
|
16382
16887
|
"tileflow:sources": sourceIdentities,
|
|
16383
16888
|
...Object.keys(loweredOverlays.identities).length > 0 ? { "tileflow:overlays": loweredOverlays.identities } : {},
|
|
16384
16889
|
"tileflow:sourceRequirements": sourceRequirements,
|
|
16385
16890
|
...interactionManifest ? { [tileflowInteractionManifestMetadataKey]: interactionManifest } : {},
|
|
16386
16891
|
[tileflowOverlayPlacementManifestMetadataKey]: overlayPlacementManifest,
|
|
16387
|
-
"tileflow:modules": Object.entries(modules).filter(([, module]) => !
|
|
16892
|
+
"tileflow:modules": Object.entries(modules).filter(([, module]) => !isRecord12(module) || module.enabled !== false).map(([name]) => name).sort(),
|
|
16388
16893
|
...config.view ? { "tileflow:view": config.view } : {}
|
|
16389
16894
|
}
|
|
16390
16895
|
};
|
|
@@ -16436,7 +16941,7 @@ function finalizeTileflowLayers(input) {
|
|
|
16436
16941
|
if (typeof minimum2 === "number" && typeof maximum2 === "number" && minimum2 > maximum2) {
|
|
16437
16942
|
throw new Error(`Compiled Tileflow layer ${id2} requires minzoom <= maxzoom.`);
|
|
16438
16943
|
}
|
|
16439
|
-
const metadata =
|
|
16944
|
+
const metadata = isRecord12(layer.metadata) ? { ...layer.metadata } : void 0;
|
|
16440
16945
|
if (metadata) {
|
|
16441
16946
|
const owner = metadata[tileflowCompilerMetadataKeys.owner];
|
|
16442
16947
|
delete metadata[tileflowCompilerProvenanceMetadataKey];
|
|
@@ -16470,13 +16975,32 @@ function assertMapLibreStyle(style, mapId) {
|
|
|
16470
16975
|
}
|
|
16471
16976
|
);
|
|
16472
16977
|
}
|
|
16473
|
-
function
|
|
16978
|
+
function isRecord12(value) {
|
|
16474
16979
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
16475
16980
|
}
|
|
16476
16981
|
function resolveGlyphs(config) {
|
|
16477
16982
|
if (config.fonts !== void 0) return void 0;
|
|
16478
16983
|
return config.glyphs?.url;
|
|
16479
16984
|
}
|
|
16985
|
+
function withPreparedTreeModels(vegetation2, config, prepared) {
|
|
16986
|
+
if (!vegetation2) return void 0;
|
|
16987
|
+
const referenced = [
|
|
16988
|
+
...new Set(Object.values(vegetation2.forms).flatMap((form) => form?.models ?? []))
|
|
16989
|
+
].sort();
|
|
16990
|
+
if (referenced.length === 0) return vegetation2;
|
|
16991
|
+
const available = prepared?.models ?? {};
|
|
16992
|
+
const missing = referenced.filter((id2) => !Object.hasOwn(available, id2));
|
|
16993
|
+
if (missing.length > 0) {
|
|
16994
|
+
const authoring = config.models?.length ? `Add ${missing.map((id2) => `${id2}.glb`).join(", ")} to a map.models directory, or run the Node build so the directories are prepared.` : "Declare map.models with directories containing those .glb files.";
|
|
16995
|
+
throw new Error(
|
|
16996
|
+
`Tileflow map "${config.id}" draws missing 3D models: ${missing.join(", ")}. ${authoring}`
|
|
16997
|
+
);
|
|
16998
|
+
}
|
|
16999
|
+
return {
|
|
17000
|
+
...vegetation2,
|
|
17001
|
+
models: Object.fromEntries(referenced.map((id2) => [id2, available[id2]]))
|
|
17002
|
+
};
|
|
17003
|
+
}
|
|
16480
17004
|
function assertPreparedIconReferences(style, config, prepared) {
|
|
16481
17005
|
const references = collectStyleImageReferences(style);
|
|
16482
17006
|
if (references.size === 0) return;
|
|
@@ -16491,8 +17015,8 @@ function assertPreparedIconReferences(style, config, prepared) {
|
|
|
16491
17015
|
function collectStyleImageReferences(style) {
|
|
16492
17016
|
const result = /* @__PURE__ */ new Set();
|
|
16493
17017
|
for (const layer of style.layers) {
|
|
16494
|
-
const layout =
|
|
16495
|
-
const paint =
|
|
17018
|
+
const layout = isRecord12(layer.layout) ? layer.layout : {};
|
|
17019
|
+
const paint = isRecord12(layer.paint) ? layer.paint : {};
|
|
16496
17020
|
const layerId = typeof layer.id === "string" ? layer.id : "<unknown>";
|
|
16497
17021
|
for (const [property, value] of [
|
|
16498
17022
|
["icon-image", layout["icon-image"]],
|
|
@@ -16581,7 +17105,7 @@ function assertGlyphFontStacks(style, config) {
|
|
|
16581
17105
|
const declared = new Set(config.glyphs.fontStacks);
|
|
16582
17106
|
const missing = /* @__PURE__ */ new Set();
|
|
16583
17107
|
for (const layer of style.layers) {
|
|
16584
|
-
const layout =
|
|
17108
|
+
const layout = isRecord12(layer.layout) ? layer.layout : void 0;
|
|
16585
17109
|
const font = layout?.["text-font"];
|
|
16586
17110
|
if (!Array.isArray(font) || !font.every((entry) => typeof entry === "string")) continue;
|
|
16587
17111
|
const stack = font.join(",");
|
|
@@ -16597,7 +17121,7 @@ function assertGlyphFontStacks(style, config) {
|
|
|
16597
17121
|
function assertTextAssets(style, config) {
|
|
16598
17122
|
const textLayers = [];
|
|
16599
17123
|
for (const layer of style.layers) {
|
|
16600
|
-
const layout =
|
|
17124
|
+
const layout = isRecord12(layer.layout) ? layer.layout : void 0;
|
|
16601
17125
|
if (layout?.["text-field"] === void 0) continue;
|
|
16602
17126
|
textLayers.push(typeof layer.id === "string" ? layer.id : "<unknown>");
|
|
16603
17127
|
const font = layout["text-font"];
|
|
@@ -16610,7 +17134,7 @@ function assertTextAssets(style, config) {
|
|
|
16610
17134
|
if (textLayers.length === 0) return;
|
|
16611
17135
|
if (config.fonts !== void 0) {
|
|
16612
17136
|
const backed = style.layers.find((layer) => {
|
|
16613
|
-
const font =
|
|
17137
|
+
const font = isRecord12(layer.layout) ? layer.layout["text-font"] : void 0;
|
|
16614
17138
|
return Array.isArray(font) && font.length === 1 && typeof font[0] === "string" && parseTileflowLineBackgroundFontStack(font[0]) !== void 0;
|
|
16615
17139
|
});
|
|
16616
17140
|
if (backed) {
|
|
@@ -16636,7 +17160,7 @@ function runCompilationPhase(phase, operation) {
|
|
|
16636
17160
|
}
|
|
16637
17161
|
}
|
|
16638
17162
|
function withCompilationPhase(error, phase) {
|
|
16639
|
-
const record2 =
|
|
17163
|
+
const record2 = isRecord12(error) ? error : {};
|
|
16640
17164
|
if (typeof record2.phase === "string") return error;
|
|
16641
17165
|
if (error instanceof Error && Object.isExtensible(error)) {
|
|
16642
17166
|
Object.defineProperty(error, "phase", { configurable: true, enumerable: true, value: phase });
|
|
@@ -16733,6 +17257,7 @@ var tileflowMapMergeStrategies = {
|
|
|
16733
17257
|
icons: "icons",
|
|
16734
17258
|
id: "identity",
|
|
16735
17259
|
marine: "atomic",
|
|
17260
|
+
models: "atomic",
|
|
16736
17261
|
modules: "modules",
|
|
16737
17262
|
name: "identity",
|
|
16738
17263
|
overlays: "keyed-resources",
|
|
@@ -17078,11 +17603,11 @@ function cloneDesign(value) {
|
|
|
17078
17603
|
function describeMap(value) {
|
|
17079
17604
|
return typeof value.id === "string" && value.id ? value.id : "<anonymous>";
|
|
17080
17605
|
}
|
|
17081
|
-
function
|
|
17606
|
+
function isRecord13(value) {
|
|
17082
17607
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
17083
17608
|
}
|
|
17084
17609
|
function isPlainRecord4(value) {
|
|
17085
|
-
if (!
|
|
17610
|
+
if (!isRecord13(value)) return false;
|
|
17086
17611
|
const prototype = Object.getPrototypeOf(value);
|
|
17087
17612
|
return prototype === Object.prototype || prototype === null;
|
|
17088
17613
|
}
|
|
@@ -17840,7 +18365,7 @@ function semanticDesign(map) {
|
|
|
17840
18365
|
}
|
|
17841
18366
|
function compareValues(before, after, path, output) {
|
|
17842
18367
|
if (Object.is(before, after)) return;
|
|
17843
|
-
if (
|
|
18368
|
+
if (isRecord14(before) && isRecord14(after)) {
|
|
17844
18369
|
const keys = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])].sort(
|
|
17845
18370
|
compareCodeUnits9
|
|
17846
18371
|
);
|
|
@@ -17882,7 +18407,7 @@ function toSemanticValue(value, path) {
|
|
|
17882
18407
|
}
|
|
17883
18408
|
throw new TypeError(`Tileflow semantic value at ${path || "/"} is not JSON-serializable.`);
|
|
17884
18409
|
}
|
|
17885
|
-
function
|
|
18410
|
+
function isRecord14(value) {
|
|
17886
18411
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
17887
18412
|
}
|
|
17888
18413
|
function isUnknownRecord(value) {
|
|
@@ -17895,7 +18420,7 @@ function deepEqual(left, right) {
|
|
|
17895
18420
|
if (Array.isArray(left) || Array.isArray(right)) {
|
|
17896
18421
|
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((value, index) => deepEqual(value, right[index]));
|
|
17897
18422
|
}
|
|
17898
|
-
if (!
|
|
18423
|
+
if (!isRecord14(left) || !isRecord14(right)) return false;
|
|
17899
18424
|
const leftKeys = Object.keys(left).sort(compareCodeUnits9);
|
|
17900
18425
|
const rightKeys = Object.keys(right).sort(compareCodeUnits9);
|
|
17901
18426
|
return leftKeys.length === rightKeys.length && leftKeys.every((key, index) => key === rightKeys[index] && deepEqual(left[key], right[key]));
|
|
@@ -18696,7 +19221,7 @@ async function requestSessionGrant(input) {
|
|
|
18696
19221
|
else throw error;
|
|
18697
19222
|
}
|
|
18698
19223
|
throwIfSessionGrantAborted(signal);
|
|
18699
|
-
if (response.status === 409 &&
|
|
19224
|
+
if (response.status === 409 && isRecord15(body) && body.code === "COMMERCIAL_SESSION_RESTART_REQUIRED" && body.ok === false && body.retryWithNewSession === true && body.sessionId === input.sessionId) {
|
|
18700
19225
|
throw new TileflowSessionRestartError();
|
|
18701
19226
|
}
|
|
18702
19227
|
if (!response.ok) {
|
|
@@ -18769,7 +19294,7 @@ function sessionGrantAbortReason(signal) {
|
|
|
18769
19294
|
return error;
|
|
18770
19295
|
}
|
|
18771
19296
|
function parseSessionGrantResponse(value, expectedSessionId) {
|
|
18772
|
-
if (!
|
|
19297
|
+
if (!isRecord15(value) || value.ok !== true || value.sessionId !== expectedSessionId) return null;
|
|
18773
19298
|
if (value.usageMode !== void 0 && value.usageMode !== "session") return null;
|
|
18774
19299
|
if (value.billingEnabled !== void 0 && value.billingEnabled !== false) return null;
|
|
18775
19300
|
if (value.disposition !== void 0 && value.disposition !== "ordinary" && value.disposition !== "unbilled_fail_open") {
|
|
@@ -18788,11 +19313,11 @@ function parseSessionGrantResponse(value, expectedSessionId) {
|
|
|
18788
19313
|
}
|
|
18789
19314
|
return value;
|
|
18790
19315
|
}
|
|
18791
|
-
function
|
|
19316
|
+
function isRecord15(value) {
|
|
18792
19317
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
18793
19318
|
}
|
|
18794
19319
|
function isPlainRuntimeRecord(value) {
|
|
18795
|
-
if (!
|
|
19320
|
+
if (!isRecord15(value)) return false;
|
|
18796
19321
|
const prototype = Object.getPrototypeOf(value);
|
|
18797
19322
|
return prototype === Object.prototype || prototype === null;
|
|
18798
19323
|
}
|
|
@@ -19465,10 +19990,10 @@ var tileflowIconCompositionSchema = z13.object({
|
|
|
19465
19990
|
})
|
|
19466
19991
|
).min(1).max(tileflowIconPackageLimits.maxIconCount)
|
|
19467
19992
|
}).strict().superRefine((receipt, context) => {
|
|
19468
|
-
const
|
|
19993
|
+
const version2 = receipt.winners.some(
|
|
19469
19994
|
(winner) => winner.appearance !== void 0 || winner.layout !== void 0
|
|
19470
19995
|
) ? 2 : 1;
|
|
19471
|
-
if (receipt.compositionVersion !==
|
|
19996
|
+
if (receipt.compositionVersion !== version2 || receipt.format !== `tileflow-icon-composition-v${version2}`)
|
|
19472
19997
|
context.addIssue({
|
|
19473
19998
|
code: "custom",
|
|
19474
19999
|
path: ["compositionVersion"],
|
|
@@ -19574,6 +20099,164 @@ var tileflowIconSpriteIndexSchema = z14.record(tileflowIconIdSchema, tileflowIco
|
|
|
19574
20099
|
(index) => Object.keys(index).length > 0 && Object.keys(index).length <= tileflowIconPackageLimits.maxIconCount,
|
|
19575
20100
|
`A generated sprite index must contain 1 through ${tileflowIconPackageLimits.maxIconCount} icons`
|
|
19576
20101
|
);
|
|
20102
|
+
|
|
20103
|
+
// src/trees-3d-mesh.ts
|
|
20104
|
+
var tileflowTreeParts = { bark: 0, leaves: 1, fronds: 2, stem: 3 };
|
|
20105
|
+
var golden = (1 + Math.sqrt(5)) / 2;
|
|
20106
|
+
var icosahedron = {
|
|
20107
|
+
corners: [
|
|
20108
|
+
[-1, golden, 0],
|
|
20109
|
+
[1, golden, 0],
|
|
20110
|
+
[-1, -golden, 0],
|
|
20111
|
+
[1, -golden, 0],
|
|
20112
|
+
[0, -1, golden],
|
|
20113
|
+
[0, 1, golden],
|
|
20114
|
+
[0, -1, -golden],
|
|
20115
|
+
[0, 1, -golden],
|
|
20116
|
+
[golden, 0, -1],
|
|
20117
|
+
[golden, 0, 1],
|
|
20118
|
+
[-golden, 0, -1],
|
|
20119
|
+
[-golden, 0, 1]
|
|
20120
|
+
].map((corner) => normalize(corner)),
|
|
20121
|
+
faces: [
|
|
20122
|
+
[0, 11, 5],
|
|
20123
|
+
[0, 5, 1],
|
|
20124
|
+
[0, 1, 7],
|
|
20125
|
+
[0, 7, 10],
|
|
20126
|
+
[0, 10, 11],
|
|
20127
|
+
[1, 5, 9],
|
|
20128
|
+
[5, 11, 4],
|
|
20129
|
+
[11, 10, 2],
|
|
20130
|
+
[10, 7, 6],
|
|
20131
|
+
[7, 1, 8],
|
|
20132
|
+
[3, 9, 4],
|
|
20133
|
+
[3, 4, 2],
|
|
20134
|
+
[3, 2, 6],
|
|
20135
|
+
[3, 6, 8],
|
|
20136
|
+
[3, 8, 9],
|
|
20137
|
+
[4, 9, 5],
|
|
20138
|
+
[2, 4, 11],
|
|
20139
|
+
[6, 2, 10],
|
|
20140
|
+
[8, 6, 7],
|
|
20141
|
+
[9, 8, 1]
|
|
20142
|
+
]
|
|
20143
|
+
};
|
|
20144
|
+
function normalize(v) {
|
|
20145
|
+
const size = Math.hypot(v[0], v[1], v[2]) || 1;
|
|
20146
|
+
return [v[0] / size, v[1] / size, v[2] / size];
|
|
20147
|
+
}
|
|
20148
|
+
|
|
20149
|
+
// src/trees-3d-model.ts
|
|
20150
|
+
var tileflowTreeModelLimits = Object.freeze({
|
|
20151
|
+
/** Triangles of a near model, the one drawn close to the camera. */
|
|
20152
|
+
nearTriangles: 1e3,
|
|
20153
|
+
/** Triangles of a far model, drawn beyond the nearest tiles. */
|
|
20154
|
+
farTriangles: 120,
|
|
20155
|
+
/** Vertices of one model. */
|
|
20156
|
+
vertices: 4096,
|
|
20157
|
+
/** Models one map carries. */
|
|
20158
|
+
models: 16,
|
|
20159
|
+
/** Models one form draws from. */
|
|
20160
|
+
perForm: 4
|
|
20161
|
+
});
|
|
20162
|
+
var magic = [84, 70, 84, 77];
|
|
20163
|
+
var version = 1;
|
|
20164
|
+
var headerBytes = 16;
|
|
20165
|
+
var vertexBytes = 12;
|
|
20166
|
+
var positionRange = 2;
|
|
20167
|
+
var partCount = Object.keys(tileflowTreeParts).length;
|
|
20168
|
+
function encodeTileflowTreeModel(mesh, level) {
|
|
20169
|
+
const count = mesh.positions.length / 3;
|
|
20170
|
+
const triangles = mesh.indices.length / 3;
|
|
20171
|
+
const limit = level === "near" ? tileflowTreeModelLimits.nearTriangles : tileflowTreeModelLimits.farTriangles;
|
|
20172
|
+
if (!Number.isInteger(count) || count < 3 || count > tileflowTreeModelLimits.vertices)
|
|
20173
|
+
throw new RangeError(`A tree model has 3 to ${tileflowTreeModelLimits.vertices} vertices.`);
|
|
20174
|
+
if (!Number.isInteger(triangles) || triangles < 1 || triangles > limit)
|
|
20175
|
+
throw new RangeError(`A ${level} tree model has 1 to ${limit} triangles.`);
|
|
20176
|
+
for (const list of [mesh.normals, mesh.positions])
|
|
20177
|
+
if (list.length !== count * 3)
|
|
20178
|
+
throw new RangeError("Every vertex needs a position and normal.");
|
|
20179
|
+
for (const list of [mesh.parts, mesh.shades, mesh.occlusion])
|
|
20180
|
+
if (list.length !== count) throw new RangeError("Every vertex needs a part, shade and light.");
|
|
20181
|
+
const bytes = new Uint8Array(headerBytes + count * vertexBytes + mesh.indices.length * 2);
|
|
20182
|
+
const view = new DataView(bytes.buffer);
|
|
20183
|
+
bytes.set(magic, 0);
|
|
20184
|
+
view.setUint16(4, version, true);
|
|
20185
|
+
view.setUint16(6, count, true);
|
|
20186
|
+
view.setUint32(8, mesh.indices.length, true);
|
|
20187
|
+
view.setUint16(12, Math.round(clamp(mesh.proportion, 0.1, 3) * 1e3), true);
|
|
20188
|
+
for (let index = 0; index < count; index += 1) {
|
|
20189
|
+
const at = headerBytes + index * vertexBytes;
|
|
20190
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
20191
|
+
const value = clamp(mesh.positions[index * 3 + axis] / positionRange, -1, 1);
|
|
20192
|
+
view.setInt16(at + axis * 2, Math.round(value * 32767), true);
|
|
20193
|
+
view.setInt8(at + 6 + axis, Math.round(clamp(mesh.normals[index * 3 + axis], -1, 1) * 127));
|
|
20194
|
+
}
|
|
20195
|
+
const part = mesh.parts[index];
|
|
20196
|
+
if (!Number.isInteger(part) || part < 0 || part >= partCount)
|
|
20197
|
+
throw new RangeError(`Vertex ${index} has no tree part.`);
|
|
20198
|
+
bytes[at + 9] = part;
|
|
20199
|
+
bytes[at + 10] = Math.round((clamp(mesh.shades[index], -1, 1) + 1) / 2 * 255);
|
|
20200
|
+
bytes[at + 11] = Math.round(clamp(mesh.occlusion[index], 0, 1) * 255);
|
|
20201
|
+
}
|
|
20202
|
+
const indexAt = headerBytes + count * vertexBytes;
|
|
20203
|
+
mesh.indices.forEach((vertex, index) => {
|
|
20204
|
+
if (!Number.isInteger(vertex) || vertex < 0 || vertex >= count)
|
|
20205
|
+
throw new RangeError(`Index ${index} names no vertex.`);
|
|
20206
|
+
view.setUint16(indexAt + index * 2, vertex, true);
|
|
20207
|
+
});
|
|
20208
|
+
let text = "";
|
|
20209
|
+
for (let at = 0; at < bytes.length; at += 32768)
|
|
20210
|
+
text += String.fromCharCode(...bytes.subarray(at, at + 32768));
|
|
20211
|
+
return btoa(text);
|
|
20212
|
+
}
|
|
20213
|
+
function decodeTileflowTreeModel(text, level) {
|
|
20214
|
+
if (typeof text !== "string" || text.length > 2e5) return void 0;
|
|
20215
|
+
let bytes;
|
|
20216
|
+
try {
|
|
20217
|
+
const binary = atob(text);
|
|
20218
|
+
bytes = new Uint8Array(binary.length);
|
|
20219
|
+
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
20220
|
+
} catch {
|
|
20221
|
+
return void 0;
|
|
20222
|
+
}
|
|
20223
|
+
if (bytes.length < headerBytes || magic.some((byte, index) => bytes[index] !== byte))
|
|
20224
|
+
return void 0;
|
|
20225
|
+
const view = new DataView(bytes.buffer);
|
|
20226
|
+
const count = view.getUint16(6, true);
|
|
20227
|
+
const indexCount = view.getUint32(8, true);
|
|
20228
|
+
const proportion = view.getUint16(12, true) / 1e3;
|
|
20229
|
+
const limit = level === "near" ? tileflowTreeModelLimits.nearTriangles : tileflowTreeModelLimits.farTriangles;
|
|
20230
|
+
if (view.getUint16(4, true) !== version || count < 3 || count > tileflowTreeModelLimits.vertices || indexCount < 3 || indexCount % 3 !== 0 || indexCount / 3 > limit || !(proportion >= 0.1 && proportion <= 3) || bytes.length !== headerBytes + count * vertexBytes + indexCount * 2)
|
|
20231
|
+
return void 0;
|
|
20232
|
+
const positions = [];
|
|
20233
|
+
const normals = [];
|
|
20234
|
+
const parts = [];
|
|
20235
|
+
const shades = [];
|
|
20236
|
+
const occlusion = [];
|
|
20237
|
+
for (let index = 0; index < count; index += 1) {
|
|
20238
|
+
const at = headerBytes + index * vertexBytes;
|
|
20239
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
20240
|
+
positions.push(view.getInt16(at + axis * 2, true) / 32767 * positionRange);
|
|
20241
|
+
normals.push(view.getInt8(at + 6 + axis) / 127);
|
|
20242
|
+
}
|
|
20243
|
+
if (bytes[at + 9] >= partCount) return void 0;
|
|
20244
|
+
parts.push(bytes[at + 9]);
|
|
20245
|
+
shades.push(bytes[at + 10] / 255 * 2 - 1);
|
|
20246
|
+
occlusion.push(bytes[at + 11] / 255);
|
|
20247
|
+
}
|
|
20248
|
+
const indices = [];
|
|
20249
|
+
const indexAt = headerBytes + count * vertexBytes;
|
|
20250
|
+
for (let index = 0; index < indexCount; index += 1) {
|
|
20251
|
+
const vertex = view.getUint16(indexAt + index * 2, true);
|
|
20252
|
+
if (vertex >= count) return void 0;
|
|
20253
|
+
indices.push(vertex);
|
|
20254
|
+
}
|
|
20255
|
+
return { proportion, positions, normals, parts, shades, occlusion, indices };
|
|
20256
|
+
}
|
|
20257
|
+
function clamp(value, low, high) {
|
|
20258
|
+
return Number.isFinite(value) ? Math.min(high, Math.max(low, value)) : 0;
|
|
20259
|
+
}
|
|
19577
20260
|
export {
|
|
19578
20261
|
TileflowIconSetError,
|
|
19579
20262
|
TileflowMapResolutionError,
|
|
@@ -19602,6 +20285,7 @@ export {
|
|
|
19602
20285
|
createTileflowLineBackgroundFontStack,
|
|
19603
20286
|
createTileflowSessionController,
|
|
19604
20287
|
createTileflowSessionId,
|
|
20288
|
+
decodeTileflowTreeModel,
|
|
19605
20289
|
defaultTileflowManifestUrl,
|
|
19606
20290
|
defaultTileflowRuntimeView,
|
|
19607
20291
|
defineMap,
|
|
@@ -19610,6 +20294,7 @@ export {
|
|
|
19610
20294
|
diffTileflowIconPackageManifests,
|
|
19611
20295
|
diffTileflowMaps,
|
|
19612
20296
|
disable,
|
|
20297
|
+
encodeTileflowTreeModel,
|
|
19613
20298
|
expr,
|
|
19614
20299
|
field,
|
|
19615
20300
|
fixed,
|
|
@@ -19658,8 +20343,11 @@ export {
|
|
|
19658
20343
|
parseTileflowMap,
|
|
19659
20344
|
parseTileflowRuntimeManifest,
|
|
19660
20345
|
poi,
|
|
20346
|
+
readTileflowBuildings3D,
|
|
19661
20347
|
readTileflowIconLayout,
|
|
20348
|
+
readTileflowStreetLights,
|
|
19662
20349
|
readTileflowSunPreset,
|
|
20350
|
+
readTileflowVegetation3D,
|
|
19663
20351
|
refine,
|
|
19664
20352
|
refineRenderTarget,
|
|
19665
20353
|
remove,
|
|
@@ -19700,6 +20388,7 @@ export {
|
|
|
19700
20388
|
tileflowBathymetryDemSourceId,
|
|
19701
20389
|
tileflowBathymetrySourceId,
|
|
19702
20390
|
tileflowBathymetryV1Schema,
|
|
20391
|
+
tileflowBuildingsMetadataKey,
|
|
19703
20392
|
tileflowCaptureApplicationTargetSchema,
|
|
19704
20393
|
tileflowCaptureBoundsCameraSchema,
|
|
19705
20394
|
tileflowCaptureCameraSchema,
|
|
@@ -19788,6 +20477,7 @@ export {
|
|
|
19788
20477
|
tileflowRuntimeManifestSchema,
|
|
19789
20478
|
tileflowRuntimeManifestVersion,
|
|
19790
20479
|
tileflowSemanticDiffSchemaVersion,
|
|
20480
|
+
tileflowStreetLightsMetadataKey,
|
|
19791
20481
|
tileflowStyleFontFaceLimits,
|
|
19792
20482
|
tileflowStyleFontFacesMetadataKey,
|
|
19793
20483
|
tileflowStyleSunPreset,
|
|
@@ -19798,6 +20488,11 @@ export {
|
|
|
19798
20488
|
tileflowThemeLimits,
|
|
19799
20489
|
tileflowThemeNameSchema,
|
|
19800
20490
|
tileflowThemeTokenCategories,
|
|
20491
|
+
tileflowTreeForms,
|
|
20492
|
+
tileflowTreeModelIdPattern,
|
|
20493
|
+
tileflowTreeModelLimits,
|
|
20494
|
+
tileflowTreeParts,
|
|
20495
|
+
tileflowVegetationMetadataKey,
|
|
19801
20496
|
tileflowWorld,
|
|
19802
20497
|
tileflowWorldGeneration,
|
|
19803
20498
|
tileflowWorldReleaseIdMaximumLength,
|