@tileflow/core 0.1.0-alpha.37 → 0.1.0-alpha.38
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 +1 -1
- package/dist/3d-D9c3i78O.d.ts +1080 -0
- package/dist/3d.d.ts +1 -0
- package/dist/3d.js +12082 -0
- package/dist/browser.d.ts +379 -1329
- package/dist/browser.js +6831 -6338
- package/dist/build.d.ts +2 -2
- package/dist/build.js +333 -138
- package/dist/config-reference.json +668 -547
- package/dist/{icon-composition-C5X3Q9Ya.d.ts → icon-composition-Br4Bd2bY.d.ts} +16 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +295 -76
- package/dist/worker/camera-tile-worker.global.js +1 -0
- package/docs/application-tile-reading.md +5 -2
- package/docs/authoring-model.md +8 -0
- package/docs/buildings-3d.md +80 -12
- package/docs/compiled-style-performance.md +11 -2
- package/docs/data-is-separate-from-design.md +6 -3
- package/docs/public-api-and-browser-subpath.md +4 -0
- package/docs/street-lights.md +5 -1
- package/docs/trees-3d.md +11 -6
- package/package.json +6 -1
- package/dist/worker/buildings-3d-worker.global.js +0 -1
package/dist/index.js
CHANGED
|
@@ -850,8 +850,11 @@ var init_time_of_day = __esm({
|
|
|
850
850
|
});
|
|
851
851
|
|
|
852
852
|
// src/themes/visual-semantics.ts
|
|
853
|
+
function isTileflowVisualColorCollection(property) {
|
|
854
|
+
return property === "colors" || property.endsWith("Colors") || property.endsWith("-colors");
|
|
855
|
+
}
|
|
853
856
|
function classifyTileflowVisualProperty(property, _value) {
|
|
854
|
-
if (property === "color" || property
|
|
857
|
+
if (property === "color" || property.endsWith("Color") || property.endsWith("-color") || isTileflowVisualColorCollection(property)) {
|
|
855
858
|
return "color";
|
|
856
859
|
}
|
|
857
860
|
if (property === "font" || property === "fallbacks" || property.endsWith("-font")) return "font";
|
|
@@ -1218,15 +1221,19 @@ function visitAuditableValue(value, path, category, state, intentRequired = fals
|
|
|
1218
1221
|
}
|
|
1219
1222
|
return;
|
|
1220
1223
|
}
|
|
1224
|
+
const collectionCategory = isTileflowVisualColorCollection(lastPathKey(path)) ? category : void 0;
|
|
1221
1225
|
for (const key of Object.keys(value).sort(compareCodeUnits2)) {
|
|
1222
1226
|
visitAuditableValue(
|
|
1223
1227
|
value[key],
|
|
1224
1228
|
`${path}.${key}`,
|
|
1225
|
-
classifyTileflowVisualProperty(key, value[key]),
|
|
1229
|
+
classifyTileflowVisualProperty(key, value[key]) ?? collectionCategory,
|
|
1226
1230
|
state
|
|
1227
1231
|
);
|
|
1228
1232
|
}
|
|
1229
1233
|
}
|
|
1234
|
+
function lastPathKey(path) {
|
|
1235
|
+
return path.endsWith("]") ? "" : path.slice(path.lastIndexOf(".") + 1);
|
|
1236
|
+
}
|
|
1230
1237
|
function visitAuditableArray(value, path, category, state, forceExpression = false, intentRequired = false) {
|
|
1231
1238
|
const operator = typeof value[0] === "string" ? value[0] : void 0;
|
|
1232
1239
|
const isExpression = forceExpression || isMapLibreExpressionOperator(operator);
|
|
@@ -3655,6 +3662,7 @@ function readTileflowBuildings3D(metadata) {
|
|
|
3655
3662
|
...floodLight ? { floodLight } : {},
|
|
3656
3663
|
...modelLighting ? { modelLighting } : {},
|
|
3657
3664
|
windows: value.windows === true,
|
|
3665
|
+
...readTileflowBuildingsEntrance(value.entrance),
|
|
3658
3666
|
shadows: typeof value.shadows === "boolean" ? value.shadows : defaults4.shadows,
|
|
3659
3667
|
occlusion: typeof value.occlusion === "boolean" ? value.occlusion : defaults4.occlusion,
|
|
3660
3668
|
modelOcclusion: within(value.modelOcclusion, 1, defaults4.modelOcclusion),
|
|
@@ -3663,6 +3671,13 @@ function readTileflowBuildings3D(metadata) {
|
|
|
3663
3671
|
...landmarksOf(value.landmarks)
|
|
3664
3672
|
};
|
|
3665
3673
|
}
|
|
3674
|
+
function readTileflowBuildingsEntrance(value) {
|
|
3675
|
+
if (!isRecord(value)) return {};
|
|
3676
|
+
const band = (entry) => Array.isArray(entry) && entry.length === 2 && entry.every((zoom3) => typeof zoom3 === "number" && zoom3 >= 0 && zoom3 <= 24) && entry[0] < entry[1] ? [entry[0], entry[1]] : void 0;
|
|
3677
|
+
const buildings2 = band(value.buildings);
|
|
3678
|
+
const models = band(value.models);
|
|
3679
|
+
return buildings2 || models ? { entrance: { ...buildings2 ? { buildings: buildings2 } : {}, ...models ? { models } : {} } } : {};
|
|
3680
|
+
}
|
|
3666
3681
|
var modelId = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
3667
3682
|
var tileflowBuildingModelPlacementLimit = 256;
|
|
3668
3683
|
var teamModelPrefix = "tileflow://team-models/";
|
|
@@ -3872,6 +3887,7 @@ function tileflowWorldV1Schema(options = {}) {
|
|
|
3872
3887
|
sidewalk: "sidewalk",
|
|
3873
3888
|
streetFurniture: "street_furniture",
|
|
3874
3889
|
trafficControl: "traffic_control",
|
|
3890
|
+
transportationOutline: "transportation_outline",
|
|
3875
3891
|
...options.layers
|
|
3876
3892
|
},
|
|
3877
3893
|
semantics: { ...options.semantics, parkLayer: "protected-only" }
|
|
@@ -3891,6 +3907,11 @@ function validateTileflowWorldV1Tilejson(tilejson, schema = tileflowWorldV1Schem
|
|
|
3891
3907
|
const roadShield = requireTilejsonLayer(layers2, schema.layers.roadShield, issues);
|
|
3892
3908
|
const canopy = optionalTilejsonLayer(layers2, schema.layers.canopy, issues);
|
|
3893
3909
|
const trafficControl = optionalTilejsonLayer(layers2, schema.layers.trafficControl, issues);
|
|
3910
|
+
const transportationOutline = requireTilejsonLayer(
|
|
3911
|
+
layers2,
|
|
3912
|
+
schema.layers.transportationOutline,
|
|
3913
|
+
issues
|
|
3914
|
+
);
|
|
3894
3915
|
if (bathymetry2) {
|
|
3895
3916
|
if (bathymetry2.minzoom !== 0 || bathymetry2.maxzoom !== 9) {
|
|
3896
3917
|
issues.push(`Tileflow World V1 ${schema.layers.bathymetry} must declare z0-z9.`);
|
|
@@ -4081,6 +4102,27 @@ function validateTileflowWorldV1Tilejson(tilejson, schema = tileflowWorldV1Schem
|
|
|
4081
4102
|
requireTilejsonField(canopy, schema.layers.canopy, field2, ["Number"], issues);
|
|
4082
4103
|
}
|
|
4083
4104
|
}
|
|
4105
|
+
if (transportationOutline) {
|
|
4106
|
+
if (transportationOutline.minzoom !== 13 || transportationOutline.maxzoom !== 15) {
|
|
4107
|
+
issues.push(
|
|
4108
|
+
`Tileflow World V1 ${schema.layers.transportationOutline} must declare native z13-z15.`
|
|
4109
|
+
);
|
|
4110
|
+
}
|
|
4111
|
+
requireTilejsonField(
|
|
4112
|
+
transportationOutline,
|
|
4113
|
+
schema.layers.transportationOutline,
|
|
4114
|
+
schema.fields.class,
|
|
4115
|
+
["String"],
|
|
4116
|
+
issues
|
|
4117
|
+
);
|
|
4118
|
+
requireTilejsonField(
|
|
4119
|
+
transportationOutline,
|
|
4120
|
+
schema.layers.transportationOutline,
|
|
4121
|
+
schema.fields.subclass,
|
|
4122
|
+
["String"],
|
|
4123
|
+
issues
|
|
4124
|
+
);
|
|
4125
|
+
}
|
|
4084
4126
|
return issues;
|
|
4085
4127
|
}
|
|
4086
4128
|
function requireTilejsonLayer(layers2, id2, issues) {
|
|
@@ -5045,7 +5087,7 @@ function applyLineStyle(layer, style) {
|
|
|
5045
5087
|
const layout = { ...asRecord2(layer.layout) };
|
|
5046
5088
|
setPaint(paint, "line-blur", style.blur);
|
|
5047
5089
|
setPaint(paint, "line-color", style.color);
|
|
5048
|
-
setPaint(paint, "line-dasharray", style.dash);
|
|
5090
|
+
if (!isSolidDash(style.dash)) setPaint(paint, "line-dasharray", style.dash);
|
|
5049
5091
|
setPaint(paint, "line-gap-width", style.gapWidth);
|
|
5050
5092
|
setPaint(paint, "line-offset", style.offset);
|
|
5051
5093
|
setPaint(paint, "line-opacity", style.opacity);
|
|
@@ -5289,6 +5331,12 @@ function withoutGovernedAllowOverlap(layout) {
|
|
|
5289
5331
|
}
|
|
5290
5332
|
return result;
|
|
5291
5333
|
}
|
|
5334
|
+
function isSolidDash(value) {
|
|
5335
|
+
if (value === void 0) return false;
|
|
5336
|
+
const dash = toMapLibreStyleValue(value);
|
|
5337
|
+
const array = Array.isArray(dash) && dash[0] === "literal" ? dash[1] : dash;
|
|
5338
|
+
return Array.isArray(array) && array.length === 2 && array[0] === 1 && array[1] === 0;
|
|
5339
|
+
}
|
|
5292
5340
|
function setPaint(paint, property, value) {
|
|
5293
5341
|
if (value !== void 0) paint[property] = toMapLibreStyleValue(value);
|
|
5294
5342
|
}
|
|
@@ -5816,6 +5864,21 @@ function compileBuildings(request, context) {
|
|
|
5816
5864
|
}
|
|
5817
5865
|
return contributions;
|
|
5818
5866
|
}
|
|
5867
|
+
var buildingTargetsByMode = {
|
|
5868
|
+
flat: ["buildings.flat.fill", "buildings.flat.outline"],
|
|
5869
|
+
"3d": ["buildings.extrusion"]
|
|
5870
|
+
};
|
|
5871
|
+
function buildingTargetsOfOtherModes(request) {
|
|
5872
|
+
const activeMode = request?.mode ?? "flat";
|
|
5873
|
+
const targets = /* @__PURE__ */ new Map();
|
|
5874
|
+
for (const [mode, modeTargets] of Object.entries(buildingTargetsByMode)) {
|
|
5875
|
+
if (mode === activeMode) continue;
|
|
5876
|
+
for (const target of modeTargets) {
|
|
5877
|
+
targets.set(target, { activeMode, mode, owner: "buildings" });
|
|
5878
|
+
}
|
|
5879
|
+
}
|
|
5880
|
+
return targets;
|
|
5881
|
+
}
|
|
5819
5882
|
function buildingColorExpression(context) {
|
|
5820
5883
|
const fields2 = context.data.schema.fields;
|
|
5821
5884
|
const colors = context.colors.buildings;
|
|
@@ -5933,29 +5996,23 @@ function isTileflowPathRoadClass(roadClass) {
|
|
|
5933
5996
|
return tileflowPathRoadClasses.includes(roadClass);
|
|
5934
5997
|
}
|
|
5935
5998
|
function tileflowRoadClassFilter(fields2, roadClass) {
|
|
5999
|
+
const classes = tileflowRoadClassValues(roadClass);
|
|
5936
6000
|
if (isTileflowPathRoadClass(roadClass)) {
|
|
5937
6001
|
return [
|
|
5938
6002
|
"all",
|
|
5939
|
-
["match", ["get", fields2.class],
|
|
6003
|
+
["match", ["get", fields2.class], classes, true, false],
|
|
5940
6004
|
["match", ["get", fields2.subclass], pathSubclasses[roadClass], true, false]
|
|
5941
6005
|
];
|
|
5942
6006
|
}
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
...
|
|
5949
|
-
] : roadClass === "service" ? [
|
|
5950
|
-
"service",
|
|
5951
|
-
...compatibleRoadClasses[roadClass] ?? [],
|
|
5952
|
-
...constructionClasses[roadClass]
|
|
5953
|
-
] : [
|
|
5954
|
-
roadClass,
|
|
6007
|
+
return ["match", ["get", fields2.class], classes, true, false];
|
|
6008
|
+
}
|
|
6009
|
+
function tileflowRoadClassValues(roadClass) {
|
|
6010
|
+
if (isTileflowPathRoadClass(roadClass)) return ["path", ...constructionClasses[roadClass]];
|
|
6011
|
+
return [
|
|
6012
|
+
...roadClass === "minor" ? ["minor", "residential", "unclassified"] : [roadClass],
|
|
5955
6013
|
...compatibleRoadClasses[roadClass] ?? [],
|
|
5956
6014
|
...constructionClasses[roadClass]
|
|
5957
6015
|
];
|
|
5958
|
-
return ["match", ["get", fields2.class], classes, true, false];
|
|
5959
6016
|
}
|
|
5960
6017
|
|
|
5961
6018
|
// src/modules/roads/index.ts
|
|
@@ -9689,35 +9746,37 @@ function compileRoundabouts(request, surfaces, context, contributions) {
|
|
|
9689
9746
|
}),
|
|
9690
9747
|
0
|
|
9691
9748
|
) : atZoom(borderWidth, level);
|
|
9692
|
-
const geometry = (casing, width) => expression(
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9749
|
+
const geometry = (casing, width) => expression(
|
|
9750
|
+
bindRepeated([
|
|
9751
|
+
"interpolate",
|
|
9752
|
+
["exponential", 2],
|
|
9753
|
+
["zoom"],
|
|
9754
|
+
...geometryLevels.flatMap((level) => {
|
|
9755
|
+
const centerline = ["*", radiusAt15, 2 ** (level - 15)];
|
|
9756
|
+
const fallback = fallbackWidth === void 0 ? select(
|
|
9757
|
+
widths.map(({ condition, value }) => ({ condition, value: atZoom(value, level) })),
|
|
9758
|
+
0
|
|
9759
|
+
) : atZoom(fallbackWidth, level);
|
|
9760
|
+
const inner = [
|
|
9761
|
+
"case",
|
|
9762
|
+
physical,
|
|
9763
|
+
["*", centerline, ["/", innerMeters, radiusMeters]],
|
|
9764
|
+
["-", centerline, ["/", fallback, 2]]
|
|
9765
|
+
];
|
|
9766
|
+
const fillWidth = [
|
|
9767
|
+
"case",
|
|
9768
|
+
physical,
|
|
9769
|
+
["*", centerline, ["/", ["-", outerMeters, innerMeters], radiusMeters]],
|
|
9770
|
+
fallback
|
|
9771
|
+
];
|
|
9772
|
+
const border = casing ? borderAt(level) : 0;
|
|
9773
|
+
return [
|
|
9774
|
+
level,
|
|
9775
|
+
width ? ["max", 0, ["+", fillWidth, border]] : ["max", 0, ["-", inner, ["/", border, 2]]]
|
|
9776
|
+
];
|
|
9777
|
+
})
|
|
9778
|
+
])
|
|
9779
|
+
);
|
|
9721
9780
|
const phaseStyle = (phase) => ({
|
|
9722
9781
|
color: "rgba(0, 0, 0, 0)",
|
|
9723
9782
|
minZoom: 15,
|
|
@@ -9774,6 +9833,63 @@ function compileRoundabouts(request, surfaces, context, contributions) {
|
|
|
9774
9833
|
});
|
|
9775
9834
|
}
|
|
9776
9835
|
}
|
|
9836
|
+
var bindable = /* @__PURE__ */ new Set([
|
|
9837
|
+
"case",
|
|
9838
|
+
"match",
|
|
9839
|
+
"all",
|
|
9840
|
+
"any",
|
|
9841
|
+
"!",
|
|
9842
|
+
"==",
|
|
9843
|
+
"!=",
|
|
9844
|
+
"<",
|
|
9845
|
+
"<=",
|
|
9846
|
+
">",
|
|
9847
|
+
">=",
|
|
9848
|
+
"has",
|
|
9849
|
+
"get",
|
|
9850
|
+
"to-number",
|
|
9851
|
+
"coalesce",
|
|
9852
|
+
"+",
|
|
9853
|
+
"-",
|
|
9854
|
+
"*",
|
|
9855
|
+
"/",
|
|
9856
|
+
"max",
|
|
9857
|
+
"min"
|
|
9858
|
+
]);
|
|
9859
|
+
function bindRepeated(curve) {
|
|
9860
|
+
let tree = curve;
|
|
9861
|
+
for (let index = 0; index < 2; index += 1) {
|
|
9862
|
+
const json = /* @__PURE__ */ new Map();
|
|
9863
|
+
const found = /* @__PURE__ */ new Map();
|
|
9864
|
+
const visit = (value) => {
|
|
9865
|
+
if (!Array.isArray(value) || value[0] === "literal")
|
|
9866
|
+
return { text: JSON.stringify(value), free: true };
|
|
9867
|
+
const parts = value.map(visit);
|
|
9868
|
+
const text = `[${parts.map((part) => part.text).join(",")}]`;
|
|
9869
|
+
json.set(value, text);
|
|
9870
|
+
const free = value[0] !== "zoom" && value[0] !== "var" && parts.every((part) => part.free);
|
|
9871
|
+
if (free && typeof value[0] === "string" && bindable.has(value[0]))
|
|
9872
|
+
found.set(text, (found.get(text) ?? 0) + 1);
|
|
9873
|
+
return { text, free };
|
|
9874
|
+
};
|
|
9875
|
+
visit(tree);
|
|
9876
|
+
let best;
|
|
9877
|
+
let saving = 256;
|
|
9878
|
+
for (const [text, count] of found) {
|
|
9879
|
+
const saved = (count - 1) * text.length;
|
|
9880
|
+
if (count > 1 && saved > saving) [best, saving] = [text, saved];
|
|
9881
|
+
}
|
|
9882
|
+
if (best === void 0) break;
|
|
9883
|
+
const name = `tileflow_${index}`;
|
|
9884
|
+
const replace = (value) => {
|
|
9885
|
+
if (!Array.isArray(value) || value[0] === "literal") return value;
|
|
9886
|
+
if (json.get(value) === best) return ["var", name];
|
|
9887
|
+
return value.map(replace);
|
|
9888
|
+
};
|
|
9889
|
+
tree = ["let", name, JSON.parse(best), replace(tree)];
|
|
9890
|
+
}
|
|
9891
|
+
return tree;
|
|
9892
|
+
}
|
|
9777
9893
|
function select(values, fallback) {
|
|
9778
9894
|
if (!values.length) return fallback;
|
|
9779
9895
|
const serialized = JSON.stringify(values[0].value);
|
|
@@ -9885,13 +10001,49 @@ function atZoom(value, level) {
|
|
|
9885
10001
|
stops.push({ level: value[index], value: value[index + 1] });
|
|
9886
10002
|
}
|
|
9887
10003
|
const exact = stops.find((stop) => stop.level === level);
|
|
9888
|
-
if (exact) return exact.value;
|
|
10004
|
+
if (exact) return foldConstants(exact.value);
|
|
9889
10005
|
const lower = [...stops].reverse().find((stop) => stop.level < level);
|
|
9890
10006
|
const upper = stops.find((stop) => stop.level > level);
|
|
9891
|
-
if (value[0] === "step") return lower?.value ?? value[2];
|
|
9892
|
-
if (!lower) return upper?.value ?? 0;
|
|
9893
|
-
if (!upper) return lower.value;
|
|
9894
|
-
|
|
10007
|
+
if (value[0] === "step") return foldConstants(lower?.value ?? value[2]);
|
|
10008
|
+
if (!lower) return foldConstants(upper?.value ?? 0);
|
|
10009
|
+
if (!upper) return foldConstants(lower.value);
|
|
10010
|
+
const at = interpolationFactor2(
|
|
10011
|
+
value[1],
|
|
10012
|
+
level - lower.level,
|
|
10013
|
+
upper.level - lower.level
|
|
10014
|
+
);
|
|
10015
|
+
const folded = Number.isFinite(at) ? interpolated(foldConstants(lower.value), foldConstants(upper.value), at) : void 0;
|
|
10016
|
+
return folded ?? ["interpolate", value[1], level, lower.level, lower.value, upper.level, upper.value];
|
|
10017
|
+
}
|
|
10018
|
+
function foldConstants(value) {
|
|
10019
|
+
if (!Array.isArray(value) || value[0] === "literal") return value;
|
|
10020
|
+
const folded = value.map(foldConstants);
|
|
10021
|
+
const [operator, ...operands] = folded;
|
|
10022
|
+
if (!operands.length || !operands.every((operand) => typeof operand === "number")) return folded;
|
|
10023
|
+
const numbers = operands;
|
|
10024
|
+
const result = operator === "*" ? numbers.reduce((product, number) => product * number, 1) : operator === "+" ? numbers.reduce((sum, number) => sum + number, 0) : operator === "-" ? numbers.length === 1 ? -numbers[0] : numbers[0] - numbers[1] : operator === "/" && numbers.length === 2 ? numbers[0] / numbers[1] : operator === "max" ? Math.max(...numbers) : operator === "min" ? Math.min(...numbers) : void 0;
|
|
10025
|
+
return result !== void 0 && Number.isFinite(result) ? result : folded;
|
|
10026
|
+
}
|
|
10027
|
+
function interpolated(lower, upper, at) {
|
|
10028
|
+
if (typeof lower === "number" && typeof upper === "number") return lower + (upper - lower) * at;
|
|
10029
|
+
if (JSON.stringify(lower) === JSON.stringify(upper)) return lower;
|
|
10030
|
+
if (!Array.isArray(lower) || !Array.isArray(upper) || lower.length !== upper.length || lower[0] !== "case" && lower[0] !== "match" || lower[0] !== upper[0])
|
|
10031
|
+
return void 0;
|
|
10032
|
+
const first = lower[0] === "case" ? 1 : 2;
|
|
10033
|
+
const result = lower.slice(0, first);
|
|
10034
|
+
if (JSON.stringify(result) !== JSON.stringify(upper.slice(0, first))) return void 0;
|
|
10035
|
+
for (let index = first; index < lower.length; index += 1) {
|
|
10036
|
+
const output = (index - first) % 2 === 1 || index === lower.length - 1;
|
|
10037
|
+
if (!output) {
|
|
10038
|
+
if (JSON.stringify(lower[index]) !== JSON.stringify(upper[index])) return void 0;
|
|
10039
|
+
result.push(lower[index]);
|
|
10040
|
+
continue;
|
|
10041
|
+
}
|
|
10042
|
+
const value = interpolated(lower[index], upper[index], at);
|
|
10043
|
+
if (value === void 0) return void 0;
|
|
10044
|
+
result.push(value);
|
|
10045
|
+
}
|
|
10046
|
+
return result;
|
|
9895
10047
|
}
|
|
9896
10048
|
|
|
9897
10049
|
// src/modules/roads/compiler.ts
|
|
@@ -9962,6 +10114,10 @@ function compileRoads(request, context) {
|
|
|
9962
10114
|
request?.classes?.[roadClass]
|
|
9963
10115
|
);
|
|
9964
10116
|
const treatments = resolveRoadTreatments(request, schema.fields, roadClass);
|
|
10117
|
+
const drawn = {
|
|
10118
|
+
field: schema.fields.class,
|
|
10119
|
+
classes: new Set(tileflowRoadClassValues(roadClass))
|
|
10120
|
+
};
|
|
9965
10121
|
const roundaboutSurface = { roadClass };
|
|
9966
10122
|
roundaboutSurfaces.push(roundaboutSurface);
|
|
9967
10123
|
for (const structure of ["tunnel", "surface", "bridge"]) {
|
|
@@ -9984,7 +10140,8 @@ function compileRoads(request, context) {
|
|
|
9984
10140
|
treatments,
|
|
9985
10141
|
structure,
|
|
9986
10142
|
phase,
|
|
9987
|
-
phaseDefaults.color
|
|
10143
|
+
phaseDefaults.color,
|
|
10144
|
+
drawn
|
|
9988
10145
|
);
|
|
9989
10146
|
const contribution = {
|
|
9990
10147
|
family: roadLinePhysicalFamily(roadClass, structure, phase),
|
|
@@ -10047,7 +10204,8 @@ function compileRoads(request, context) {
|
|
|
10047
10204
|
treatments,
|
|
10048
10205
|
structure,
|
|
10049
10206
|
"fill",
|
|
10050
|
-
roadColor(context, roadClass)
|
|
10207
|
+
roadColor(context, roadClass),
|
|
10208
|
+
drawn
|
|
10051
10209
|
);
|
|
10052
10210
|
const size = hatch.size === void 0 ? scaleStyleValue(treatedFill.width ?? 1, 0.68) : toMapLibreStyleValue(hatch.size);
|
|
10053
10211
|
const minZoom = hatch.minZoom ?? treatedFill.minZoom;
|
|
@@ -10168,31 +10326,24 @@ function compileRoads(request, context) {
|
|
|
10168
10326
|
const areaTargets = [
|
|
10169
10327
|
{
|
|
10170
10328
|
id: "tileflow-road-area",
|
|
10171
|
-
|
|
10329
|
+
kind: void 0,
|
|
10172
10330
|
name: "road",
|
|
10173
10331
|
style: areaStyles.road
|
|
10174
10332
|
},
|
|
10175
10333
|
{
|
|
10176
10334
|
id: "tileflow-road-pedestrian-area",
|
|
10177
|
-
|
|
10178
|
-
"all",
|
|
10179
|
-
["==", ["geometry-type"], "Polygon"],
|
|
10180
|
-
tileflowRoadClassFilter(schema.fields, "pedestrian")
|
|
10181
|
-
],
|
|
10335
|
+
kind: tileflowRoadClassFilter(schema.fields, "pedestrian"),
|
|
10182
10336
|
name: "pedestrian",
|
|
10183
10337
|
style: areaStyles.pedestrian
|
|
10184
10338
|
},
|
|
10185
10339
|
{
|
|
10186
10340
|
id: "tileflow-road-pier-area",
|
|
10187
|
-
|
|
10188
|
-
"all",
|
|
10189
|
-
["==", ["geometry-type"], "Polygon"],
|
|
10190
|
-
["==", ["get", schema.fields.class], "pier"]
|
|
10191
|
-
],
|
|
10341
|
+
kind: ["==", ["get", schema.fields.class], "pier"],
|
|
10192
10342
|
name: "pier",
|
|
10193
10343
|
style: areaStyles.pier
|
|
10194
10344
|
}
|
|
10195
10345
|
];
|
|
10346
|
+
const polygons2 = ["==", ["geometry-type"], "Polygon"];
|
|
10196
10347
|
let areaOrder = 900;
|
|
10197
10348
|
for (const target of areaTargets) {
|
|
10198
10349
|
if (!target.style) continue;
|
|
@@ -10202,13 +10353,19 @@ function compileRoads(request, context) {
|
|
|
10202
10353
|
type: "fill",
|
|
10203
10354
|
source,
|
|
10204
10355
|
"source-layer": schema.layers.road,
|
|
10205
|
-
filter: target.
|
|
10356
|
+
filter: target.kind ? ["all", polygons2, target.kind] : polygons2
|
|
10206
10357
|
},
|
|
10207
10358
|
target.style
|
|
10208
10359
|
)) {
|
|
10360
|
+
const { filter: _polygonFilter, ...unfiltered } = area.layer;
|
|
10361
|
+
const outline = area.phase === "outline" && schema.layers.transportationOutline ? {
|
|
10362
|
+
...unfiltered,
|
|
10363
|
+
"source-layer": schema.layers.transportationOutline,
|
|
10364
|
+
...target.kind ? { filter: target.kind } : {}
|
|
10365
|
+
} : area.layer;
|
|
10209
10366
|
contributions.push({
|
|
10210
10367
|
kind: "layer",
|
|
10211
|
-
layer:
|
|
10368
|
+
layer: outline,
|
|
10212
10369
|
localOrder: areaOrder++,
|
|
10213
10370
|
owner: "roads",
|
|
10214
10371
|
slot: "transport-areas",
|
|
@@ -10485,9 +10642,10 @@ function resolveRoadTreatments(request, fields2, roadClass) {
|
|
|
10485
10642
|
add2(request?.modifiers?.unpaved, ["==", ["get", fields2.surface], "unpaved"]);
|
|
10486
10643
|
add2(request?.modifiers?.indoor, flagFilter(fields2.indoor));
|
|
10487
10644
|
add2(request?.modifiers?.official, flagFilter(fields2.official));
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10645
|
+
if (isTileflowPathRoadClass(roadClass) || roadClass === "track")
|
|
10646
|
+
for (const [scale, style] of Object.entries(request?.mountainBike ?? {})) {
|
|
10647
|
+
add2(style, ["==", ["to-string", ["get", fields2.mtbScale]], scale]);
|
|
10648
|
+
}
|
|
10491
10649
|
if (roadClass === "service") {
|
|
10492
10650
|
for (const [serviceType, value] of Object.entries(serviceTypeValues)) {
|
|
10493
10651
|
add2(request?.serviceTypes?.[serviceType], [
|
|
@@ -10499,7 +10657,7 @@ function resolveRoadTreatments(request, fields2, roadClass) {
|
|
|
10499
10657
|
}
|
|
10500
10658
|
return entries;
|
|
10501
10659
|
}
|
|
10502
|
-
function applyRoadTreatments(base, treatments, structure, phase, fallbackColor) {
|
|
10660
|
+
function applyRoadTreatments(base, treatments, structure, phase, fallbackColor, drawn) {
|
|
10503
10661
|
const result = { ...base };
|
|
10504
10662
|
const paintProperties = [
|
|
10505
10663
|
"blur",
|
|
@@ -10516,12 +10674,12 @@ function applyRoadTreatments(base, treatments, structure, phase, fallbackColor)
|
|
|
10516
10674
|
return value === void 0 ? [] : [
|
|
10517
10675
|
{
|
|
10518
10676
|
condition,
|
|
10519
|
-
resolve: () => expressionOutput(toMapLibreStyleValue(value))
|
|
10677
|
+
resolve: () => expressionOutput(withinClasses(toMapLibreStyleValue(value), drawn))
|
|
10520
10678
|
}
|
|
10521
10679
|
];
|
|
10522
10680
|
});
|
|
10523
10681
|
if (branches.length > 0) {
|
|
10524
|
-
if (property === "dash" && isSolidRoadDash(result[property] ?? treatmentPaintDefaults.dash) && branches.every(({ resolve }) => isSolidRoadDash(resolve()))) {
|
|
10682
|
+
if (property === "dash" && isSolidRoadDash(withinClasses(result[property] ?? treatmentPaintDefaults.dash, drawn)) && branches.every(({ resolve }) => isSolidRoadDash(resolve()))) {
|
|
10525
10683
|
delete result[property];
|
|
10526
10684
|
continue;
|
|
10527
10685
|
}
|
|
@@ -10551,6 +10709,49 @@ function applyRoadTreatments(base, treatments, structure, phase, fallbackColor)
|
|
|
10551
10709
|
}
|
|
10552
10710
|
return result;
|
|
10553
10711
|
}
|
|
10712
|
+
function withinClasses(value, drawn) {
|
|
10713
|
+
const decided = (condition) => {
|
|
10714
|
+
if (!Array.isArray(condition)) return typeof condition === "boolean" ? condition : void 0;
|
|
10715
|
+
const [operator, ...operands] = condition;
|
|
10716
|
+
const isClass = (operand) => Array.isArray(operand) && operand.length === 2 && operand[0] === "get" && (operand[1] === drawn.field || typeof operand[1] === "object" && operand[1] !== null && operand[1].kind === "tileflow-data-field" && operand[1].name === "class");
|
|
10717
|
+
const among = (labels2) => {
|
|
10718
|
+
const hits = [...drawn.classes].filter((value2) => labels2.includes(value2)).length;
|
|
10719
|
+
return hits === 0 ? false : hits === drawn.classes.size ? true : void 0;
|
|
10720
|
+
};
|
|
10721
|
+
if ((operator === "==" || operator === "!=") && operands.length === 2) {
|
|
10722
|
+
const label = isClass(operands[0]) ? operands[1] : isClass(operands[1]) ? operands[0] : null;
|
|
10723
|
+
if (typeof label !== "string") return void 0;
|
|
10724
|
+
const equal = among([label]);
|
|
10725
|
+
return equal === void 0 ? void 0 : operator === "==" ? equal : !equal;
|
|
10726
|
+
}
|
|
10727
|
+
if (operator === "match" && operands.length === 4 && isClass(operands[0]) && typeof operands[2] === "boolean" && typeof operands[3] === "boolean") {
|
|
10728
|
+
const labels2 = Array.isArray(operands[1]) ? operands[1] : [operands[1]];
|
|
10729
|
+
const matched = among(labels2);
|
|
10730
|
+
return matched === void 0 ? void 0 : matched ? operands[2] : operands[3];
|
|
10731
|
+
}
|
|
10732
|
+
if (operator === "!" && operands.length === 1) {
|
|
10733
|
+
const inner = decided(operands[0]);
|
|
10734
|
+
return inner === void 0 ? void 0 : !inner;
|
|
10735
|
+
}
|
|
10736
|
+
if (operator === "all" || operator === "any") {
|
|
10737
|
+
const results = operands.map(decided);
|
|
10738
|
+
if (results.includes(operator === "all" ? false : true)) return operator !== "all";
|
|
10739
|
+
return results.every((result) => result !== void 0) ? operator === "all" : void 0;
|
|
10740
|
+
}
|
|
10741
|
+
return void 0;
|
|
10742
|
+
};
|
|
10743
|
+
if (!Array.isArray(value) || value[0] !== "case") return value;
|
|
10744
|
+
const branches = [];
|
|
10745
|
+
for (let index = 1; index < value.length - 1; index += 2) {
|
|
10746
|
+
const holds = decided(value[index]);
|
|
10747
|
+
if (holds === false) continue;
|
|
10748
|
+
const output = withinClasses(value[index + 1], drawn);
|
|
10749
|
+
if (holds === true) return branches.length ? ["case", ...branches, output] : output;
|
|
10750
|
+
branches.push(value[index], output);
|
|
10751
|
+
}
|
|
10752
|
+
const fallback = withinClasses(value.at(-1), drawn);
|
|
10753
|
+
return branches.length ? ["case", ...branches, fallback] : fallback;
|
|
10754
|
+
}
|
|
10554
10755
|
function isSolidRoadDash(value) {
|
|
10555
10756
|
const output = expressionOutput(value);
|
|
10556
10757
|
const dash = Array.isArray(output) && output[0] === "literal" ? output[1] : output;
|
|
@@ -14286,7 +14487,7 @@ function compileRenderSelector(selector, data) {
|
|
|
14286
14487
|
assertRenderSelectorConstraints(selector);
|
|
14287
14488
|
return lowerSelector(selector, data);
|
|
14288
14489
|
}
|
|
14289
|
-
function applyCompiledRenderStacks(input, operations2) {
|
|
14490
|
+
function applyCompiledRenderStacks(input, operations2, targetsOfOtherModes = /* @__PURE__ */ new Map()) {
|
|
14290
14491
|
let layers2 = input.map(cloneJson21);
|
|
14291
14492
|
const passes = operations2.filter(
|
|
14292
14493
|
(operation) => operation.kind === "layer"
|
|
@@ -14317,9 +14518,10 @@ function applyCompiledRenderStacks(input, operations2) {
|
|
|
14317
14518
|
for (const refinement of activeRefinements) {
|
|
14318
14519
|
const index = findTargetIndex(layers2, refinement.target);
|
|
14319
14520
|
if (index < 0 && !passTargets.has(refinement.target)) {
|
|
14521
|
+
const other = targetsOfOtherModes.get(refinement.target);
|
|
14320
14522
|
throw renderStackError(
|
|
14321
14523
|
"unknown-refinement-target",
|
|
14322
|
-
`Render refinement targets unknown semantic contribution: ${refinement.target}.`
|
|
14524
|
+
other === void 0 ? `Render refinement targets unknown semantic contribution: ${refinement.target}.` : `Render refinement targets ${refinement.target}, ${describeOtherMode(other)}`
|
|
14323
14525
|
);
|
|
14324
14526
|
}
|
|
14325
14527
|
if (refinement.placement !== void 0 && placementAnchor(refinement.placement) === refinement.target) {
|
|
@@ -14341,9 +14543,10 @@ function applyCompiledRenderStacks(input, operations2) {
|
|
|
14341
14543
|
for (const operation of pending) {
|
|
14342
14544
|
const anchor = placementAnchor(operation.placement);
|
|
14343
14545
|
if (anchor !== void 0 && !knownTargets.has(anchor)) {
|
|
14546
|
+
const other = targetsOfOtherModes.get(anchor);
|
|
14344
14547
|
throw renderStackError(
|
|
14345
14548
|
"unknown-or-circular-anchor",
|
|
14346
|
-
`${operation.target} is placed beside unknown semantic target ${anchor}.`
|
|
14549
|
+
other === void 0 ? `${operation.target} is placed beside unknown semantic target ${anchor}.` : `${operation.target} is placed beside ${anchor}, ${describeOtherMode(other)}`
|
|
14347
14550
|
);
|
|
14348
14551
|
}
|
|
14349
14552
|
}
|
|
@@ -15016,6 +15219,9 @@ function assertOnlyKeys(input, allowed, description) {
|
|
|
15016
15219
|
);
|
|
15017
15220
|
}
|
|
15018
15221
|
}
|
|
15222
|
+
function describeOtherMode({ activeMode, mode, owner }) {
|
|
15223
|
+
return `which ${owner} draws only in mode '${mode}'; this map draws ${owner} in mode '${activeMode}'. Place the operation beside a target drawn in mode '${activeMode}' or at a band edge, or remove it; refine({mode: '${activeMode}', renderStack: reset()}) removes an inherited ${owner} render stack.`;
|
|
15224
|
+
}
|
|
15019
15225
|
function renderStackError(code, message) {
|
|
15020
15226
|
return Object.assign(new Error(message), { code, name: "TileflowRenderStackError" });
|
|
15021
15227
|
}
|
|
@@ -16106,6 +16312,7 @@ function boundedThemeNumberSchema(min, max) {
|
|
|
16106
16312
|
}).strict()
|
|
16107
16313
|
]);
|
|
16108
16314
|
}
|
|
16315
|
+
var entranceBandSchema = z7.tuple([z7.number().finite().min(0).max(24), z7.number().finite().min(0).max(24)]).refine(([from, to]) => from < to, "A band starts at a lower zoom than it ends.");
|
|
16109
16316
|
var modelRoleLightingSchema = z7.object({
|
|
16110
16317
|
emissiveStrength: boundedThemeNumberSchema(0, 5).optional(),
|
|
16111
16318
|
emissiveVariation: boundedThemeNumberSchema(0, 1).optional(),
|
|
@@ -16161,6 +16368,7 @@ var buildingsModuleSchema = z7.object({
|
|
|
16161
16368
|
lamp: modelRoleLightingSchema.optional(),
|
|
16162
16369
|
logo: modelRoleLightingSchema.optional()
|
|
16163
16370
|
}).strict().optional(),
|
|
16371
|
+
entrance: z7.object({ buildings: entranceBandSchema.optional(), models: entranceBandSchema.optional() }).strict().optional(),
|
|
16164
16372
|
occlusion: z7.boolean().optional(),
|
|
16165
16373
|
modelOcclusion: boundedThemeNumberSchema(0, 1).optional(),
|
|
16166
16374
|
shadows: z7.boolean().optional(),
|
|
@@ -16540,6 +16748,7 @@ var layerBindingsSchema = z7.object({
|
|
|
16540
16748
|
streetFurniture: z7.string().trim().min(1).optional(),
|
|
16541
16749
|
trafficControl: z7.string().trim().min(1).optional(),
|
|
16542
16750
|
tree: z7.string().trim().min(1).optional(),
|
|
16751
|
+
transportationOutline: z7.string().trim().min(1).optional(),
|
|
16543
16752
|
water: z7.string().trim().min(1),
|
|
16544
16753
|
waterName: z7.string().trim().min(1),
|
|
16545
16754
|
waterway: z7.string().trim().min(1)
|
|
@@ -18415,6 +18624,8 @@ function mergeRoadLineGroup(key, layers2) {
|
|
|
18415
18624
|
const paintKeys = new Set(layers2.flatMap((layer) => Object.keys(layer.style.appearance ?? {})));
|
|
18416
18625
|
for (const key2 of paintKeys) {
|
|
18417
18626
|
const values = layers2.map((layer) => layer.style.appearance?.[key2]);
|
|
18627
|
+
if (key2 === "line-dasharray" && values.every((value) => isSolidDash(value ?? linePaintDefaults[key2])))
|
|
18628
|
+
continue;
|
|
18418
18629
|
const combined = combineConditionalValues(
|
|
18419
18630
|
values.map((value, index) => ({
|
|
18420
18631
|
condition: conditions[index],
|
|
@@ -19208,6 +19419,7 @@ function tileflowBuildings3DDesignOf(module, context, layers2, buildingModels, t
|
|
|
19208
19419
|
)
|
|
19209
19420
|
} : {},
|
|
19210
19421
|
windows: style.windows === true,
|
|
19422
|
+
...readTileflowBuildingsEntrance(style.entrance),
|
|
19211
19423
|
shadows: typeof style.shadows === "boolean" ? style.shadows : defaults4.shadows,
|
|
19212
19424
|
occlusion: typeof style.occlusion === "boolean" ? style.occlusion : defaults4.occlusion,
|
|
19213
19425
|
modelOcclusion: number(style.modelOcclusion, defaults4.modelOcclusion),
|
|
@@ -19491,7 +19703,11 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
19491
19703
|
const requestedRenderOperations = domainIR.renderOperations;
|
|
19492
19704
|
const stackedFamilies = runCompilationPhase(
|
|
19493
19705
|
"render-stack",
|
|
19494
|
-
() => applyCompiledRenderStacks(
|
|
19706
|
+
() => applyCompiledRenderStacks(
|
|
19707
|
+
assembledFamilies,
|
|
19708
|
+
requestedRenderOperations,
|
|
19709
|
+
buildingTargetsOfOtherModes(modules.buildings)
|
|
19710
|
+
)
|
|
19495
19711
|
);
|
|
19496
19712
|
const plannedFamilies = runCompilationPhase(
|
|
19497
19713
|
"physical-planner",
|
|
@@ -20296,6 +20512,9 @@ function applyModuleOperation(resolved, moduleName, operation, mapId, path) {
|
|
|
20296
20512
|
assertNoReset(patch, mapId, `${path}/patches/${index}`, true);
|
|
20297
20513
|
next = applyModulePatch(next, patch, mapId, `${path}/patches/${index}`);
|
|
20298
20514
|
}
|
|
20515
|
+
if (isPlainRecord4(next.renderStack) && Object.keys(next.renderStack).length === 0) {
|
|
20516
|
+
delete next.renderStack;
|
|
20517
|
+
}
|
|
20299
20518
|
assertModuleOwner(next, moduleName, mapId, path);
|
|
20300
20519
|
resolved[moduleName] = next;
|
|
20301
20520
|
return;
|