@tileflow/core 0.1.0-alpha.43 → 0.1.0-alpha.45
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 +103 -56
- package/THIRD_PARTY_NOTICES.md +2 -2
- package/dist/{3d-CW5Ls0An.d.ts → 3d-EHN80Dhw.d.ts} +16 -1
- package/dist/3d.d.ts +1 -1
- package/dist/3d.js +436 -180
- package/dist/browser.d.ts +180 -9
- package/dist/browser.js +4877 -1372
- package/dist/build.d.ts +15 -5
- package/dist/build.js +1161 -167
- package/dist/config-reference.json +93 -44
- package/dist/{icon-composition-Bbw9umUA.d.ts → icon-composition-Dph-24oC.d.ts} +11 -2
- package/dist/index.d.ts +7 -7
- package/dist/index.js +1020 -486
- package/dist/{manifest-types-CwjHd4qc.d.ts → manifest-types-GeYn0SQM.d.ts} +102 -2
- package/dist/manifest.d.ts +2 -2
- package/dist/manifest.js +13 -1
- package/dist/native-profile.d.ts +4 -0
- package/dist/native.d.ts +8 -1
- package/dist/native.js +66 -7
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +3079 -27
- package/dist/worker/camera-tile-worker.global.js +2 -2
- package/package.json +2 -2
package/dist/3d.js
CHANGED
|
@@ -331,6 +331,57 @@ function createBuildingFlatLayers(map) {
|
|
|
331
331
|
};
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
// src/building-layer-ids.ts
|
|
335
|
+
var tileflowNativeBuildingsLayerId = "tileflow-buildings-native-extrusion";
|
|
336
|
+
var tileflowBuildingsSceneLayerId = "tileflow-buildings-scene-3d";
|
|
337
|
+
|
|
338
|
+
// src/building-native-layers-browser.ts
|
|
339
|
+
function createBuildingNativeLayers(map) {
|
|
340
|
+
let saved;
|
|
341
|
+
let updating = false;
|
|
342
|
+
function restore() {
|
|
343
|
+
if (updating || !saved || !map.getLayoutProperty || !map.setLayoutProperty) return;
|
|
344
|
+
updating = true;
|
|
345
|
+
try {
|
|
346
|
+
if (map.getLayer(tileflowNativeBuildingsLayerId) === saved.layer && map.getLayoutProperty(tileflowNativeBuildingsLayerId, "visibility") !== saved.visibility)
|
|
347
|
+
map.setLayoutProperty(tileflowNativeBuildingsLayerId, "visibility", saved.visibility);
|
|
348
|
+
saved = void 0;
|
|
349
|
+
} finally {
|
|
350
|
+
updating = false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return {
|
|
354
|
+
/** Undefined gives control back to the compiled style. */
|
|
355
|
+
setVisible(visible) {
|
|
356
|
+
if (visible === void 0) return restore();
|
|
357
|
+
if (updating || !map.getLayoutProperty || !map.setLayoutProperty) return;
|
|
358
|
+
const layer = map.getLayer(tileflowNativeBuildingsLayerId);
|
|
359
|
+
if (!layer) {
|
|
360
|
+
saved = void 0;
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
updating = true;
|
|
364
|
+
try {
|
|
365
|
+
if (!saved || saved.layer !== layer)
|
|
366
|
+
saved = {
|
|
367
|
+
layer,
|
|
368
|
+
visibility: map.getLayoutProperty(tileflowNativeBuildingsLayerId, "visibility") ?? "visible"
|
|
369
|
+
};
|
|
370
|
+
const next = visible ? "visible" : "none";
|
|
371
|
+
if (map.getLayoutProperty(tileflowNativeBuildingsLayerId, "visibility") !== next)
|
|
372
|
+
map.setLayoutProperty(tileflowNativeBuildingsLayerId, "visibility", next);
|
|
373
|
+
} finally {
|
|
374
|
+
updating = false;
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
restore,
|
|
378
|
+
/** Removing a map must not write to its destroyed style. */
|
|
379
|
+
forget() {
|
|
380
|
+
saved = void 0;
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
334
385
|
// src/models-3d-model.ts
|
|
335
386
|
var tileflowModelParts = Object.freeze({
|
|
336
387
|
surface: 0,
|
|
@@ -678,8 +729,9 @@ function readTileflowBuildings3D(metadata) {
|
|
|
678
729
|
};
|
|
679
730
|
}
|
|
680
731
|
function readTileflowBuildingsEntrance(value) {
|
|
732
|
+
if (value === false) return { entrance: false };
|
|
681
733
|
if (!isRecord(value)) return {};
|
|
682
|
-
const band = (entry) => Array.isArray(entry) && entry.length === 2 && entry.every((zoom) => typeof zoom === "number" && zoom >= 0 && zoom <= 24) && entry[0]
|
|
734
|
+
const band = (entry) => Array.isArray(entry) && entry.length === 2 && entry.every((zoom) => typeof zoom === "number" && zoom >= 0 && zoom <= 24) && entry[0] <= entry[1] ? [entry[0], entry[1]] : void 0;
|
|
683
735
|
const buildings = band(value.buildings);
|
|
684
736
|
const models = band(value.models);
|
|
685
737
|
return buildings || models ? { entrance: { ...buildings ? { buildings } : {}, ...models ? { models } : {} } } : {};
|
|
@@ -724,6 +776,116 @@ function isRecord(value) {
|
|
|
724
776
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
725
777
|
}
|
|
726
778
|
|
|
779
|
+
// src/sun.ts
|
|
780
|
+
var tileflowSunMetadataKey = "tileflow:sun";
|
|
781
|
+
var tileflowDefaultSunPreset = Object.freeze({
|
|
782
|
+
azimuth: 210,
|
|
783
|
+
altitude: 60,
|
|
784
|
+
color: "#ffffff",
|
|
785
|
+
intensity: 0.2,
|
|
786
|
+
shadowIntensity: 1,
|
|
787
|
+
ambient: Object.freeze({ color: "#ffffff", intensity: 0.8 })
|
|
788
|
+
});
|
|
789
|
+
var degrees = Math.PI / 180;
|
|
790
|
+
function normalizeTileflowAzimuth(azimuth) {
|
|
791
|
+
const turned = azimuth % 360;
|
|
792
|
+
return turned < 0 ? turned + 360 : turned === 0 ? 0 : turned;
|
|
793
|
+
}
|
|
794
|
+
function tileflowSunDirection(azimuth, altitude) {
|
|
795
|
+
const a = azimuth * degrees;
|
|
796
|
+
const h2 = altitude * degrees;
|
|
797
|
+
return Object.freeze([
|
|
798
|
+
Math.sin(a) * Math.cos(h2),
|
|
799
|
+
Math.cos(a) * Math.cos(h2),
|
|
800
|
+
Math.sin(h2)
|
|
801
|
+
]);
|
|
802
|
+
}
|
|
803
|
+
function resolveTileflowSun(preset, direction = preset, source = "theme") {
|
|
804
|
+
const azimuth = normalizeTileflowAzimuth(direction.azimuth);
|
|
805
|
+
const altitude = Math.min(90, Math.max(-90, direction.altitude));
|
|
806
|
+
const horizon = smoothstep(-0.5, 3, altitude);
|
|
807
|
+
const intensity = clamp01(preset.intensity) * horizon;
|
|
808
|
+
const rgb = rgbOf(preset.color);
|
|
809
|
+
const ambientRgb = rgbOf(preset.ambient.color);
|
|
810
|
+
const ambientIntensity = clamp01(preset.ambient.intensity);
|
|
811
|
+
const brightness = clamp01(
|
|
812
|
+
(luminance(ambientRgb) * ambientIntensity + luminance(rgb) * intensity * Math.max(0, Math.sin(altitude * degrees))) / 2
|
|
813
|
+
);
|
|
814
|
+
return Object.freeze({
|
|
815
|
+
azimuth,
|
|
816
|
+
altitude,
|
|
817
|
+
direction: tileflowSunDirection(azimuth, altitude),
|
|
818
|
+
color: preset.color,
|
|
819
|
+
rgb,
|
|
820
|
+
intensity,
|
|
821
|
+
shadowIntensity: clamp01(preset.shadowIntensity),
|
|
822
|
+
ambient: Object.freeze({
|
|
823
|
+
color: preset.ambient.color,
|
|
824
|
+
rgb: ambientRgb,
|
|
825
|
+
intensity: ambientIntensity
|
|
826
|
+
}),
|
|
827
|
+
brightness: Number(brightness.toFixed(6)),
|
|
828
|
+
source
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
function readTileflowSunPreset(metadata) {
|
|
832
|
+
if (!isRecord2(metadata)) return void 0;
|
|
833
|
+
const value = metadata[tileflowSunMetadataKey];
|
|
834
|
+
if (!isRecord2(value) || value.version !== 1 || !isRecord2(value.ambient)) return void 0;
|
|
835
|
+
const { azimuth, altitude, color, intensity, shadowIntensity } = value;
|
|
836
|
+
const ambient = value.ambient;
|
|
837
|
+
if (!isFiniteNumber(azimuth) || !isFiniteNumber(altitude) || !isUnit(intensity) || !isUnit(shadowIntensity) || !isUnit(ambient.intensity) || !isColour(color) || !isColour(ambient.color))
|
|
838
|
+
return void 0;
|
|
839
|
+
return Object.freeze({
|
|
840
|
+
azimuth: normalizeTileflowAzimuth(azimuth),
|
|
841
|
+
altitude: Math.min(90, Math.max(-90, altitude)),
|
|
842
|
+
color,
|
|
843
|
+
intensity,
|
|
844
|
+
shadowIntensity,
|
|
845
|
+
ambient: Object.freeze({ color: ambient.color, intensity: ambient.intensity })
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
function tileflowStyleSunPreset(style) {
|
|
849
|
+
const published = readTileflowSunPreset(style?.metadata);
|
|
850
|
+
if (published) return published;
|
|
851
|
+
const light = isRecord2(style?.light) ? style.light : void 0;
|
|
852
|
+
const position = light?.position;
|
|
853
|
+
if (!position) return tileflowDefaultSunPreset;
|
|
854
|
+
return Object.freeze({
|
|
855
|
+
...tileflowDefaultSunPreset,
|
|
856
|
+
azimuth: normalizeTileflowAzimuth(position[1]),
|
|
857
|
+
altitude: Math.min(90, Math.max(-90, 90 - position[2])),
|
|
858
|
+
...typeof light.color === "string" && isColour(light.color) ? { color: light.color } : {}
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
function rgbOf(colour) {
|
|
862
|
+
const channels = tileflowColourChannels(colour) ?? [1, 1, 1, 1];
|
|
863
|
+
return Object.freeze([channels[0], channels[1], channels[2]]);
|
|
864
|
+
}
|
|
865
|
+
function luminance([r, g, b2]) {
|
|
866
|
+
const linear = (value) => value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
867
|
+
return 0.2126 * linear(r) + 0.7152 * linear(g) + 0.0722 * linear(b2);
|
|
868
|
+
}
|
|
869
|
+
function smoothstep(from, to, value) {
|
|
870
|
+
const t = clamp01((value - from) / (to - from));
|
|
871
|
+
return t * t * (3 - 2 * t);
|
|
872
|
+
}
|
|
873
|
+
function clamp01(value) {
|
|
874
|
+
return Math.min(1, Math.max(0, Number.isFinite(value) ? value : 0));
|
|
875
|
+
}
|
|
876
|
+
function isRecord2(value) {
|
|
877
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
878
|
+
}
|
|
879
|
+
function isFiniteNumber(value) {
|
|
880
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
881
|
+
}
|
|
882
|
+
function isUnit(value) {
|
|
883
|
+
return isFiniteNumber(value) && value >= 0 && value <= 1;
|
|
884
|
+
}
|
|
885
|
+
function isColour(value) {
|
|
886
|
+
return typeof value === "string" && tileflowColourChannels(value) !== null;
|
|
887
|
+
}
|
|
888
|
+
|
|
727
889
|
// src/theme-blend.ts
|
|
728
890
|
function tileflowColourChannels(colour) {
|
|
729
891
|
const rgba = parseColour(colour);
|
|
@@ -2553,11 +2715,11 @@ var growth = `
|
|
|
2553
2715
|
uniform float u_scale;
|
|
2554
2716
|
uniform vec2 u_offset; // this tile's corner from the scene's origin, in tile units
|
|
2555
2717
|
uniform float u_metres; // metres per tile unit
|
|
2556
|
-
//
|
|
2557
|
-
//
|
|
2558
|
-
// ground, in this tile's axes.
|
|
2718
|
+
// In this tile's units: origin and start/end of the fade along the view, or centre and radii of the
|
|
2719
|
+
// fallback covered disc. The direction is along the ground in this tile's axes.
|
|
2559
2720
|
uniform vec4 u_ring;
|
|
2560
2721
|
uniform vec2 u_ring_ahead;
|
|
2722
|
+
uniform bool u_ring_directional;
|
|
2561
2723
|
|
|
2562
2724
|
float progressOf() {
|
|
2563
2725
|
return clamp(u_scale * 1.25 - a_wave.x * 0.25, 0.0, 1.0);
|
|
@@ -2569,9 +2731,11 @@ float elevationOf(float own, float top, float p) {
|
|
|
2569
2731
|
}
|
|
2570
2732
|
|
|
2571
2733
|
// Buildings sink into the ground over the last stretch of the city's reach, so it ends without an
|
|
2572
|
-
// edge of cut-off blocks.
|
|
2573
|
-
//
|
|
2734
|
+
// edge of cut-off blocks. The view-aligned fade leaves the entire near width standing; the legacy
|
|
2735
|
+
// disc fallback also exempts its near side.
|
|
2574
2736
|
float reachOf(vec2 position) {
|
|
2737
|
+
if (u_ring_directional)
|
|
2738
|
+
return 1.0 - smoothstep(u_ring.z, u_ring.w, dot(position - u_ring.xy, u_ring_ahead));
|
|
2575
2739
|
if (u_ring.w <= 0.0) return 1.0;
|
|
2576
2740
|
vec2 from = position - u_ring.xy;
|
|
2577
2741
|
float far = smoothstep(0.0, u_ring.w - u_ring.z, dot(from, u_ring_ahead));
|
|
@@ -2740,12 +2904,12 @@ float hash(vec2 p) {
|
|
|
2740
2904
|
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
|
2741
2905
|
}
|
|
2742
2906
|
|
|
2743
|
-
// The
|
|
2744
|
-
//
|
|
2907
|
+
// The authored gradient follows the facade's height, leaving its upper edge light. Ground
|
|
2908
|
+
// contact and inner corners stay local; their shades never multiply into a dark lower band.
|
|
2745
2909
|
float facadeShade() {
|
|
2746
2910
|
if (v_building.z < 0.5) return 1.0;
|
|
2747
|
-
float reach =
|
|
2748
|
-
float gradient = 0.
|
|
2911
|
+
float reach = max((v_facade.z - v_base) * 0.85, 0.1);
|
|
2912
|
+
float gradient = 0.12 * u_style_gradient * (1.0 - smoothstep(0.0, reach, v_facade.y - v_base));
|
|
2749
2913
|
// Exponential attenuation leaves a soft tail above the first floor, without a band ending
|
|
2750
2914
|
// at its radius. Height above ground also keeps raised parts from acquiring a dark lower rim.
|
|
2751
2915
|
float up = max(v_facade.y, 0.0);
|
|
@@ -2777,10 +2941,10 @@ vec3 styleColour(vec3 colour, vec3 normal) {
|
|
|
2777
2941
|
|
|
2778
2942
|
// A surface's light over the light a sunlit roof takes, in the map's colours: a sunlit roof keeps
|
|
2779
2943
|
// its colour, a wall turned to a low sun glows, and shade takes the sky's colour. A wall sees half
|
|
2780
|
-
// the sky;
|
|
2944
|
+
// the sky; broad daylight fill keeps facades luminous, while night has little bounced light.
|
|
2781
2945
|
vec3 shade(vec3 normal, float lit) {
|
|
2782
2946
|
float facing = dot(normal, u_sun_dir);
|
|
2783
|
-
vec3 sky = u_sky_light * mix(mix(0.
|
|
2947
|
+
vec3 sky = u_sky_light * mix(mix(0.92, 0.5, u_night), 1.0, normal.z);
|
|
2784
2948
|
vec3 light = sky + u_sun_light * max(facing, 0.0) * (1.0 - u_shadow * (1.0 - lit));
|
|
2785
2949
|
vec3 roof = u_sky_light + u_sun_light * max(u_sun_dir.z, 0.0);
|
|
2786
2950
|
return min(pow(light / max(roof, vec3(1e-4)), vec3(1.0 / 2.2)), vec3(1.7));
|
|
@@ -3903,13 +4067,13 @@ function unit(seed, salt) {
|
|
|
3903
4067
|
var tileflowTreeModelIdPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
3904
4068
|
var tileflowVegetationMetadataKey = "tileflow:vegetation";
|
|
3905
4069
|
function readTileflowVegetation3D(metadata) {
|
|
3906
|
-
if (!
|
|
4070
|
+
if (!isRecord3(metadata)) return void 0;
|
|
3907
4071
|
const value = metadata[tileflowVegetationMetadataKey];
|
|
3908
|
-
if (!
|
|
4072
|
+
if (!isRecord3(value) || value.version !== 1) return void 0;
|
|
3909
4073
|
const { source, layers, fields, colors, heightScale, crownScale, unknownForms, regions } = value;
|
|
3910
|
-
if (typeof source !== "string" || !
|
|
4074
|
+
if (typeof source !== "string" || !isRecord3(layers) || typeof layers.tree !== "string")
|
|
3911
4075
|
return void 0;
|
|
3912
|
-
if (!
|
|
4076
|
+
if (!isRecord3(fields) || !isRecord3(colors) || typeof colors.bark !== "string") return void 0;
|
|
3913
4077
|
const palette = (list) => Array.isArray(list) && list.length > 0 && list.every((entry) => typeof entry === "string") ? list : void 0;
|
|
3914
4078
|
const broadleaf = palette(colors.broadleaf);
|
|
3915
4079
|
const conifer = palette(colors.conifer);
|
|
@@ -3919,18 +4083,18 @@ function readTileflowVegetation3D(metadata) {
|
|
|
3919
4083
|
const scale = (number) => typeof number === "number" && number > 0 && number <= 10 ? number : 1;
|
|
3920
4084
|
const mix2 = tileflowTreeFormMixProblem(unknownForms) === void 0 ? unknownForms : void 0;
|
|
3921
4085
|
const models = Object.fromEntries(
|
|
3922
|
-
Object.entries(
|
|
3923
|
-
([id, model]) => tileflowTreeModelIdPattern.test(id) &&
|
|
4086
|
+
Object.entries(isRecord3(value.models) ? value.models : {}).filter(
|
|
4087
|
+
([id, model]) => tileflowTreeModelIdPattern.test(id) && isRecord3(model) && typeof model.near === "string" && (model.far === void 0 || typeof model.far === "string")
|
|
3924
4088
|
).slice(0, 16).map(([id, model]) => {
|
|
3925
4089
|
const { near, far } = model;
|
|
3926
4090
|
return [id, far === void 0 ? { near } : { near, far }];
|
|
3927
4091
|
})
|
|
3928
4092
|
);
|
|
3929
|
-
const ownScales =
|
|
4093
|
+
const ownScales = isRecord3(value.forms) ? value.forms : {};
|
|
3930
4094
|
const forms = Object.fromEntries(
|
|
3931
4095
|
tileflowTreeForms.flatMap((form) => {
|
|
3932
4096
|
const own = ownScales[form];
|
|
3933
|
-
if (!
|
|
4097
|
+
if (!isRecord3(own)) return [];
|
|
3934
4098
|
const drawn = Array.isArray(own.models) ? [...new Set(own.models)].filter((id) => typeof id === "string" && id in models).slice(0, 4) : [];
|
|
3935
4099
|
return [
|
|
3936
4100
|
[
|
|
@@ -3950,7 +4114,7 @@ function readTileflowVegetation3D(metadata) {
|
|
|
3950
4114
|
const finish = tileflowTreeFinishes.find((name) => name === value.finish) ?? "faceted";
|
|
3951
4115
|
const edges = typeof value.edges === "number" && value.edges >= 0 && value.edges <= 1 ? value.edges : 0;
|
|
3952
4116
|
const zones = Array.isArray(regions) ? regions.filter(
|
|
3953
|
-
(region) =>
|
|
4117
|
+
(region) => isRecord3(region) && tileflowTreeRegionProblem(region) === void 0
|
|
3954
4118
|
) : [];
|
|
3955
4119
|
const named = Object.fromEntries(
|
|
3956
4120
|
Object.entries(tileflowWorldTreeFields).map(([key, fallback]) => [
|
|
@@ -3982,7 +4146,7 @@ function readTileflowVegetation3D(metadata) {
|
|
|
3982
4146
|
};
|
|
3983
4147
|
}
|
|
3984
4148
|
function tileflowTreeRegionProblem(region) {
|
|
3985
|
-
if (!
|
|
4149
|
+
if (!isRecord3(region)) return "a region is an object with bounds and unknownForms";
|
|
3986
4150
|
const bounds = region.bounds;
|
|
3987
4151
|
if (!Array.isArray(bounds) || bounds.length !== 4 || !bounds.every((value) => typeof value === "number" && Number.isFinite(value)))
|
|
3988
4152
|
return "bounds are [west, south, east, north] in degrees";
|
|
@@ -3993,7 +4157,7 @@ function tileflowTreeRegionProblem(region) {
|
|
|
3993
4157
|
const mix2 = tileflowTreeFormMixProblem(region.unknownForms);
|
|
3994
4158
|
return mix2 ? `unknownForms: ${mix2}` : void 0;
|
|
3995
4159
|
}
|
|
3996
|
-
function
|
|
4160
|
+
function isRecord3(value) {
|
|
3997
4161
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3998
4162
|
}
|
|
3999
4163
|
|
|
@@ -4260,7 +4424,7 @@ function browserWorker() {
|
|
|
4260
4424
|
if (typeof Worker === "undefined" || false)
|
|
4261
4425
|
return;
|
|
4262
4426
|
const url = URL.createObjectURL(
|
|
4263
|
-
new Blob(['"use strict";(()=>{var Be=new Set,ln=!1;function Pe(e,n,t=2){let i=n&&n.length,o=i?n[0]*t:e.length;Be.size&&Be.clear();let r=In(e,0,o,t,!0),s=[];if(!r||r.next===r.prev)return s;let a=0,l=0,u=0;if(i&&(r=xt(e,n,r,t)),e.length>80*t){a=e[0],l=e[1];let c=a,f=l;for(let d=t;d<o;d+=t){let g=e[d],m=e[d+1];g<a&&(a=g),m<l&&(l=m),g>c&&(c=g),m>f&&(f=m)}u=Math.max(c-a,f-l),u=u!==0?32767/u:0}return un(r,s,a,l,u),s}function In(e,n,t,i,o){let r=null;if(o===Ct(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=En(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=En(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ue(r),r=r.next),r}function ge(e,n=e){let t=n===e,i=e,o;do o=!1,i!==i.next&&(Be.size===0||!Be.has(i))&&(Oe(i,i.next)||Q(i.prev,i,i.next)===0)?((t||i===n)&&(n=i.prev),ln=!0,Ue(i),i=i.prev,o=!0):(t||i!==n)&&(i=i.next,o=!t);while(o||i!==n);return n}function un(e,n,t,i,o){o&&Ft(e,t,i,o);let r=e,s=!1;for(;e.prev!==e.next;){let a=e.prev,l=e.next;if(Q(a,e,l)<0&&(o?bt(e,t,i,o):yt(e))){n.push(a.i,e.i,l.i),Ue(e),e=l,r=l;continue}if(e=l,e===r){if(ln=!1,e=ge(e),ln){r=e;continue}if(!s){e=gt(e,n),r=e,s=!0;continue}wt(e,n,t,i,o);break}}}function yt(e){let n=e.prev,t=e,i=e.next,o=n.x,r=t.x,s=i.x,a=n.y,l=t.y,u=i.y,c=Math.min(o,r,s),f=Math.min(a,l,u),d=Math.max(o,r,s),g=Math.max(a,l,u),m=i.next;for(;m!==n;){if(m.x>=c&&m.x<=d&&m.y>=f&&m.y<=g&&!(o===m.x&&a===m.y)&&Ke(o,a,r,l,s,u,m.x,m.y)&&Q(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function bt(e,n,t,i){let o=e.prev,r=e,s=e.next,a=o.x,l=r.x,u=s.x,c=o.y,f=r.y,d=s.y,g=Math.min(a,l,u),m=Math.min(c,f,d),p=Math.max(a,l,u),h=Math.max(c,f,d),A=mn(g,m,n,t,i),F=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=A;){if(k.x>=g&&k.x<=p&&k.y>=m&&k.y<=h&&k!==s&&!(a===k.x&&c===k.y)&&Ke(a,c,l,f,u,d,k.x,k.y)&&Q(k.prev,k,k.next)>=0)return!1;k=k.prevZ}let M=e.nextZ;for(;M&&M.z<=F;){if(M.x>=g&&M.x<=p&&M.y>=m&&M.y<=h&&M!==s&&!(a===M.x&&c===M.y)&&Ke(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.nextZ}return!0}function gt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Dn(o,t,t.next,r,!1)&&Ce(o,r)&&Ce(r,o)&&(n.push(o.i,t.i,r.i),Ue(t),Ue(t.next),t=e=r,i=!0),t=t.next}while(t!==e);return i?ge(t):t}function wt(e,n,t,i,o){let r=e;do{let s=r.next.next;for(;s!==r.prev;){if(r.i!==s.i&&Lt(r,s)){let a=Vn(r,s);r=ge(r,r.next),a=ge(a,a.next),un(r,n,t,i,o),un(a,n,t,i,o);return}s=s.next}r=r.next}while(r!==e)}var cn=!1;function xt(e,n,t,i){let o=[];for(let r=0,s=n.length;r<s;r++){let a=n[r]*i,l=r<s-1?n[r+1]*i:e.length,u=In(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),kt(e.length/i,n.length),Nn(t,t),cn=!0;for(let r=0;r<o.length;r++)t=Mt(o[r],t);return cn=!1,ge(t)}function Tt(e,n){return e.x-n.x||e.y-n.y||(e.next.y-e.y)/(e.next.x-e.x)-(n.next.y-n.y)/(n.next.x-n.x)}function Mt(e,n){let t=Rt(e,n);if(!t)return n;let i=Vn(t,e),o=i.next;return Nn(t,o.next),ge(i,i.next),ge(t,t.next)}var jn=16,X=new Float64Array(0),Je=0,fn=[],dn=[];function kt(e,n){let t=Math.ceil((e+2*n)/jn)+n+2;X.length<t*4&&(X=new Float64Array(t*4)),Je=0}function Nn(e,n){let t=e;do{let i=Je++;fn[i]=t;let o=t.x,r=t.y,s=t.x,a=t.y,l=0;do{let c=t.next;t.z=i,c.x<o&&(o=c.x),c.x>s&&(s=c.x),c.y<r&&(r=c.y),c.y>a&&(a=c.y),t=c}while(++l<jn&&t!==n);dn[i]=t;let u=i*4;X[u]=o,X[u+1]=r,X[u+2]=s,X[u+3]=a}while(t!==n)}function vt(e,n){let t=e.z*4;n.x<X[t]&&(X[t]=n.x),n.y<X[t+1]&&(X[t+1]=n.y),n.x>X[t+2]&&(X[t+2]=n.x),n.y>X[t+3]&&(X[t+3]=n.y)}function Pn(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function zn(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function Rt(e,n){let t=n,i=e.x,o=e.y,r=-1/0,s;if(Oe(e,t))return t;for(let d=0,g=0;d<Je;d++,g+=4){if(o<X[g+1]||o>X[g+3]||X[g]>i||X[g+2]<=r)continue;let m=Pn(d);t=zn(d);do{if(t.prev.next===t){if(Oe(e,t.next))return t.next;if(o<=t.y&&o>=t.next.y&&t.next.y!==t.y){let p=t.x+(o-t.y)*(t.next.x-t.x)/(t.next.y-t.y);if(p<=i&&p>r&&(r=p,s=t.x<t.next.x?t:t.next,p===i))return s}}t=t.next}while(t!==m)}if(!s)return null;let a=s.x,l=s.y,u=Math.min(o,l),c=Math.max(o,l),f=1/0;for(let d=0,g=0;d<Je;d++,g+=4){if(X[g+2]<a||X[g]>i||X[g+3]<u||X[g+1]>c)continue;let m=Pn(d);t=zn(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Ke(o<l?i:r,o,a,l,o<l?r:i,o,t.x,t.y)){let p=Math.abs(o-t.y)/(i-t.x);(Ce(t,e)||t.y===o&&t.next.y===o&&t.next.x>i)&&(p<f||p===f&&(t.x>s.x||t.x===s.x&&At(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function At(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ve=[],be=new Uint32Array(0),Se=new Uint32Array(0),Le=new Uint32Array(256);function Ft(e,n,t,i){let o=e,r=0;do o.z=mn(o.x,o.y,n,t,i),ie[r++]=o,o=o.next;while(o!==e);_t(r);let s=null;for(let a=0;a<r;a++){let l=ie[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,ie.fill(null,0,r),ve.fill(null,0,r)}function _t(e){if(e<=32){for(let n=1;n<e;n++){let t=ie[n],i=t.z,o=n-1;for(;o>=0&&ie[o].z>i;)ie[o+1]=ie[o],o--;ie[o+1]=t}return}be.length<e&&(be=new Uint32Array(e),Se=new Uint32Array(e),ve=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ve,Se,0),Xe(e,ve,Se,ie,be,8),Xe(e,ie,be,ve,Se,16),Xe(e,ve,Se,ie,be,24)}function Xe(e,n,t,i,o,r){Le.fill(0);for(let a=0;a<e;a++)Le[t[a]>>>r&255]++;let s=0;for(let a=0;a<256;a++){let l=Le[a];Le[a]=s,s+=l}for(let a=0;a<e;a++){let l=t[a],u=Le[l>>>r&255]++;i[u]=n[a],o[u]=l}}function mn(e,n,t,i,o){return e=(e-t)*o|0,n=(n-i)*o|0,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,n=(n|n<<8)&16711935,n=(n|n<<4)&252645135,n=(n|n<<2)&858993459,n=(n|n<<1)&1431655765,e|n<<1}function St(e){let n=e,t=e;do(n.x<t.x||n.x===t.x&&n.y<t.y)&&(t=n),n=n.next;while(n!==e);return t}function Ke(e,n,t,i,o,r,s,a){return(o-s)*(n-a)>=(e-s)*(r-a)&&(e-s)*(i-a)>=(t-s)*(n-a)&&(t-s)*(r-a)>=(o-s)*(i-a)}function Lt(e,n){let t=Oe(e,n)&&Q(e.prev,e,e.next)>0&&Q(n.prev,n,n.next)>0;return e.next.i!==n.i&&(t||Ce(e,n)&&Ce(n,e)&&(Q(e.prev,e,n.prev)!==0||Q(e,n.prev,n)!==0))&&!Bt(e,n)&&(t||Ot(e,n))}function Q(e,n,t){return(n.y-e.y)*(t.x-n.x)-(n.x-e.x)*(t.y-n.y)}function Oe(e,n){return e.x===n.x&&e.y===n.y}function Dn(e,n,t,i,o=!0){let r=Q(e,n,t),s=Q(e,n,i),a=Q(t,i,e),l=Q(t,i,n);return(r>0&&s<0||r<0&&s>0)&&(a>0&&l<0||a<0&&l>0)?!0:o?!!(r===0&&Ye(e,t,n)||s===0&&Ye(e,i,n)||a===0&&Ye(t,e,i)||l===0&&Ye(t,n,i)):!1}function Ye(e,n,t){return n.x<=Math.max(e.x,t.x)&&n.x>=Math.min(e.x,t.x)&&n.y<=Math.max(e.y,t.y)&&n.y>=Math.min(e.y,t.y)}function Bt(e,n){let t=Math.min(e.x,n.x),i=Math.max(e.x,n.x),o=Math.min(e.y,n.y),r=Math.max(e.y,n.y),s=e;do{let a=s.next;if(s.x>i&&a.x>i||s.x<t&&a.x<t||s.y>r&&a.y>r||s.y<o&&a.y<o){s=a;continue}if(s.i!==e.i&&a.i!==e.i&&s.i!==n.i&&a.i!==n.i&&Dn(s,a,e,n))return!0;s=a}while(s!==e);return!1}function Ce(e,n){return Q(e.prev,e,e.next)<0?Q(e,n,e.next)>=0&&Q(e,e.prev,n)>=0:Q(e,n,e.prev)<0||Q(e,e.next,n)<0}function Ot(e,n){let t=e,i=!1,o=(e.x+n.x)/2,r=(e.y+n.y)/2;do{let s=t.next;t.y>r!=s.y>r&&o<(s.x-t.x)*(r-t.y)/(s.y-t.y)+t.x&&(i=!i),t=s}while(t!==e);return i}function Vn(e,n){let t=hn(e.i,e.x,e.y),i=hn(n.i,n.x,n.y),o=e.next,r=n.prev;return e.next=n,n.prev=e,t.next=o,o.prev=t,i.next=t,t.prev=i,r.next=i,i.prev=r,i}function En(e,n,t,i){let o=hn(e,n,t);return i?(o.next=i.next,o.prev=i,i.next.prev=o,i.next=o):(o.prev=o,o.next=o),o}function Ue(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ),cn&&vt(e.prev,e.next)}function hn(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Ct(e,n,t,i){let o=0;for(let r=n,s=t-i;r<t;r+=i)o+=(e[s]-e[r])*(e[r+1]+e[s+1]),s=r;return o}var Ut=.7,Pt=Math.tan(Math.PI/6),zt=Math.tan(35*Math.PI/180),Et=Math.tan(Math.PI/18),ze=.65,Ee=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Nt(e);if(!l||Math.abs(pn(e))<Ut*4*l.halfU*l.halfV)return;let u=l.u,c=l.v,f=l.halfU*r,d=l.halfV*r;f<d&&([u,c,f,d]=[c,u,d,f]);let g=Gn(t.roof_direction),m=g===void 0?void 0:[Math.sin(g*Math.PI/180),-Math.cos(g*Math.PI/180)];(m!==void 0?Math.abs(m[0]*u[0]+m[1]*u[1])>Math.abs(m[0]*c[0]+m[1]*c[1]):t.roof_orientation==="across")&&a!=="skillion"&&([u,c,f,d]=[c,u,d,f]);let h=jt(a,f,d,m&&[$n(m,u),$n(m,c)]);if(!h)return;let A=Math.max(0,o-i),F=Gn(t.roof_height),k,M;if(F!==void 0&&F>0)M=o,k=Math.max(i+Math.min(2,A/2),o-F);else{let y=Math.min(It(a,d),A*.6,30);t.height_source==="height"?(M=o,k=o-y):(k=o,M=o+y)}let B=M-k;if(!(B>=.3))return;let[C,z]=l.centre,U=(y,b)=>{let x=(y-C)*r,T=(b-z)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},E=(y,b)=>[C+(y*u[0]+b*c[0])/r,z+(y*u[1]+b*c[1])/r],D=(y,b)=>{let x=1/0;for(let[T,_,v]of h)x=Math.min(x,T*y+_*b+v);return Math.max(0,x)},K=(y,b)=>k+B*D(...U(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...U(n[y],n[y+1]));pn($)<0&&Ht($);let N=1.01,Y=[-f*N,-d*N,f*N,-d*N,f*N,d*N,-f*N,d*N],w=[];for(let[y,b]of h.entries()){let x=Y;for(let[P,Z]of h.entries()){if(P===y)continue;let j=b[0]-Z[0],G=b[1]-Z[1],W=b[2]-Z[2];if(Math.abs(j)+Math.abs(G)+Math.abs(W)<1e-9){P<y&&(x=[]);continue}if(x=Hn(x,j,G,W),x.length<6)break}if(x.length<6)continue;let T=$,_=x.length/2;for(let P=0;P<_&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%_*2],x[(P+1)%_*2+1]];T=Hn(T,W-j,Z-G,-(W-j)*Z-(Z-G)*j)}if(T.length<6||Math.abs(pn(T))<1e-6)continue;let v=[];for(let P=0;P<T.length;P+=2)v.push(...E(T[P],T[P+1]));let L=Pe(v);if(L.length===0)continue;let O=B*b[0],V=B*b[1],R=O*u[0]+V*c[0],S=O*u[1]+V*c[1],I=Math.hypot(R,S,1);w.push({ring:v,triangles:L,normal:[-R/I,-S/I]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[_,v]=U(y,b),[L,O]=U(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let I=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=I(_,v),Z=I(L,O);if(P===Z||P*Z>0)continue;let j=P/(P-Z);if(j<=1e-4||j>=1-1e-4)continue;let G=_+(L-_)*j,W=v+(O-v)*j;h[R][0]*G+h[R][1]*W+h[R][2]<=D(G,W)+1e-6&&V.push(j)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,S)=>R-S)}}}function It(e,n){switch(e){case"skillion":return 2*n*Et;case"pyramidal":return n*zt;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Pt}}function jt(e,n,t,i){let o=n,r=t,s=[[0,-1/r,1],[0,1/r,1]],a=u=>u.flatMap(c=>[1,-1].flatMap(f=>{let d=c==="v"?r:o,g=ze/(Ee*r)*f,m=(1-ze)/((1-Ee)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),ze/(Ee*r)*d],[...p(m),ze+(1-ze)/((1-Ee)*r)*(d-Ee*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return s;case"saltbox":{let u=r/3;return[[0,-1/(r-u),1+u/(r-u)],[0,1/(r+u),1-u/(r+u)]]}case"hipped":return[...s,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...s,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...s,[-1/o,0,1],[1/o,0,1]];case"gambrel":return a(["v"]);case"mansard":return a(["v","u"]);case"skillion":{let[u,c]=i??[0,1],f=Math.abs(u)*o+Math.abs(c)*r;return f>0?[[-u/(2*f),-c/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return[1,-1].map(f=>[0,-f*u/(r*c),1/c])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return Array.from({length:12},(f,d)=>{let g=d*Math.PI/6;return[-u*Math.cos(g)/(o*c),-u*Math.sin(g)/(r*c),1/c]})})];default:return}}function Hn(e,n,t,i){let o=e.length/2,r=[];for(let s=0;s<o;s+=1){let a=e[s*2],l=e[s*2+1],u=e[(s+1)%o*2],c=e[(s+1)%o*2+1],f=n*a+t*l+i,d=n*u+t*c+i;if(f<=0&&r.push(a,l),f<0&&d>0||f>0&&d<0){let g=f/(f-d);r.push(a+(u-a)*g,l+(c-l)*g)}}return r}function Nt(e){let n=Dt(e);if(n.length<3)return;let t,i=1/0;for(let o=0;o<n.length;o+=1){let[r,s]=n[o],[a,l]=n[(o+1)%n.length],u=Math.hypot(a-r,l-s);if(u===0)continue;let c=[(a-r)/u,(l-s)/u],f=[-c[1],c[0]],[d,g,m,p]=[1/0,-1/0,1/0,-1/0];for(let[A,F]of n){let k=A*c[0]+F*c[1],M=A*f[0]+F*f[1];d=Math.min(d,k),g=Math.max(g,k),m=Math.min(m,M),p=Math.max(p,M)}let h=(g-d)*(p-m);if(h<i){i=h;let A=(d+g)/2,F=(m+p)/2;t={centre:[A*c[0]+F*f[0],A*c[1]+F*f[1]],u:c,v:f,halfU:(g-d)/2,halfV:(p-m)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function Dt(e){let n=[];for(let r=0;r+1<e.length;r+=2)n.push([e[r],e[r+1]]);n.sort((r,s)=>r[0]-s[0]||r[1]-s[1]);let t=(r,s,a)=>(s[0]-r[0])*(a[1]-r[1])-(s[1]-r[1])*(a[0]-r[0]),i=[];for(let r of n){for(;i.length>=2&&t(i.at(-2),i.at(-1),r)<=0;)i.pop();i.push(r)}let o=[];for(let r of n.reverse()){for(;o.length>=2&&t(o.at(-2),o.at(-1),r)<=0;)o.pop();o.push(r)}return[...i.slice(0,-1),...o.slice(0,-1)]}function Vt(e,n){let[t,i,o,r]=[1/0,-1/0,1/0,-1/0];for(let a=0;a+1<e.length;a+=2)t=Math.min(t,e[a]),i=Math.max(i,e[a]),o=Math.min(o,e[a+1]),r=Math.max(r,e[a+1]);let s=e.length/2;for(let a=0;a<s;a+=1){let l=e[a*2],u=e[a*2+1],c=e[(a+1)%s*2],f=e[(a+1)%s*2+1];if(t<0&&l===t&&c===t||i>n&&l===i&&c===i||o<0&&u===o&&f===o||r>n&&u===r&&f===r)return!0}return!1}function pn(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n/2}function Ht(e){let n=[];for(let t=0;t<e.length;t+=2)n.push([e[t],e[t+1]]);n.reverse(),e.splice(0,e.length,...n.flat())}function $n(e,n){return e[0]*n[0]+e[1]*n[1]}function Gn(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var $t=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Nr=Object.freeze(Object.keys($t));var Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6});var Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024,parts:16});function yn(e,n,t){for(let i of e){let o=!1;for(let r=0,s=i.length-2;r<i.length;s=r,r+=2){let a=i[r],l=i[r+1],u=i[s],c=i[s+1];l>t!=c>t&&n<(u-a)*(t-l)/(c-l)+a&&(o=!o)}if(o)return!0}return!1}function Yn(e,n,t){for(let i of n){let[o,r,s,a]=Xn(i);for(let l of e){let[u,c,f,d]=Xn(l);if(!(u>s-t||f<o+t||c>a-t||d<r+t)&&(Wn(l,i,t)||Wn(i,l,t)))return!0}}return!1}function Wn(e,n,t){let i=(o,r)=>yn([n],o,r)&&Zt(n,o,r)>t;for(let o=0;o+1<e.length;o+=2)if(i(e[o],e[o+1]))return!0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=[0,1];for(let f=0,d=n.length-2;f<n.length;d=f,f+=2){let g=Gt(s,a,l,u,n[d],n[d+1],n[f],n[f+1]);g!==void 0&&c.push(g)}if(c.length!==2){c.sort((f,d)=>f-d);for(let f=1;f<c.length;f+=1){let d=(c[f-1]+c[f])/2;if(i(s+(l-s)*d,a+(u-a)*d))return!0}}}return!1}function Gt(e,n,t,i,o,r,s,a){let l=t-e,u=i-n,c=s-o,f=a-r,d=l*f-u*c;if(d===0)return;let g=((o-e)*f-(r-n)*c)/d,m=((o-e)*u-(r-n)*l)/d;return g>0&&g<1&&m>=0&&m<=1?g:void 0}function Zt(e,n,t){let i=1/0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=(l-s)**2+(u-a)**2,f=c>0?Math.max(0,Math.min(1,((n-s)*(l-s)+(t-a)*(u-a))/c)):0;i=Math.min(i,Math.hypot(n-(s+(l-s)*f),t-(a+(u-a)*f)))}return i}function Xn(e){let[n,t,i,o]=[1/0,1/0,-1/0,-1/0];for(let r=0;r+1<e.length;r+=2)n=Math.min(n,e[r]),i=Math.max(i,e[r]),t=Math.min(t,e[r+1]),o=Math.max(o,e[r+1]);return[n,t,i,o]}var ue=8192,pe=28,Wt={commercial:1,active:2,destination:3},Xt={residential:1,...Object.fromEntries(["civic","commercial","education","entertainment","medical","transportation"].map(e=>[e,2])),...Object.fromEntries(["agricultural","industrial","military","outbuilding","religious","service"].map(e=>[e,3]))},Yt={dining:1,entertainment:2,nightlife:3},bn={...Object.fromEntries(["alcoholic_beverage_venue","bar","beer","biergarten","brewery","casino","cocktail_bar","dance_club","karaoke","lounge","music_venue","night_club","nightclub","pub","wine_bar"].map(e=>[e,3])),...Object.fromEntries(["arts_centre","bowling_alley","cinema","comedy_club","concert_hall","movie_theater","opera","performing_arts_venue","theater","theatre","theatre_venue"].map(e=>[e,2])),...Object.fromEntries(["casual_eatery","fast_food","fast_food_restaurant","food_court","restaurant"].map(e=>[e,1]))},Jt=6,Kt=.5,Qt=.5;function Kn(e,n){let t=ue/e.extent,i=n.tileMetres/ue,o=n.defaultHeight??5,r=Number.isFinite(n.edgeRadius)?Math.max(0,Math.min(1.5,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=tr(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let C=B.properties,z=C.hide_3d;if(z===!0||z===1||z==="1"||z==="true")continue;let U=Math.min(6e3,Jn(C.render_height)??o),E=Math.min(U,Jn(C.render_min_height)??0),D=Wt[String(C.building_tone??"")]??0,K=Xt[String(C.class??"")]??0,$=d.get(M)??0,N=u.length,Y=!1;for(let w of rr(B.geometry,t)){let y=w.map(ir).filter(S=>S.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=or(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Qt/i)))continue;let T={cell:Math.min(7,Math.max(0,Math.floor(x/1024)))*8+Math.min(7,Math.max(0,Math.floor(b/1024))),bounds:[1/0,1/0,-1/0,-1/0,U+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let I=0;I<S.length;I+=2)T.bounds[0]=Math.min(T.bounds[0],S[I]-1),T.bounds[1]=Math.min(T.bounds[1],S[I+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[I]+1),T.bounds[3]=Math.max(T.bounds[3],S[I+1]+1);Y=!0,f=Math.max(f,U);let _=Number.isSafeInteger(B.id),v=gn(_?B.id*.0731:b*.0731+x*.19137+N*1.618),L=!_&&y[0].some(S=>S<=0||S>=ue)?gn(U*7.31+E*3.17+D):v,O={base:E,top:U,jitter:L,seed:v,tone:D,group:K,use:$,cx:b,cy:x,index:N},V=y.map((S,I)=>nr(S,I,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],C,E,U,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),er(R,O,s,a)):qt(y,O,s,a);for(let[S,I]of y.entries()){let P=qe(I)>0,Z=S===0?P?-1:1:P?1:-1,j=I.length/2,G=H=>{let J=(H%j+j)%j;return[I[J*2],I[J*2+1]]},W=H=>{let[J,re]=G(H-1),[ne,te]=G(H),[le,de]=G(H+1);if(we(J,re,ne,te)||we(ne,te,le,de))return!1;let me=Math.hypot(ne-J,te-re),ce=Math.hypot(le-ne,de-te);if(!me||!ce)return!1;let je=-(te-re)/me*Z,Ne=(ne-J)/me*Z;return(je*(le-ne)+Ne*(de-te))/ce>Kt},se=(H,J)=>R?R.heightAt(H,J):U,ae=0;for(let H=0;H<j;H+=1){let[J,re]=G(H),[ne,te]=G(H+1),le=Math.hypot(ne-J,te-re);if(le===0||we(J,re,ne,te))continue;let de=-(te-re)/le*Z,me=(ne-J)/le*Z,ce=V[S].normals[H]??[de,me],je=V[S].normals[(H+1)%j]??[de,me],Ne=oe=>{let Ae=ce[0]+(je[0]-ce[0])*oe,Fe=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(Ae,Fe)||1;return[Ae/ye,Fe/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let Ae=oe===0,Fe=oe+2===he.length,ye=J+(ne-J)*he[oe],De=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],He=re+(te-re)*he[oe+1],_e=Math.hypot(Ve-ye,He-De)/ue*n.tileMetres,$e=(Ae&&W(H)?1:0)|(Fe&&W(H+1)?2:0)|(S>0?4:0),Ge=(Ae&&xn(J,re)?1:0)|(Fe&&xn(ne,te)?2:0),an=ae+_e,Ze=Ne(he[oe]),We=Ne(he[oe+1]),Cn=se(ye,De),Un=se(Ve,He),ke=s.write(O,ye,De,0,Ze[0],Ze[1],1,ae,$e,_e,0,Ge,Cn);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,_e,1,Ge,Un),s.write(O,ye,De,1,Ze[0],Ze[1],1,ae,$e,_e,0,Ge,Cn),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,_e,1,Ge,Un),l.push(ke,ke+1,ke+2,ke+1,ke+3,ke+2),ae=an}}}T.roofsCount=a.length-T.roofsFrom,T.wallsCount=l.length-T.wallsFrom,c.push(T)}Y&&u.push(C)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,A=a.values(),F=l.values();c.sort((M,B)=>M.cell-B.cell);let k=-1;for(let M of c){M.cell!==k&&(k=M.cell,m.push({bounds:[...M.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let C=0;C<5;C+=1)B.bounds[C]=C<2?Math.min(B.bounds[C],M.bounds[C]):Math.max(B.bounds[C],M.bounds[C]);g.set(A.subarray(M.roofsFrom,M.roofsFrom+M.roofsCount),p),g.set(F.subarray(M.wallsFrom,M.wallsFrom+M.wallsCount),h),p+=M.roofsCount,h+=M.wallsCount,B.roofsCount+=M.roofsCount,B.wallsCount+=M.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function qt(e,n,t,i){let o=[],r=[];for(let l of e)r.push(o.length/2),o.push(...l);r.push(o.length/2);let s=(l,u)=>{let c=r.findIndex((p,h)=>l>=p&&l<r[h+1]),[f,d]=[r[c],r[c+1]-1];if(u<f||u>d)return!1;let[g,m]=l<u?[l,u]:[u,l];return m-g!==1&&!(g===f&&m===d)?!1:!we(o[l*2],o[l*2+1],o[u*2],o[u*2+1])},a=Pe(o,r.slice(1,-1),2);for(let l=0;l+2<a.length;l+=3){let u=[a[l],a[l+1],a[l+2]],c=0;for(let f=0;f<3;f+=1)s(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries())i.push(t.write(n,o[d*2],o[d*2+1],1,0,0,0,0,0,0,f,c))}}function er(e,n,t,i){for(let o of e.faces){let r=o.ring,s=r.length/2,a=(l,u)=>{let[c,f]=l<u?[l,u]:[u,l];return f-c!==1&&!(c===0&&f===s-1)?!1:!we(r[l*2],r[l*2+1],r[u*2],r[u*2+1])};for(let l=0;l+2<o.triangles.length;l+=3){let u=[o.triangles[l],o.triangles[l+1],o.triangles[l+2]],c=0;for(let f=0;f<3;f+=1)a(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries()){let g=r[d*2],m=r[d*2+1];i.push(t.write(n,g,m,1,o.normal[0],o.normal[1],0,0,0,0,f,c,e.heightAt(g,m)))}}}}function nr(e,n,t,i=Math.PI/6){if(t<1)return{ring:e,normals:[]};let o=e.length/2,r=qe(e)>0,s=n===0?r?-1:1:r?1:-1,a=[],l=[],u=(c,f,d)=>{c=Re(c),f=Re(f),!(a.at(-2)===c&&a.at(-1)===f)&&(a.push(c,f),l.push(d))};for(let c=0;c<o;c+=1){let f=(c+o-1)%o,d=(c+1)%o,[g,m]=[e[f*2],e[f*2+1]],[p,h]=[e[c*2],e[c*2+1]],[A,F]=[e[d*2],e[d*2+1]],k=Math.hypot(p-g,h-m),M=Math.hypot(A-p,F-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,A,F)){u(p,h);continue}let[B,C]=[(p-g)/k,(h-m)/k],[z,U]=[(A-p)/M,(F-h)/M],E=Math.atan2(B*U-C*z,B*z+C*U);if(E*s>=-.08||Math.abs(E)>Math.PI*.85){u(p,h);continue}let D=Math.tan(Math.abs(E)/2),K=Math.min(t*D,k*.2,M*.2),$=K/D;if($<1){u(p,h);continue}let[N,Y]=[-C*s,B*s],[w,y]=[p-B*K-N*$,h-C*K-Y*$],b=Math.atan2(Y,N),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(E)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let _=b+E*T/x,v=[Math.cos(_),Math.sin(_)];u(w+v[0]*$,y+v[1]*$,v)}}return a[0]===a.at(-2)&&a[1]===a.at(-1)&&(a.splice(-2),l.pop()),a.length>=6?{ring:a,normals:l}:{ring:e,normals:[]}}var wn=class{#e=new ArrayBuffer(4096*pe);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s,a,l,u,c,f=0,d=0,g=n.top){let m=pe;if((this.count+1)*m>this.#e.byteLength){let A=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(A).set(new Uint8Array(this.#e)),this.#e=A,this.#n=new DataView(A)}let p=this.#n,h=this.count*m;return p.setUint16(h,Re(t),!0),p.setUint16(h+2,Re(i),!0),p.setUint16(h+4,Math.min(65535,Math.round(n.base*10)),!0),p.setUint16(h+6,Math.min(65535,Math.max(0,Math.round(g*10))),!0),p.setInt8(h+8,Math.round(r*127)),p.setInt8(h+9,Math.round(s*127)),p.setUint8(h+10,o),p.setUint8(h+11,a),p.setUint16(h+12,Math.round(l*10)%65536,!0),p.setUint8(h+14,Math.round(n.jitter*255)),p.setUint8(h+15,Math.round(n.seed*255)),p.setUint16(h+16,Re(n.cx),!0),p.setUint16(h+18,Re(n.cy),!0),p.setUint8(h+20,n.tone+4*n.group),p.setUint8(h+21,n.use),p.setUint8(h+22,u),p.setUint8(h+23,Math.min(255,Math.round(c))),p.setUint16(h+24,n.index,!0),p.setUint8(h+26,f),p.setUint8(h+27,d),this.count+=1,this.count-1}bytes(){return new Uint8Array(this.#e.slice(0,this.count*pe))}},Qe=class{#e=new Uint32Array(8192);length=0;push(...n){if(this.length+n.length>this.#e.length){let t=new Uint32Array(Math.max(this.length+n.length,this.#e.length*2));t.set(this.#e),this.#e=t}for(let t of n)this.#e[this.length++]=t}values(){return this.#e.subarray(0,this.length)}};function tr(e,n){let t=new Map;if(e.features.some(a=>a.properties.night_use!==void 0)){for(let[a,l]of e.features.entries()){let u=Yt[String(l.properties.night_use??"")];u&&t.set(a,u)}return t}let i=n.places;if(!i||i.features.length===0)return t;let o=Jt/n.tileMetres*e.extent,r=[];for(let[a,l]of e.features.entries()){if(l.type!=="Polygon")continue;let u=l.properties.hide_3d;if(u===!0||u===1||u==="1"||u==="true")continue;let c=[1/0,1/0,-1/0,-1/0];for(let f of l.geometry)for(let d=0;d+1<f.length;d+=2)c[0]=Math.min(c[0],f[d]),c[1]=Math.min(c[1],f[d+1]),c[2]=Math.max(c[2],f[d]),c[3]=Math.max(c[3],f[d+1]);r.push({index:a,rings:l.geometry,box:c})}let s=e.extent/i.extent;for(let a of i.features){if(a.type!=="Point")continue;let l=a.properties,u=bn[String(l.type??"")]??bn[String(l.subclass??"")]??bn[String(l.class??"")];if(u)for(let c of a.geometry)for(let f=0;f+1<c.length;f+=2){let d=c[f]*s,g=c[f+1]*s,m,p,h=o;for(let F of r){let[k,M,B,C]=F.box;if(d<k-o||d>B+o||g<M-o||g>C+o)continue;let z=!1;for(let U of F.rings)for(let E=0,D=U.length-2;E+1<U.length;D=E,E+=2){let K=U[D],$=U[D+1],N=U[E],Y=U[E+1];Y>g!=$>g&&d<(K-N)*(g-Y)/($-Y)+N&&(z=!z);let w=N-K,y=Y-$,b=w*w+y*y,x=b?Math.min(1,Math.max(0,((d-K)*w+(g-$)*y)/b)):0,T=Math.hypot(d-K-x*w,g-$-x*y);T<h&&(h=T,p=F.index)}if(z){m=F.index;break}}let A=m??p;A!==void 0&&t.set(A,Math.max(t.get(A)??0,u))}}return t}function Re(e){return Math.min(ue,Math.max(0,Math.round(e)))}function Jn(e){let n=Number(e);return Number.isFinite(n)&&n>0?n:void 0}function rr(e,n){let t=[],i;for(let o of e){let r=[];for(let a=0;a+1<o.length;a+=2){let l=o[a]*n,u=o[a+1]*n;r.length&&l===r.at(-2)&&u===r.at(-1)||r.push(l,u)}if(r.length>=6&&r[0]===r.at(-2)&&r[1]===r.at(-1)&&(r.length-=2),r.length<6)continue;let s=Math.sign(qe(r));s&&(i??=s,s===i||t.length===0?t.push([r]):t.at(-1).push(r))}return t}function qe(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n}function or(e){let n=0,t=0,i=e.length/2;for(let o=0;o<i;o+=1)n+=e[o*2],t+=e[o*2+1];return[n/i,t/i]}function xn(e,n){return e<=0||n<=0||e>=ue||n>=ue}function we(e,n,t,i){let o=ue;return e<=0&&t<=0||e>=o&&t>=o||n<=0&&i<=0||n>=o&&i>=o}function ir(e){let n=ue,t=[...e],i=[[0,0,o=>o>=0],[0,n,o=>o<=n],[1,0,o=>o>=0],[1,n,o=>o<=n]];for(let[o,r,s]of i){let a=[],l=t.length/2;for(let u=0;u<l;u+=1){let c=[t[u*2],t[u*2+1]],f=[t[(u+1)%l*2],t[(u+1)%l*2+1]],d=s(c[o]),g=s(f[o]);if(d&&a.push(c[0],c[1]),d!==g){let m=(r-c[o])/(f[o]-c[o]);a.push(c[0]+(f[0]-c[0])*m,c[1]+(f[1]-c[1])*m)}}if(t=a,t.length<6)return[]}return t}function gn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var Qn=`\nin float v_haze_depth;\nuniform vec3 u_haze_colour;\nuniform vec3 u_haze; // strength; the view depths where the haze starts and is complete\n\nfloat hazeOf() {\n return u_haze.x > 0.0 ? u_haze.x * smoothstep(u_haze.y, u_haze.z, v_haze_depth) : 0.0;\n}\n\nvec3 hazed(vec3 colour) {\n return mix(colour, u_haze_colour, hazeOf());\n}`;function qn(e){let n=(e.indices.length-e.wallsFrom)/6,t=new Uint8Array(n*16);for(let i=0;i<n;i+=1){let o=e.wallsFrom+i*6,r=e.indices[o]*pe,s=e.indices[o+1]*pe;t.set(e.vertices.subarray(r,r+4),i*16),t.set(e.vertices.subarray(s,s+4),i*16+4),t.set(e.vertices.subarray(r+4,r+8),i*16+8),t[i*16+12]=e.vertices[r+14],t[i*16+13]=e.vertices[r+27]}return t}var Kr=`#version 300 es\nprecision highp float;\nuniform highp sampler2D u_contact;\n${Qn}\nout vec4 fragColor;\nvoid main() {\n float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());\n fragColor = vec4(vec3(shade), 1.0);\n}`;function et(e){let n=e.vertices.length/pe;return{mesh:{...e.groups?{groups:e.groups}:{},wallsFrom:e.wallsFrom,top:e.top,features:e.features,vertexCount:n,indexCount:e.indices.length},data:{vertices:e.vertices,indices:n<=65536?Uint16Array.from(e.indices):e.indices,contact:qn(e)}}}function nt({data:e}){return[e.vertices.buffer,e.indices.buffer,e.contact.buffer]}function Tn(e){let n=sr(e);return n?[Math.min(1,Math.max(0,n[0]/255)),Math.min(1,Math.max(0,n[1]/255)),Math.min(1,Math.max(0,n[2]/255)),Math.min(1,Math.max(0,n[3]))]:null}function sr(e){let n=e.trim().toLowerCase(),t=/^#([\\da-f]{3,8})$/u.exec(n)?.[1];if(t&&[3,4,6,8].includes(t.length)){let A=(t.length<=4?[...t].map(F=>F+F).join(""):t).match(/../gu).map(F=>Number.parseInt(F,16));return[A[0],A[1],A[2],A.length>3?A[3]/255:1]}let i=/^(rgba?|hsla?)\\(([^)]+)\\)$/u.exec(n);if(!i)return null;let o=i[2].split(/[\\s,/]+/u).filter(Boolean);if(o.length<3||o.length>4)return null;let r=o[3]===void 0?1:en(o[3],1);if(i[1].startsWith("rgb")){let[h,A,F]=o.slice(0,3).map(k=>en(k,255));return[h,A,F,r].some(k=>k===null)?null:[h,A,F,r]}let s=Number.parseFloat(o[0]),a=en(o[1],1),l=en(o[2],1);if(!Number.isFinite(s)||a===null||l===null||r===null)return null;let u=(1-Math.abs(2*l-1))*a,c=(s%360+360)%360/60,f=u*(1-Math.abs(c%2-1)),[d,g,m]=c<1?[u,f,0]:c<2?[f,u,0]:c<3?[0,u,f]:c<4?[0,f,u]:c<5?[f,0,u]:[u,0,f],p=l-u/2;return[(d+p)*255,(g+p)*255,(m+p)*255,r]}function en(e,n){let t=e.endsWith("%"),i=Number.parseFloat(e);return Number.isFinite(i)?t?i/100*n:i:null}var fe=8192,Mn=12,ar={primary:{spacing:30,kerb:10},secondary:{spacing:32,kerb:8.5},tertiary:{spacing:34,kerb:7},minor:{spacing:36,kerb:5.5},pedestrian:{spacing:26,kerb:3}},lr={motorway:{spacing:45,kerb:14},trunk:{spacing:40,kerb:12},service:{spacing:38,kerb:4},path:{spacing:28,kerb:1.5},track:{spacing:40,kerb:2.5}},ur={spacing:30,kerb:0},cr=12,fr=18,dr=9,mr={sodium:"#ffa64d",high_pressure_sodium:"#ffa64d",low_pressure_sodium:"#ff9326",led:"#fff1db",mercury:"#e3ecff",metal_halide:"#f4f4ff",fluorescent:"#eef9ff",electric:"#ffd59a",incandescent:"#ffd59a",halogen:"#ffe3b0",gas:"#ffd28a",gaslight:"#ffd28a"},hr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},pr=new Set(["wall","wall_mounted","wall_bracket"]),yr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new vn,o=new nn(fr),r=new nn(dr),s=e.streetFurniture;if(s){let m=fe/s.extent;for(let p of s.features){let h=p.properties;if(p.type!=="Point"||h.subclass!=="street_lamp")continue;let A=br(h),F=gr(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,A*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let C=0;C+1<B.length;C+=2){let z=B[C]*m,U=B[C+1]*m;if(!rt(z,U))continue;i.write(z,U,A,M,!0,F);let E=ot(z,U,n.tileMetres);o.add(...E),r.add(...E)}}}let a=i.count;if(t==="none")return i.done(a);let l=e.transportation,u=0;if(l){let m=n.tileMetres/l.extent;for(let p of l.features)if(!(p.type!=="LineString"||!tt(p.properties,"streets")))for(let h of p.geometry)u+=wr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=cr,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,A)=>{let F=fe/m.extent,k=[];for(let D=0;D+1<p.length;D+=2)k.push(p[D]*F,p[D+1]*F);let M=n.tileMetres/fe,B=h.kerb*.45/M,C=Rn(k[0]*.013+k[1]*.029+A)*h.spacing,z=0,U=C,E=Rn(k[0]+k[1]*3.1)<.5?1:-1;for(let D=2;D<k.length;D+=2){let K=k[D-2],$=k[D-1],N=k[D],Y=k[D+1],w=Math.hypot(N-K,Y-$)*M;if(w!==0){for(;U<=z+w;){let y=(U-z)/w,b=-(Y-$)/(w/M)*E,x=(N-K)/(w/M)*E,T=K+(N-K)*y+b*B,_=$+(Y-$)*y+x*B;if(U+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(E=-E),!rt(T,_))continue;let v=ot(T,_,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,_,7,15,!1))}z+=w}}};if(l)for(let m of l.features){if(m.type!=="LineString")continue;let p=tt(m.properties,f);if(p)for(let h of m.geometry)d(l,h,p,1)}let g=e.sidewalks;if(g){for(let m of g.features)if(!(m.type==="Point"||!kn(m.properties.lit)))for(let p of m.geometry)d(g,p,ur,2)}return i.done(a)}function tt(e,n){if(e.brunnel==="tunnel"||e.covered===!0)return;let t=e.lit;if(t===!1||t==="no")return;let i=String(e.class??""),o=String(e.subclass??""),r=i==="path"&&(o==="pedestrian"||o==="living_street")?"pedestrian":i,s=ar[r];if(s&&(n==="streets"||kn(t)))return s;let a=lr[r];if(a&&kn(t))return a}function kn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function br(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return pr.has(t)?4.5:yr.has(t)?7.5:7}function gr(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(hr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=mr[t];if(!i)return;let o=Tn(i);return[o[0],o[1],o[2]]}function rt(e,n){return e>=0&&n>=0&&e<fe&&n<fe}function ot(e,n,t){return[e/fe*t,n/fe*t]}function wr(e,n){let t=0;for(let i=2;i+1<e.length;i+=2){let o=(e[i-2]+e[i])/2,r=(e[i-1]+e[i+1])/2;o<0||r<0||o>=n||r>=n||(t+=Math.hypot(e[i]-e[i-2],e[i+1]-e[i-1]))}return t}var nn=class{constructor(n){this.size=n}size;#e=new Map;add(n,t){let i=`${Math.floor(n/this.size)}/${Math.floor(t/this.size)}`,o=this.#e.get(i);o?o.push([n,t]):this.#e.set(i,[[n,t]])}near(n,t){let i=Math.floor(n/this.size),o=Math.floor(t/this.size);for(let r=-1;r<=1;r+=1)for(let s=-1;s<=1;s+=1)for(let[a,l]of this.#e.get(`${i+r}/${o+s}`)??[])if(Math.hypot(a-n,l-t)<this.size)return!0;return!1}},vn=class{#e=new ArrayBuffer(256*Mn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Mn;if((this.count+1)*a>this.#e.byteLength){let c=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(c).set(new Uint8Array(this.#e)),this.#e=c,this.#n=new DataView(c)}let l=this.#n,u=this.count*a;l.setUint16(u,Math.min(fe,Math.max(0,Math.round(n))),!0),l.setUint16(u+2,Math.min(fe,Math.max(0,Math.round(t))),!0),l.setUint16(u+4,Math.min(65535,Math.round(i*10)),!0),l.setUint8(u+6,Math.min(255,Math.round(o))),l.setUint8(u+7,(r?1:0)|(s?2:0)),l.setUint8(u+8,Math.round((s?.[0]??0)*255)),l.setUint8(u+9,Math.round((s?.[1]??0)*255)),l.setUint8(u+10,Math.round((s?.[2]??0)*255)),l.setUint8(u+11,Math.round(Rn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Mn)),mapped:n,estimated:this.count-n}}};function Rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var oo=Object.freeze({source:"tileflow",layers:Object.freeze({streetFurniture:"street_furniture",transportation:"transportation",sidewalk:"sidewalk"}),estimate:"lit",color:"#ffcf8f",intensity:1});var Me=["round","open","tall","conifer","columnar","palm"];var ut=Object.freeze({height:"height",diameterCrown:"diameter_crown",circumference:"circumference",genus:"genus",species:"species",leafType:"leaf_type",taxon:"taxon",canopyRank:"rank",canopyClearance:"clearance_px_z15",canopyCover:"cover_pct",canopyHeight:"height_m",subclass:"subclass",hedge:"hedge"}),Sn=Object.freeze({round:1,open:1,tall:1}),tn=16,q=8192,rn=16,st={round:{height:[6,12],crown:[.66,.9]},open:{height:[5,10],crown:[.8,1.05]},tall:{height:[9,17],crown:[.48,.68]},conifer:{height:[7,16],crown:[.46,.66]},columnar:{height:[9,18],crown:[.22,.36]},palm:{height:[12,20],crown:[.42,.55]}};var on=[2,45],An=[1,25],xr=1.2,Tr=1.5,Mr=1.3,kr=1,vr=[.3,10],Rr=new Set(["acoelorrhaphe","adonidia","archontophoenix","areca","arecastrum","bismarckia","brahea","butia","caryota","chamaedorea","chamaerops","coccothrinax","cocos","dypsis","elaeis","howea","jubaea","licuala","livistona","phoenix","pritchardia","ptychosperma","rhapis","roystonea","sabal","serenoa","syagrus","thrinax","trachycarpus","veitchia","washingtonia","wodyetia"]),Ar=new Set(["cupressus","calocedrus","thuja"]),Fr=new Set(["abies","araucaria","cedrus","cryptomeria","juniperus","larix","metasequoia","picea","pinus","pseudotsuga","sequoia","sequoiadendron","taxodium","taxus","tsuga"]),at=Object.freeze({...Object.fromEntries(["acacia","albizia","arbutus","bursera","ceratonia","delonix","ficus","gleditsia","jacaranda","olea","quercus","robinia","schinus","sophora","styphnolobium","tamarix"].map(e=>[e,"open"])),...Object.fromEntries(["betula","celtis","fraxinus","ginkgo","liquidambar","liriodendron","magnolia","platanus","populus","pyrus","ulmus","zelkova"].map(e=>[e,"tall"])),...Object.fromEntries(["acer","aesculus","carpinus","castanea","catalpa","cercis","citrus","fagus","lagerstroemia","malus","melia","morus","prunus","sorbus","tilia"].map(e=>[e,"round"]))});function lt(e,n={}){let t={...ut,...n},i=String(e[t.leafType]??"").toLowerCase(),o=String(e[t.taxon]??"").toLowerCase(),r=Fn(e[t.genus])??Fn(e[t.species])??(o.endsWith("aceae")?void 0:Fn(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&Rr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Ar.has(r))return"columnar";if(i.includes("needle")||r&&Fr.has(r))return"conifer";if(r&&at[r])return at[r];if(i.includes("broad"))return"broadleaf"}function Fn(e){return typeof e!="string"?void 0:e.trim().split(/\\s+/u)[0]?.toLowerCase()||void 0}function ct(e,n){let t={...ut,...n.fields},i=n.unknownForms??Sn,o=n.regions??[],{tile:r,tileMetres:s}=n,a=s/2**(15-r.z)/512,l=[],u=0,c=0,f=(w,y)=>{if(o.length===0)return i;let[b,x]=Sr(r,w/q,y/q);for(let T of o){let[_,v,L,O]=T.bounds;if(x>=v&&x<=O&&(_<=L?b>=_&&b<=L:b>=_||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],_=_n(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=_n(T.height,ee(y,1))),v===void 0&&(v=L/_),L===void 0&&(L=v*_),{height:Te(v,on),crown:Te(L,An)}},g=(w,y,b,x,T,_)=>{let v=Ie(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(_r(f(w,y)),ee(v,3)):b,O=x===void 0&&T===void 0&&_!==void 0?d(L,v,_n(st[L].height,Te(_/3,[0,1]))):d(L,v,x,T);l.push({x:w,y,...O,turn:ee(v,4),shade:ee(v,5),form:Me.indexOf(L),rank:Math.floor(ee(v,6)*rn),seed:ee(v,7),canopy:0}),u+=1},m=e.trees;if(m){let w=q/m.extent;for(let y of m.features){if(y.type!=="Point")continue;let b=y.properties,x=lt(b,t),T=xe(b[t.height],on),_=xe(b[t.diameterCrown],An),v=xe(b[t.circumference],[.1,12]);for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];V<0||R<0||V>=m.extent||R>=m.extent||g(V*w,R*w,x,T,_,v)}}}let p=e.trees;if(p){let w=q/p.extent,y=(n.rowSpacing??8)/(s/p.extent);for(let b of p.features){if(b.type!=="LineString")continue;let x=b.properties,T=lt(x,t),_=xe(x[t.height],on),v=xe(x[t.diameterCrown],An);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,I,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-I);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=I+(Z-I)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,_,v,void 0),O+=y}V+=j}}}}let h=e.canopy;if(h){let w=q/h.extent;for(let y of h.features){if(y.type!=="Point")continue;let b=y.properties,x=Te(Math.floor(Number(b[t.canopyRank]??8)),[0,rn-1]),T=Math.max(4,Number(b[t.canopyClearance]??8))*a,_=Number(b[t.canopyCover]??30),v=_>=60?3:_>=30?2:1;for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];if(V<0||R<0||V>=h.extent||R>=h.extent)continue;let S=V*w,I=R*w,P=Ie(r.x*q+S,r.y*q+I,11),Z=f(S,I),j=xe(b[t.canopyHeight],on),G=Te(Math.min(T*(v===1?1.3:.95),11)*(.85+ee(P,1)*.25),[3,12]),W=Math.max(0,Math.min(G*.5,T-G/2)),se=ee(P,2)*Math.PI*2;for(let ae=0;ae<v;ae+=1){let H=Ie(P,ae,13),J=se+ae*Math.PI*2/v,re=v===1?W*.3*ee(H,1):W,ne=S+Math.cos(J)*re/(s/q),te=I+Math.sin(J)*re/(s/q);if(ne<0||te<0||ne>=q||te>=q)continue;let le=sn(Z,ee(H,3)),de=G*(.85+ee(H,2)*.3),me=j===void 0?void 0:j*(.85+ee(H,6)*.25),ce=d(le,H,me,le==="palm"?void 0:de);l.push({x:ne,y:te,...ce,turn:ee(H,4),shade:ee(H,5),form:Me.indexOf(le),rank:x,seed:ee(H,7),canopy:1}),c+=1}}}}let A=[],F=e.hedges;if(F){let w=q/F.extent,y=xr/(s/F.extent);for(let b of F.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?kr:0,T=(xe(b.properties[t.height],vr)??Mr)+x;for(let _ of b.geometry){let v=y/2,L=0;for(let O=0;O+3<_.length;O+=2){let[V,R,S,I]=[_[O],_[O+1],_[O+2],_[O+3]],P=Math.hypot(S-V,I-R),Z=(Math.atan2(R-I,S-V)/(Math.PI*2)+1)%1;for(;v<=L+P;){let j=P>0?(v-L)/P:0,G=V+(S-V)*j,W=R+(I-R)*j;if(G>=0&&W>=0&&G<F.extent&&W<F.extent){let se=Ie(r.x*q+G*w,r.y*q+W*w,17);A.push({x:G*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}v+=y}L+=P}}}}let k=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(k(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*k(w.form))),B=l.map(M),C=l.map((w,y)=>y);C.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let z=new Uint8Array(l.length*tn),U=new DataView(z.buffer),E=0,D=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...D(),variants:Array.from({length:k(y)},D)}])),$=(w,y,b)=>{w.count===0&&(w.start=y),w.count+=1;for(let x=b;x<rn;x+=1)w.upTo[x]+=1};C.forEach((w,y)=>{let b=l[w],x=y*tn;U.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),U.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),U.setUint16(x+4,Math.round(b.height*10),!0),U.setUint16(x+6,Math.round(b.crown*10),!0),z[x+8]=Math.floor(b.turn*256)&255,z[x+9]=Math.floor(b.shade*256)&255,z[x+10]=b.form,z[x+11]=b.rank,z[x+12]=Math.floor(b.seed*256)&255,z[x+13]=b.canopy,z[x+14]=B[w],E=Math.max(E,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let N=new Uint8Array(A.length*tn),Y=new DataView(N.buffer);return A.forEach((w,y)=>{let b=y*tn;Y.setUint16(b,Math.min(q-1,Math.round(w.x)),!0),Y.setUint16(b+2,Math.min(q-1,Math.round(w.y)),!0),Y.setUint16(b+4,Math.round(w.height*10),!0),Y.setUint16(b+6,Math.round(Tr*10),!0),N[b+8]=Math.round(w.turn*256)&255,N[b+9]=Math.floor(w.shade*256)&255,N[b+12]=Math.floor(w.seed*256)&255,E=Math.max(E,w.height)}),{trees:z,forms:K,hedges:N,tallest:E,mapped:u,canopy:c}}function _r(e){let n={round:e.round??0,open:e.open??0,tall:e.tall??0};return n.round+n.open+n.tall>0?n:Sn}function sn(e,n){let t=0;for(let o of Me)t+=Math.max(0,e[o]??0);if(t<=0)return sn(Sn,n);let i=n*t;for(let o of Me){let r=Math.max(0,e[o]??0);if(i<r)return o;i-=r}return"round"}function xe(e,n){let t=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):NaN;return Number.isFinite(t)&&t>0?Te(t,n):void 0}function Te(e,[n,t]){return Math.min(t,Math.max(n,e))}function _n([e,n],t){return e+(n-e)*t}function Sr(e,n,t){let i=2**e.z,o=(e.x+n)/i*360-180,r=Math.atan(Math.sinh(Math.PI*(1-2*(e.y+t)/i)))*180/Math.PI;return[o,r]}function Ie(e,n,t){let i=(Math.imul(Math.floor(e)|0,668265261)^Math.imul(Math.floor(n)|0,374761393)^Math.imul(t,2654435761))>>>0;return i=Math.imul(i^i>>>15,2246822507)>>>0,i=Math.imul(i^i>>>13,3266489909)>>>0,(i^i>>>16)>>>0}function ee(e,n){return Ie(e,n,20973)/4294967296}var Lr=[void 0,"Point","LineString","Polygon"];function ft(e,n={}){let t=n.layers?new Set(n.layers):void 0,i={},o=new Bn(e,0,e.length);for(;o.more();){let[r,s]=o.tag();if(r!==3){o.skip(s);continue}let a=o.message(),l=Br(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Br(e,n){let t,i=4096,o=[],r=[],s=[];for(;e.more();){let[a,l]=e.tag();if(a===1?t=e.string():a===2?s.push(e.message()):a===3?o.push(e.string()):a===4?r.push(Ur(e.message())):a===5?i=e.varint():e.skip(l),t!==void 0&&n&&!n.has(t))return}if(!(t===void 0||n&&!n.has(t)))return{name:t,layer:Object.freeze({extent:i,features:Object.freeze(s.flatMap(a=>{let l=Or(a,o,r);return l?[l]:[]}))})}}function Or(e,n,t){let i,o,r={},s=[];for(;e.more();){let[a,l]=e.tag();if(a===1)i=e.varint();else if(a===2){let u=e.packed();for(let c=0;c+1<u.length;c+=2){let f=n[u[c]],d=t[u[c+1]];f!==void 0&&d!==void 0&&(r[f]=d)}}else a===3?o=Lr[e.varint()]:a===4?s=e.packed():e.skip(l)}if(o)return Object.freeze({...i===void 0?{}:{id:i},type:o,properties:Object.freeze(r),geometry:Object.freeze(Cr(s,o))})}function Cr(e,n){let t=[],i,o=0,r=0,s=0;for(;s<e.length;){let a=e[s++],l=a&7,u=a>>>3;if(l===7){i&&i.length>=2&&i.push(i[0],i[1]);continue}if(l!==1&&l!==2)throw new Error(`Unknown geometry command ${l} in vector tile.`);if(s+u*2>e.length)throw new Error("Truncated vector tile geometry.");for(let c=0;c<u;c+=1){if(o+=Ln(e[s++]),r+=Ln(e[s++]),l===1&&(n!=="Point"||c===0)&&t.push(i=[]),!i)throw new Error("Vector tile geometry draws a line before moving to its start.");i.push(o,r)}}return t}var Ln=e=>e%2===1?-(e+1)/2:e/2;function Ur(e){let n="";for(;e.more();){let[t,i]=e.tag();t===1?n=e.string():t===2?n=e.float():t===3?n=e.double():t===4?n=e.varint(!0):t===5?n=e.varint():t===6?n=Ln(e.varint()):t===7?n=e.varint()!==0:e.skip(i)}return n}var Pr=new TextDecoder,Bn=class e{constructor(n,t,i){this.bytes=n;this.end=i;this.position=t,this.view=new DataView(n.buffer,n.byteOffset,n.byteLength)}bytes;end;position;view;more(){return this.position<this.end}tag(){let n=this.varint();return[Math.floor(n/8),n&7]}varint(n=!1){let t=0,i=0;for(let o=0;o<10;o+=1){if(this.position>=this.end)throw new Error("Truncated vector tile.");let r=this.bytes[this.position++];if(o<4?t|=(r&127)<<o*7:o===4?(t|=(r&15)<<28,i=(r&112)>>4):o<9?i|=(r&127)<<(o-5)*7+3:i|=(r&1)<<31,r<128)return n?i*4294967296+(t>>>0):(i>>>0)*4294967296+(t>>>0)}throw new Error("Invalid varint in vector tile.")}span(){let n=this.varint(),t=this.position;if(t+n>this.end)throw new Error("Truncated vector tile.");return this.position=t+n,[t,t+n]}message(){let[n,t]=this.span();return new e(this.bytes,n,t)}string(){let[n,t]=this.span();return Pr.decode(this.bytes.subarray(n,t))}packed(){let[n,t]=this.span(),i=new e(this.bytes,n,t),o=[];for(;i.more();)o.push(i.varint());return o}float(){if(this.position+4>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat32(this.position,!0);return this.position+=4,n}double(){if(this.position+8>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat64(this.position,!0);return this.position+=8,n}skip(n){if(n===0)this.varint();else if(n===1)this.position+=8;else if(n===2)this.span();else if(n===5)this.position+=4;else throw new Error(`Unsupported protocol buffer wire type ${n} in vector tile.`);if(this.position>this.end)throw new Error("Truncated vector tile.")}};function dt(e){return Object.values(e.layers).filter(n=>typeof n=="string")}function mt(e,n){if(e.kind==="buildings"){let r=n(e.layers.building);if(!r)return;let s=n(e.layers.places),a=Kn(r,{...e.options,...s?{places:s}:{}});return a&&et(a)}if(e.kind==="trees"){let r=n(e.layers.tree),s=n(e.layers.canopy),a=n(e.layers.hedge);if(!r&&!s&&!a)return;let l=ct({...r?{trees:r}:{},...s?{canopy:s}:{},...a?{hedges:a}:{}},e.options);return l.trees.length>0||l.hedges.length>0?l:void 0}let t=n(e.layers.streetFurniture),i=n(e.layers.transportation),o=n(e.layers.sidewalk);return it({...t?{streetFurniture:t}:{},...i?{transportation:i}:{},...o?{sidewalks:o}:{}},e.options)}function ht(e,n){if(!n)return[];if(e==="buildings")return nt(n);if(e==="trees"){let{trees:t,hedges:i}=n;return[t.buffer,i.buffer].filter((o,r,s)=>s.indexOf(o)===r)}return[n.lamps.buffer]}function pt(e=16){let n=new Map;return{read(t,i,o){let r=n.get(t);for(n.delete(t),r??={bytes:i,layers:new Map},n.set(t,r);n.size>e;)n.delete(n.keys().next().value);let s=o.filter(l=>!r.layers.has(l));if(s.length>0){let l=ft(r.bytes,{layers:s});for(let u of s)r.layers.set(u,l[u])}let a=r.layers;return l=>l===void 0?void 0:a.get(l)}}}var On=globalThis,zr=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,zr.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();\n'], { type: "text/javascript" })
|
|
4427
|
+
new Blob(['"use strict";(()=>{var Be=new Set,ln=!1;function Pe(e,n,t=2){let i=n&&n.length,o=i?n[0]*t:e.length;Be.size&&Be.clear();let r=In(e,0,o,t,!0),s=[];if(!r||r.next===r.prev)return s;let a=0,l=0,u=0;if(i&&(r=xt(e,n,r,t)),e.length>80*t){a=e[0],l=e[1];let c=a,f=l;for(let d=t;d<o;d+=t){let g=e[d],m=e[d+1];g<a&&(a=g),m<l&&(l=m),g>c&&(c=g),m>f&&(f=m)}u=Math.max(c-a,f-l),u=u!==0?32767/u:0}return un(r,s,a,l,u),s}function In(e,n,t,i,o){let r=null;if(o===Ct(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=En(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=En(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ue(r),r=r.next),r}function ge(e,n=e){let t=n===e,i=e,o;do o=!1,i!==i.next&&(Be.size===0||!Be.has(i))&&(Oe(i,i.next)||Q(i.prev,i,i.next)===0)?((t||i===n)&&(n=i.prev),ln=!0,Ue(i),i=i.prev,o=!0):(t||i!==n)&&(i=i.next,o=!t);while(o||i!==n);return n}function un(e,n,t,i,o){o&&_t(e,t,i,o);let r=e,s=!1;for(;e.prev!==e.next;){let a=e.prev,l=e.next;if(Q(a,e,l)<0&&(o?bt(e,t,i,o):yt(e))){n.push(a.i,e.i,l.i),Ue(e),e=l,r=l;continue}if(e=l,e===r){if(ln=!1,e=ge(e),ln){r=e;continue}if(!s){e=gt(e,n),r=e,s=!0;continue}wt(e,n,t,i,o);break}}}function yt(e){let n=e.prev,t=e,i=e.next,o=n.x,r=t.x,s=i.x,a=n.y,l=t.y,u=i.y,c=Math.min(o,r,s),f=Math.min(a,l,u),d=Math.max(o,r,s),g=Math.max(a,l,u),m=i.next;for(;m!==n;){if(m.x>=c&&m.x<=d&&m.y>=f&&m.y<=g&&!(o===m.x&&a===m.y)&&Ke(o,a,r,l,s,u,m.x,m.y)&&Q(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function bt(e,n,t,i){let o=e.prev,r=e,s=e.next,a=o.x,l=r.x,u=s.x,c=o.y,f=r.y,d=s.y,g=Math.min(a,l,u),m=Math.min(c,f,d),p=Math.max(a,l,u),h=Math.max(c,f,d),A=mn(g,m,n,t,i),_=mn(p,h,n,t,i),v=e.prevZ;for(;v&&v.z>=A;){if(v.x>=g&&v.x<=p&&v.y>=m&&v.y<=h&&v!==s&&!(a===v.x&&c===v.y)&&Ke(a,c,l,f,u,d,v.x,v.y)&&Q(v.prev,v,v.next)>=0)return!1;v=v.prevZ}let M=e.nextZ;for(;M&&M.z<=_;){if(M.x>=g&&M.x<=p&&M.y>=m&&M.y<=h&&M!==s&&!(a===M.x&&c===M.y)&&Ke(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.nextZ}return!0}function gt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Dn(o,t,t.next,r,!1)&&Ce(o,r)&&Ce(r,o)&&(n.push(o.i,t.i,r.i),Ue(t),Ue(t.next),t=e=r,i=!0),t=t.next}while(t!==e);return i?ge(t):t}function wt(e,n,t,i,o){let r=e;do{let s=r.next.next;for(;s!==r.prev;){if(r.i!==s.i&&Lt(r,s)){let a=Vn(r,s);r=ge(r,r.next),a=ge(a,a.next),un(r,n,t,i,o),un(a,n,t,i,o);return}s=s.next}r=r.next}while(r!==e)}var cn=!1;function xt(e,n,t,i){let o=[];for(let r=0,s=n.length;r<s;r++){let a=n[r]*i,l=r<s-1?n[r+1]*i:e.length,u=In(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),vt(e.length/i,n.length),Nn(t,t),cn=!0;for(let r=0;r<o.length;r++)t=Mt(o[r],t);return cn=!1,ge(t)}function Tt(e,n){return e.x-n.x||e.y-n.y||(e.next.y-e.y)/(e.next.x-e.x)-(n.next.y-n.y)/(n.next.x-n.x)}function Mt(e,n){let t=Rt(e,n);if(!t)return n;let i=Vn(t,e),o=i.next;return Nn(t,o.next),ge(i,i.next),ge(t,t.next)}var jn=16,X=new Float64Array(0),Je=0,fn=[],dn=[];function vt(e,n){let t=Math.ceil((e+2*n)/jn)+n+2;X.length<t*4&&(X=new Float64Array(t*4)),Je=0}function Nn(e,n){let t=e;do{let i=Je++;fn[i]=t;let o=t.x,r=t.y,s=t.x,a=t.y,l=0;do{let c=t.next;t.z=i,c.x<o&&(o=c.x),c.x>s&&(s=c.x),c.y<r&&(r=c.y),c.y>a&&(a=c.y),t=c}while(++l<jn&&t!==n);dn[i]=t;let u=i*4;X[u]=o,X[u+1]=r,X[u+2]=s,X[u+3]=a}while(t!==n)}function kt(e,n){let t=e.z*4;n.x<X[t]&&(X[t]=n.x),n.y<X[t+1]&&(X[t+1]=n.y),n.x>X[t+2]&&(X[t+2]=n.x),n.y>X[t+3]&&(X[t+3]=n.y)}function Pn(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function zn(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function Rt(e,n){let t=n,i=e.x,o=e.y,r=-1/0,s;if(Oe(e,t))return t;for(let d=0,g=0;d<Je;d++,g+=4){if(o<X[g+1]||o>X[g+3]||X[g]>i||X[g+2]<=r)continue;let m=Pn(d);t=zn(d);do{if(t.prev.next===t){if(Oe(e,t.next))return t.next;if(o<=t.y&&o>=t.next.y&&t.next.y!==t.y){let p=t.x+(o-t.y)*(t.next.x-t.x)/(t.next.y-t.y);if(p<=i&&p>r&&(r=p,s=t.x<t.next.x?t:t.next,p===i))return s}}t=t.next}while(t!==m)}if(!s)return null;let a=s.x,l=s.y,u=Math.min(o,l),c=Math.max(o,l),f=1/0;for(let d=0,g=0;d<Je;d++,g+=4){if(X[g+2]<a||X[g]>i||X[g+3]<u||X[g+1]>c)continue;let m=Pn(d);t=zn(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Ke(o<l?i:r,o,a,l,o<l?r:i,o,t.x,t.y)){let p=Math.abs(o-t.y)/(i-t.x);(Ce(t,e)||t.y===o&&t.next.y===o&&t.next.x>i)&&(p<f||p===f&&(t.x>s.x||t.x===s.x&&At(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function At(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ke=[],be=new Uint32Array(0),Se=new Uint32Array(0),Le=new Uint32Array(256);function _t(e,n,t,i){let o=e,r=0;do o.z=mn(o.x,o.y,n,t,i),ie[r++]=o,o=o.next;while(o!==e);Ft(r);let s=null;for(let a=0;a<r;a++){let l=ie[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,ie.fill(null,0,r),ke.fill(null,0,r)}function Ft(e){if(e<=32){for(let n=1;n<e;n++){let t=ie[n],i=t.z,o=n-1;for(;o>=0&&ie[o].z>i;)ie[o+1]=ie[o],o--;ie[o+1]=t}return}be.length<e&&(be=new Uint32Array(e),Se=new Uint32Array(e),ke=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ke,Se,0),Xe(e,ke,Se,ie,be,8),Xe(e,ie,be,ke,Se,16),Xe(e,ke,Se,ie,be,24)}function Xe(e,n,t,i,o,r){Le.fill(0);for(let a=0;a<e;a++)Le[t[a]>>>r&255]++;let s=0;for(let a=0;a<256;a++){let l=Le[a];Le[a]=s,s+=l}for(let a=0;a<e;a++){let l=t[a],u=Le[l>>>r&255]++;i[u]=n[a],o[u]=l}}function mn(e,n,t,i,o){return e=(e-t)*o|0,n=(n-i)*o|0,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,n=(n|n<<8)&16711935,n=(n|n<<4)&252645135,n=(n|n<<2)&858993459,n=(n|n<<1)&1431655765,e|n<<1}function St(e){let n=e,t=e;do(n.x<t.x||n.x===t.x&&n.y<t.y)&&(t=n),n=n.next;while(n!==e);return t}function Ke(e,n,t,i,o,r,s,a){return(o-s)*(n-a)>=(e-s)*(r-a)&&(e-s)*(i-a)>=(t-s)*(n-a)&&(t-s)*(r-a)>=(o-s)*(i-a)}function Lt(e,n){let t=Oe(e,n)&&Q(e.prev,e,e.next)>0&&Q(n.prev,n,n.next)>0;return e.next.i!==n.i&&(t||Ce(e,n)&&Ce(n,e)&&(Q(e.prev,e,n.prev)!==0||Q(e,n.prev,n)!==0))&&!Bt(e,n)&&(t||Ot(e,n))}function Q(e,n,t){return(n.y-e.y)*(t.x-n.x)-(n.x-e.x)*(t.y-n.y)}function Oe(e,n){return e.x===n.x&&e.y===n.y}function Dn(e,n,t,i,o=!0){let r=Q(e,n,t),s=Q(e,n,i),a=Q(t,i,e),l=Q(t,i,n);return(r>0&&s<0||r<0&&s>0)&&(a>0&&l<0||a<0&&l>0)?!0:o?!!(r===0&&Ye(e,t,n)||s===0&&Ye(e,i,n)||a===0&&Ye(t,e,i)||l===0&&Ye(t,n,i)):!1}function Ye(e,n,t){return n.x<=Math.max(e.x,t.x)&&n.x>=Math.min(e.x,t.x)&&n.y<=Math.max(e.y,t.y)&&n.y>=Math.min(e.y,t.y)}function Bt(e,n){let t=Math.min(e.x,n.x),i=Math.max(e.x,n.x),o=Math.min(e.y,n.y),r=Math.max(e.y,n.y),s=e;do{let a=s.next;if(s.x>i&&a.x>i||s.x<t&&a.x<t||s.y>r&&a.y>r||s.y<o&&a.y<o){s=a;continue}if(s.i!==e.i&&a.i!==e.i&&s.i!==n.i&&a.i!==n.i&&Dn(s,a,e,n))return!0;s=a}while(s!==e);return!1}function Ce(e,n){return Q(e.prev,e,e.next)<0?Q(e,n,e.next)>=0&&Q(e,e.prev,n)>=0:Q(e,n,e.prev)<0||Q(e,e.next,n)<0}function Ot(e,n){let t=e,i=!1,o=(e.x+n.x)/2,r=(e.y+n.y)/2;do{let s=t.next;t.y>r!=s.y>r&&o<(s.x-t.x)*(r-t.y)/(s.y-t.y)+t.x&&(i=!i),t=s}while(t!==e);return i}function Vn(e,n){let t=hn(e.i,e.x,e.y),i=hn(n.i,n.x,n.y),o=e.next,r=n.prev;return e.next=n,n.prev=e,t.next=o,o.prev=t,i.next=t,t.prev=i,r.next=i,i.prev=r,i}function En(e,n,t,i){let o=hn(e,n,t);return i?(o.next=i.next,o.prev=i,i.next.prev=o,i.next=o):(o.prev=o,o.next=o),o}function Ue(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ),cn&&kt(e.prev,e.next)}function hn(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Ct(e,n,t,i){let o=0;for(let r=n,s=t-i;r<t;r+=i)o+=(e[s]-e[r])*(e[r+1]+e[s+1]),s=r;return o}var Ut=.7,Pt=Math.tan(Math.PI/6),zt=Math.tan(35*Math.PI/180),Et=Math.tan(Math.PI/18),ze=.65,Ee=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Nt(e);if(!l||Math.abs(pn(e))<Ut*4*l.halfU*l.halfV)return;let u=l.u,c=l.v,f=l.halfU*r,d=l.halfV*r;f<d&&([u,c,f,d]=[c,u,d,f]);let g=Gn(t.roof_direction),m=g===void 0?void 0:[Math.sin(g*Math.PI/180),-Math.cos(g*Math.PI/180)];(m!==void 0?Math.abs(m[0]*u[0]+m[1]*u[1])>Math.abs(m[0]*c[0]+m[1]*c[1]):t.roof_orientation==="across")&&a!=="skillion"&&([u,c,f,d]=[c,u,d,f]);let h=jt(a,f,d,m&&[$n(m,u),$n(m,c)]);if(!h)return;let A=Math.max(0,o-i),_=Gn(t.roof_height),v,M;if(_!==void 0&&_>0)M=o,v=Math.max(i+Math.min(2,A/2),o-_);else{let y=Math.min(It(a,d),A*.6,30);t.height_source==="height"?(M=o,v=o-y):(v=o,M=o+y)}let B=M-v;if(!(B>=.3))return;let[C,z]=l.centre,U=(y,b)=>{let x=(y-C)*r,T=(b-z)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},E=(y,b)=>[C+(y*u[0]+b*c[0])/r,z+(y*u[1]+b*c[1])/r],D=(y,b)=>{let x=1/0;for(let[T,F,k]of h)x=Math.min(x,T*y+F*b+k);return Math.max(0,x)},K=(y,b)=>v+B*D(...U(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...U(n[y],n[y+1]));pn($)<0&&Ht($);let N=1.01,Y=[-f*N,-d*N,f*N,-d*N,f*N,d*N,-f*N,d*N],w=[];for(let[y,b]of h.entries()){let x=Y;for(let[P,Z]of h.entries()){if(P===y)continue;let j=b[0]-Z[0],G=b[1]-Z[1],W=b[2]-Z[2];if(Math.abs(j)+Math.abs(G)+Math.abs(W)<1e-9){P<y&&(x=[]);continue}if(x=Hn(x,j,G,W),x.length<6)break}if(x.length<6)continue;let T=$,F=x.length/2;for(let P=0;P<F&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%F*2],x[(P+1)%F*2+1]];T=Hn(T,W-j,Z-G,-(W-j)*Z-(Z-G)*j)}if(T.length<6||Math.abs(pn(T))<1e-6)continue;let k=[];for(let P=0;P<T.length;P+=2)k.push(...E(T[P],T[P+1]));let L=Pe(k);if(L.length===0)continue;let O=B*b[0],V=B*b[1],R=O*u[0]+V*c[0],S=O*u[1]+V*c[1],I=Math.hypot(R,S,1);w.push({ring:k,triangles:L,normal:[-R/I,-S/I]})}if(w.length!==0)return{eaves:v,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[F,k]=U(y,b),[L,O]=U(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let I=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=I(F,k),Z=I(L,O);if(P===Z||P*Z>0)continue;let j=P/(P-Z);if(j<=1e-4||j>=1-1e-4)continue;let G=F+(L-F)*j,W=k+(O-k)*j;h[R][0]*G+h[R][1]*W+h[R][2]<=D(G,W)+1e-6&&V.push(j)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,S)=>R-S)}}}function It(e,n){switch(e){case"skillion":return 2*n*Et;case"pyramidal":return n*zt;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Pt}}function jt(e,n,t,i){let o=n,r=t,s=[[0,-1/r,1],[0,1/r,1]],a=u=>u.flatMap(c=>[1,-1].flatMap(f=>{let d=c==="v"?r:o,g=ze/(Ee*r)*f,m=(1-ze)/((1-Ee)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),ze/(Ee*r)*d],[...p(m),ze+(1-ze)/((1-Ee)*r)*(d-Ee*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return s;case"saltbox":{let u=r/3;return[[0,-1/(r-u),1+u/(r-u)],[0,1/(r+u),1-u/(r+u)]]}case"hipped":return[...s,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...s,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...s,[-1/o,0,1],[1/o,0,1]];case"gambrel":return a(["v"]);case"mansard":return a(["v","u"]);case"skillion":{let[u,c]=i??[0,1],f=Math.abs(u)*o+Math.abs(c)*r;return f>0?[[-u/(2*f),-c/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return[1,-1].map(f=>[0,-f*u/(r*c),1/c])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return Array.from({length:12},(f,d)=>{let g=d*Math.PI/6;return[-u*Math.cos(g)/(o*c),-u*Math.sin(g)/(r*c),1/c]})})];default:return}}function Hn(e,n,t,i){let o=e.length/2,r=[];for(let s=0;s<o;s+=1){let a=e[s*2],l=e[s*2+1],u=e[(s+1)%o*2],c=e[(s+1)%o*2+1],f=n*a+t*l+i,d=n*u+t*c+i;if(f<=0&&r.push(a,l),f<0&&d>0||f>0&&d<0){let g=f/(f-d);r.push(a+(u-a)*g,l+(c-l)*g)}}return r}function Nt(e){let n=Dt(e);if(n.length<3)return;let t,i=1/0;for(let o=0;o<n.length;o+=1){let[r,s]=n[o],[a,l]=n[(o+1)%n.length],u=Math.hypot(a-r,l-s);if(u===0)continue;let c=[(a-r)/u,(l-s)/u],f=[-c[1],c[0]],[d,g,m,p]=[1/0,-1/0,1/0,-1/0];for(let[A,_]of n){let v=A*c[0]+_*c[1],M=A*f[0]+_*f[1];d=Math.min(d,v),g=Math.max(g,v),m=Math.min(m,M),p=Math.max(p,M)}let h=(g-d)*(p-m);if(h<i){i=h;let A=(d+g)/2,_=(m+p)/2;t={centre:[A*c[0]+_*f[0],A*c[1]+_*f[1]],u:c,v:f,halfU:(g-d)/2,halfV:(p-m)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function Dt(e){let n=[];for(let r=0;r+1<e.length;r+=2)n.push([e[r],e[r+1]]);n.sort((r,s)=>r[0]-s[0]||r[1]-s[1]);let t=(r,s,a)=>(s[0]-r[0])*(a[1]-r[1])-(s[1]-r[1])*(a[0]-r[0]),i=[];for(let r of n){for(;i.length>=2&&t(i.at(-2),i.at(-1),r)<=0;)i.pop();i.push(r)}let o=[];for(let r of n.reverse()){for(;o.length>=2&&t(o.at(-2),o.at(-1),r)<=0;)o.pop();o.push(r)}return[...i.slice(0,-1),...o.slice(0,-1)]}function Vt(e,n){let[t,i,o,r]=[1/0,-1/0,1/0,-1/0];for(let a=0;a+1<e.length;a+=2)t=Math.min(t,e[a]),i=Math.max(i,e[a]),o=Math.min(o,e[a+1]),r=Math.max(r,e[a+1]);let s=e.length/2;for(let a=0;a<s;a+=1){let l=e[a*2],u=e[a*2+1],c=e[(a+1)%s*2],f=e[(a+1)%s*2+1];if(t<0&&l===t&&c===t||i>n&&l===i&&c===i||o<0&&u===o&&f===o||r>n&&u===r&&f===r)return!0}return!1}function pn(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n/2}function Ht(e){let n=[];for(let t=0;t<e.length;t+=2)n.push([e[t],e[t+1]]);n.reverse(),e.splice(0,e.length,...n.flat())}function $n(e,n){return e[0]*n[0]+e[1]*n[1]}function Gn(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var $t=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Nr=Object.freeze(Object.keys($t));var Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6});var Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024,parts:16});function yn(e,n,t){for(let i of e){let o=!1;for(let r=0,s=i.length-2;r<i.length;s=r,r+=2){let a=i[r],l=i[r+1],u=i[s],c=i[s+1];l>t!=c>t&&n<(u-a)*(t-l)/(c-l)+a&&(o=!o)}if(o)return!0}return!1}function Yn(e,n,t){for(let i of n){let[o,r,s,a]=Xn(i);for(let l of e){let[u,c,f,d]=Xn(l);if(!(u>s-t||f<o+t||c>a-t||d<r+t)&&(Wn(l,i,t)||Wn(i,l,t)))return!0}}return!1}function Wn(e,n,t){let i=(o,r)=>yn([n],o,r)&&Zt(n,o,r)>t;for(let o=0;o+1<e.length;o+=2)if(i(e[o],e[o+1]))return!0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=[0,1];for(let f=0,d=n.length-2;f<n.length;d=f,f+=2){let g=Gt(s,a,l,u,n[d],n[d+1],n[f],n[f+1]);g!==void 0&&c.push(g)}if(c.length!==2){c.sort((f,d)=>f-d);for(let f=1;f<c.length;f+=1){let d=(c[f-1]+c[f])/2;if(i(s+(l-s)*d,a+(u-a)*d))return!0}}}return!1}function Gt(e,n,t,i,o,r,s,a){let l=t-e,u=i-n,c=s-o,f=a-r,d=l*f-u*c;if(d===0)return;let g=((o-e)*f-(r-n)*c)/d,m=((o-e)*u-(r-n)*l)/d;return g>0&&g<1&&m>=0&&m<=1?g:void 0}function Zt(e,n,t){let i=1/0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=(l-s)**2+(u-a)**2,f=c>0?Math.max(0,Math.min(1,((n-s)*(l-s)+(t-a)*(u-a))/c)):0;i=Math.min(i,Math.hypot(n-(s+(l-s)*f),t-(a+(u-a)*f)))}return i}function Xn(e){let[n,t,i,o]=[1/0,1/0,-1/0,-1/0];for(let r=0;r+1<e.length;r+=2)n=Math.min(n,e[r]),i=Math.max(i,e[r]),t=Math.min(t,e[r+1]),o=Math.max(o,e[r+1]);return[n,t,i,o]}var ue=8192,pe=28,Wt={commercial:1,active:2,destination:3},Xt={residential:1,...Object.fromEntries(["civic","commercial","education","entertainment","medical","transportation"].map(e=>[e,2])),...Object.fromEntries(["agricultural","industrial","military","outbuilding","religious","service"].map(e=>[e,3]))},Yt={dining:1,entertainment:2,nightlife:3},bn={...Object.fromEntries(["alcoholic_beverage_venue","bar","beer","biergarten","brewery","casino","cocktail_bar","dance_club","karaoke","lounge","music_venue","night_club","nightclub","pub","wine_bar"].map(e=>[e,3])),...Object.fromEntries(["arts_centre","bowling_alley","cinema","comedy_club","concert_hall","movie_theater","opera","performing_arts_venue","theater","theatre","theatre_venue"].map(e=>[e,2])),...Object.fromEntries(["casual_eatery","fast_food","fast_food_restaurant","food_court","restaurant"].map(e=>[e,1]))},Jt=6,Kt=.5,Qt=.5;function Kn(e,n){let t=ue/e.extent,i=n.tileMetres/ue,o=n.defaultHeight??5,r=Number.isFinite(n.edgeRadius)?Math.max(0,Math.min(1.5,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=tr(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let C=B.properties,z=C.hide_3d;if(z===!0||z===1||z==="1"||z==="true")continue;let U=Math.min(6e3,Jn(C.render_height)??o),E=Math.min(U,Jn(C.render_min_height)??0),D=Wt[String(C.building_tone??"")]??0,K=Xt[String(C.class??"")]??0,$=d.get(M)??0,N=u.length,Y=!1;for(let w of rr(B.geometry,t)){let y=w.map(ir).filter(S=>S.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=or(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Qt/i)))continue;let T={cell:Math.min(7,Math.max(0,Math.floor(x/1024)))*8+Math.min(7,Math.max(0,Math.floor(b/1024))),bounds:[1/0,1/0,-1/0,-1/0,U+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let I=0;I<S.length;I+=2)T.bounds[0]=Math.min(T.bounds[0],S[I]-1),T.bounds[1]=Math.min(T.bounds[1],S[I+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[I]+1),T.bounds[3]=Math.max(T.bounds[3],S[I+1]+1);Y=!0,f=Math.max(f,U);let F=Number.isSafeInteger(B.id),k=gn(F?B.id*.0731:b*.0731+x*.19137+N*1.618),L=!F&&y[0].some(S=>S<=0||S>=ue)?gn(U*7.31+E*3.17+D):k,O={base:E,top:U,jitter:L,seed:k,tone:D,group:K,use:$,cx:b,cy:x,index:N},V=y.map((S,I)=>nr(S,I,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],C,E,U,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),er(R,O,s,a)):qt(y,O,s,a);for(let[S,I]of y.entries()){let P=qe(I)>0,Z=S===0?P?-1:1:P?1:-1,j=I.length/2,G=H=>{let J=(H%j+j)%j;return[I[J*2],I[J*2+1]]},W=H=>{let[J,re]=G(H-1),[ne,te]=G(H),[le,de]=G(H+1);if(we(J,re,ne,te)||we(ne,te,le,de))return!1;let me=Math.hypot(ne-J,te-re),ce=Math.hypot(le-ne,de-te);if(!me||!ce)return!1;let je=-(te-re)/me*Z,Ne=(ne-J)/me*Z;return(je*(le-ne)+Ne*(de-te))/ce>Kt},se=(H,J)=>R?R.heightAt(H,J):U,ae=0;for(let H=0;H<j;H+=1){let[J,re]=G(H),[ne,te]=G(H+1),le=Math.hypot(ne-J,te-re);if(le===0||we(J,re,ne,te))continue;let de=-(te-re)/le*Z,me=(ne-J)/le*Z,ce=V[S].normals[H]??[de,me],je=V[S].normals[(H+1)%j]??[de,me],Ne=oe=>{let Ae=ce[0]+(je[0]-ce[0])*oe,_e=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(Ae,_e)||1;return[Ae/ye,_e/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let Ae=oe===0,_e=oe+2===he.length,ye=J+(ne-J)*he[oe],De=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],He=re+(te-re)*he[oe+1],Fe=Math.hypot(Ve-ye,He-De)/ue*n.tileMetres,$e=(Ae&&W(H)?1:0)|(_e&&W(H+1)?2:0)|(S>0?4:0),Ge=(Ae&&xn(J,re)?1:0)|(_e&&xn(ne,te)?2:0),an=ae+Fe,Ze=Ne(he[oe]),We=Ne(he[oe+1]),Cn=se(ye,De),Un=se(Ve,He),ve=s.write(O,ye,De,0,Ze[0],Ze[1],1,ae,$e,Fe,0,Ge,Cn);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Fe,1,Ge,Un),s.write(O,ye,De,1,Ze[0],Ze[1],1,ae,$e,Fe,0,Ge,Cn),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Fe,1,Ge,Un),l.push(ve,ve+1,ve+2,ve+1,ve+3,ve+2),ae=an}}}T.roofsCount=a.length-T.roofsFrom,T.wallsCount=l.length-T.wallsFrom,c.push(T)}Y&&u.push(C)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,A=a.values(),_=l.values();c.sort((M,B)=>M.cell-B.cell);let v=-1;for(let M of c){M.cell!==v&&(v=M.cell,m.push({bounds:[...M.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let C=0;C<5;C+=1)B.bounds[C]=C<2?Math.min(B.bounds[C],M.bounds[C]):Math.max(B.bounds[C],M.bounds[C]);g.set(A.subarray(M.roofsFrom,M.roofsFrom+M.roofsCount),p),g.set(_.subarray(M.wallsFrom,M.wallsFrom+M.wallsCount),h),p+=M.roofsCount,h+=M.wallsCount,B.roofsCount+=M.roofsCount,B.wallsCount+=M.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function qt(e,n,t,i){let o=[],r=[];for(let l of e)r.push(o.length/2),o.push(...l);r.push(o.length/2);let s=(l,u)=>{let c=r.findIndex((p,h)=>l>=p&&l<r[h+1]),[f,d]=[r[c],r[c+1]-1];if(u<f||u>d)return!1;let[g,m]=l<u?[l,u]:[u,l];return m-g!==1&&!(g===f&&m===d)?!1:!we(o[l*2],o[l*2+1],o[u*2],o[u*2+1])},a=Pe(o,r.slice(1,-1),2);for(let l=0;l+2<a.length;l+=3){let u=[a[l],a[l+1],a[l+2]],c=0;for(let f=0;f<3;f+=1)s(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries())i.push(t.write(n,o[d*2],o[d*2+1],1,0,0,0,0,0,0,f,c))}}function er(e,n,t,i){for(let o of e.faces){let r=o.ring,s=r.length/2,a=(l,u)=>{let[c,f]=l<u?[l,u]:[u,l];return f-c!==1&&!(c===0&&f===s-1)?!1:!we(r[l*2],r[l*2+1],r[u*2],r[u*2+1])};for(let l=0;l+2<o.triangles.length;l+=3){let u=[o.triangles[l],o.triangles[l+1],o.triangles[l+2]],c=0;for(let f=0;f<3;f+=1)a(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries()){let g=r[d*2],m=r[d*2+1];i.push(t.write(n,g,m,1,o.normal[0],o.normal[1],0,0,0,0,f,c,e.heightAt(g,m)))}}}}function nr(e,n,t,i=Math.PI/6){if(t<1)return{ring:e,normals:[]};let o=e.length/2,r=qe(e)>0,s=n===0?r?-1:1:r?1:-1,a=[],l=[],u=(c,f,d)=>{c=Re(c),f=Re(f),!(a.at(-2)===c&&a.at(-1)===f)&&(a.push(c,f),l.push(d))};for(let c=0;c<o;c+=1){let f=(c+o-1)%o,d=(c+1)%o,[g,m]=[e[f*2],e[f*2+1]],[p,h]=[e[c*2],e[c*2+1]],[A,_]=[e[d*2],e[d*2+1]],v=Math.hypot(p-g,h-m),M=Math.hypot(A-p,_-h);if(!v||!M||xn(p,h)||we(g,m,p,h)||we(p,h,A,_)){u(p,h);continue}let[B,C]=[(p-g)/v,(h-m)/v],[z,U]=[(A-p)/M,(_-h)/M],E=Math.atan2(B*U-C*z,B*z+C*U);if(E*s>=-.08||Math.abs(E)>Math.PI*.85){u(p,h);continue}let D=Math.tan(Math.abs(E)/2),K=Math.min(t*D,v*.2,M*.2),$=K/D;if($<1){u(p,h);continue}let[N,Y]=[-C*s,B*s],[w,y]=[p-B*K-N*$,h-C*K-Y*$],b=Math.atan2(Y,N),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(E)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let F=b+E*T/x,k=[Math.cos(F),Math.sin(F)];u(w+k[0]*$,y+k[1]*$,k)}}return a[0]===a.at(-2)&&a[1]===a.at(-1)&&(a.splice(-2),l.pop()),a.length>=6?{ring:a,normals:l}:{ring:e,normals:[]}}var wn=class{#e=new ArrayBuffer(4096*pe);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s,a,l,u,c,f=0,d=0,g=n.top){let m=pe;if((this.count+1)*m>this.#e.byteLength){let A=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(A).set(new Uint8Array(this.#e)),this.#e=A,this.#n=new DataView(A)}let p=this.#n,h=this.count*m;return p.setUint16(h,Re(t),!0),p.setUint16(h+2,Re(i),!0),p.setUint16(h+4,Math.min(65535,Math.round(n.base*10)),!0),p.setUint16(h+6,Math.min(65535,Math.max(0,Math.round(g*10))),!0),p.setInt8(h+8,Math.round(r*127)),p.setInt8(h+9,Math.round(s*127)),p.setUint8(h+10,o),p.setUint8(h+11,a),p.setUint16(h+12,Math.round(l*10)%65536,!0),p.setUint8(h+14,Math.round(n.jitter*255)),p.setUint8(h+15,Math.round(n.seed*255)),p.setUint16(h+16,Re(n.cx),!0),p.setUint16(h+18,Re(n.cy),!0),p.setUint8(h+20,n.tone+4*n.group),p.setUint8(h+21,n.use),p.setUint8(h+22,u),p.setUint8(h+23,Math.min(255,Math.round(c))),p.setUint16(h+24,n.index,!0),p.setUint8(h+26,f),p.setUint8(h+27,d),this.count+=1,this.count-1}bytes(){return new Uint8Array(this.#e.slice(0,this.count*pe))}},Qe=class{#e=new Uint32Array(8192);length=0;push(...n){if(this.length+n.length>this.#e.length){let t=new Uint32Array(Math.max(this.length+n.length,this.#e.length*2));t.set(this.#e),this.#e=t}for(let t of n)this.#e[this.length++]=t}values(){return this.#e.subarray(0,this.length)}};function tr(e,n){let t=new Map;if(e.features.some(a=>a.properties.night_use!==void 0)){for(let[a,l]of e.features.entries()){let u=Yt[String(l.properties.night_use??"")];u&&t.set(a,u)}return t}let i=n.places;if(!i||i.features.length===0)return t;let o=Jt/n.tileMetres*e.extent,r=[];for(let[a,l]of e.features.entries()){if(l.type!=="Polygon")continue;let u=l.properties.hide_3d;if(u===!0||u===1||u==="1"||u==="true")continue;let c=[1/0,1/0,-1/0,-1/0];for(let f of l.geometry)for(let d=0;d+1<f.length;d+=2)c[0]=Math.min(c[0],f[d]),c[1]=Math.min(c[1],f[d+1]),c[2]=Math.max(c[2],f[d]),c[3]=Math.max(c[3],f[d+1]);r.push({index:a,rings:l.geometry,box:c})}let s=e.extent/i.extent;for(let a of i.features){if(a.type!=="Point")continue;let l=a.properties,u=bn[String(l.type??"")]??bn[String(l.subclass??"")]??bn[String(l.class??"")];if(u)for(let c of a.geometry)for(let f=0;f+1<c.length;f+=2){let d=c[f]*s,g=c[f+1]*s,m,p,h=o;for(let _ of r){let[v,M,B,C]=_.box;if(d<v-o||d>B+o||g<M-o||g>C+o)continue;let z=!1;for(let U of _.rings)for(let E=0,D=U.length-2;E+1<U.length;D=E,E+=2){let K=U[D],$=U[D+1],N=U[E],Y=U[E+1];Y>g!=$>g&&d<(K-N)*(g-Y)/($-Y)+N&&(z=!z);let w=N-K,y=Y-$,b=w*w+y*y,x=b?Math.min(1,Math.max(0,((d-K)*w+(g-$)*y)/b)):0,T=Math.hypot(d-K-x*w,g-$-x*y);T<h&&(h=T,p=_.index)}if(z){m=_.index;break}}let A=m??p;A!==void 0&&t.set(A,Math.max(t.get(A)??0,u))}}return t}function Re(e){return Math.min(ue,Math.max(0,Math.round(e)))}function Jn(e){let n=Number(e);return Number.isFinite(n)&&n>0?n:void 0}function rr(e,n){let t=[],i;for(let o of e){let r=[];for(let a=0;a+1<o.length;a+=2){let l=o[a]*n,u=o[a+1]*n;r.length&&l===r.at(-2)&&u===r.at(-1)||r.push(l,u)}if(r.length>=6&&r[0]===r.at(-2)&&r[1]===r.at(-1)&&(r.length-=2),r.length<6)continue;let s=Math.sign(qe(r));s&&(i??=s,s===i||t.length===0?t.push([r]):t.at(-1).push(r))}return t}function qe(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n}function or(e){let n=0,t=0,i=e.length/2;for(let o=0;o<i;o+=1)n+=e[o*2],t+=e[o*2+1];return[n/i,t/i]}function xn(e,n){return e<=0||n<=0||e>=ue||n>=ue}function we(e,n,t,i){let o=ue;return e<=0&&t<=0||e>=o&&t>=o||n<=0&&i<=0||n>=o&&i>=o}function ir(e){let n=ue,t=[...e],i=[[0,0,o=>o>=0],[0,n,o=>o<=n],[1,0,o=>o>=0],[1,n,o=>o<=n]];for(let[o,r,s]of i){let a=[],l=t.length/2;for(let u=0;u<l;u+=1){let c=[t[u*2],t[u*2+1]],f=[t[(u+1)%l*2],t[(u+1)%l*2+1]],d=s(c[o]),g=s(f[o]);if(d&&a.push(c[0],c[1]),d!==g){let m=(r-c[o])/(f[o]-c[o]);a.push(c[0]+(f[0]-c[0])*m,c[1]+(f[1]-c[1])*m)}}if(t=a,t.length<6)return[]}return t}function gn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var Qn=`\nin float v_haze_depth;\nuniform vec3 u_haze_colour;\nuniform vec3 u_haze; // strength; the view depths where the haze starts and is complete\n\nfloat hazeOf() {\n return u_haze.x > 0.0 ? u_haze.x * smoothstep(u_haze.y, u_haze.z, v_haze_depth) : 0.0;\n}\n\nvec3 hazed(vec3 colour) {\n return mix(colour, u_haze_colour, hazeOf());\n}`;function qn(e){let n=(e.indices.length-e.wallsFrom)/6,t=new Uint8Array(n*16);for(let i=0;i<n;i+=1){let o=e.wallsFrom+i*6,r=e.indices[o]*pe,s=e.indices[o+1]*pe;t.set(e.vertices.subarray(r,r+4),i*16),t.set(e.vertices.subarray(s,s+4),i*16+4),t.set(e.vertices.subarray(r+4,r+8),i*16+8),t[i*16+12]=e.vertices[r+14],t[i*16+13]=e.vertices[r+27]}return t}var Kr=`#version 300 es\nprecision highp float;\nuniform highp sampler2D u_contact;\n${Qn}\nout vec4 fragColor;\nvoid main() {\n float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());\n fragColor = vec4(vec3(shade), 1.0);\n}`;function et(e){let n=e.vertices.length/pe;return{mesh:{...e.groups?{groups:e.groups}:{},wallsFrom:e.wallsFrom,top:e.top,features:e.features,vertexCount:n,indexCount:e.indices.length},data:{vertices:e.vertices,indices:n<=65536?Uint16Array.from(e.indices):e.indices,contact:qn(e)}}}function nt({data:e}){return[e.vertices.buffer,e.indices.buffer,e.contact.buffer]}function Tn(e){let n=sr(e);return n?[Math.min(1,Math.max(0,n[0]/255)),Math.min(1,Math.max(0,n[1]/255)),Math.min(1,Math.max(0,n[2]/255)),Math.min(1,Math.max(0,n[3]))]:null}function sr(e){let n=e.trim().toLowerCase(),t=/^#([\\da-f]{3,8})$/u.exec(n)?.[1];if(t&&[3,4,6,8].includes(t.length)){let A=(t.length<=4?[...t].map(_=>_+_).join(""):t).match(/../gu).map(_=>Number.parseInt(_,16));return[A[0],A[1],A[2],A.length>3?A[3]/255:1]}let i=/^(rgba?|hsla?)\\(([^)]+)\\)$/u.exec(n);if(!i)return null;let o=i[2].split(/[\\s,/]+/u).filter(Boolean);if(o.length<3||o.length>4)return null;let r=o[3]===void 0?1:en(o[3],1);if(i[1].startsWith("rgb")){let[h,A,_]=o.slice(0,3).map(v=>en(v,255));return[h,A,_,r].some(v=>v===null)?null:[h,A,_,r]}let s=Number.parseFloat(o[0]),a=en(o[1],1),l=en(o[2],1);if(!Number.isFinite(s)||a===null||l===null||r===null)return null;let u=(1-Math.abs(2*l-1))*a,c=(s%360+360)%360/60,f=u*(1-Math.abs(c%2-1)),[d,g,m]=c<1?[u,f,0]:c<2?[f,u,0]:c<3?[0,u,f]:c<4?[0,f,u]:c<5?[f,0,u]:[u,0,f],p=l-u/2;return[(d+p)*255,(g+p)*255,(m+p)*255,r]}function en(e,n){let t=e.endsWith("%"),i=Number.parseFloat(e);return Number.isFinite(i)?t?i/100*n:i:null}var fe=8192,Mn=12,ar={primary:{spacing:30,kerb:10},secondary:{spacing:32,kerb:8.5},tertiary:{spacing:34,kerb:7},minor:{spacing:36,kerb:5.5},pedestrian:{spacing:26,kerb:3}},lr={motorway:{spacing:45,kerb:14},trunk:{spacing:40,kerb:12},service:{spacing:38,kerb:4},path:{spacing:28,kerb:1.5},track:{spacing:40,kerb:2.5}},ur={spacing:30,kerb:0},cr=12,fr=18,dr=9,mr={sodium:"#ffa64d",high_pressure_sodium:"#ffa64d",low_pressure_sodium:"#ff9326",led:"#fff1db",mercury:"#e3ecff",metal_halide:"#f4f4ff",fluorescent:"#eef9ff",electric:"#ffd59a",incandescent:"#ffd59a",halogen:"#ffe3b0",gas:"#ffd28a",gaslight:"#ffd28a"},hr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},pr=new Set(["wall","wall_mounted","wall_bracket"]),yr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new kn,o=new nn(fr),r=new nn(dr),s=e.streetFurniture;if(s){let m=fe/s.extent;for(let p of s.features){let h=p.properties;if(p.type!=="Point"||h.subclass!=="street_lamp")continue;let A=br(h),_=gr(h),v=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,A*1.7*(v>1?1.15:1)));for(let B of p.geometry)for(let C=0;C+1<B.length;C+=2){let z=B[C]*m,U=B[C+1]*m;if(!rt(z,U))continue;i.write(z,U,A,M,!0,_);let E=ot(z,U,n.tileMetres);o.add(...E),r.add(...E)}}}let a=i.count;if(t==="none")return i.done(a);let l=e.transportation,u=0;if(l){let m=n.tileMetres/l.extent;for(let p of l.features)if(!(p.type!=="LineString"||!tt(p.properties,"streets")))for(let h of p.geometry)u+=wr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=cr,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,A)=>{let _=fe/m.extent,v=[];for(let D=0;D+1<p.length;D+=2)v.push(p[D]*_,p[D+1]*_);let M=n.tileMetres/fe,B=h.kerb*.45/M,C=Rn(v[0]*.013+v[1]*.029+A)*h.spacing,z=0,U=C,E=Rn(v[0]+v[1]*3.1)<.5?1:-1;for(let D=2;D<v.length;D+=2){let K=v[D-2],$=v[D-1],N=v[D],Y=v[D+1],w=Math.hypot(N-K,Y-$)*M;if(w!==0){for(;U<=z+w;){let y=(U-z)/w,b=-(Y-$)/(w/M)*E,x=(N-K)/(w/M)*E,T=K+(N-K)*y+b*B,F=$+(Y-$)*y+x*B;if(U+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(E=-E),!rt(T,F))continue;let k=ot(T,F,n.tileMetres);o.near(...k)||r.near(...k)||(r.add(...k),i.write(T,F,7,15,!1))}z+=w}}};if(l)for(let m of l.features){if(m.type!=="LineString")continue;let p=tt(m.properties,f);if(p)for(let h of m.geometry)d(l,h,p,1)}let g=e.sidewalks;if(g){for(let m of g.features)if(!(m.type==="Point"||!vn(m.properties.lit)))for(let p of m.geometry)d(g,p,ur,2)}return i.done(a)}function tt(e,n){if(e.brunnel==="tunnel"||e.covered===!0)return;let t=e.lit;if(t===!1||t==="no")return;let i=String(e.class??""),o=String(e.subclass??""),r=i==="path"&&(o==="pedestrian"||o==="living_street")?"pedestrian":i,s=ar[r];if(s&&(n==="streets"||vn(t)))return s;let a=lr[r];if(a&&vn(t))return a}function vn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function br(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return pr.has(t)?4.5:yr.has(t)?7.5:7}function gr(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(hr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=mr[t];if(!i)return;let o=Tn(i);return[o[0],o[1],o[2]]}function rt(e,n){return e>=0&&n>=0&&e<fe&&n<fe}function ot(e,n,t){return[e/fe*t,n/fe*t]}function wr(e,n){let t=0;for(let i=2;i+1<e.length;i+=2){let o=(e[i-2]+e[i])/2,r=(e[i-1]+e[i+1])/2;o<0||r<0||o>=n||r>=n||(t+=Math.hypot(e[i]-e[i-2],e[i+1]-e[i-1]))}return t}var nn=class{constructor(n){this.size=n}size;#e=new Map;add(n,t){let i=`${Math.floor(n/this.size)}/${Math.floor(t/this.size)}`,o=this.#e.get(i);o?o.push([n,t]):this.#e.set(i,[[n,t]])}near(n,t){let i=Math.floor(n/this.size),o=Math.floor(t/this.size);for(let r=-1;r<=1;r+=1)for(let s=-1;s<=1;s+=1)for(let[a,l]of this.#e.get(`${i+r}/${o+s}`)??[])if(Math.hypot(a-n,l-t)<this.size)return!0;return!1}},kn=class{#e=new ArrayBuffer(256*Mn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Mn;if((this.count+1)*a>this.#e.byteLength){let c=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(c).set(new Uint8Array(this.#e)),this.#e=c,this.#n=new DataView(c)}let l=this.#n,u=this.count*a;l.setUint16(u,Math.min(fe,Math.max(0,Math.round(n))),!0),l.setUint16(u+2,Math.min(fe,Math.max(0,Math.round(t))),!0),l.setUint16(u+4,Math.min(65535,Math.round(i*10)),!0),l.setUint8(u+6,Math.min(255,Math.round(o))),l.setUint8(u+7,(r?1:0)|(s?2:0)),l.setUint8(u+8,Math.round((s?.[0]??0)*255)),l.setUint8(u+9,Math.round((s?.[1]??0)*255)),l.setUint8(u+10,Math.round((s?.[2]??0)*255)),l.setUint8(u+11,Math.round(Rn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Mn)),mapped:n,estimated:this.count-n}}};function Rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var oo=Object.freeze({source:"tileflow",layers:Object.freeze({streetFurniture:"street_furniture",transportation:"transportation",sidewalk:"sidewalk"}),estimate:"lit",color:"#ffcf8f",intensity:1});var Me=["round","open","tall","conifer","columnar","palm"];var ut=Object.freeze({height:"height",diameterCrown:"diameter_crown",circumference:"circumference",genus:"genus",species:"species",leafType:"leaf_type",taxon:"taxon",canopyRank:"rank",canopyClearance:"clearance_px_z15",canopyCover:"cover_pct",canopyHeight:"height_m",subclass:"subclass",hedge:"hedge"}),Sn=Object.freeze({round:1,open:1,tall:1}),tn=16,q=8192,rn=16,st={round:{height:[6,12],crown:[.66,.9]},open:{height:[5,10],crown:[.8,1.05]},tall:{height:[9,17],crown:[.48,.68]},conifer:{height:[7,16],crown:[.46,.66]},columnar:{height:[9,18],crown:[.22,.36]},palm:{height:[12,20],crown:[.42,.55]}};var on=[2,45],An=[1,25],xr=1.2,Tr=1.5,Mr=1.3,vr=1,kr=[.3,10],Rr=new Set(["acoelorrhaphe","adonidia","archontophoenix","areca","arecastrum","bismarckia","brahea","butia","caryota","chamaedorea","chamaerops","coccothrinax","cocos","dypsis","elaeis","howea","jubaea","licuala","livistona","phoenix","pritchardia","ptychosperma","rhapis","roystonea","sabal","serenoa","syagrus","thrinax","trachycarpus","veitchia","washingtonia","wodyetia"]),Ar=new Set(["cupressus","calocedrus","thuja"]),_r=new Set(["abies","araucaria","cedrus","cryptomeria","juniperus","larix","metasequoia","picea","pinus","pseudotsuga","sequoia","sequoiadendron","taxodium","taxus","tsuga"]),at=Object.freeze({...Object.fromEntries(["acacia","albizia","arbutus","bursera","ceratonia","delonix","ficus","gleditsia","jacaranda","olea","quercus","robinia","schinus","sophora","styphnolobium","tamarix"].map(e=>[e,"open"])),...Object.fromEntries(["betula","celtis","fraxinus","ginkgo","liquidambar","liriodendron","magnolia","platanus","populus","pyrus","ulmus","zelkova"].map(e=>[e,"tall"])),...Object.fromEntries(["acer","aesculus","carpinus","castanea","catalpa","cercis","citrus","fagus","lagerstroemia","malus","melia","morus","prunus","sorbus","tilia"].map(e=>[e,"round"]))});function lt(e,n={}){let t={...ut,...n},i=String(e[t.leafType]??"").toLowerCase(),o=String(e[t.taxon]??"").toLowerCase(),r=_n(e[t.genus])??_n(e[t.species])??(o.endsWith("aceae")?void 0:_n(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&Rr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Ar.has(r))return"columnar";if(i.includes("needle")||r&&_r.has(r))return"conifer";if(r&&at[r])return at[r];if(i.includes("broad"))return"broadleaf"}function _n(e){return typeof e!="string"?void 0:e.trim().split(/\\s+/u)[0]?.toLowerCase()||void 0}function ct(e,n){let t={...ut,...n.fields},i=n.unknownForms??Sn,o=n.regions??[],{tile:r,tileMetres:s}=n,a=s/2**(15-r.z)/512,l=[],u=0,c=0,f=(w,y)=>{if(o.length===0)return i;let[b,x]=Sr(r,w/q,y/q);for(let T of o){let[F,k,L,O]=T.bounds;if(x>=k&&x<=O&&(F<=L?b>=F&&b<=L:b>=F||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],F=Fn(T.crown,ee(y,2)),k=b,L=x;return k===void 0&&L===void 0&&(k=Fn(T.height,ee(y,1))),k===void 0&&(k=L/F),L===void 0&&(L=k*F),{height:Te(k,on),crown:Te(L,An)}},g=(w,y,b,x,T,F)=>{let k=Ie(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(k,3)):b==="broadleaf"?sn(Fr(f(w,y)),ee(k,3)):b,O=x===void 0&&T===void 0&&F!==void 0?d(L,k,Fn(st[L].height,Te(F/3,[0,1]))):d(L,k,x,T);l.push({x:w,y,...O,turn:ee(k,4),shade:ee(k,5),form:Me.indexOf(L),rank:Math.floor(ee(k,6)*rn),seed:ee(k,7),canopy:0}),u+=1},m=e.trees;if(m){let w=q/m.extent;for(let y of m.features){if(y.type!=="Point")continue;let b=y.properties,x=lt(b,t),T=xe(b[t.height],on),F=xe(b[t.diameterCrown],An),k=xe(b[t.circumference],[.1,12]);for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];V<0||R<0||V>=m.extent||R>=m.extent||g(V*w,R*w,x,T,F,k)}}}let p=e.trees;if(p){let w=q/p.extent,y=(n.rowSpacing??8)/(s/p.extent);for(let b of p.features){if(b.type!=="LineString")continue;let x=b.properties,T=lt(x,t),F=xe(x[t.height],on),k=xe(x[t.diameterCrown],An);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,I,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-I);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=I+(Z-I)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,F,k,void 0),O+=y}V+=j}}}}let h=e.canopy;if(h){let w=q/h.extent;for(let y of h.features){if(y.type!=="Point")continue;let b=y.properties,x=Te(Math.floor(Number(b[t.canopyRank]??8)),[0,rn-1]),T=Math.max(4,Number(b[t.canopyClearance]??8))*a,F=Number(b[t.canopyCover]??30),k=F>=60?3:F>=30?2:1;for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];if(V<0||R<0||V>=h.extent||R>=h.extent)continue;let S=V*w,I=R*w,P=Ie(r.x*q+S,r.y*q+I,11),Z=f(S,I),j=xe(b[t.canopyHeight],on),G=Te(Math.min(T*(k===1?1.3:.95),11)*(.85+ee(P,1)*.25),[3,12]),W=Math.max(0,Math.min(G*.5,T-G/2)),se=ee(P,2)*Math.PI*2;for(let ae=0;ae<k;ae+=1){let H=Ie(P,ae,13),J=se+ae*Math.PI*2/k,re=k===1?W*.3*ee(H,1):W,ne=S+Math.cos(J)*re/(s/q),te=I+Math.sin(J)*re/(s/q);if(ne<0||te<0||ne>=q||te>=q)continue;let le=sn(Z,ee(H,3)),de=G*(.85+ee(H,2)*.3),me=j===void 0?void 0:j*(.85+ee(H,6)*.25),ce=d(le,H,me,le==="palm"?void 0:de);l.push({x:ne,y:te,...ce,turn:ee(H,4),shade:ee(H,5),form:Me.indexOf(le),rank:x,seed:ee(H,7),canopy:1}),c+=1}}}}let A=[],_=e.hedges;if(_){let w=q/_.extent,y=xr/(s/_.extent);for(let b of _.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?vr:0,T=(xe(b.properties[t.height],kr)??Mr)+x;for(let F of b.geometry){let k=y/2,L=0;for(let O=0;O+3<F.length;O+=2){let[V,R,S,I]=[F[O],F[O+1],F[O+2],F[O+3]],P=Math.hypot(S-V,I-R),Z=(Math.atan2(R-I,S-V)/(Math.PI*2)+1)%1;for(;k<=L+P;){let j=P>0?(k-L)/P:0,G=V+(S-V)*j,W=R+(I-R)*j;if(G>=0&&W>=0&&G<_.extent&&W<_.extent){let se=Ie(r.x*q+G*w,r.y*q+W*w,17);A.push({x:G*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}k+=y}L+=P}}}}let v=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(v(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*v(w.form))),B=l.map(M),C=l.map((w,y)=>y);C.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let z=new Uint8Array(l.length*tn),U=new DataView(z.buffer),E=0,D=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...D(),variants:Array.from({length:v(y)},D)}])),$=(w,y,b)=>{w.count===0&&(w.start=y),w.count+=1;for(let x=b;x<rn;x+=1)w.upTo[x]+=1};C.forEach((w,y)=>{let b=l[w],x=y*tn;U.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),U.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),U.setUint16(x+4,Math.round(b.height*10),!0),U.setUint16(x+6,Math.round(b.crown*10),!0),z[x+8]=Math.floor(b.turn*256)&255,z[x+9]=Math.floor(b.shade*256)&255,z[x+10]=b.form,z[x+11]=b.rank,z[x+12]=Math.floor(b.seed*256)&255,z[x+13]=b.canopy,z[x+14]=B[w],E=Math.max(E,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let N=new Uint8Array(A.length*tn),Y=new DataView(N.buffer);return A.forEach((w,y)=>{let b=y*tn;Y.setUint16(b,Math.min(q-1,Math.round(w.x)),!0),Y.setUint16(b+2,Math.min(q-1,Math.round(w.y)),!0),Y.setUint16(b+4,Math.round(w.height*10),!0),Y.setUint16(b+6,Math.round(Tr*10),!0),N[b+8]=Math.round(w.turn*256)&255,N[b+9]=Math.floor(w.shade*256)&255,N[b+12]=Math.floor(w.seed*256)&255,E=Math.max(E,w.height)}),{trees:z,forms:K,hedges:N,tallest:E,mapped:u,canopy:c}}function Fr(e){let n={round:e.round??0,open:e.open??0,tall:e.tall??0};return n.round+n.open+n.tall>0?n:Sn}function sn(e,n){let t=0;for(let o of Me)t+=Math.max(0,e[o]??0);if(t<=0)return sn(Sn,n);let i=n*t;for(let o of Me){let r=Math.max(0,e[o]??0);if(i<r)return o;i-=r}return"round"}function xe(e,n){let t=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):NaN;return Number.isFinite(t)&&t>0?Te(t,n):void 0}function Te(e,[n,t]){return Math.min(t,Math.max(n,e))}function Fn([e,n],t){return e+(n-e)*t}function Sr(e,n,t){let i=2**e.z,o=(e.x+n)/i*360-180,r=Math.atan(Math.sinh(Math.PI*(1-2*(e.y+t)/i)))*180/Math.PI;return[o,r]}function Ie(e,n,t){let i=(Math.imul(Math.floor(e)|0,668265261)^Math.imul(Math.floor(n)|0,374761393)^Math.imul(t,2654435761))>>>0;return i=Math.imul(i^i>>>15,2246822507)>>>0,i=Math.imul(i^i>>>13,3266489909)>>>0,(i^i>>>16)>>>0}function ee(e,n){return Ie(e,n,20973)/4294967296}var Lr=[void 0,"Point","LineString","Polygon"];function ft(e,n={}){let t=n.layers?new Set(n.layers):void 0,i={},o=new Bn(e,0,e.length);for(;o.more();){let[r,s]=o.tag();if(r!==3){o.skip(s);continue}let a=o.message(),l=Br(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Br(e,n){let t,i=4096,o=[],r=[],s=[];for(;e.more();){let[a,l]=e.tag();if(a===1?t=e.string():a===2?s.push(e.message()):a===3?o.push(e.string()):a===4?r.push(Ur(e.message())):a===5?i=e.varint():e.skip(l),t!==void 0&&n&&!n.has(t))return}if(!(t===void 0||n&&!n.has(t)))return{name:t,layer:Object.freeze({extent:i,features:Object.freeze(s.flatMap(a=>{let l=Or(a,o,r);return l?[l]:[]}))})}}function Or(e,n,t){let i,o,r={},s=[];for(;e.more();){let[a,l]=e.tag();if(a===1)i=e.varint();else if(a===2){let u=e.packed();for(let c=0;c+1<u.length;c+=2){let f=n[u[c]],d=t[u[c+1]];f!==void 0&&d!==void 0&&(r[f]=d)}}else a===3?o=Lr[e.varint()]:a===4?s=e.packed():e.skip(l)}if(o)return Object.freeze({...i===void 0?{}:{id:i},type:o,properties:Object.freeze(r),geometry:Object.freeze(Cr(s,o))})}function Cr(e,n){let t=[],i,o=0,r=0,s=0;for(;s<e.length;){let a=e[s++],l=a&7,u=a>>>3;if(l===7){i&&i.length>=2&&i.push(i[0],i[1]);continue}if(l!==1&&l!==2)throw new Error(`Unknown geometry command ${l} in vector tile.`);if(s+u*2>e.length)throw new Error("Truncated vector tile geometry.");for(let c=0;c<u;c+=1){if(o+=Ln(e[s++]),r+=Ln(e[s++]),l===1&&(n!=="Point"||c===0)&&t.push(i=[]),!i)throw new Error("Vector tile geometry draws a line before moving to its start.");i.push(o,r)}}return t}var Ln=e=>e%2===1?-(e+1)/2:e/2;function Ur(e){let n="";for(;e.more();){let[t,i]=e.tag();t===1?n=e.string():t===2?n=e.float():t===3?n=e.double():t===4?n=e.varint(!0):t===5?n=e.varint():t===6?n=Ln(e.varint()):t===7?n=e.varint()!==0:e.skip(i)}return n}var Pr=new TextDecoder,Bn=class e{constructor(n,t,i){this.bytes=n;this.end=i;this.position=t,this.view=new DataView(n.buffer,n.byteOffset,n.byteLength)}bytes;end;position;view;more(){return this.position<this.end}tag(){let n=this.varint();return[Math.floor(n/8),n&7]}varint(n=!1){let t=0,i=0;for(let o=0;o<10;o+=1){if(this.position>=this.end)throw new Error("Truncated vector tile.");let r=this.bytes[this.position++];if(o<4?t|=(r&127)<<o*7:o===4?(t|=(r&15)<<28,i=(r&112)>>4):o<9?i|=(r&127)<<(o-5)*7+3:i|=(r&1)<<31,r<128)return n?i*4294967296+(t>>>0):(i>>>0)*4294967296+(t>>>0)}throw new Error("Invalid varint in vector tile.")}span(){let n=this.varint(),t=this.position;if(t+n>this.end)throw new Error("Truncated vector tile.");return this.position=t+n,[t,t+n]}message(){let[n,t]=this.span();return new e(this.bytes,n,t)}string(){let[n,t]=this.span();return Pr.decode(this.bytes.subarray(n,t))}packed(){let[n,t]=this.span(),i=new e(this.bytes,n,t),o=[];for(;i.more();)o.push(i.varint());return o}float(){if(this.position+4>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat32(this.position,!0);return this.position+=4,n}double(){if(this.position+8>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat64(this.position,!0);return this.position+=8,n}skip(n){if(n===0)this.varint();else if(n===1)this.position+=8;else if(n===2)this.span();else if(n===5)this.position+=4;else throw new Error(`Unsupported protocol buffer wire type ${n} in vector tile.`);if(this.position>this.end)throw new Error("Truncated vector tile.")}};function dt(e){return Object.values(e.layers).filter(n=>typeof n=="string")}function mt(e,n){if(e.kind==="buildings"){let r=n(e.layers.building);if(!r)return;let s=n(e.layers.places),a=Kn(r,{...e.options,...s?{places:s}:{}});return a&&et(a)}if(e.kind==="trees"){let r=n(e.layers.tree),s=n(e.layers.canopy),a=n(e.layers.hedge);if(!r&&!s&&!a)return;let l=ct({...r?{trees:r}:{},...s?{canopy:s}:{},...a?{hedges:a}:{}},e.options);return l.trees.length>0||l.hedges.length>0?l:void 0}let t=n(e.layers.streetFurniture),i=n(e.layers.transportation),o=n(e.layers.sidewalk);return it({...t?{streetFurniture:t}:{},...i?{transportation:i}:{},...o?{sidewalks:o}:{}},e.options)}function ht(e,n){if(!n)return[];if(e==="buildings")return nt(n);if(e==="trees"){let{trees:t,hedges:i}=n;return[t.buffer,i.buffer].filter((o,r,s)=>s.indexOf(o)===r)}return[n.lamps.buffer]}function pt(e=16){let n=new Map;return{read(t,i,o){let r=n.get(t);for(n.delete(t),r??={bytes:i,layers:new Map},n.set(t,r);n.size>e;)n.delete(n.keys().next().value);let s=o.filter(l=>!r.layers.has(l));if(s.length>0){let l=ft(r.bytes,{layers:s});for(let u of s)r.layers.set(u,l[u])}let a=r.layers;return l=>l===void 0?void 0:a.get(l)}}}var On=globalThis,zr=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,zr.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();\n'], { type: "text/javascript" })
|
|
4264
4428
|
);
|
|
4265
4429
|
try {
|
|
4266
4430
|
return new Worker(url, { name: "tileflow-tiles" });
|
|
@@ -5275,7 +5439,7 @@ var TileflowPmtilesProtocol = class {
|
|
|
5275
5439
|
const archive2 = this.#archive(parseArchiveTarget(request.url));
|
|
5276
5440
|
const header2 = await archive2.getHeader();
|
|
5277
5441
|
const tileJson = await archive2.getTileJson(request.url);
|
|
5278
|
-
if (!
|
|
5442
|
+
if (!isRecord4(tileJson))
|
|
5279
5443
|
throw new TypeError("A PMTiles archive described no TileJSON object.");
|
|
5280
5444
|
const data = header2.tileType === O.Mlt ? { ...tileJson, encoding: "mlt" } : tileJson;
|
|
5281
5445
|
abortController.signal.throwIfAborted();
|
|
@@ -5411,7 +5575,7 @@ function assertRelativeRange(offset, length, sectionLength) {
|
|
|
5411
5575
|
throw new Error("Tileflow PMTiles directory range is invalid.");
|
|
5412
5576
|
}
|
|
5413
5577
|
}
|
|
5414
|
-
function
|
|
5578
|
+
function isRecord4(value) {
|
|
5415
5579
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5416
5580
|
}
|
|
5417
5581
|
function protocolCompatibility(handler) {
|
|
@@ -5665,7 +5829,8 @@ function createCameraTiles(options) {
|
|
|
5665
5829
|
const chosen = cameraTileRing(
|
|
5666
5830
|
{ ...centre, zoom: currentZoom, pitch: map.getPitch(), bearing: map.getBearing() },
|
|
5667
5831
|
zoom,
|
|
5668
|
-
options.maxTiles
|
|
5832
|
+
options.maxTiles,
|
|
5833
|
+
cameraViewport(map, zoom)
|
|
5669
5834
|
);
|
|
5670
5835
|
ring = chosen;
|
|
5671
5836
|
wanted = chosen.tiles.map(({ x: x3, y: y2 }) => `${x3}/${y2}`);
|
|
@@ -5677,7 +5842,7 @@ function createCameraTiles(options) {
|
|
|
5677
5842
|
return;
|
|
5678
5843
|
}
|
|
5679
5844
|
const now = performance.now();
|
|
5680
|
-
for (const { x: x3, y: y2
|
|
5845
|
+
for (const [priority, { x: x3, y: y2 }] of chosen.tiles.entries()) {
|
|
5681
5846
|
const key = `${x3}/${y2}`;
|
|
5682
5847
|
let entry = tiles.get(key);
|
|
5683
5848
|
if (!entry) {
|
|
@@ -5685,7 +5850,7 @@ function createCameraTiles(options) {
|
|
|
5685
5850
|
tiles.set(key, entry);
|
|
5686
5851
|
}
|
|
5687
5852
|
entry.used = now;
|
|
5688
|
-
entry.
|
|
5853
|
+
entry.priority = priority;
|
|
5689
5854
|
if ((!entry.value && !entry.pending || entry.retryAt !== void 0) && !entry.loading && (entry.retryAt ?? 0) <= now)
|
|
5690
5855
|
load(source, key, entry, chosen.tileMetres);
|
|
5691
5856
|
}
|
|
@@ -5698,7 +5863,7 @@ function createCameraTiles(options) {
|
|
|
5698
5863
|
entry.retryAt = void 0;
|
|
5699
5864
|
source.read(
|
|
5700
5865
|
{ z: zoom, x: entry.x, y: entry.y },
|
|
5701
|
-
{ signal: controller.signal, priority: entry.
|
|
5866
|
+
{ signal: controller.signal, priority: entry.priority ?? 0 }
|
|
5702
5867
|
).then((tile) => {
|
|
5703
5868
|
if (disposed || tiles.get(key) !== entry || entry.loading !== controller) return;
|
|
5704
5869
|
if (!tile) {
|
|
@@ -5733,14 +5898,14 @@ function createCameraTiles(options) {
|
|
|
5733
5898
|
while (!disposed && queue.length && performance.now() - started < buildBudgetMs) {
|
|
5734
5899
|
let nearest = 0;
|
|
5735
5900
|
for (let at = 1; at < queue.length; at += 1)
|
|
5736
|
-
if ((queue[at].entry.
|
|
5901
|
+
if ((queue[at].entry.priority ?? 0) < (queue[nearest].entry.priority ?? 0))
|
|
5737
5902
|
nearest = at;
|
|
5738
5903
|
const { key, entry, controller, tile, metres: tileMetres } = queue.splice(nearest, 1)[0];
|
|
5739
5904
|
const current = () => !disposed && tiles.get(key) === entry && entry.loading === controller && !controller.signal.aborted;
|
|
5740
5905
|
if (!current()) continue;
|
|
5741
5906
|
let value;
|
|
5742
5907
|
try {
|
|
5743
|
-
value = await options.build(tile, tileMetres, controller.signal, entry.
|
|
5908
|
+
value = await options.build(tile, tileMetres, controller.signal, entry.priority ?? 0);
|
|
5744
5909
|
} catch {
|
|
5745
5910
|
if (current()) {
|
|
5746
5911
|
entry.loading = void 0;
|
|
@@ -5810,6 +5975,7 @@ function createCameraTiles(options) {
|
|
|
5810
5975
|
map.on("sourcedata", onSource);
|
|
5811
5976
|
map.on("move", onMove);
|
|
5812
5977
|
map.on("moveend", onMoveEnd);
|
|
5978
|
+
map.on("resize", onMoveEnd);
|
|
5813
5979
|
return {
|
|
5814
5980
|
update,
|
|
5815
5981
|
ready() {
|
|
@@ -5864,6 +6030,7 @@ function createCameraTiles(options) {
|
|
|
5864
6030
|
map.off("sourcedata", onSource);
|
|
5865
6031
|
map.off("move", onMove);
|
|
5866
6032
|
map.off("moveend", onMoveEnd);
|
|
6033
|
+
map.off("resize", onMoveEnd);
|
|
5867
6034
|
for (const entry of tiles.values()) {
|
|
5868
6035
|
entry.loading?.abort();
|
|
5869
6036
|
if (entry.pending && entry.pending !== options.empty) options.release(entry.pending);
|
|
@@ -5931,33 +6098,110 @@ function cameraFrame(callback) {
|
|
|
5931
6098
|
if (typeof requestAnimationFrame === "function") requestAnimationFrame(callback);
|
|
5932
6099
|
else setTimeout(callback, 16);
|
|
5933
6100
|
}
|
|
5934
|
-
function cameraTileRing(camera, tileZoom, maxTiles) {
|
|
6101
|
+
function cameraTileRing(camera, tileZoom, maxTiles, viewport) {
|
|
5935
6102
|
const reach = Math.min(
|
|
5936
6103
|
5e3,
|
|
5937
6104
|
Math.max(800, 1600 * 2 ** (16 - camera.zoom) * (1 + camera.pitch / 60))
|
|
5938
6105
|
);
|
|
5939
6106
|
const bearing = camera.bearing * Math.PI / 180;
|
|
6107
|
+
const direction = [Math.sin(bearing), -Math.cos(bearing)];
|
|
5940
6108
|
const ahead = reach * 0.35 * Math.min(1, camera.pitch / 60);
|
|
5941
6109
|
const latitude = camera.lat + Math.cos(bearing) * ahead / 111320;
|
|
5942
6110
|
const longitude = camera.lng + Math.sin(bearing) * ahead / (111320 * Math.cos(camera.lat * Math.PI / 180));
|
|
5943
6111
|
const [cx, cy] = cameraTileAt(longitude, latitude, tileZoom);
|
|
5944
|
-
const
|
|
6112
|
+
const [ox, oy] = cameraTileAt(camera.lng, camera.lat, tileZoom);
|
|
6113
|
+
const tileMetres = earth * Math.cos(camera.lat * Math.PI / 180) / 2 ** tileZoom;
|
|
6114
|
+
const far = (reach + ahead) / tileMetres;
|
|
6115
|
+
const along = ([x3, y2]) => (x3 - ox) * direction[0] + (y2 - oy) * direction[1];
|
|
6116
|
+
const visible = viewport && clipGround(viewport, (point) => far - along(point));
|
|
5945
6117
|
const span = Math.ceil(reach / tileMetres);
|
|
6118
|
+
const left = Math.floor(Math.min(cx - span, ...visible?.map(([x3]) => x3) ?? []));
|
|
6119
|
+
const right = Math.floor(Math.max(cx + span, ...visible?.map(([x3]) => x3) ?? []));
|
|
6120
|
+
const top = Math.floor(Math.min(cy - span, ...visible?.map(([, y2]) => y2) ?? []));
|
|
6121
|
+
const bottom = Math.floor(Math.max(cy + span, ...visible?.map(([, y2]) => y2) ?? []));
|
|
5946
6122
|
const candidates = [];
|
|
5947
|
-
for (let
|
|
5948
|
-
for (let
|
|
5949
|
-
const
|
|
5950
|
-
|
|
5951
|
-
const
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
6123
|
+
for (let x3 = left; x3 <= right; x3++)
|
|
6124
|
+
for (let y2 = top; y2 <= bottom; y2++) {
|
|
6125
|
+
const distance = Math.hypot(Math.max(x3 - cx, 0, cx - x3 - 1), Math.max(y2 - cy, 0, cy - y2 - 1));
|
|
6126
|
+
let intersection = visible ?? [];
|
|
6127
|
+
for (const boundary of [
|
|
6128
|
+
([px]) => px - x3,
|
|
6129
|
+
([px]) => x3 + 1 - px,
|
|
6130
|
+
([, py]) => py - y2,
|
|
6131
|
+
([, py]) => y2 + 1 - py
|
|
6132
|
+
])
|
|
6133
|
+
intersection = clipGround(intersection, boundary);
|
|
6134
|
+
const near2 = Math.min(...intersection.map(along));
|
|
6135
|
+
if (near2 < Infinity || distance * tileMetres <= reach)
|
|
6136
|
+
candidates.push({ x: x3, y: y2, distance, near: near2 });
|
|
6137
|
+
}
|
|
6138
|
+
candidates.sort((a, b2) => a.near - b2.near || a.distance - b2.distance);
|
|
6139
|
+
const tiles = candidates.slice(0, maxTiles).map(({ x: x3, y: y2, distance }) => ({ x: x3, y: y2, distance }));
|
|
6140
|
+
const omitted = candidates.slice(tiles.length);
|
|
6141
|
+
const radius = omitted.reduce(
|
|
6142
|
+
(radius2, tile) => Math.min(radius2, tile.distance),
|
|
6143
|
+
reach / tileMetres
|
|
6144
|
+
);
|
|
6145
|
+
const end = Math.min(far, ...omitted.map((tile) => tile.near));
|
|
6146
|
+
const near = visible?.length ? Math.min(...visible.map(along)) : end;
|
|
6147
|
+
return {
|
|
6148
|
+
tiles,
|
|
6149
|
+
centre: [cx, cy],
|
|
6150
|
+
radius,
|
|
6151
|
+
tileMetres,
|
|
6152
|
+
...visible?.length ? {
|
|
6153
|
+
fade: {
|
|
6154
|
+
origin: [ox, oy],
|
|
6155
|
+
start: end - Math.max(0.25, (end - near) * 0.2),
|
|
6156
|
+
end
|
|
6157
|
+
}
|
|
6158
|
+
} : {}
|
|
6159
|
+
};
|
|
6160
|
+
}
|
|
6161
|
+
function cameraViewport(map, zoom) {
|
|
6162
|
+
const canvas = map.getCanvas?.();
|
|
6163
|
+
const width = canvas?.clientWidth ?? 0;
|
|
6164
|
+
const height = canvas?.clientHeight ?? 0;
|
|
6165
|
+
if (!map.unproject || width <= 0 || height <= 0) return void 0;
|
|
6166
|
+
const origin = cameraTileAt(map.getCenter().lng, map.getCenter().lat, zoom)[0];
|
|
6167
|
+
const world = 2 ** zoom;
|
|
6168
|
+
const pointAt = (x3, y2) => {
|
|
6169
|
+
const location = map.unproject([x3, y2]);
|
|
6170
|
+
const [tx, ty] = cameraTileAt(location.lng, location.lat, zoom);
|
|
6171
|
+
return [tx + Math.round((origin - tx) / world) * world, ty];
|
|
6172
|
+
};
|
|
6173
|
+
const bearing = map.getBearing() * Math.PI / 180;
|
|
6174
|
+
const points = [];
|
|
6175
|
+
for (const x3 of [0, width]) {
|
|
6176
|
+
const bottom = pointAt(x3, height);
|
|
6177
|
+
const middle = pointAt(x3, height / 2);
|
|
6178
|
+
let top = pointAt(x3, 0);
|
|
6179
|
+
if ((top[0] - middle[0]) * Math.sin(bearing) - (top[1] - middle[1]) * Math.cos(bearing) <= 0) {
|
|
6180
|
+
const stretch = world / Math.hypot(middle[0] - bottom[0], middle[1] - bottom[1]);
|
|
6181
|
+
top = [
|
|
6182
|
+
middle[0] + (middle[0] - bottom[0]) * stretch,
|
|
6183
|
+
middle[1] + (middle[1] - bottom[1]) * stretch
|
|
6184
|
+
];
|
|
5956
6185
|
}
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
return
|
|
6186
|
+
points.push(bottom, top);
|
|
6187
|
+
}
|
|
6188
|
+
if (points.some((point) => point.some((value) => !Number.isFinite(value)))) return void 0;
|
|
6189
|
+
return [points[0], points[1], points[3], points[2]];
|
|
6190
|
+
}
|
|
6191
|
+
function clipGround(points, distance) {
|
|
6192
|
+
const result = [];
|
|
6193
|
+
for (let i2 = 0; i2 < points.length; i2++) {
|
|
6194
|
+
const a = points[i2];
|
|
6195
|
+
const b2 = points[(i2 + 1) % points.length];
|
|
6196
|
+
const da = distance(a);
|
|
6197
|
+
const db = distance(b2);
|
|
6198
|
+
if (da >= 0) result.push([a[0], a[1]]);
|
|
6199
|
+
if (da < 0 !== db < 0) {
|
|
6200
|
+
const t = da / (da - db);
|
|
6201
|
+
result.push([a[0] + (b2[0] - a[0]) * t, a[1] + (b2[1] - a[1]) * t]);
|
|
6202
|
+
}
|
|
6203
|
+
}
|
|
6204
|
+
return result;
|
|
5961
6205
|
}
|
|
5962
6206
|
function cameraTileAt(longitude, latitude, zoom) {
|
|
5963
6207
|
const phi = Math.min(85.05, Math.max(-85.05, latitude)) * Math.PI / 180;
|
|
@@ -6640,7 +6884,7 @@ function validFootprint(footprint) {
|
|
|
6640
6884
|
return points <= tileflowModelLimits.footprintPoints;
|
|
6641
6885
|
}
|
|
6642
6886
|
function readTileflowLandmarkRegion(json) {
|
|
6643
|
-
if (!
|
|
6887
|
+
if (!isRecord5(json)) return void 0;
|
|
6644
6888
|
if (json.format !== "tileflow-landmark-region-v2") return void 0;
|
|
6645
6889
|
const region = json.region;
|
|
6646
6890
|
if (json.zoom !== tileflowLandmarkTileZoom || !Array.isArray(region) || region.length !== 3 || region[0] !== tileflowLandmarkRegionZoom || !Array.isArray(json.tiles))
|
|
@@ -6666,7 +6910,7 @@ function readLandmarks(listed, tx, ty) {
|
|
|
6666
6910
|
if (!Array.isArray(listed) || listed.length === 0) return void 0;
|
|
6667
6911
|
const out = [];
|
|
6668
6912
|
for (const landmark of listed) {
|
|
6669
|
-
if (!
|
|
6913
|
+
if (!isRecord5(landmark)) return void 0;
|
|
6670
6914
|
const { id, at, heading, footprint } = landmark;
|
|
6671
6915
|
if (typeof id !== "string" || !landmarkId.test(id)) return void 0;
|
|
6672
6916
|
if (!Array.isArray(at) || at.length !== 2 || !at.every((value) => typeof value === "number"))
|
|
@@ -6690,10 +6934,10 @@ function readLandmarks(listed, tx, ty) {
|
|
|
6690
6934
|
return out;
|
|
6691
6935
|
}
|
|
6692
6936
|
function readTileflowLandmarksTileJson(json, url) {
|
|
6693
|
-
if (!
|
|
6937
|
+
if (!isRecord5(json) || json.format !== "tileflow-landmarks-v2") return void 0;
|
|
6694
6938
|
const tile = Array.isArray(json.tiles) ? json.tiles[0] : void 0;
|
|
6695
6939
|
const regions = json.regions;
|
|
6696
|
-
if (typeof tile !== "string" || !tile.includes("{sha256}") || json.minzoom !== tileflowLandmarkTileZoom || json.maxzoom !== tileflowLandmarkTileZoom || !
|
|
6940
|
+
if (typeof tile !== "string" || !tile.includes("{sha256}") || json.minzoom !== tileflowLandmarkTileZoom || json.maxzoom !== tileflowLandmarkTileZoom || !isRecord5(regions) || regions.zoom !== tileflowLandmarkRegionZoom || typeof regions.url !== "string" || !regions.url.includes("{x}") || !regions.url.includes("{y}") || !Array.isArray(regions.available))
|
|
6697
6941
|
return void 0;
|
|
6698
6942
|
const available = /* @__PURE__ */ new Set();
|
|
6699
6943
|
for (const region of regions.available) {
|
|
@@ -6711,7 +6955,7 @@ function readTileflowLandmarksTileJson(json, url) {
|
|
|
6711
6955
|
regions: available
|
|
6712
6956
|
};
|
|
6713
6957
|
}
|
|
6714
|
-
function
|
|
6958
|
+
function isRecord5(value) {
|
|
6715
6959
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6716
6960
|
}
|
|
6717
6961
|
|
|
@@ -8369,115 +8613,8 @@ var tileflowSceneFadeZooms = 0.25;
|
|
|
8369
8613
|
function tileflowSceneOpacity(zoom, minzoom = tileflowSceneMinzoom) {
|
|
8370
8614
|
return Math.min(1, Math.max(0, (zoom - minzoom) / tileflowSceneFadeZooms));
|
|
8371
8615
|
}
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
var tileflowSunMetadataKey = "tileflow:sun";
|
|
8375
|
-
var tileflowDefaultSunPreset = Object.freeze({
|
|
8376
|
-
azimuth: 210,
|
|
8377
|
-
altitude: 60,
|
|
8378
|
-
color: "#ffffff",
|
|
8379
|
-
intensity: 0.2,
|
|
8380
|
-
shadowIntensity: 1,
|
|
8381
|
-
ambient: Object.freeze({ color: "#ffffff", intensity: 0.8 })
|
|
8382
|
-
});
|
|
8383
|
-
var degrees = Math.PI / 180;
|
|
8384
|
-
function normalizeTileflowAzimuth(azimuth) {
|
|
8385
|
-
const turned = azimuth % 360;
|
|
8386
|
-
return turned < 0 ? turned + 360 : turned === 0 ? 0 : turned;
|
|
8387
|
-
}
|
|
8388
|
-
function tileflowSunDirection(azimuth, altitude) {
|
|
8389
|
-
const a = azimuth * degrees;
|
|
8390
|
-
const h2 = altitude * degrees;
|
|
8391
|
-
return Object.freeze([
|
|
8392
|
-
Math.sin(a) * Math.cos(h2),
|
|
8393
|
-
Math.cos(a) * Math.cos(h2),
|
|
8394
|
-
Math.sin(h2)
|
|
8395
|
-
]);
|
|
8396
|
-
}
|
|
8397
|
-
function resolveTileflowSun(preset, direction = preset, source = "theme") {
|
|
8398
|
-
const azimuth = normalizeTileflowAzimuth(direction.azimuth);
|
|
8399
|
-
const altitude = Math.min(90, Math.max(-90, direction.altitude));
|
|
8400
|
-
const horizon = smoothstep(-0.5, 3, altitude);
|
|
8401
|
-
const intensity = clamp01(preset.intensity) * horizon;
|
|
8402
|
-
const rgb = rgbOf(preset.color);
|
|
8403
|
-
const ambientRgb = rgbOf(preset.ambient.color);
|
|
8404
|
-
const ambientIntensity = clamp01(preset.ambient.intensity);
|
|
8405
|
-
const brightness = clamp01(
|
|
8406
|
-
(luminance(ambientRgb) * ambientIntensity + luminance(rgb) * intensity * Math.max(0, Math.sin(altitude * degrees))) / 2
|
|
8407
|
-
);
|
|
8408
|
-
return Object.freeze({
|
|
8409
|
-
azimuth,
|
|
8410
|
-
altitude,
|
|
8411
|
-
direction: tileflowSunDirection(azimuth, altitude),
|
|
8412
|
-
color: preset.color,
|
|
8413
|
-
rgb,
|
|
8414
|
-
intensity,
|
|
8415
|
-
shadowIntensity: clamp01(preset.shadowIntensity),
|
|
8416
|
-
ambient: Object.freeze({
|
|
8417
|
-
color: preset.ambient.color,
|
|
8418
|
-
rgb: ambientRgb,
|
|
8419
|
-
intensity: ambientIntensity
|
|
8420
|
-
}),
|
|
8421
|
-
brightness: Number(brightness.toFixed(6)),
|
|
8422
|
-
source
|
|
8423
|
-
});
|
|
8424
|
-
}
|
|
8425
|
-
function readTileflowSunPreset(metadata) {
|
|
8426
|
-
if (!isRecord5(metadata)) return void 0;
|
|
8427
|
-
const value = metadata[tileflowSunMetadataKey];
|
|
8428
|
-
if (!isRecord5(value) || value.version !== 1 || !isRecord5(value.ambient)) return void 0;
|
|
8429
|
-
const { azimuth, altitude, color, intensity, shadowIntensity } = value;
|
|
8430
|
-
const ambient = value.ambient;
|
|
8431
|
-
if (!isFiniteNumber(azimuth) || !isFiniteNumber(altitude) || !isUnit(intensity) || !isUnit(shadowIntensity) || !isUnit(ambient.intensity) || !isColour(color) || !isColour(ambient.color))
|
|
8432
|
-
return void 0;
|
|
8433
|
-
return Object.freeze({
|
|
8434
|
-
azimuth: normalizeTileflowAzimuth(azimuth),
|
|
8435
|
-
altitude: Math.min(90, Math.max(-90, altitude)),
|
|
8436
|
-
color,
|
|
8437
|
-
intensity,
|
|
8438
|
-
shadowIntensity,
|
|
8439
|
-
ambient: Object.freeze({ color: ambient.color, intensity: ambient.intensity })
|
|
8440
|
-
});
|
|
8441
|
-
}
|
|
8442
|
-
function tileflowStyleSunPreset(style) {
|
|
8443
|
-
const published = readTileflowSunPreset(style?.metadata);
|
|
8444
|
-
if (published) return published;
|
|
8445
|
-
const light = isRecord5(style?.light) ? style.light : void 0;
|
|
8446
|
-
const position = light?.position;
|
|
8447
|
-
if (!position) return tileflowDefaultSunPreset;
|
|
8448
|
-
return Object.freeze({
|
|
8449
|
-
...tileflowDefaultSunPreset,
|
|
8450
|
-
azimuth: normalizeTileflowAzimuth(position[1]),
|
|
8451
|
-
altitude: Math.min(90, Math.max(-90, 90 - position[2])),
|
|
8452
|
-
...typeof light.color === "string" && isColour(light.color) ? { color: light.color } : {}
|
|
8453
|
-
});
|
|
8454
|
-
}
|
|
8455
|
-
function rgbOf(colour) {
|
|
8456
|
-
const channels = tileflowColourChannels(colour) ?? [1, 1, 1, 1];
|
|
8457
|
-
return Object.freeze([channels[0], channels[1], channels[2]]);
|
|
8458
|
-
}
|
|
8459
|
-
function luminance([r, g, b2]) {
|
|
8460
|
-
const linear = (value) => value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
8461
|
-
return 0.2126 * linear(r) + 0.7152 * linear(g) + 0.0722 * linear(b2);
|
|
8462
|
-
}
|
|
8463
|
-
function smoothstep(from, to, value) {
|
|
8464
|
-
const t = clamp01((value - from) / (to - from));
|
|
8465
|
-
return t * t * (3 - 2 * t);
|
|
8466
|
-
}
|
|
8467
|
-
function clamp01(value) {
|
|
8468
|
-
return Math.min(1, Math.max(0, Number.isFinite(value) ? value : 0));
|
|
8469
|
-
}
|
|
8470
|
-
function isRecord5(value) {
|
|
8471
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8472
|
-
}
|
|
8473
|
-
function isFiniteNumber(value) {
|
|
8474
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
8475
|
-
}
|
|
8476
|
-
function isUnit(value) {
|
|
8477
|
-
return isFiniteNumber(value) && value >= 0 && value <= 1;
|
|
8478
|
-
}
|
|
8479
|
-
function isColour(value) {
|
|
8480
|
-
return typeof value === "string" && tileflowColourChannels(value) !== null;
|
|
8616
|
+
function tileflowSceneEntrance(zoom, [from, to], animate) {
|
|
8617
|
+
return animate && to > from ? Math.min(1, Math.max(0, (zoom - from) / (to - from))) : Number(zoom >= from);
|
|
8481
8618
|
}
|
|
8482
8619
|
|
|
8483
8620
|
// src/sky-haze.ts
|
|
@@ -8505,6 +8642,7 @@ var tileflowSkyHazeReachFloor = 3;
|
|
|
8505
8642
|
var nineTenths = 0.8042;
|
|
8506
8643
|
function tileflowSkyReachDepth(view, reach) {
|
|
8507
8644
|
const sin = Math.sin(radians(view.pitch));
|
|
8645
|
+
if (reach.forward !== void 0) return 1 + reach.forward * sin;
|
|
8508
8646
|
const cos = Math.cos(radians(view.pitch));
|
|
8509
8647
|
const back = -sin;
|
|
8510
8648
|
const across = Math.atan(view.aspect * Math.tan(view.fov / 2));
|
|
@@ -8577,7 +8715,8 @@ function reachOf(map, distance) {
|
|
|
8577
8715
|
return {
|
|
8578
8716
|
ahead: (east * Math.sin(bearing) + north * Math.cos(bearing)) / metres,
|
|
8579
8717
|
across: (east * Math.cos(bearing) - north * Math.sin(bearing)) / metres,
|
|
8580
|
-
radius: reach.radius / metres
|
|
8718
|
+
radius: reach.radius / metres,
|
|
8719
|
+
...reach.forward === void 0 ? {} : { forward: reach.forward / metres }
|
|
8581
8720
|
};
|
|
8582
8721
|
}
|
|
8583
8722
|
function fovOf(map, args) {
|
|
@@ -8598,7 +8737,7 @@ function bindTileflowSkyHaze(context, uniforms, haze) {
|
|
|
8598
8737
|
}
|
|
8599
8738
|
|
|
8600
8739
|
// src/buildings-3d-browser.ts
|
|
8601
|
-
var tileflowBuildings3DLayerId =
|
|
8740
|
+
var tileflowBuildings3DLayerId = tileflowBuildingsSceneLayerId;
|
|
8602
8741
|
var preferredZoom = 15;
|
|
8603
8742
|
var defaultTransition = 0;
|
|
8604
8743
|
var flood = { reach: 10, colour: [1, 0.7, 0.4] };
|
|
@@ -8637,6 +8776,20 @@ function createTileflowBuildings3D(options) {
|
|
|
8637
8776
|
const floodMask = createBuildingContactMask();
|
|
8638
8777
|
let masks = {};
|
|
8639
8778
|
let disposed = false;
|
|
8779
|
+
let ready = false;
|
|
8780
|
+
let installedLayer;
|
|
8781
|
+
let reportedError = false;
|
|
8782
|
+
function setReady(next) {
|
|
8783
|
+
if (ready === next) return;
|
|
8784
|
+
ready = next;
|
|
8785
|
+
options.onReadyChange?.(next);
|
|
8786
|
+
}
|
|
8787
|
+
function reportError(error) {
|
|
8788
|
+
setReady(false);
|
|
8789
|
+
if (reportedError) return;
|
|
8790
|
+
reportedError = true;
|
|
8791
|
+
options.onError?.(error);
|
|
8792
|
+
}
|
|
8640
8793
|
let hazeDepth = Infinity;
|
|
8641
8794
|
let ahead = [0, -1];
|
|
8642
8795
|
const scene = tileflowScene3D(map);
|
|
@@ -8684,6 +8837,8 @@ function createTileflowBuildings3D(options) {
|
|
|
8684
8837
|
context.texParameteri(context.TEXTURE_2D, context.TEXTURE_MAG_FILTER, context.NEAREST);
|
|
8685
8838
|
},
|
|
8686
8839
|
onRemove(_2, context) {
|
|
8840
|
+
setReady(false);
|
|
8841
|
+
installedLayer = void 0;
|
|
8687
8842
|
if (!isWebGL2(context)) return;
|
|
8688
8843
|
models.release(context);
|
|
8689
8844
|
for (const program of Object.values(programs))
|
|
@@ -8738,13 +8893,22 @@ function createTileflowBuildings3D(options) {
|
|
|
8738
8893
|
map.triggerRepaint();
|
|
8739
8894
|
return;
|
|
8740
8895
|
}
|
|
8741
|
-
} catch {
|
|
8896
|
+
} catch (error) {
|
|
8897
|
+
reportError(error);
|
|
8742
8898
|
return;
|
|
8743
8899
|
}
|
|
8744
8900
|
if (target > 0 || scale > 0) upload(context);
|
|
8901
|
+
const coverageReady = visibleScale() > 0 && preparedCoverage();
|
|
8902
|
+
if (ready && !coverageReady) setReady(false);
|
|
8745
8903
|
scene.setReach(visibleScale() > 0 ? reachNow() : void 0);
|
|
8746
8904
|
if (visibleScale() <= 0 && modelScale() <= 0) return;
|
|
8747
|
-
|
|
8905
|
+
try {
|
|
8906
|
+
draw(context, args);
|
|
8907
|
+
if (!ready && coverageReady) setReady(true);
|
|
8908
|
+
reportedError = false;
|
|
8909
|
+
} catch (error) {
|
|
8910
|
+
reportError(error);
|
|
8911
|
+
}
|
|
8748
8912
|
}
|
|
8749
8913
|
};
|
|
8750
8914
|
const makeCamera = (layers, source, edgeRadius = 0) => createCameraTiles({
|
|
@@ -9006,7 +9170,7 @@ function createTileflowBuildings3D(options) {
|
|
|
9006
9170
|
}
|
|
9007
9171
|
let text2;
|
|
9008
9172
|
for (const [layerId, property] of [
|
|
9009
|
-
[
|
|
9173
|
+
[tileflowNativeBuildingsLayerId, "fill-extrusion-color"],
|
|
9010
9174
|
["tileflow-buildings-fill", "fill-color"]
|
|
9011
9175
|
]) {
|
|
9012
9176
|
if (!map.getLayer(layerId)) continue;
|
|
@@ -9031,8 +9195,9 @@ function createTileflowBuildings3D(options) {
|
|
|
9031
9195
|
models: [minzoom - 0.8, minzoom - 0.4]
|
|
9032
9196
|
};
|
|
9033
9197
|
function entering(part) {
|
|
9034
|
-
const
|
|
9035
|
-
|
|
9198
|
+
const entrance = design().entrance;
|
|
9199
|
+
const band = entrance && entrance[part] || defaultEntrance[part];
|
|
9200
|
+
return tileflowSceneEntrance(map.getZoom(), band, entrance !== false);
|
|
9036
9201
|
}
|
|
9037
9202
|
function visibleScale() {
|
|
9038
9203
|
return visibleOpacity() > 0 ? scale * (reducedMotion?.matches ? 1 : entering("buildings")) : 0;
|
|
@@ -9049,6 +9214,15 @@ function createTileflowBuildings3D(options) {
|
|
|
9049
9214
|
function drawn() {
|
|
9050
9215
|
return camera.ready().filter((entry) => entry.value.gl);
|
|
9051
9216
|
}
|
|
9217
|
+
function preparedCoverage() {
|
|
9218
|
+
const coverage = camera.coverage();
|
|
9219
|
+
if (coverage.length === 0) return false;
|
|
9220
|
+
const resident = new Map([...camera.all()].map((tile) => [`${tile.x}/${tile.y}`, tile.value]));
|
|
9221
|
+
return coverage.every(({ x: x3, y: y2 }) => {
|
|
9222
|
+
const value = resident.get(`${x3}/${y2}`);
|
|
9223
|
+
return value === emptyTile || Boolean(value?.gl);
|
|
9224
|
+
});
|
|
9225
|
+
}
|
|
9052
9226
|
const caster = {
|
|
9053
9227
|
groundOrder: 0,
|
|
9054
9228
|
bounds() {
|
|
@@ -9112,6 +9286,7 @@ function createTileflowBuildings3D(options) {
|
|
|
9112
9286
|
context.uniform2f(program.uniforms.u_offset, ...offset);
|
|
9113
9287
|
context.uniform4f(program.uniforms.u_ring ?? null, ...ring);
|
|
9114
9288
|
context.uniform2f(program.uniforms.u_ring_ahead ?? null, ...ahead);
|
|
9289
|
+
context.uniform1i(program.uniforms.u_ring_directional ?? null, camera.ring()?.fade ? 1 : 0);
|
|
9115
9290
|
const buffers = value.gl;
|
|
9116
9291
|
context.bindVertexArray(buffers.vao);
|
|
9117
9292
|
for (const range of ranges)
|
|
@@ -9152,7 +9327,9 @@ function createTileflowBuildings3D(options) {
|
|
|
9152
9327
|
return models.shown().filter((model) => model.gl);
|
|
9153
9328
|
}
|
|
9154
9329
|
function appearanceOf(model, now) {
|
|
9155
|
-
|
|
9330
|
+
const entrance = design().entrance;
|
|
9331
|
+
if (entrance === false || entrance?.models && entrance.models[0] === entrance.models[1] || model.standingSince === void 0)
|
|
9332
|
+
return 1;
|
|
9156
9333
|
const reduced = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
9157
9334
|
return reduced ? 1 : Math.min(1, Math.max(0, (now - model.standingSince) / modelFade));
|
|
9158
9335
|
}
|
|
@@ -9394,13 +9571,21 @@ function createTileflowBuildings3D(options) {
|
|
|
9394
9571
|
return {
|
|
9395
9572
|
lng: ring.centre[0] / n * 360 - 180,
|
|
9396
9573
|
lat: Math.atan(Math.sinh(Math.PI * (1 - 2 * ring.centre[1] / n))) * 180 / Math.PI,
|
|
9397
|
-
radius: ring.radius * ring.tileMetres
|
|
9574
|
+
radius: ring.radius * ring.tileMetres,
|
|
9575
|
+
...ring.fade ? { forward: ring.fade.end * ring.tileMetres } : {}
|
|
9398
9576
|
};
|
|
9399
9577
|
}
|
|
9400
9578
|
function ringIn(x3, y2) {
|
|
9401
9579
|
const ring = camera.ring();
|
|
9402
9580
|
if (!ring) return [0, 0, 0, 0];
|
|
9403
9581
|
const extent4 = tileflowBuildingExtent;
|
|
9582
|
+
if (ring.fade)
|
|
9583
|
+
return [
|
|
9584
|
+
(ring.fade.origin[0] - x3) * extent4,
|
|
9585
|
+
(ring.fade.origin[1] - y2) * extent4,
|
|
9586
|
+
ring.fade.start * extent4,
|
|
9587
|
+
ring.fade.end * extent4
|
|
9588
|
+
];
|
|
9404
9589
|
const cx = (ring.centre[0] - x3) * extent4;
|
|
9405
9590
|
const cy = (ring.centre[1] - y2) * extent4;
|
|
9406
9591
|
const inner = ring.radius * extent4 * 0.8;
|
|
@@ -9414,6 +9599,8 @@ function createTileflowBuildings3D(options) {
|
|
|
9414
9599
|
return [Math.sin(bearing), -Math.cos(bearing)];
|
|
9415
9600
|
}
|
|
9416
9601
|
function insideRing(ring, left, top, right, bottom) {
|
|
9602
|
+
if (camera.ring()?.fade)
|
|
9603
|
+
return Math.min(ahead[0] * (left - ring[0]), ahead[0] * (right - ring[0])) + Math.min(ahead[1] * (top - ring[1]), ahead[1] * (bottom - ring[1])) < ring[3];
|
|
9417
9604
|
const radius = ring[3];
|
|
9418
9605
|
if (!(radius > 0)) return true;
|
|
9419
9606
|
const cx = ring[0];
|
|
@@ -9631,9 +9818,10 @@ function createTileflowBuildings3D(options) {
|
|
|
9631
9818
|
);
|
|
9632
9819
|
context.uniform4f(u.u_ring ?? null, ...ringIn(x3, y2));
|
|
9633
9820
|
context.uniform2f(u.u_ring_ahead ?? null, ...ahead);
|
|
9821
|
+
context.uniform1i(u.u_ring_directional ?? null, camera.ring()?.fade ? 1 : 0);
|
|
9822
|
+
context.activeTexture(context.TEXTURE1);
|
|
9634
9823
|
const palette = themes ? paletteOf(context, entry, themes.themes) : void 0;
|
|
9635
9824
|
context.uniform1f(u.u_palette_on, palette ? 1 : 0);
|
|
9636
|
-
context.activeTexture(context.TEXTURE1);
|
|
9637
9825
|
context.bindTexture(context.TEXTURE_2D, palette?.texture ?? blank ?? null);
|
|
9638
9826
|
context.uniform1i(u.u_palette, 1);
|
|
9639
9827
|
if (palette && themes) {
|
|
@@ -9994,6 +10182,7 @@ ${shaderData.define}`;
|
|
|
9994
10182
|
if (disposed || map.getLayer(tileflowBuildings3DLayerId) || !map.isStyleLoaded()) return;
|
|
9995
10183
|
try {
|
|
9996
10184
|
map.addLayer(layer, beforeId());
|
|
10185
|
+
installedLayer = map.getLayer(tileflowBuildings3DLayerId);
|
|
9997
10186
|
} catch {
|
|
9998
10187
|
}
|
|
9999
10188
|
}
|
|
@@ -10098,6 +10287,9 @@ ${shaderData.define}`;
|
|
|
10098
10287
|
get scale() {
|
|
10099
10288
|
return scale;
|
|
10100
10289
|
},
|
|
10290
|
+
get ready() {
|
|
10291
|
+
return ready;
|
|
10292
|
+
},
|
|
10101
10293
|
get stats() {
|
|
10102
10294
|
let buildings = 0;
|
|
10103
10295
|
let vertices = 0;
|
|
@@ -10126,7 +10318,8 @@ ${shaderData.define}`;
|
|
|
10126
10318
|
scene.setReach(void 0);
|
|
10127
10319
|
models.dispose();
|
|
10128
10320
|
try {
|
|
10129
|
-
if (map.getLayer(tileflowBuildings3DLayerId)
|
|
10321
|
+
if (installedLayer && map.getLayer(tileflowBuildings3DLayerId) === installedLayer)
|
|
10322
|
+
map.removeLayer(tileflowBuildings3DLayerId);
|
|
10130
10323
|
} catch {
|
|
10131
10324
|
}
|
|
10132
10325
|
if (gl) {
|
|
@@ -10145,6 +10338,9 @@ function isWebGL2(context) {
|
|
|
10145
10338
|
return typeof WebGL2RenderingContext !== "undefined" && context instanceof WebGL2RenderingContext;
|
|
10146
10339
|
}
|
|
10147
10340
|
|
|
10341
|
+
// src/camera-limits.ts
|
|
10342
|
+
var tileflowMaxPitch = 85;
|
|
10343
|
+
|
|
10148
10344
|
// src/camera.ts
|
|
10149
10345
|
var tileflowCameraMetadataKey = "tileflow:camera";
|
|
10150
10346
|
function readTileflowCamera(metadata) {
|
|
@@ -10152,7 +10348,12 @@ function readTileflowCamera(metadata) {
|
|
|
10152
10348
|
const value = metadata[tileflowCameraMetadataKey];
|
|
10153
10349
|
if (!value || typeof value !== "object") return {};
|
|
10154
10350
|
const policy = value;
|
|
10155
|
-
|
|
10351
|
+
if (policy.version !== 1) return {};
|
|
10352
|
+
const limit = policy.pitchLimit;
|
|
10353
|
+
return {
|
|
10354
|
+
...typeof policy.adaptivePerspective === "boolean" ? { adaptivePerspective: policy.adaptivePerspective } : {},
|
|
10355
|
+
...limit && typeof limit.maxZoom === "number" && limit.maxZoom >= 0 && limit.maxZoom <= 24 && typeof limit.maxPitch === "number" && limit.maxPitch >= 0 && limit.maxPitch <= tileflowMaxPitch ? { pitchLimit: { maxZoom: limit.maxZoom, maxPitch: limit.maxPitch } } : {}
|
|
10356
|
+
};
|
|
10156
10357
|
}
|
|
10157
10358
|
|
|
10158
10359
|
// src/camera-browser.ts
|
|
@@ -10221,6 +10422,41 @@ function createTileflowAdaptiveCamera(map) {
|
|
|
10221
10422
|
map.on("remove", onRemove);
|
|
10222
10423
|
return { setEnabled, dispose };
|
|
10223
10424
|
}
|
|
10425
|
+
function createTileflowPitchLimit(map) {
|
|
10426
|
+
let limit;
|
|
10427
|
+
let original;
|
|
10428
|
+
let applying = false;
|
|
10429
|
+
let disposed = false;
|
|
10430
|
+
const update = () => {
|
|
10431
|
+
if (disposed || applying || original === void 0) return;
|
|
10432
|
+
const maximum = limit && map.getZoom() <= limit.maxZoom ? Math.min(original, limit.maxPitch) : original;
|
|
10433
|
+
if (map.getMaxPitch?.() === maximum) return;
|
|
10434
|
+
applying = true;
|
|
10435
|
+
try {
|
|
10436
|
+
map.setMaxPitch?.(maximum);
|
|
10437
|
+
} finally {
|
|
10438
|
+
applying = false;
|
|
10439
|
+
}
|
|
10440
|
+
};
|
|
10441
|
+
const setLimit = (next) => {
|
|
10442
|
+
if (disposed || !map.getMaxPitch || !map.setMaxPitch) return;
|
|
10443
|
+
limit = next;
|
|
10444
|
+
if (next) original ??= map.getMaxPitch();
|
|
10445
|
+
update();
|
|
10446
|
+
if (!next) original = void 0;
|
|
10447
|
+
};
|
|
10448
|
+
const onRemove = () => dispose(false);
|
|
10449
|
+
function dispose(restore = true) {
|
|
10450
|
+
if (disposed) return;
|
|
10451
|
+
if (restore) setLimit(void 0);
|
|
10452
|
+
disposed = true;
|
|
10453
|
+
map.off("zoom", update);
|
|
10454
|
+
map.off("remove", onRemove);
|
|
10455
|
+
}
|
|
10456
|
+
map.on("zoom", update);
|
|
10457
|
+
map.on("remove", onRemove);
|
|
10458
|
+
return { setLimit, dispose };
|
|
10459
|
+
}
|
|
10224
10460
|
|
|
10225
10461
|
// src/vegetation-display.ts
|
|
10226
10462
|
var tileflowVegetationDisplayMetadataKey = "tileflow:vegetation-display";
|
|
@@ -12811,11 +13047,13 @@ function createTileflowMap3D(options) {
|
|
|
12811
13047
|
let vegetationVisible = options.vegetation;
|
|
12812
13048
|
let adaptivePerspective = options.camera?.adaptivePerspective;
|
|
12813
13049
|
const camera = createTileflowAdaptiveCamera(map);
|
|
13050
|
+
const pitchLimit = createTileflowPitchLimit(map);
|
|
12814
13051
|
let authoredPerspective;
|
|
12815
13052
|
let buildings;
|
|
12816
13053
|
let vegetation;
|
|
12817
13054
|
let streetLights;
|
|
12818
13055
|
const flatBuildings = createBuildingFlatLayers(map);
|
|
13056
|
+
const nativeBuildings = createBuildingNativeLayers(map);
|
|
12819
13057
|
let footprintLayers;
|
|
12820
13058
|
let footprintZoom = 15.3;
|
|
12821
13059
|
let disposed = false;
|
|
@@ -12827,6 +13065,14 @@ function createTileflowMap3D(options) {
|
|
|
12827
13065
|
};
|
|
12828
13066
|
const instant = { transition: { duration: 0 } };
|
|
12829
13067
|
let declarations;
|
|
13068
|
+
let declaresBuildings = false;
|
|
13069
|
+
function syncNativeBuildings() {
|
|
13070
|
+
if (disposed) return;
|
|
13071
|
+
nativeBuildings.setVisible(
|
|
13072
|
+
declaresBuildings ? viewMode === "3d" && !buildings?.ready : void 0
|
|
13073
|
+
);
|
|
13074
|
+
syncFlatBuildings();
|
|
13075
|
+
}
|
|
12830
13076
|
function sync() {
|
|
12831
13077
|
if (disposed || syncing || !map.isStyleLoaded()) return;
|
|
12832
13078
|
syncing = true;
|
|
@@ -12837,12 +13083,14 @@ function createTileflowMap3D(options) {
|
|
|
12837
13083
|
const metadata = themes ? { [tileflowBuildingsMetadataKey]: themes.values[Math.round(themes.position)] } : map.getStyle()?.metadata;
|
|
12838
13084
|
const design = readTileflowBuildings3D(metadata);
|
|
12839
13085
|
footprintLayers = design?.flatLayers ?? [];
|
|
12840
|
-
footprintZoom = design?.entrance?.buildings?.[1] ?? 15.3;
|
|
13086
|
+
footprintZoom = design?.entrance === false ? 15 : design?.entrance?.buildings?.[1] ?? 15.3;
|
|
12841
13087
|
}
|
|
12842
13088
|
if (authoredPerspective === void 0) {
|
|
12843
13089
|
const themes = controller?.getThemeMetadata?.(tileflowCameraMetadataKey);
|
|
12844
13090
|
const metadata = themes ? { [tileflowCameraMetadataKey]: themes.values[Math.round(themes.position)] } : map.getStyle()?.metadata;
|
|
12845
|
-
|
|
13091
|
+
const policy = readTileflowCamera(metadata);
|
|
13092
|
+
authoredPerspective = policy.adaptivePerspective ?? false;
|
|
13093
|
+
pitchLimit.setLimit(options.camera?.pitchLimit ?? policy.pitchLimit);
|
|
12846
13094
|
}
|
|
12847
13095
|
camera.setEnabled(shown && (adaptivePerspective ?? authoredPerspective));
|
|
12848
13096
|
const declared = declarations ??= tileflowMap3DDeclarations({
|
|
@@ -12850,15 +13098,20 @@ function createTileflowMap3D(options) {
|
|
|
12850
13098
|
...controller ? { controller } : {}
|
|
12851
13099
|
});
|
|
12852
13100
|
const declares = (key) => declared.has(key);
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
13101
|
+
declaresBuildings = declares(tileflowBuildingsMetadataKey);
|
|
13102
|
+
if (shown && declaresBuildings)
|
|
13103
|
+
buildings ??= createTileflowBuildings3D({
|
|
13104
|
+
...shared3,
|
|
13105
|
+
onReadyChange: syncNativeBuildings,
|
|
13106
|
+
...options.onError ? { onError: options.onError } : {}
|
|
13107
|
+
});
|
|
13108
|
+
else if (!declaresBuildings && buildings) {
|
|
12856
13109
|
buildings.dispose();
|
|
12857
13110
|
buildings = void 0;
|
|
12858
13111
|
}
|
|
12859
13112
|
if (!vegetation && (declares(tileflowVegetationMetadataKey) || declares(tileflowVegetationDisplayMetadataKey)))
|
|
12860
13113
|
vegetation = createTileflowVegetation({ ...shared3, visible: vegetationVisible, viewMode });
|
|
12861
|
-
|
|
13114
|
+
syncNativeBuildings();
|
|
12862
13115
|
if (shown && declares(tileflowStreetLightsMetadataKey))
|
|
12863
13116
|
streetLights ??= createTileflowStreetLights(shared3);
|
|
12864
13117
|
else if (streetLights) {
|
|
@@ -12878,7 +13131,7 @@ function createTileflowMap3D(options) {
|
|
|
12878
13131
|
const canvas = map.getCanvas?.();
|
|
12879
13132
|
flatBuildings.update(
|
|
12880
13133
|
footprintLayers,
|
|
12881
|
-
viewMode === "3d" && Boolean(buildings) && map.getZoom() >= footprintZoom && Boolean(canvas?.getContext?.("webgl2"))
|
|
13134
|
+
viewMode === "3d" && Boolean(buildings?.ready) && map.getZoom() >= footprintZoom && Boolean(canvas?.getContext?.("webgl2"))
|
|
12882
13135
|
);
|
|
12883
13136
|
}
|
|
12884
13137
|
function change(next, transition) {
|
|
@@ -12902,6 +13155,7 @@ function createTileflowMap3D(options) {
|
|
|
12902
13155
|
disposed = true;
|
|
12903
13156
|
flatBuildings.restore();
|
|
12904
13157
|
camera.dispose();
|
|
13158
|
+
pitchLimit.dispose();
|
|
12905
13159
|
map.off("styledata", restyle);
|
|
12906
13160
|
map.off("style.load", restyle);
|
|
12907
13161
|
map.off("idle", sync);
|
|
@@ -12909,6 +13163,7 @@ function createTileflowMap3D(options) {
|
|
|
12909
13163
|
map.off("move", syncFlatBuildings);
|
|
12910
13164
|
streetLights?.dispose();
|
|
12911
13165
|
buildings?.dispose();
|
|
13166
|
+
nativeBuildings.restore();
|
|
12912
13167
|
vegetation?.dispose();
|
|
12913
13168
|
streetLights = void 0;
|
|
12914
13169
|
buildings = void 0;
|
|
@@ -12923,6 +13178,7 @@ function createTileflowMap3D(options) {
|
|
|
12923
13178
|
}
|
|
12924
13179
|
function onRemove() {
|
|
12925
13180
|
flatBuildings.forget();
|
|
13181
|
+
nativeBuildings.forget();
|
|
12926
13182
|
dispose();
|
|
12927
13183
|
}
|
|
12928
13184
|
map.on("styledata", restyle);
|