@tileflow/core 0.1.0-alpha.40 → 0.1.0-alpha.42
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 +2 -2
- package/dist/3d.js +280 -110
- package/dist/browser.d.ts +38 -19
- package/dist/browser.js +288 -117
- package/dist/build.d.ts +3 -3
- package/dist/build.js +52 -11
- package/dist/config-reference.json +1062 -669
- package/dist/{icon-composition-CcSHApUm.d.ts → icon-composition-B1A2udKb.d.ts} +66 -20
- package/dist/index.d.ts +26 -19
- package/dist/index.js +189 -62
- package/dist/{manifest-types-DnhSJjCM.d.ts → manifest-types-B0lQjabX.d.ts} +2 -0
- package/dist/manifest.d.ts +2 -2
- package/dist/native.d.ts +87 -1
- package/dist/native.js +193 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/worker/camera-tile-worker.global.js +2 -2
- package/docs/boundary-areas-and-choropleths.md +24 -11
- package/docs/buildings-3d.md +51 -21
- package/docs/cartographic-defaults.md +4 -0
- package/package.json +1 -1
package/dist/native.d.ts
CHANGED
|
@@ -362,4 +362,90 @@ declare function planTileflowThemeBlend(styles: readonly MapLibreStyle[], option
|
|
|
362
362
|
/** Fills one blend template for a position. Plain values pass through unchanged. */
|
|
363
363
|
declare function fillTileflowThemeBlendTemplate(template: unknown, position: number): unknown;
|
|
364
364
|
|
|
365
|
-
|
|
365
|
+
/**
|
|
366
|
+
* Boundaries families. Each one has its own license, attribution, TileJSON path and style source
|
|
367
|
+
* ID; families are never merged.
|
|
368
|
+
*/
|
|
369
|
+
declare const tileflowBoundaryFamilies: Readonly<{
|
|
370
|
+
boundaries: Readonly<{
|
|
371
|
+
attribution: "© OpenStreetMap contributors";
|
|
372
|
+
license: "ODbL-1.0";
|
|
373
|
+
path: "/tiles/boundaries/tiles.json";
|
|
374
|
+
sourceId: "tileflow-boundaries";
|
|
375
|
+
}>;
|
|
376
|
+
}>;
|
|
377
|
+
type TileflowBoundaryFamily = keyof typeof tileflowBoundaryFamilies;
|
|
378
|
+
|
|
379
|
+
/** A value a choropleth can colour: a number for scales, a string for categories. */
|
|
380
|
+
type TileflowBoundaryValue = number | string;
|
|
381
|
+
/** One row of an application's data, keyed by a registry ID or an official code. */
|
|
382
|
+
type TileflowBoundaryRow = Readonly<{
|
|
383
|
+
key: number | string;
|
|
384
|
+
/** `null` leaves the area without a value. */
|
|
385
|
+
value: TileflowBoundaryValue | null;
|
|
386
|
+
}>;
|
|
387
|
+
/** Keys present on every `boundary_area` polygon, usable without the lookup table. */
|
|
388
|
+
type TileflowBoundaryFeatureKey = 'id' | 'iso_3166_1' | 'ref';
|
|
389
|
+
/** Rows joined to areas by one polygon key. */
|
|
390
|
+
type TileflowBoundaryValues = Readonly<{
|
|
391
|
+
joinBy: TileflowBoundaryFeatureKey;
|
|
392
|
+
rows: readonly TileflowBoundaryRow[];
|
|
393
|
+
}>;
|
|
394
|
+
|
|
395
|
+
type FeatureTarget = {
|
|
396
|
+
id?: number | string;
|
|
397
|
+
source: string;
|
|
398
|
+
sourceLayer?: string;
|
|
399
|
+
};
|
|
400
|
+
/** The part of a MapLibre map the controller uses. */
|
|
401
|
+
type TileflowFeatureStateMap = {
|
|
402
|
+
getSource(id: string): unknown;
|
|
403
|
+
getStyle?(): {
|
|
404
|
+
sources?: Record<string, unknown>;
|
|
405
|
+
} | undefined;
|
|
406
|
+
off(type: 'styledata', listener: () => void): unknown;
|
|
407
|
+
on(type: 'styledata', listener: () => void): unknown;
|
|
408
|
+
removeFeatureState(target: FeatureTarget, key?: string): void;
|
|
409
|
+
setFeatureState(target: FeatureTarget & {
|
|
410
|
+
id: number | string;
|
|
411
|
+
}, state: Record<string, unknown>): void;
|
|
412
|
+
};
|
|
413
|
+
type CreateBoundaryFeatureStateOptions = Readonly<{
|
|
414
|
+
/** Defaults to `boundaries`. */
|
|
415
|
+
family?: TileflowBoundaryFamily;
|
|
416
|
+
/** Also set the values on `boundary_label` points, for labels styled by value. */
|
|
417
|
+
labels?: boolean;
|
|
418
|
+
/** Feature-state key; it must match the choropleth's `state`. Defaults to `value`. */
|
|
419
|
+
state?: string;
|
|
420
|
+
}>;
|
|
421
|
+
type TileflowBoundaryFeatureState = Readonly<{
|
|
422
|
+
/** Remove every value this controller set. */
|
|
423
|
+
clear: () => void;
|
|
424
|
+
/** Remove the values and stop following style reloads. */
|
|
425
|
+
dispose: () => void;
|
|
426
|
+
/**
|
|
427
|
+
* Replace the values. Rows must be keyed by the source's feature ID: `id` by default, or `ref`
|
|
428
|
+
* when the map declares `promoteId: 'ref'`. Rows with a `null` value are removed.
|
|
429
|
+
*/
|
|
430
|
+
set: (values: TileflowBoundaryValues) => void;
|
|
431
|
+
}>;
|
|
432
|
+
/**
|
|
433
|
+
* Keep Boundaries feature-state in sync with application rows. Values survive a style reload: the
|
|
434
|
+
* controller sets them again once the source is back.
|
|
435
|
+
*/
|
|
436
|
+
declare function createBoundaryFeatureState(map: TileflowFeatureStateMap, options?: CreateBoundaryFeatureStateOptions): TileflowBoundaryFeatureState;
|
|
437
|
+
|
|
438
|
+
/** Public selectors only; authority is acquired separately for each protected resource. */
|
|
439
|
+
type TileflowMobileDiscovery = Readonly<{
|
|
440
|
+
version: 1;
|
|
441
|
+
mapId: string;
|
|
442
|
+
deploymentVersion: number;
|
|
443
|
+
representations: Readonly<Partial<Record<'native-v1' | 'webview-v1', Readonly<{
|
|
444
|
+
manifestUrl: string;
|
|
445
|
+
}>>>>;
|
|
446
|
+
}>;
|
|
447
|
+
declare const tileflowMobileDiscoveryMaximumBytes = 4096;
|
|
448
|
+
/** Bind every advertised representation to the exact Hosted origin and Map being requested. */
|
|
449
|
+
declare function parseTileflowMobileDiscovery(value: unknown, discoveryUrl: string): TileflowMobileDiscovery;
|
|
450
|
+
|
|
451
|
+
export { type CreateBoundaryFeatureStateOptions, type TileflowBoundaryFamily, type TileflowBoundaryFeatureState, type TileflowBoundaryRow, type TileflowBoundaryValues, type TileflowFeatureStateMap, type TileflowMobileDiscovery, type TileflowNativeAbortSignal, type TileflowNativeInitialView, type TileflowNativeInitialViewOptions, type TileflowNativeManifestAcquire, type TileflowNativeManifestLoadOptions, type TileflowNativeManifestOperation, type TileflowNativeManifestReader, type TileflowNativeManifestResponse, type TileflowNativeManifestResult, type TileflowNativeNetworkOptions, type TileflowNativeResourceUrlOptions, type TileflowNativeSource, type TileflowNativeSourceController, TileflowNativeSourceError, type TileflowNativeSourceErrorCode, type TileflowNativeSourceErrorField, type TileflowNativeSourceOptions, type TileflowNativeSourceState, TileflowNativeUrlError, type TileflowNativeUrlErrorCode, type TileflowNativeUrlField, type TileflowThemeBlendClock, TileflowThemeBlendError, type TileflowThemeBlendImage, type TileflowThemeBlendOptions, type TileflowThemeBlendPaint, type TileflowThemeBlendPlan, type TileflowThemeBlendSelection, type TileflowThemeBlendSwitch, type TileflowTimeOfDay, type TileflowTimeOfDayVariants, createBoundaryFeatureState, createTileflowNativeSourceController, fillTileflowThemeBlendTemplate, loadTileflowNativeManifest, nearestTileflowBlendTheme, parseTileflowMobileDiscovery, planTileflowThemeBlend, resolveTileflowNativeInitialView, resolveTileflowNativeManifestUrl, resolveTileflowNativeResourceUrl, tileflowBoundaryFamilies, tileflowMobileDiscoveryMaximumBytes, tileflowNativeManifestLimits, tileflowNativeUrlLimits, tileflowThemeBlendLimits, validateTileflowThemeBlendSelection };
|
package/dist/native.js
CHANGED
|
@@ -5951,18 +5951,211 @@ function snapshotView(input) {
|
|
|
5951
5951
|
|
|
5952
5952
|
// src/native.ts
|
|
5953
5953
|
init_theme_blend();
|
|
5954
|
+
|
|
5955
|
+
// src/boundary-areas/schema.ts
|
|
5956
|
+
var tileflowBoundaryClasses = [
|
|
5957
|
+
"country",
|
|
5958
|
+
"dependency",
|
|
5959
|
+
"region",
|
|
5960
|
+
"province_or_county",
|
|
5961
|
+
"municipality",
|
|
5962
|
+
"district",
|
|
5963
|
+
"neighbourhood"
|
|
5964
|
+
];
|
|
5965
|
+
var tileflowBoundaryClassTiers = ["primary", "secondary"];
|
|
5966
|
+
var tileflowBoundaryAreasV1Schema = Object.freeze({
|
|
5967
|
+
classes: tileflowBoundaryClasses,
|
|
5968
|
+
/** First zoom at which each class appears, by tier. */
|
|
5969
|
+
classMinzoom: Object.freeze({
|
|
5970
|
+
country: Object.freeze({ primary: 0, secondary: 0 }),
|
|
5971
|
+
dependency: Object.freeze({ primary: 0, secondary: 0 }),
|
|
5972
|
+
region: Object.freeze({ primary: 3, secondary: 3 }),
|
|
5973
|
+
province_or_county: Object.freeze({ primary: 6, secondary: 7 }),
|
|
5974
|
+
municipality: Object.freeze({ primary: 8, secondary: 8 }),
|
|
5975
|
+
district: Object.freeze({ primary: 10, secondary: 10 }),
|
|
5976
|
+
neighbourhood: Object.freeze({ primary: 11, secondary: 11 })
|
|
5977
|
+
}),
|
|
5978
|
+
fields: Object.freeze({
|
|
5979
|
+
adminDepth: "admin_depth",
|
|
5980
|
+
adminLevel: "admin_level",
|
|
5981
|
+
class: "class",
|
|
5982
|
+
classTier: "class_tier",
|
|
5983
|
+
iso31661: "iso_3166_1",
|
|
5984
|
+
iso31662: "iso_3166_2",
|
|
5985
|
+
name: "name",
|
|
5986
|
+
nuts: "nuts",
|
|
5987
|
+
ref: "ref",
|
|
5988
|
+
wikidata: "wikidata"
|
|
5989
|
+
}),
|
|
5990
|
+
layers: Object.freeze({ areas: "boundary_area", labels: "boundary_label" }),
|
|
5991
|
+
/** Properties present on `boundary_area` polygons. */
|
|
5992
|
+
areaProperties: Object.freeze([
|
|
5993
|
+
"class",
|
|
5994
|
+
"class_tier",
|
|
5995
|
+
"admin_level",
|
|
5996
|
+
"admin_depth",
|
|
5997
|
+
"ref",
|
|
5998
|
+
"iso_3166_1"
|
|
5999
|
+
]),
|
|
6000
|
+
maxzoom: 12,
|
|
6001
|
+
minzoom: 0,
|
|
6002
|
+
product: "boundaries-v1",
|
|
6003
|
+
schemaVersion: 1,
|
|
6004
|
+
tiers: tileflowBoundaryClassTiers
|
|
6005
|
+
});
|
|
6006
|
+
var tileflowBoundaryFamilies = Object.freeze({
|
|
6007
|
+
boundaries: Object.freeze({
|
|
6008
|
+
attribution: "\xA9 OpenStreetMap contributors",
|
|
6009
|
+
license: "ODbL-1.0",
|
|
6010
|
+
path: "/tiles/boundaries/tiles.json",
|
|
6011
|
+
sourceId: "tileflow-boundaries"
|
|
6012
|
+
})
|
|
6013
|
+
});
|
|
6014
|
+
function isTileflowBoundaryFamily(value) {
|
|
6015
|
+
return typeof value === "string" && Object.hasOwn(tileflowBoundaryFamilies, value);
|
|
6016
|
+
}
|
|
6017
|
+
|
|
6018
|
+
// src/boundary-areas/feature-state.ts
|
|
6019
|
+
function createBoundaryFeatureState(map2, options = {}) {
|
|
6020
|
+
const family = options.family ?? "boundaries";
|
|
6021
|
+
if (!isTileflowBoundaryFamily(family)) {
|
|
6022
|
+
throw new Error(`Unknown Tileflow Boundaries family: ${String(family)}.`);
|
|
6023
|
+
}
|
|
6024
|
+
const source = tileflowBoundaryFamilies[family].sourceId;
|
|
6025
|
+
const stateKey = options.state?.trim() || "value";
|
|
6026
|
+
const sourceLayers = [
|
|
6027
|
+
tileflowBoundaryAreasV1Schema.layers.areas,
|
|
6028
|
+
...options.labels ? [tileflowBoundaryAreasV1Schema.layers.labels] : []
|
|
6029
|
+
];
|
|
6030
|
+
let applied = /* @__PURE__ */ new Map();
|
|
6031
|
+
let disposed = false;
|
|
6032
|
+
const write = (id, value) => {
|
|
6033
|
+
for (const sourceLayer of sourceLayers) {
|
|
6034
|
+
map2.setFeatureState({ id, source, sourceLayer }, { [stateKey]: value });
|
|
6035
|
+
}
|
|
6036
|
+
};
|
|
6037
|
+
const erase = (id) => {
|
|
6038
|
+
for (const sourceLayer of sourceLayers) {
|
|
6039
|
+
map2.removeFeatureState({ id, source, sourceLayer }, stateKey);
|
|
6040
|
+
}
|
|
6041
|
+
};
|
|
6042
|
+
const sourceReady = () => map2.getSource(source) !== void 0;
|
|
6043
|
+
let pendingReload = false;
|
|
6044
|
+
const onStyleData = () => {
|
|
6045
|
+
if (!sourceReady()) {
|
|
6046
|
+
pendingReload = true;
|
|
6047
|
+
return;
|
|
6048
|
+
}
|
|
6049
|
+
if (!pendingReload) return;
|
|
6050
|
+
pendingReload = false;
|
|
6051
|
+
for (const [id, value] of applied) write(id, value);
|
|
6052
|
+
};
|
|
6053
|
+
map2.on("styledata", onStyleData);
|
|
6054
|
+
const assertOpen = () => {
|
|
6055
|
+
if (disposed) throw new Error("This Boundaries feature-state controller was disposed.");
|
|
6056
|
+
};
|
|
6057
|
+
return Object.freeze({
|
|
6058
|
+
clear() {
|
|
6059
|
+
assertOpen();
|
|
6060
|
+
if (sourceReady()) for (const id of applied.keys()) erase(id);
|
|
6061
|
+
applied = /* @__PURE__ */ new Map();
|
|
6062
|
+
},
|
|
6063
|
+
dispose() {
|
|
6064
|
+
if (disposed) return;
|
|
6065
|
+
if (sourceReady()) for (const id of applied.keys()) erase(id);
|
|
6066
|
+
applied = /* @__PURE__ */ new Map();
|
|
6067
|
+
map2.off("styledata", onStyleData);
|
|
6068
|
+
disposed = true;
|
|
6069
|
+
},
|
|
6070
|
+
set(values) {
|
|
6071
|
+
assertOpen();
|
|
6072
|
+
const featureKey = promotedKey(map2, source) ?? "id";
|
|
6073
|
+
if (values.joinBy !== featureKey) {
|
|
6074
|
+
throw new Error(
|
|
6075
|
+
`Boundaries feature-state is keyed by ${featureKey}; join the rows to ${featureKey} first with joinBoundaryRows.`
|
|
6076
|
+
);
|
|
6077
|
+
}
|
|
6078
|
+
const next = /* @__PURE__ */ new Map();
|
|
6079
|
+
for (const row of values.rows) {
|
|
6080
|
+
if (row.value === null) continue;
|
|
6081
|
+
if (featureKey === "id") {
|
|
6082
|
+
if (typeof row.key !== "number" || !Number.isSafeInteger(row.key) || row.key < 0) {
|
|
6083
|
+
throw new Error("Boundaries feature-state rows keyed by id need integer keys.");
|
|
6084
|
+
}
|
|
6085
|
+
} else if (typeof row.key !== "string" || !row.key) {
|
|
6086
|
+
throw new Error("Boundaries feature-state rows keyed by ref need string keys.");
|
|
6087
|
+
}
|
|
6088
|
+
next.set(row.key, row.value);
|
|
6089
|
+
}
|
|
6090
|
+
if (sourceReady()) {
|
|
6091
|
+
for (const id of applied.keys()) if (!next.has(id)) erase(id);
|
|
6092
|
+
for (const [id, value] of next) if (applied.get(id) !== value) write(id, value);
|
|
6093
|
+
} else {
|
|
6094
|
+
pendingReload = true;
|
|
6095
|
+
}
|
|
6096
|
+
applied = next;
|
|
6097
|
+
}
|
|
6098
|
+
});
|
|
6099
|
+
}
|
|
6100
|
+
function promotedKey(map2, source) {
|
|
6101
|
+
const definition = map2.getStyle?.()?.sources?.[source];
|
|
6102
|
+
const promoteId = definition?.promoteId;
|
|
6103
|
+
if (promoteId === void 0) return void 0;
|
|
6104
|
+
const value = typeof promoteId === "string" ? promoteId : promoteId[tileflowBoundaryAreasV1Schema.layers.areas];
|
|
6105
|
+
return value === "ref" ? "ref" : void 0;
|
|
6106
|
+
}
|
|
6107
|
+
|
|
6108
|
+
// src/mobile-discovery.ts
|
|
6109
|
+
var tileflowMobileDiscoveryMaximumBytes = 4096;
|
|
6110
|
+
function parseTileflowMobileDiscovery(value, discoveryUrl) {
|
|
6111
|
+
const fail = () => {
|
|
6112
|
+
throw new Error("Invalid mobile discovery.");
|
|
6113
|
+
};
|
|
6114
|
+
if (typeof discoveryUrl !== "string" || discoveryUrl.length > 2048) return fail();
|
|
6115
|
+
const url = parseNativeUrl(discoveryUrl);
|
|
6116
|
+
const match = /^\/maps\/(map_[A-Za-z0-9_-]{16})\/mobile\/manifest\.json$/u.exec(url.pathname);
|
|
6117
|
+
if (!match || url.protocol !== "https:" || discoveryUrl !== `${url.origin}${url.pathname}`)
|
|
6118
|
+
return fail();
|
|
6119
|
+
const record2 = (candidate) => candidate !== null && typeof candidate === "object" && !Array.isArray(candidate);
|
|
6120
|
+
if (!record2(value) || Object.keys(value).sort().join(",") !== "deploymentVersion,mapId,representations,version")
|
|
6121
|
+
return fail();
|
|
6122
|
+
if (value.version !== 1 || value.mapId !== match[1] || !Number.isSafeInteger(value.deploymentVersion) || Number(value.deploymentVersion) < 1 || !record2(value.representations))
|
|
6123
|
+
return fail();
|
|
6124
|
+
const representations = {};
|
|
6125
|
+
const entries = Object.entries(value.representations);
|
|
6126
|
+
if (!entries.length || entries.length > 2) fail();
|
|
6127
|
+
for (const [profile, representation] of entries) {
|
|
6128
|
+
if (profile !== "native-v1" && profile !== "webview-v1") return fail();
|
|
6129
|
+
if (!record2(representation) || Object.keys(representation).join(",") !== "manifestUrl")
|
|
6130
|
+
return fail();
|
|
6131
|
+
const path = profile === "native-v1" ? "native" : "mobile/webview-v1";
|
|
6132
|
+
const expected = `${url.origin}/maps/${value.mapId}/${path}/manifest.json`;
|
|
6133
|
+
if (representation.manifestUrl !== expected) fail();
|
|
6134
|
+
representations[profile] = Object.freeze({ manifestUrl: expected });
|
|
6135
|
+
}
|
|
6136
|
+
return Object.freeze({
|
|
6137
|
+
version: 1,
|
|
6138
|
+
mapId: value.mapId,
|
|
6139
|
+
deploymentVersion: Number(value.deploymentVersion),
|
|
6140
|
+
representations: Object.freeze(representations)
|
|
6141
|
+
});
|
|
6142
|
+
}
|
|
5954
6143
|
export {
|
|
5955
6144
|
TileflowNativeSourceError,
|
|
5956
6145
|
TileflowNativeUrlError,
|
|
5957
6146
|
TileflowThemeBlendError,
|
|
6147
|
+
createBoundaryFeatureState,
|
|
5958
6148
|
createTileflowNativeSourceController,
|
|
5959
6149
|
fillTileflowThemeBlendTemplate,
|
|
5960
6150
|
loadTileflowNativeManifest,
|
|
5961
6151
|
nearestTileflowBlendTheme,
|
|
6152
|
+
parseTileflowMobileDiscovery,
|
|
5962
6153
|
planTileflowThemeBlend,
|
|
5963
6154
|
resolveTileflowNativeInitialView,
|
|
5964
6155
|
resolveTileflowNativeManifestUrl,
|
|
5965
6156
|
resolveTileflowNativeResourceUrl,
|
|
6157
|
+
tileflowBoundaryFamilies,
|
|
6158
|
+
tileflowMobileDiscoveryMaximumBytes,
|
|
5966
6159
|
tileflowNativeManifestLimits,
|
|
5967
6160
|
tileflowNativeUrlLimits,
|
|
5968
6161
|
tileflowThemeBlendLimits,
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { C as TileflowAnalytics, a2 as TileflowManifestFetchOptions, a3 as TileflowManifestLoadOptions, a4 as TileflowMapMode, a5 as TileflowMapModeOptions, ai as TileflowResolvedRuntimeTheme, aG as TileflowRuntimeCenterLike, a as TileflowRuntimeColorScheme, T as TileflowRuntimeManifest, aH as TileflowRuntimeManifestMap, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, aI as TileflowRuntimeSource, aJ as TileflowRuntimeSourceValidation, aK as TileflowRuntimeStyle, aL as TileflowRuntimeStyleOptions, d as TileflowRuntimeSystemThemes, aM as TileflowRuntimeViewOptions, aN as TileflowSessionController, aO as TileflowSessionGrantResponse, aR as TileflowStyleFontFace, ba as TileflowThemeBlendSelection, bh as TileflowThemeSelection, e as TileflowTimeOfDay, f as TileflowTimeOfDayVariants, bp as assertValidTileflowRuntimeSource, bq as clearTileflowManifestCache, bs as createTileflowSessionController, bt as createTileflowSessionId, bu as defaultTileflowManifestUrl, bv as defaultTileflowRuntimeView, bx as getTileflowAnalyticsApiUrl, by as getTileflowStyleFontFaces, bz as inferTileflowAnalyticsFromStyleUrl, bA as isTileflowTimeOfDay, bB as loadTileflowManifest, bC as mergeTileflowAnalytics, bD as nearestTileflowBlendTheme, bE as normalizeTileflowRuntimeCenter, bF as normalizeTileflowStaticImageSize, c2 as normalizeTileflowSurfaceId, bG as normalizeTileflowUrl, bH as resolveTileflowAnalyticsRequestUrl, bI as resolveTileflowManifestMap, bJ as resolveTileflowMapMode, bK as resolveTileflowRuntimeStyle, bL as resolveTileflowRuntimeTheme, bM as resolveTileflowRuntimeThemeBlend, bN as resolveTileflowRuntimeView, bO as resolveTileflowStaticImageUrl, bP as shouldLoadTileflowManifest, bQ as startTileflowSession, bS as tileflowStyleFontFaceLimits, bT as tileflowStyleFontFacesMetadataKey, bU as tileflowThemeBlendLimits, bW as tileflowTimesOfDay, bY as validateTileflowRuntimeSource, bZ as validateTileflowThemeBlendSelection, b_ as validateTileflowThemeSelection } from './manifest-types-
|
|
1
|
+
export { C as TileflowAnalytics, a2 as TileflowManifestFetchOptions, a3 as TileflowManifestLoadOptions, a4 as TileflowMapMode, a5 as TileflowMapModeOptions, ai as TileflowResolvedRuntimeTheme, aG as TileflowRuntimeCenterLike, a as TileflowRuntimeColorScheme, T as TileflowRuntimeManifest, aH as TileflowRuntimeManifestMap, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, aI as TileflowRuntimeSource, aJ as TileflowRuntimeSourceValidation, aK as TileflowRuntimeStyle, aL as TileflowRuntimeStyleOptions, d as TileflowRuntimeSystemThemes, aM as TileflowRuntimeViewOptions, aN as TileflowSessionController, aO as TileflowSessionGrantResponse, aR as TileflowStyleFontFace, ba as TileflowThemeBlendSelection, bh as TileflowThemeSelection, e as TileflowTimeOfDay, f as TileflowTimeOfDayVariants, bp as assertValidTileflowRuntimeSource, bq as clearTileflowManifestCache, bs as createTileflowSessionController, bt as createTileflowSessionId, bu as defaultTileflowManifestUrl, bv as defaultTileflowRuntimeView, bx as getTileflowAnalyticsApiUrl, by as getTileflowStyleFontFaces, bz as inferTileflowAnalyticsFromStyleUrl, bA as isTileflowTimeOfDay, bB as loadTileflowManifest, bC as mergeTileflowAnalytics, bD as nearestTileflowBlendTheme, bE as normalizeTileflowRuntimeCenter, bF as normalizeTileflowStaticImageSize, c2 as normalizeTileflowSurfaceId, bG as normalizeTileflowUrl, bH as resolveTileflowAnalyticsRequestUrl, bI as resolveTileflowManifestMap, bJ as resolveTileflowMapMode, bK as resolveTileflowRuntimeStyle, bL as resolveTileflowRuntimeTheme, bM as resolveTileflowRuntimeThemeBlend, bN as resolveTileflowRuntimeView, bO as resolveTileflowStaticImageUrl, bP as shouldLoadTileflowManifest, bQ as startTileflowSession, bS as tileflowStyleFontFaceLimits, bT as tileflowStyleFontFacesMetadataKey, bU as tileflowThemeBlendLimits, bW as tileflowTimesOfDay, bY as validateTileflowRuntimeSource, bZ as validateTileflowThemeBlendSelection, b_ as validateTileflowThemeSelection } from './manifest-types-B0lQjabX.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"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=zn(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 zn(e,n,t,i,o){let r=null;if(o===Ut(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=In(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=In(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ce(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,Ce(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),Ce(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),_=mn(g,m,n,t,i),F=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=_;){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;Nn(o,t,t.next,r,!1)&&Ue(o,r)&&Ue(r,o)&&(n.push(o.i,t.i,r.i),Ce(t),Ce(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=zn(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),kt(e.length/i,n.length),Dn(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 Dn(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 Dn(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 En(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=En(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=En(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);(Ue(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&&_t(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function _t(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);At(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 At(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||Ue(e,n)&&Ue(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 Nn(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&&Nn(s,a,e,n))return!0;s=a}while(s!==e);return!1}function Ue(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 In(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 Ce(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 Ut(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 Ct=.7,Pt=Math.tan(Math.PI/6),Et=Math.tan(35*Math.PI/180),It=Math.tan(Math.PI/18),Ee=.65,Ie=.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=Dt(e);if(!l||Math.abs(pn(e))<Ct*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 _=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,_/2),o-F);else{let y=Math.min(zt(a,d),_*.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[U,E]=l.centre,C=(y,b)=>{let x=(y-U)*r,T=(b-E)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},I=(y,b)=>[U+(y*u[0]+b*c[0])/r,E+(y*u[1]+b*c[1])/r],N=(y,b)=>{let x=1/0;for(let[T,A,v]of h)x=Math.min(x,T*y+A*b+v);return Math.max(0,x)},K=(y,b)=>k+B*N(...C(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...C(n[y],n[y+1]));pn($)<0&&Ht($);let D=1.01,Y=[-f*D,-d*D,f*D,-d*D,f*D,d*D,-f*D,d*D],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=$,A=x.length/2;for(let P=0;P<A&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%A*2],x[(P+1)%A*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(...I(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],z=Math.hypot(R,S,1);w.push({ring:v,triangles:L,normal:[-R/z,-S/z]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[A,v]=C(y,b),[L,O]=C(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let z=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=z(A,v),Z=z(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=A+(L-A)*j,W=v+(O-v)*j;h[R][0]*G+h[R][1]*W+h[R][2]<=N(G,W)+1e-6&&V.push(j)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,S)=>R-S)}}}function zt(e,n){switch(e){case"skillion":return 2*n*It;case"pyramidal":return n*Et;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=Ee/(Ie*r)*f,m=(1-Ee)/((1-Ie)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),Ee/(Ie*r)*d],[...p(m),Ee+(1-Ee)/((1-Ie)*r)*(d-Ie*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 Dt(e){let n=Nt(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[_,F]of n){let k=_*c[0]+F*c[1],M=_*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 _=(d+g)/2,F=(m+p)/2;t={centre:[_*c[0]+F*f[0],_*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 Nt(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 jr=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6}),Nr=Object.freeze([1,1,4,1,3]),Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024});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)&&Gt(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=$t(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 $t(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 Gt(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,Zt={commercial:1,active:2,destination:3},Wt={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]))},Xt={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]))},Yt=6,Jt=.5,Kt=.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,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=nr(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let U=B.properties,E=U.hide_3d;if(E===!0||E===1||E==="1"||E==="true")continue;let C=Math.min(6e3,Jn(U.render_height)??o),I=Math.min(C,Jn(U.render_min_height)??0),N=Zt[String(U.building_tone??"")]??0,K=Wt[String(U.class??"")]??0,$=d.get(M)??0,D=u.length,Y=!1;for(let w of tr(B.geometry,t)){let y=w.map(or).filter(S=>S.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=rr(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Kt/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,C+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let z=0;z<S.length;z+=2)T.bounds[0]=Math.min(T.bounds[0],S[z]-1),T.bounds[1]=Math.min(T.bounds[1],S[z+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[z]+1),T.bounds[3]=Math.max(T.bounds[3],S[z+1]+1);Y=!0,f=Math.max(f,C);let A=Number.isSafeInteger(B.id),v=gn(A?B.id*.0731:b*.0731+x*.19137+D*1.618),L=!A&&y[0].some(S=>S<=0||S>=ue)?gn(C*7.31+I*3.17+N):v,O={base:I,top:C,jitter:L,seed:v,tone:N,group:K,use:$,cx:b,cy:x,index:D},V=y.map((S,z)=>er(S,z,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],U,I,C,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),qt(R,O,s,a)):Qt(y,O,s,a);for(let[S,z]of y.entries()){let P=qe(z)>0,Z=S===0?P?-1:1:P?1:-1,j=z.length/2,G=H=>{let J=(H%j+j)%j;return[z[J*2],z[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,De=(ne-J)/me*Z;return(je*(le-ne)+De*(de-te))/ce>Jt},se=(H,J)=>R?R.heightAt(H,J):C,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],De=oe=>{let _e=ce[0]+(je[0]-ce[0])*oe,Fe=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(_e,Fe)||1;return[_e/ye,Fe/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let _e=oe===0,Fe=oe+2===he.length,ye=J+(ne-J)*he[oe],Ne=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],He=re+(te-re)*he[oe+1],Ae=Math.hypot(Ve-ye,He-Ne)/ue*n.tileMetres,$e=(_e&&W(H)?1:0)|(Fe&&W(H+1)?2:0)|(S>0?4:0),Ge=(_e&&xn(J,re)?1:0)|(Fe&&xn(ne,te)?2:0),an=ae+Ae,Ze=De(he[oe]),We=De(he[oe+1]),Un=se(ye,Ne),Cn=se(Ve,He),ke=s.write(O,ye,Ne,0,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),s.write(O,ye,Ne,1,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),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(U)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,_=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 U=0;U<5;U+=1)B.bounds[U]=U<2?Math.min(B.bounds[U],M.bounds[U]):Math.max(B.bounds[U],M.bounds[U]);g.set(_.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 qt(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 er(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]],[_,F]=[e[d*2],e[d*2+1]],k=Math.hypot(p-g,h-m),M=Math.hypot(_-p,F-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,_,F)){u(p,h);continue}let[B,U]=[(p-g)/k,(h-m)/k],[E,C]=[(_-p)/M,(F-h)/M],I=Math.atan2(B*C-U*E,B*E+U*C);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let N=Math.tan(Math.abs(I)/2),K=Math.min(t*N,k*.2,M*.2),$=K/N;if($<1){u(p,h);continue}let[D,Y]=[-U*s,B*s],[w,y]=[p-B*K-D*$,h-U*K-Y*$],b=Math.atan2(Y,D),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(I)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let A=b+I*T/x,v=[Math.cos(A),Math.sin(A)];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 _=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(_).set(new Uint8Array(this.#e)),this.#e=_,this.#n=new DataView(_)}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 nr(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=Xt[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=Yt/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,U]=F.box;if(d<k-o||d>B+o||g<M-o||g>U+o)continue;let E=!1;for(let C of F.rings)for(let I=0,N=C.length-2;I+1<C.length;N=I,I+=2){let K=C[N],$=C[N+1],D=C[I],Y=C[I+1];Y>g!=$>g&&d<(K-D)*(g-Y)/($-Y)+D&&(E=!E);let w=D-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(E){m=F.index;break}}let _=m??p;_!==void 0&&t.set(_,Math.max(t.get(_)??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 tr(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 rr(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 or(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=`
|
|
1
|
+
"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=zn(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 zn(e,n,t,i,o){let r=null;if(o===Ut(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=In(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=In(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ce(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,Ce(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),Ce(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),_=mn(g,m,n,t,i),F=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=_;){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)&&Ue(o,r)&&Ue(r,o)&&(n.push(o.i,t.i,r.i),Ce(t),Ce(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=zn(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 En(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=En(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=En(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);(Ue(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&&_t(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function _t(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);At(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 At(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||Ue(e,n)&&Ue(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 Ue(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 In(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 Ce(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 Ut(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 Ct=.7,Pt=Math.tan(Math.PI/6),Et=Math.tan(35*Math.PI/180),It=Math.tan(Math.PI/18),Ee=.65,Ie=.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))<Ct*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 _=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,_/2),o-F);else{let y=Math.min(zt(a,d),_*.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[U,E]=l.centre,C=(y,b)=>{let x=(y-U)*r,T=(b-E)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},I=(y,b)=>[U+(y*u[0]+b*c[0])/r,E+(y*u[1]+b*c[1])/r],D=(y,b)=>{let x=1/0;for(let[T,A,v]of h)x=Math.min(x,T*y+A*b+v);return Math.max(0,x)},K=(y,b)=>k+B*D(...C(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...C(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=$,A=x.length/2;for(let P=0;P<A&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%A*2],x[(P+1)%A*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(...I(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],z=Math.hypot(R,S,1);w.push({ring:v,triangles:L,normal:[-R/z,-S/z]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[A,v]=C(y,b),[L,O]=C(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let z=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=z(A,v),Z=z(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=A+(L-A)*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 zt(e,n){switch(e){case"skillion":return 2*n*It;case"pyramidal":return n*Et;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=Ee/(Ie*r)*f,m=(1-Ee)/((1-Ie)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),Ee/(Ie*r)*d],[...p(m),Ee+(1-Ee)/((1-Ie)*r)*(d-Ie*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[_,F]of n){let k=_*c[0]+F*c[1],M=_*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 _=(d+g)/2,F=(m+p)/2;t={centre:[_*c[0]+F*f[0],_*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 U=B.properties,E=U.hide_3d;if(E===!0||E===1||E==="1"||E==="true")continue;let C=Math.min(6e3,Jn(U.render_height)??o),I=Math.min(C,Jn(U.render_min_height)??0),D=Wt[String(U.building_tone??"")]??0,K=Xt[String(U.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,C+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let z=0;z<S.length;z+=2)T.bounds[0]=Math.min(T.bounds[0],S[z]-1),T.bounds[1]=Math.min(T.bounds[1],S[z+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[z]+1),T.bounds[3]=Math.max(T.bounds[3],S[z+1]+1);Y=!0,f=Math.max(f,C);let A=Number.isSafeInteger(B.id),v=gn(A?B.id*.0731:b*.0731+x*.19137+N*1.618),L=!A&&y[0].some(S=>S<=0||S>=ue)?gn(C*7.31+I*3.17+D):v,O={base:I,top:C,jitter:L,seed:v,tone:D,group:K,use:$,cx:b,cy:x,index:N},V=y.map((S,z)=>nr(S,z,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],U,I,C,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,z]of y.entries()){let P=qe(z)>0,Z=S===0?P?-1:1:P?1:-1,j=z.length/2,G=H=>{let J=(H%j+j)%j;return[z[J*2],z[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):C,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 _e=ce[0]+(je[0]-ce[0])*oe,Fe=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(_e,Fe)||1;return[_e/ye,Fe/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let _e=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],Ae=Math.hypot(Ve-ye,He-De)/ue*n.tileMetres,$e=(_e&&W(H)?1:0)|(Fe&&W(H+1)?2:0)|(S>0?4:0),Ge=(_e&&xn(J,re)?1:0)|(Fe&&xn(ne,te)?2:0),an=ae+Ae,Ze=Ne(he[oe]),We=Ne(he[oe+1]),Un=se(ye,De),Cn=se(Ve,He),ke=s.write(O,ye,De,0,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),s.write(O,ye,De,1,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),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(U)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,_=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 U=0;U<5;U+=1)B.bounds[U]=U<2?Math.min(B.bounds[U],M.bounds[U]):Math.max(B.bounds[U],M.bounds[U]);g.set(_.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]],[_,F]=[e[d*2],e[d*2+1]],k=Math.hypot(p-g,h-m),M=Math.hypot(_-p,F-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,_,F)){u(p,h);continue}let[B,U]=[(p-g)/k,(h-m)/k],[E,C]=[(_-p)/M,(F-h)/M],I=Math.atan2(B*C-U*E,B*E+U*C);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let D=Math.tan(Math.abs(I)/2),K=Math.min(t*D,k*.2,M*.2),$=K/D;if($<1){u(p,h);continue}let[N,Y]=[-U*s,B*s],[w,y]=[p-B*K-N*$,h-U*K-Y*$],b=Math.atan2(Y,N),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(I)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let A=b+I*T/x,v=[Math.cos(A),Math.sin(A)];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 _=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(_).set(new Uint8Array(this.#e)),this.#e=_,this.#n=new DataView(_)}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,U]=F.box;if(d<k-o||d>B+o||g<M-o||g>U+o)continue;let E=!1;for(let C of F.rings)for(let I=0,D=C.length-2;I+1<C.length;D=I,I+=2){let K=C[D],$=C[D+1],N=C[I],Y=C[I+1];Y>g!=$>g&&d<(K-N)*(g-Y)/($-Y)+N&&(E=!E);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(E){m=F.index;break}}let _=m??p;_!==void 0&&t.set(_,Math.max(t.get(_)??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=`
|
|
2
2
|
in float v_haze_depth;
|
|
3
3
|
uniform vec3 u_haze_colour;
|
|
4
4
|
uniform vec3 u_haze; // strength; the view depths where the haze starts and is complete
|
|
@@ -17,4 +17,4 @@ out vec4 fragColor;
|
|
|
17
17
|
void main() {
|
|
18
18
|
float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());
|
|
19
19
|
fragColor = vec4(vec3(shade), 1.0);
|
|
20
|
-
}`;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=ir(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 ir(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 _=(t.length<=4?[...t].map(F=>F+F).join(""):t).match(/../gu).map(F=>Number.parseInt(F,16));return[_[0],_[1],_[2],_.length>3?_[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,_,F]=o.slice(0,3).map(k=>en(k,255));return[h,_,F,r].some(k=>k===null)?null:[h,_,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,sr={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}},ar={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}},lr={spacing:30,kerb:0},ur=12,cr=18,fr=9,dr={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"},mr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},hr=new Set(["wall","wall_mounted","wall_bracket"]),pr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new vn,o=new nn(cr),r=new nn(fr),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 _=yr(h),F=br(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,_*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let U=0;U+1<B.length;U+=2){let E=B[U]*m,C=B[U+1]*m;if(!rt(E,C))continue;i.write(E,C,_,M,!0,F);let I=ot(E,C,n.tileMetres);o.add(...I),r.add(...I)}}}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+=gr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=ur,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,_)=>{let F=fe/m.extent,k=[];for(let N=0;N+1<p.length;N+=2)k.push(p[N]*F,p[N+1]*F);let M=n.tileMetres/fe,B=h.kerb*.45/M,U=Rn(k[0]*.013+k[1]*.029+_)*h.spacing,E=0,C=U,I=Rn(k[0]+k[1]*3.1)<.5?1:-1;for(let N=2;N<k.length;N+=2){let K=k[N-2],$=k[N-1],D=k[N],Y=k[N+1],w=Math.hypot(D-K,Y-$)*M;if(w!==0){for(;C<=E+w;){let y=(C-E)/w,b=-(Y-$)/(w/M)*I,x=(D-K)/(w/M)*I,T=K+(D-K)*y+b*B,A=$+(Y-$)*y+x*B;if(C+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!rt(T,A))continue;let v=ot(T,A,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,A,7,15,!1))}E+=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,lr,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=sr[r];if(s&&(n==="streets"||kn(t)))return s;let a=ar[r];if(a&&kn(t))return a}function kn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function yr(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return hr.has(t)?4.5:pr.has(t)?7.5:7}function br(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(mr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=dr[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 gr(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],_n=[1,25],wr=1.2,xr=1.5,Tr=1.3,Mr=1,kr=[.3,10],vr=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"]),Rr=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=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&&vr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Rr.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 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]=Ar(r,w/q,y/q);for(let T of o){let[A,v,L,O]=T.bounds;if(x>=v&&x<=O&&(A<=L?b>=A&&b<=L:b>=A||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],A=An(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=An(T.height,ee(y,1))),v===void 0&&(v=L/A),L===void 0&&(L=v*A),{height:Te(v,on),crown:Te(L,_n)}},g=(w,y,b,x,T,A)=>{let v=ze(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(Fr(f(w,y)),ee(v,3)):b,O=x===void 0&&T===void 0&&A!==void 0?d(L,v,An(st[L].height,Te(A/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),A=xe(b[t.diameterCrown],_n),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,A,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),A=xe(x[t.height],on),v=xe(x[t.diameterCrown],_n);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,z,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-z);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=z+(Z-z)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,A,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,A=Number(b[t.canopyCover]??30),v=A>=60?3:A>=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,z=R*w,P=ze(r.x*q+S,r.y*q+z,11),Z=f(S,z),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=ze(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=z+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 _=[],F=e.hedges;if(F){let w=q/F.extent,y=wr/(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"?Mr:0,T=(xe(b.properties[t.height],kr)??Tr)+x;for(let A of b.geometry){let v=y/2,L=0;for(let O=0;O+3<A.length;O+=2){let[V,R,S,z]=[A[O],A[O+1],A[O+2],A[O+3]],P=Math.hypot(S-V,z-R),Z=(Math.atan2(R-z,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+(z-R)*j;if(G>=0&&W>=0&&G<F.extent&&W<F.extent){let se=ze(r.x*q+G*w,r.y*q+W*w,17);_.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),U=l.map((w,y)=>y);U.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let E=new Uint8Array(l.length*tn),C=new DataView(E.buffer),I=0,N=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...N(),variants:Array.from({length:k(y)},N)}])),$=(w,y,b)=>{w.count===0&&(w.start=y),w.count+=1;for(let x=b;x<rn;x+=1)w.upTo[x]+=1};U.forEach((w,y)=>{let b=l[w],x=y*tn;C.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),C.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),C.setUint16(x+4,Math.round(b.height*10),!0),C.setUint16(x+6,Math.round(b.crown*10),!0),E[x+8]=Math.floor(b.turn*256)&255,E[x+9]=Math.floor(b.shade*256)&255,E[x+10]=b.form,E[x+11]=b.rank,E[x+12]=Math.floor(b.seed*256)&255,E[x+13]=b.canopy,E[x+14]=B[w],I=Math.max(I,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let D=new Uint8Array(_.length*tn),Y=new DataView(D.buffer);return _.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(xr*10),!0),D[b+8]=Math.round(w.turn*256)&255,D[b+9]=Math.floor(w.shade*256)&255,D[b+12]=Math.floor(w.seed*256)&255,I=Math.max(I,w.height)}),{trees:E,forms:K,hedges:D,tallest:I,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 An([e,n],t){return e+(n-e)*t}function Ar(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 ze(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 ze(e,n,20973)/4294967296}var Sr=[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=Lr(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Lr(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=Br(a,o,r);return l?[l]:[]}))})}}function Br(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=Sr[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(Or(s,o))})}function Or(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 Cr=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 Cr.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,Pr=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,Pr.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();
|
|
20
|
+
}`;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 _=(t.length<=4?[...t].map(F=>F+F).join(""):t).match(/../gu).map(F=>Number.parseInt(F,16));return[_[0],_[1],_[2],_.length>3?_[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,_,F]=o.slice(0,3).map(k=>en(k,255));return[h,_,F,r].some(k=>k===null)?null:[h,_,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 _=br(h),F=gr(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,_*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let U=0;U+1<B.length;U+=2){let E=B[U]*m,C=B[U+1]*m;if(!rt(E,C))continue;i.write(E,C,_,M,!0,F);let I=ot(E,C,n.tileMetres);o.add(...I),r.add(...I)}}}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,_)=>{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,U=Rn(k[0]*.013+k[1]*.029+_)*h.spacing,E=0,C=U,I=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(;C<=E+w;){let y=(C-E)/w,b=-(Y-$)/(w/M)*I,x=(N-K)/(w/M)*I,T=K+(N-K)*y+b*B,A=$+(Y-$)*y+x*B;if(C+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!rt(T,A))continue;let v=ot(T,A,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,A,7,15,!1))}E+=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],_n=[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"]),_r=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&&_r.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[A,v,L,O]=T.bounds;if(x>=v&&x<=O&&(A<=L?b>=A&&b<=L:b>=A||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],A=An(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=An(T.height,ee(y,1))),v===void 0&&(v=L/A),L===void 0&&(L=v*A),{height:Te(v,on),crown:Te(L,_n)}},g=(w,y,b,x,T,A)=>{let v=ze(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(Ar(f(w,y)),ee(v,3)):b,O=x===void 0&&T===void 0&&A!==void 0?d(L,v,An(st[L].height,Te(A/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),A=xe(b[t.diameterCrown],_n),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,A,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),A=xe(x[t.height],on),v=xe(x[t.diameterCrown],_n);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,z,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-z);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=z+(Z-z)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,A,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,A=Number(b[t.canopyCover]??30),v=A>=60?3:A>=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,z=R*w,P=ze(r.x*q+S,r.y*q+z,11),Z=f(S,z),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=ze(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=z+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 _=[],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 A of b.geometry){let v=y/2,L=0;for(let O=0;O+3<A.length;O+=2){let[V,R,S,z]=[A[O],A[O+1],A[O+2],A[O+3]],P=Math.hypot(S-V,z-R),Z=(Math.atan2(R-z,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+(z-R)*j;if(G>=0&&W>=0&&G<F.extent&&W<F.extent){let se=ze(r.x*q+G*w,r.y*q+W*w,17);_.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),U=l.map((w,y)=>y);U.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let E=new Uint8Array(l.length*tn),C=new DataView(E.buffer),I=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};U.forEach((w,y)=>{let b=l[w],x=y*tn;C.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),C.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),C.setUint16(x+4,Math.round(b.height*10),!0),C.setUint16(x+6,Math.round(b.crown*10),!0),E[x+8]=Math.floor(b.turn*256)&255,E[x+9]=Math.floor(b.shade*256)&255,E[x+10]=b.form,E[x+11]=b.rank,E[x+12]=Math.floor(b.seed*256)&255,E[x+13]=b.canopy,E[x+14]=B[w],I=Math.max(I,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let N=new Uint8Array(_.length*tn),Y=new DataView(N.buffer);return _.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,I=Math.max(I,w.height)}),{trees:E,forms:K,hedges:N,tallest:I,mapped:u,canopy:c}}function Ar(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 An([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 ze(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 ze(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(Cr(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(Ur(s,o))})}function Ur(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 Cr(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,Er=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,Er.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();
|
|
@@ -168,26 +168,36 @@ fails with `TF_BOUNDARY_CHOROPLETH_JOIN`.
|
|
|
168
168
|
|
|
169
169
|
In React, `useBoundaryFeatureState(map, values, options)` from `@tileflow/react` keeps
|
|
170
170
|
feature-state equal to `values`; see the
|
|
171
|
-
[React README](https://github.com/tileflow/tileflow-sdk/blob/main/packages/react/README.md).
|
|
171
|
+
[React README](https://github.com/tileflow/tileflow-sdk/blob/main/packages/react/README.md). In
|
|
172
|
+
React Native, the `Map` prop `boundaryFeatureState={{values, labels, state}}` does the same with
|
|
173
|
+
the same rows and options; see the
|
|
174
|
+
[React Native README](https://github.com/tileflow/tileflow-sdk/blob/main/packages/react-native/README.md).
|
|
172
175
|
|
|
173
176
|
## Join by codes the polygons do not carry
|
|
174
177
|
|
|
175
|
-
Rows keyed by `
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
Rows keyed by `iso_3166_1` or `ref` need no table: the polygons carry both codes, and a map that
|
|
179
|
+
promotes `ref` can set feature-state by official code directly. Rows keyed by `iso_3166_2`, `nuts`
|
|
180
|
+
or `wikidata`, or keyed by `ref` while feature-state uses registry IDs, go through the release's
|
|
181
|
+
lookup table.
|
|
182
|
+
|
|
183
|
+
The table is split by class, one gzip CSV per class with one row per area of that class:
|
|
184
|
+
`boundaries-lookup-country.csv.gz`, `boundaries-lookup-region.csv.gz`, and so on for every class.
|
|
185
|
+
The Boundaries TileJSON lists their URLs under `tileflow.boundaries.lookup.classes`, by class, and
|
|
186
|
+
the description of the table under `tileflow.boundaries.lookup.manifest`. Fine classes cover many
|
|
187
|
+
areas worldwide, so join where the data is prepared, on a server or at build time, and send the
|
|
188
|
+
application the joined rows, keyed by `id` or `ref`. Parse a file with `parseBoundaryLookupCsv`;
|
|
189
|
+
`joinBoundaryRows` then re-keys the rows:
|
|
179
190
|
|
|
180
191
|
<!-- docs:check -->
|
|
181
192
|
|
|
182
193
|
```ts
|
|
194
|
+
import {readFile} from 'node:fs/promises';
|
|
195
|
+
import {gunzipSync} from 'node:zlib';
|
|
183
196
|
import {createBoundaryLookup, joinBoundaryRows, parseBoundaryLookupCsv} from '@tileflow/core';
|
|
184
197
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const text = await new Response(
|
|
189
|
-
response.body.pipeThrough(new DecompressionStream('gzip')),
|
|
190
|
-
).text();
|
|
198
|
+
// A downloaded `boundaries-lookup-region.csv.gz`, read where the data is prepared.
|
|
199
|
+
export async function regionsByNuts(lookupFile: string, rows: {nuts: string; value: number}[]) {
|
|
200
|
+
const text = gunzipSync(await readFile(lookupFile)).toString('utf8');
|
|
191
201
|
const lookup = createBoundaryLookup(parseBoundaryLookupCsv(text));
|
|
192
202
|
const joined = joinBoundaryRows(
|
|
193
203
|
rows.map(({nuts, value}) => ({key: nuts, value})),
|
|
@@ -198,6 +208,9 @@ export async function regionsByNuts(csvGzipUrl: string, rows: {nuts: string; val
|
|
|
198
208
|
}
|
|
199
209
|
```
|
|
200
210
|
|
|
211
|
+
Rows from several classes join against one lookup built from the rows of each class file. Lookup
|
|
212
|
+
downloads are web delivery, counted like stored tiles; a native app does not download them.
|
|
213
|
+
|
|
201
214
|
The result has the same `{joinBy, rows}` shape that `values` and `set` accept, keyed by `id` or,
|
|
202
215
|
with `to: 'ref'`, by `ref`. It also lists the keys it could not use:
|
|
203
216
|
|