@tileflow/dev 0.1.0-alpha.27 → 0.1.0-alpha.29
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 +11 -4
- package/dist/artifacts.d.ts +42 -2
- package/dist/artifacts.js +9 -1
- package/dist/{chunk-6OJICHB3.js → chunk-CJGM6HTT.js} +70 -8
- package/dist/{chunk-QAMFAM3S.js → chunk-LXSFLPIU.js} +465 -255
- package/dist/{chunk-UCBGTEQV.js → chunk-QYM2CUZB.js} +13 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -3
- package/dist/preview.d.ts +2 -0
- package/dist/preview.js +1 -1
- package/dist/server.js +2 -2
- package/docs/native-artifacts.md +18 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -73,6 +73,12 @@ manifest pointer, tracks its own files, and refuses to replace a hosted manifest
|
|
|
73
73
|
Production rejects unresolved local PMTiles; publish data explicitly or provide an application-owned
|
|
74
74
|
production source. Local development snapshots do not publish or redistribute the original dataset.
|
|
75
75
|
|
|
76
|
+
Maps whose labels use a line-fitted `text.background` draw text with derived glyph stacks. Local
|
|
77
|
+
previews and captures route such a map's glyph URL through `__glyphs/<map>/…`. Ordinary stacks pass
|
|
78
|
+
through from the declared provider; derived ranges are computed from their source ranges, which are
|
|
79
|
+
cached under `.tileflow/cache/glyphs/v1`. Production output keeps the declared provider, which must
|
|
80
|
+
serve derived stacks.
|
|
81
|
+
|
|
76
82
|
## Keep a watched request handler
|
|
77
83
|
|
|
78
84
|
Use one session for repeated work and close it when the owning server stops:
|
|
@@ -137,8 +143,9 @@ This is the one normal icon-preparation path. `compileTileflowIconPackages`,
|
|
|
137
143
|
`prepareTileflowCatalogIcons`, `inspectTileflowIconCatalogs` and `getTileflowIconWatchPaths` all use
|
|
138
144
|
it, so `createTileflowBuildArtifacts`, `createTileflowArtifactSession`, and every adapter that
|
|
139
145
|
enters them accept the same explicit `icons` resolution options: `cacheRoot`, `offline`,
|
|
140
|
-
`deliveryOrigins`, `fetch` and `signal`.
|
|
141
|
-
|
|
146
|
+
`deliveryOrigins`, `fetch` and `signal`. An explicit `cacheRoot` takes precedence over
|
|
147
|
+
`TILEFLOW_ICON_CACHE_DIR`, then the OS cache default. Origins and transport use their documented
|
|
148
|
+
defaults unless supplied explicitly; no build or watch polls a catalog head. `prepareTileflowCatalogIcons`
|
|
142
149
|
returns `mapIconCompositions` alongside `mapIconSources`, and build-manifest entries carry the
|
|
143
150
|
receipt as `sourceAssets.iconComposition` with `mapRevisionSchemaVersion: 2`.
|
|
144
151
|
|
|
@@ -159,8 +166,8 @@ Applications may explicitly configure trusted `deliveryOrigins`; locks cannot ad
|
|
|
159
166
|
forbids all fetches and fails on missing or corrupt entries. Complete-map offline rendering still
|
|
160
167
|
depends on unrelated tiles, glyphs, and other external resources.
|
|
161
168
|
|
|
162
|
-
The cache lives under the OS user cache with `tileflow/icons/v1/<contentHash>`. `cacheRoot
|
|
163
|
-
`TILEFLOW_ICON_CACHE_DIR
|
|
169
|
+
The cache lives under the OS user cache with `tileflow/icons/v1/<contentHash>`. `cacheRoot`, then
|
|
170
|
+
`TILEFLOW_ICON_CACHE_DIR`, overrides its parent. Atomic directory installation and exact-entry
|
|
164
171
|
retirement support concurrent writers and corruption repair. Symlink entries are rejected. This is
|
|
165
172
|
a disposable cache, not a security sandbox against another process controlling the same user
|
|
166
173
|
account. Incomplete temporary entries are never accepted as published cache entries.
|
package/dist/artifacts.d.ts
CHANGED
|
@@ -5,6 +5,38 @@ import { TileflowRenderer, TileflowNativeBuildRecord } from '@tileflow/core/nati
|
|
|
5
5
|
import { TileflowBuildAsset, TileflowIconResolutionOptions, PreparedTileflowBuildCatalog, TileflowSourceCatalog, PreparedTileflowCatalog } from './icons.js';
|
|
6
6
|
export { defaultTileflowConfigPath } from './config.js';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Local glyph serving for line-fitted text backgrounds.
|
|
10
|
+
*
|
|
11
|
+
* A style whose text uses a derived `<stack> lines-v1-…` font stack needs a glyph provider that
|
|
12
|
+
* derives those ranges. Local previews and captures route such a map's glyph URL through
|
|
13
|
+
* `__glyphs/<map>/…`: ordinary stacks pass through from the map's declared provider unchanged, and
|
|
14
|
+
* derived stacks are computed from their source stack's range. Production output keeps the
|
|
15
|
+
* declared provider, which must serve derived stacks itself.
|
|
16
|
+
*/
|
|
17
|
+
declare const tileflowLineBackgroundGlyphRoute = "__glyphs";
|
|
18
|
+
/** Map name to the upstream glyph URL template its styles declared. Local only; never serialized. */
|
|
19
|
+
type TileflowLineBackgroundGlyphProviders = Readonly<Record<string, string>>;
|
|
20
|
+
type TileflowLineBackgroundGlyphResponderOptions = {
|
|
21
|
+
/** Project root; ranges are cached under `.tileflow/cache/glyphs/v1`. */
|
|
22
|
+
cwd: string;
|
|
23
|
+
fetch?: typeof globalThis.fetch;
|
|
24
|
+
};
|
|
25
|
+
type TileflowLineBackgroundGlyphResponder = (upstream: string, fontStack: string, range: string) => Promise<Response>;
|
|
26
|
+
/** Whether a compiled style draws text with a derived line-background stack. */
|
|
27
|
+
declare function usesTileflowLineBackgroundGlyphs(style: MapLibreStyle): boolean;
|
|
28
|
+
/** Parses `/__glyphs/<map>/<fontstack>/<range>.pbf` from a decoded route path. */
|
|
29
|
+
declare function parseTileflowLineBackgroundGlyphPath(path: string): {
|
|
30
|
+
fontStack: string;
|
|
31
|
+
mapName: string;
|
|
32
|
+
range: string;
|
|
33
|
+
} | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Serves one glyph range for a declared upstream template. Upstream ranges are cached on disk;
|
|
36
|
+
* derived ranges are recomputed from them and kept in a bounded in-memory cache.
|
|
37
|
+
*/
|
|
38
|
+
declare function createTileflowLineBackgroundGlyphResponder(options: TileflowLineBackgroundGlyphResponderOptions): TileflowLineBackgroundGlyphResponder;
|
|
39
|
+
|
|
8
40
|
type TileflowLocalTilesetFile = Readonly<{
|
|
9
41
|
byteLength: number;
|
|
10
42
|
etag: string;
|
|
@@ -121,6 +153,12 @@ type TileflowBuildArtifactsOptions = {
|
|
|
121
153
|
assetBaseUrl?: string;
|
|
122
154
|
config?: string;
|
|
123
155
|
cwd?: string;
|
|
156
|
+
/**
|
|
157
|
+
* Native local preview only: the exact HTTP origin serving these artifacts, such as
|
|
158
|
+
* `http://127.0.0.1:3333`. Native checks accept HTTP resources at this origin only; every other
|
|
159
|
+
* origin still requires HTTPS. It is never inferred, and web or production output rejects it.
|
|
160
|
+
*/
|
|
161
|
+
developmentOrigin?: string;
|
|
124
162
|
/**
|
|
125
163
|
* Explicit shared Icon Set resolution settings for this build.
|
|
126
164
|
*
|
|
@@ -149,6 +187,8 @@ type TileflowBuildArtifacts = {
|
|
|
149
187
|
project: TileflowBuildCatalog;
|
|
150
188
|
/** Local-only archive ports. Paths never enter serialized build artifacts. */
|
|
151
189
|
localTilesets?: TileflowLocalTilesetFile[];
|
|
190
|
+
/** Local-only upstream glyph templates for maps whose text uses line-fitted backgrounds. */
|
|
191
|
+
lineBackgroundGlyphs?: TileflowLineBackgroundGlyphProviders;
|
|
152
192
|
/** Optional local-only provenance. It is never serialized as a build artifact. */
|
|
153
193
|
styleInspections?: TileflowBuildStyleInspections;
|
|
154
194
|
styles: TileflowBuildStyles;
|
|
@@ -172,7 +212,7 @@ type TileflowArtifactPlan = TileflowBuildArtifacts & {
|
|
|
172
212
|
schemaVersion: typeof tileflowArtifactPlanSchemaVersion;
|
|
173
213
|
sourceProject: TileflowSourceCatalog;
|
|
174
214
|
};
|
|
175
|
-
type CreateTileflowArtifactPlanOptions = Pick<TileflowBuildArtifactsOptions, 'apiBaseUrl' | 'assetBaseUrl' | 'inspection' | 'renderer' | 'styleBaseUrl' | 'target'> & {
|
|
215
|
+
type CreateTileflowArtifactPlanOptions = Pick<TileflowBuildArtifactsOptions, 'apiBaseUrl' | 'assetBaseUrl' | 'developmentOrigin' | 'inspection' | 'renderer' | 'styleBaseUrl' | 'target'> & {
|
|
176
216
|
inputFiles?: readonly string[];
|
|
177
217
|
};
|
|
178
218
|
type WriteTileflowArtifactPlanOptions = {
|
|
@@ -222,4 +262,4 @@ declare function assertTileflowSelfHostedManifestTarget(manifestPath: string, op
|
|
|
222
262
|
overwriteHostedManifest?: boolean;
|
|
223
263
|
}): Promise<void>;
|
|
224
264
|
|
|
225
|
-
export { type CreateTileflowArtifactPlanOptions, PreparedTileflowBuildCatalog, PreparedTileflowCatalog, type TileflowArtifactAcquisition, type TileflowArtifactDiagnostic, type TileflowArtifactFile, type TileflowArtifactInputGraph, type TileflowArtifactPlan, type TileflowArtifactSession, type TileflowArtifactSessionOptions, type TileflowArtifactSessionState, type TileflowBuildArtifacts, type TileflowBuildArtifactsOptions, TileflowBuildAsset, type TileflowBuildStyleInspections, TileflowHostedManifestOverwriteError, TileflowIconResolutionOptions, type TileflowLocalTilesetFile, TileflowLocalTilesetProductionError, type TileflowManifestOptions, TileflowSourceCatalog, type WriteTileflowArtifactPlanOptions, type WriteTileflowBuildArtifactsOptions, assertNoLocalTilesetsForProduction, assertTileflowSelfHostedManifestTarget, createTileflowArtifactDiagnostics, createTileflowArtifactPlan, createTileflowArtifactSession, createTileflowBuildArtifacts, createTileflowBuildProvenance, createTileflowManifest, createTileflowStyle, createTileflowStyles, disposeTileflowBuildArtifacts, getTileflowArtifactFiles, getTileflowAssetBasePath, getTileflowAssetFileName, getTileflowWatchPaths, isTileflowArtifactInputPath, joinTileflowPublicUrl, normalizeTileflowBasePath, prepareTileflowHostedNativeDeployment, prepareTileflowLocalTilesets, refreshTileflowArtifactSession, resolveTileflowArtifactPublicUrls, tileflowArtifactInventoryFileName, tileflowArtifactPlanSchemaVersion, tileflowArtifactSessionSchemaVersion, writeTileflowArtifactPlan, writeTileflowBuildArtifacts };
|
|
265
|
+
export { type CreateTileflowArtifactPlanOptions, PreparedTileflowBuildCatalog, PreparedTileflowCatalog, type TileflowArtifactAcquisition, type TileflowArtifactDiagnostic, type TileflowArtifactFile, type TileflowArtifactInputGraph, type TileflowArtifactPlan, type TileflowArtifactSession, type TileflowArtifactSessionOptions, type TileflowArtifactSessionState, type TileflowBuildArtifacts, type TileflowBuildArtifactsOptions, TileflowBuildAsset, type TileflowBuildStyleInspections, TileflowHostedManifestOverwriteError, TileflowIconResolutionOptions, type TileflowLineBackgroundGlyphProviders, type TileflowLineBackgroundGlyphResponder, type TileflowLocalTilesetFile, TileflowLocalTilesetProductionError, type TileflowManifestOptions, TileflowSourceCatalog, type WriteTileflowArtifactPlanOptions, type WriteTileflowBuildArtifactsOptions, assertNoLocalTilesetsForProduction, assertTileflowSelfHostedManifestTarget, createTileflowArtifactDiagnostics, createTileflowArtifactPlan, createTileflowArtifactSession, createTileflowBuildArtifacts, createTileflowBuildProvenance, createTileflowLineBackgroundGlyphResponder, createTileflowManifest, createTileflowStyle, createTileflowStyles, disposeTileflowBuildArtifacts, getTileflowArtifactFiles, getTileflowAssetBasePath, getTileflowAssetFileName, getTileflowWatchPaths, isTileflowArtifactInputPath, joinTileflowPublicUrl, normalizeTileflowBasePath, parseTileflowLineBackgroundGlyphPath, prepareTileflowHostedNativeDeployment, prepareTileflowLocalTilesets, refreshTileflowArtifactSession, resolveTileflowArtifactPublicUrls, tileflowArtifactInventoryFileName, tileflowArtifactPlanSchemaVersion, tileflowArtifactSessionSchemaVersion, tileflowLineBackgroundGlyphRoute, usesTileflowLineBackgroundGlyphs, writeTileflowArtifactPlan, writeTileflowBuildArtifacts };
|
package/dist/artifacts.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
createTileflowArtifactSession,
|
|
9
9
|
createTileflowBuildArtifacts,
|
|
10
10
|
createTileflowBuildProvenance,
|
|
11
|
+
createTileflowLineBackgroundGlyphResponder,
|
|
11
12
|
createTileflowManifest,
|
|
12
13
|
createTileflowStyle,
|
|
13
14
|
createTileflowStyles,
|
|
@@ -15,15 +16,18 @@ import {
|
|
|
15
16
|
getTileflowArtifactFiles,
|
|
16
17
|
getTileflowWatchPaths,
|
|
17
18
|
isTileflowArtifactInputPath,
|
|
19
|
+
parseTileflowLineBackgroundGlyphPath,
|
|
18
20
|
prepareTileflowHostedNativeDeployment,
|
|
19
21
|
prepareTileflowLocalTilesets,
|
|
20
22
|
refreshTileflowArtifactSession,
|
|
21
23
|
tileflowArtifactInventoryFileName,
|
|
22
24
|
tileflowArtifactPlanSchemaVersion,
|
|
23
25
|
tileflowArtifactSessionSchemaVersion,
|
|
26
|
+
tileflowLineBackgroundGlyphRoute,
|
|
27
|
+
usesTileflowLineBackgroundGlyphs,
|
|
24
28
|
writeTileflowArtifactPlan,
|
|
25
29
|
writeTileflowBuildArtifacts
|
|
26
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-LXSFLPIU.js";
|
|
27
31
|
import "./chunk-ONYQNLNA.js";
|
|
28
32
|
import {
|
|
29
33
|
getTileflowAssetBasePath,
|
|
@@ -49,6 +53,7 @@ export {
|
|
|
49
53
|
createTileflowArtifactSession,
|
|
50
54
|
createTileflowBuildArtifacts,
|
|
51
55
|
createTileflowBuildProvenance,
|
|
56
|
+
createTileflowLineBackgroundGlyphResponder,
|
|
52
57
|
createTileflowManifest,
|
|
53
58
|
createTileflowStyle,
|
|
54
59
|
createTileflowStyles,
|
|
@@ -61,6 +66,7 @@ export {
|
|
|
61
66
|
isTileflowArtifactInputPath,
|
|
62
67
|
joinTileflowPublicUrl,
|
|
63
68
|
normalizeTileflowBasePath,
|
|
69
|
+
parseTileflowLineBackgroundGlyphPath,
|
|
64
70
|
prepareTileflowHostedNativeDeployment,
|
|
65
71
|
prepareTileflowLocalTilesets,
|
|
66
72
|
refreshTileflowArtifactSession,
|
|
@@ -68,6 +74,8 @@ export {
|
|
|
68
74
|
tileflowArtifactInventoryFileName,
|
|
69
75
|
tileflowArtifactPlanSchemaVersion,
|
|
70
76
|
tileflowArtifactSessionSchemaVersion,
|
|
77
|
+
tileflowLineBackgroundGlyphRoute,
|
|
78
|
+
usesTileflowLineBackgroundGlyphs,
|
|
71
79
|
writeTileflowArtifactPlan,
|
|
72
80
|
writeTileflowBuildArtifacts
|
|
73
81
|
};
|
|
@@ -168,7 +168,7 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
168
168
|
body { font-family: ui-sans-serif, system-ui, sans-serif; }
|
|
169
169
|
#map {
|
|
170
170
|
--tileflow-globe-radius: 220px;
|
|
171
|
-
background-color: #2F5070;
|
|
171
|
+
background-color: var(--tileflow-space, #2F5070);
|
|
172
172
|
background-image:
|
|
173
173
|
radial-gradient(circle at 18% 24%, rgba(225, 240, 250, 0.34) 0 1px, transparent 1.4px),
|
|
174
174
|
radial-gradient(circle at 72% 62%, rgba(225, 240, 250, 0.22) 0 1px, transparent 1.3px),
|
|
@@ -191,12 +191,12 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
191
191
|
top: 50%;
|
|
192
192
|
width: calc(var(--tileflow-globe-radius) * 2);
|
|
193
193
|
height: calc(var(--tileflow-globe-radius) * 2);
|
|
194
|
-
border: 1px solid rgba(248, 252, 255, 0.88);
|
|
194
|
+
border: 1px solid var(--tileflow-rim-line, rgba(248, 252, 255, 0.88));
|
|
195
195
|
border-radius: 50%;
|
|
196
196
|
box-shadow:
|
|
197
|
-
0 0 9px 3px rgba(248, 252, 255, 0.9),
|
|
198
|
-
0 0 28px 10px rgba(176, 220, 246, 0.52),
|
|
199
|
-
0 0 58px 20px rgba(132, 195, 232, 0.2);
|
|
197
|
+
0 0 9px 3px var(--tileflow-rim-core, rgba(248, 252, 255, 0.9)),
|
|
198
|
+
0 0 28px 10px var(--tileflow-rim-glow, rgba(176, 220, 246, 0.52)),
|
|
199
|
+
0 0 58px 20px var(--tileflow-rim-haze, rgba(132, 195, 232, 0.2));
|
|
200
200
|
pointer-events: none;
|
|
201
201
|
transform: translate(-50%, -50%);
|
|
202
202
|
}
|
|
@@ -233,7 +233,8 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
233
233
|
white-space: pre-wrap;
|
|
234
234
|
}
|
|
235
235
|
.maplibregl-ctrl-group .tileflow-3d-toggle,
|
|
236
|
-
.maplibregl-ctrl-group .tileflow-tree-toggle
|
|
236
|
+
.maplibregl-ctrl-group .tileflow-tree-toggle,
|
|
237
|
+
.maplibregl-ctrl-group .tileflow-theme-toggle {
|
|
237
238
|
width: auto;
|
|
238
239
|
min-width: 58px;
|
|
239
240
|
padding: 0 9px;
|
|
@@ -247,7 +248,8 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
247
248
|
color: #174EA6;
|
|
248
249
|
}
|
|
249
250
|
.maplibregl-ctrl-group .tileflow-3d-toggle:hover,
|
|
250
|
-
.maplibregl-ctrl-group .tileflow-tree-toggle:hover
|
|
251
|
+
.maplibregl-ctrl-group .tileflow-tree-toggle:hover,
|
|
252
|
+
.maplibregl-ctrl-group .tileflow-theme-toggle:hover {
|
|
251
253
|
background-color: #F1F3F4;
|
|
252
254
|
}
|
|
253
255
|
</style>
|
|
@@ -275,6 +277,8 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
275
277
|
const previewLabel = ${JSON.stringify(preview?.label)};
|
|
276
278
|
const styleUrl = ${JSON.stringify(styleUrl)};
|
|
277
279
|
const previewMapOptions = ${JSON.stringify(mapOptions)};
|
|
280
|
+
const previewTheme = ${serializeInlineJson(preview?.themeName ?? null)};
|
|
281
|
+
const previewThemes = ${serializeInlineJson(preview?.themeNames ?? [])};
|
|
278
282
|
const isSemanticPreview = ${JSON.stringify(isSemanticPreview)};
|
|
279
283
|
const previewFontFaces = ${serializeInlineJson(fontFaces)};
|
|
280
284
|
const treeSearchParameters = new URL(location.href).searchParams;
|
|
@@ -985,6 +989,30 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
985
989
|
);
|
|
986
990
|
container.classList.add("tileflow-globe");
|
|
987
991
|
container.style.setProperty("--tileflow-globe-radius", radius.toFixed(2) + "px");
|
|
992
|
+
applyAtmosphereBackdrop(map, container);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
// Uses the map's declared atmosphere for the preview's space and rim, so a themed globe shows
|
|
996
|
+
// its own colours; maps without one keep the default backdrop.
|
|
997
|
+
function applyAtmosphereBackdrop(map, container) {
|
|
998
|
+
const atmosphere = map.getStyle?.()?.metadata?.["tileflow:atmosphere"];
|
|
999
|
+
const rgba = (hex, alpha) => {
|
|
1000
|
+
const match = /^#([0-9a-f]{6})$/i.exec(String(hex ?? ""));
|
|
1001
|
+
if (!match) return undefined;
|
|
1002
|
+
const value = Number.parseInt(match[1], 16);
|
|
1003
|
+
return "rgba(" + (value >> 16) + ", " + ((value >> 8) & 255) + ", " + (value & 255) + ", " + alpha + ")";
|
|
1004
|
+
};
|
|
1005
|
+
const properties = {
|
|
1006
|
+
"--tileflow-space": rgba(atmosphere?.spaceColor, 1),
|
|
1007
|
+
"--tileflow-rim-line": rgba(atmosphere?.horizonColor, 0.88),
|
|
1008
|
+
"--tileflow-rim-core": rgba(atmosphere?.horizonColor, 0.9),
|
|
1009
|
+
"--tileflow-rim-glow": rgba(atmosphere?.horizonColor, 0.52),
|
|
1010
|
+
"--tileflow-rim-haze": rgba(atmosphere?.skyColor, 0.35),
|
|
1011
|
+
};
|
|
1012
|
+
for (const [name, value] of Object.entries(properties)) {
|
|
1013
|
+
if (value) container.style.setProperty(name, value);
|
|
1014
|
+
else container.style.removeProperty(name);
|
|
1015
|
+
}
|
|
988
1016
|
}
|
|
989
1017
|
|
|
990
1018
|
function createBuildingWireframeLayer(map, styleLayer) {
|
|
@@ -3777,6 +3805,38 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
3777
3805
|
}
|
|
3778
3806
|
}
|
|
3779
3807
|
|
|
3808
|
+
// Switches a map preview between its themes. The preview reloads with the next theme and keeps
|
|
3809
|
+
// the camera and toggles already written to the URL; scene previews own their theme.
|
|
3810
|
+
class ThemeControl {
|
|
3811
|
+
onAdd(map) {
|
|
3812
|
+
this.map = map;
|
|
3813
|
+
this.container = document.createElement("div");
|
|
3814
|
+
this.container.className = "maplibregl-ctrl maplibregl-ctrl-group";
|
|
3815
|
+
this.button = document.createElement("button");
|
|
3816
|
+
this.button.type = "button";
|
|
3817
|
+
this.button.className = "tileflow-theme-toggle";
|
|
3818
|
+
const next = previewThemes[(previewThemes.indexOf(previewTheme) + 1) % previewThemes.length];
|
|
3819
|
+
this.button.textContent = String(previewTheme).toUpperCase();
|
|
3820
|
+
this.button.title = "Switch to the " + next + " theme";
|
|
3821
|
+
this.button.setAttribute("aria-label", "Switch to the " + next + " theme");
|
|
3822
|
+
this.handleClick = () => {
|
|
3823
|
+
writeCameraToUrl(map);
|
|
3824
|
+
const url = new URL(location.href);
|
|
3825
|
+
url.searchParams.set("theme", next);
|
|
3826
|
+
location.assign(url.href);
|
|
3827
|
+
};
|
|
3828
|
+
this.button.addEventListener("click", this.handleClick);
|
|
3829
|
+
this.container.appendChild(this.button);
|
|
3830
|
+
return this.container;
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
onRemove() {
|
|
3834
|
+
this.button?.removeEventListener("click", this.handleClick);
|
|
3835
|
+
this.container?.remove();
|
|
3836
|
+
this.map = undefined;
|
|
3837
|
+
}
|
|
3838
|
+
}
|
|
3839
|
+
|
|
3780
3840
|
const previewLayerGroupIds = [
|
|
3781
3841
|
"labels", "pois", "roads", "transit", "buildings", "landuse", "water"
|
|
3782
3842
|
];
|
|
@@ -3913,6 +3973,7 @@ function renderTileflowPreviewHtml(preview, basePath, initialStatus, isSemanticP
|
|
|
3913
3973
|
map.addControl(threeDimensionalControl, "top-right");
|
|
3914
3974
|
map.addControl(treeControl, "top-right");
|
|
3915
3975
|
}
|
|
3976
|
+
if (previewThemes.length > 1) map.addControl(new ThemeControl(), "top-right");
|
|
3916
3977
|
let ensuringThreeDimensionalLayers;
|
|
3917
3978
|
const treeRuntimeMinimumZoom = 16;
|
|
3918
3979
|
const ensureThreeDimensionalLayers = () => {
|
|
@@ -4200,7 +4261,8 @@ function resolveTileflowPreview(project, selection = {}) {
|
|
|
4200
4261
|
},
|
|
4201
4262
|
label: `${mapName} / ${selectedTheme.name}`,
|
|
4202
4263
|
mapName,
|
|
4203
|
-
themeName: selectedTheme.name
|
|
4264
|
+
themeName: selectedTheme.name,
|
|
4265
|
+
themeNames: Object.keys(resolvedMap.themes)
|
|
4204
4266
|
};
|
|
4205
4267
|
}
|
|
4206
4268
|
function resolvePreviewTheme(map, requested) {
|