@tileflow/static 0.1.0-alpha.26 → 0.1.0-alpha.28
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 +22 -22
- package/dist/{chunk-TBI5AED6.js → chunk-ALFVZ3PC.js} +3 -0
- package/dist/client.d.ts +2 -2
- package/dist/client.js +361 -15
- package/dist/{errors-B9rwehK0.d.ts → errors-CSz1xaDx.d.ts} +2 -0
- package/dist/manifest.d.ts +33 -5
- package/dist/manifest.js +322 -17
- package/dist/overlays.d.ts +2 -2
- package/dist/overlays.js +164 -8
- package/dist/{scene-contract-Cr6BNLz0.d.ts → scene-contract-NFnIcQtt.d.ts} +13 -13
- package/dist/scene.d.ts +15 -15
- package/dist/scene.js +1 -1
- package/package.json +2 -9
- package/dist/chunk-HVVIAOBE.js +0 -175
- package/dist/chunk-RGXE4HDY.js +0 -380
- package/dist/chunk-XMT7VJL5.js +0 -297
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -116
package/dist/manifest.js
CHANGED
|
@@ -1,21 +1,326 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import "
|
|
2
|
+
analyzeStaticAutoFit,
|
|
3
|
+
normalizeStaticScene,
|
|
4
|
+
staticAutoFitPlanSchema,
|
|
5
|
+
validateStaticScene
|
|
6
|
+
} from "./chunk-ALFVZ3PC.js";
|
|
7
|
+
import {
|
|
8
|
+
hashStableValue,
|
|
9
|
+
isSafeHttpUrl,
|
|
10
|
+
jsonByteLength,
|
|
11
|
+
stableStringify,
|
|
12
|
+
staticOverlayPlacements,
|
|
13
|
+
staticSceneSchema,
|
|
14
|
+
stripUndefined
|
|
15
|
+
} from "./chunk-6DWVCK64.js";
|
|
16
|
+
|
|
17
|
+
// src/manifest.ts
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
var staticRendererSchemaVersion = 1;
|
|
20
|
+
var staticAttributionPlanSchemaVersion = 1;
|
|
21
|
+
var staticRenderCompositionSchemaVersion = 1;
|
|
22
|
+
var staticAttributionLimits = {
|
|
23
|
+
maxBytes: 32 * 1024,
|
|
24
|
+
maxEntries: 18,
|
|
25
|
+
maxLinksPerEntry: 8,
|
|
26
|
+
maxTextLength: 16384,
|
|
27
|
+
maxUrlLength: 2048
|
|
28
|
+
};
|
|
29
|
+
var sha256HexSchema = z.string().regex(/^[0-9a-f]{64}$/u);
|
|
30
|
+
var sourceIdSchema = z.string().min(1).max(128);
|
|
31
|
+
var boundedIdentitySchema = z.string().min(1).max(512).refine(hasNoControlCharacters, {
|
|
32
|
+
message: "Expected no control characters"
|
|
33
|
+
});
|
|
34
|
+
var staticResolvedAttributionPositionSchema = z.enum([
|
|
35
|
+
"top-left",
|
|
36
|
+
"top-right",
|
|
37
|
+
"bottom-left",
|
|
38
|
+
"bottom-right"
|
|
39
|
+
]);
|
|
40
|
+
var staticAttributionSegmentSchema = z.discriminatedUnion("kind", [
|
|
41
|
+
z.object({
|
|
42
|
+
kind: z.literal("text"),
|
|
43
|
+
text: z.string().min(1).max(staticAttributionLimits.maxTextLength).refine(hasNoControlCharacters, { message: "Attribution text contains control characters" })
|
|
44
|
+
}).strict(),
|
|
45
|
+
z.object({
|
|
46
|
+
kind: z.literal("link"),
|
|
47
|
+
label: z.string().min(1).max(staticAttributionLimits.maxTextLength).refine(hasNoControlCharacters, {
|
|
48
|
+
message: "Attribution link label contains control characters"
|
|
49
|
+
}),
|
|
50
|
+
url: z.string().trim().url().max(staticAttributionLimits.maxUrlLength).refine(isSafeHttpUrl, {
|
|
51
|
+
message: "Expected an http(s) URL without credentials or a fragment"
|
|
52
|
+
})
|
|
53
|
+
}).strict()
|
|
54
|
+
]);
|
|
55
|
+
var attributionSourceSchema = z.object({
|
|
56
|
+
sourceId: sourceIdSchema,
|
|
57
|
+
sourceSelectionIdentity: boundedIdentitySchema
|
|
58
|
+
}).strict();
|
|
59
|
+
var attributionSourcesSchema = z.array(attributionSourceSchema).min(1).max(18).refine(isUniqueSortedSources, {
|
|
60
|
+
message: "Attribution sources must be unique and sorted"
|
|
61
|
+
});
|
|
62
|
+
var staticAttributionProvenanceSchema = z.discriminatedUnion("authority", [
|
|
63
|
+
z.object({
|
|
64
|
+
authority: z.literal("platform-notice"),
|
|
65
|
+
noticeId: boundedIdentitySchema,
|
|
66
|
+
noticeSha256: sha256HexSchema,
|
|
67
|
+
resource: z.enum(["terrain", "world"]),
|
|
68
|
+
sources: attributionSourcesSchema
|
|
69
|
+
}).strict(),
|
|
70
|
+
z.object({
|
|
71
|
+
authority: z.literal("team-declared"),
|
|
72
|
+
sources: z.array(
|
|
73
|
+
attributionSourceSchema.extend({
|
|
74
|
+
mapRevision: boundedIdentitySchema,
|
|
75
|
+
resourceId: boundedIdentitySchema
|
|
76
|
+
}).strict()
|
|
77
|
+
).min(1).max(18).refine(isUniqueSortedSources, {
|
|
78
|
+
message: "Attribution sources must be unique and sorted"
|
|
79
|
+
})
|
|
80
|
+
}).strict()
|
|
81
|
+
]);
|
|
82
|
+
var staticAttributionEntrySchema = z.object({
|
|
83
|
+
authority: z.enum(["platform-notice", "team-declared"]),
|
|
84
|
+
provenance: staticAttributionProvenanceSchema,
|
|
85
|
+
segments: z.array(staticAttributionSegmentSchema).min(1).max(17)
|
|
86
|
+
}).strict().superRefine((entry, context) => {
|
|
87
|
+
if (entry.authority !== entry.provenance.authority) {
|
|
88
|
+
context.addIssue({
|
|
89
|
+
code: "custom",
|
|
90
|
+
message: "Attribution entry authority must match its provenance",
|
|
91
|
+
path: ["authority"]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const links = entry.segments.filter((segment) => segment.kind === "link").length;
|
|
95
|
+
if (links > staticAttributionLimits.maxLinksPerEntry) {
|
|
96
|
+
context.addIssue({
|
|
97
|
+
code: "custom",
|
|
98
|
+
message: `Attribution entries can contain at most ${staticAttributionLimits.maxLinksPerEntry} links`,
|
|
99
|
+
path: ["segments"]
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
var staticAttributionPlanSchema = z.object({
|
|
104
|
+
entries: z.array(staticAttributionEntrySchema).max(staticAttributionLimits.maxEntries),
|
|
105
|
+
mode: z.enum(["embedded", "external"]),
|
|
106
|
+
position: z.union([z.literal("auto"), staticResolvedAttributionPositionSchema, z.null()]),
|
|
107
|
+
schemaVersion: z.literal(staticAttributionPlanSchemaVersion)
|
|
108
|
+
}).strict().superRefine((plan, context) => {
|
|
109
|
+
if (plan.mode === "external" && plan.position !== null || plan.mode === "embedded" && plan.position === null) {
|
|
110
|
+
context.addIssue({
|
|
111
|
+
code: "custom",
|
|
112
|
+
message: "Attribution position must match its mode",
|
|
113
|
+
path: ["position"]
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (jsonByteLength(plan) > staticAttributionLimits.maxBytes) {
|
|
117
|
+
context.addIssue({
|
|
118
|
+
code: "custom",
|
|
119
|
+
message: `Attribution plan exceeds ${staticAttributionLimits.maxBytes} bytes`
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
var placementAnchorsSchema = z.object({
|
|
124
|
+
"above-water": z.string().min(1).max(256).nullable(),
|
|
125
|
+
"below-roads": z.string().min(1).max(256).nullable(),
|
|
126
|
+
"above-roads": z.string().min(1).max(256).nullable(),
|
|
127
|
+
"above-buildings": z.string().min(1).max(256).nullable(),
|
|
128
|
+
"below-labels": z.string().min(1).max(256).nullable(),
|
|
129
|
+
"above-labels": z.null()
|
|
130
|
+
}).strict().refine(anchorsHaveTerminalNulls, {
|
|
131
|
+
message: "Placement anchors may become null only at the end of semantic order"
|
|
132
|
+
});
|
|
133
|
+
var iconCoordinate = z.number().int().nonnegative().max(2048);
|
|
134
|
+
var iconStretchRegions = z.array(z.tuple([iconCoordinate, iconCoordinate])).min(1).max(2048);
|
|
135
|
+
var iconLayoutSchema = z.object({
|
|
136
|
+
stretchX: iconStretchRegions.optional(),
|
|
137
|
+
stretchY: iconStretchRegions.optional(),
|
|
138
|
+
content: z.tuple([iconCoordinate, iconCoordinate, iconCoordinate, iconCoordinate]).optional()
|
|
139
|
+
}).strict();
|
|
140
|
+
var resolvedIconSchema = z.object({
|
|
141
|
+
layout: iconLayoutSchema.optional(),
|
|
142
|
+
// Verified asset defaults supplied by the manifest producer, never scene input.
|
|
143
|
+
appearance: z.object({
|
|
144
|
+
representation: z.literal("sdf"),
|
|
145
|
+
defaults: z.object({
|
|
146
|
+
color: z.string().min(1).max(128).refine(hasNoControlCharacters),
|
|
147
|
+
haloColor: z.string().min(1).max(128).refine(hasNoControlCharacters),
|
|
148
|
+
haloWidth: z.number().finite().min(0).max(2),
|
|
149
|
+
haloBlur: z.number().finite().min(0).max(1)
|
|
150
|
+
}).strict()
|
|
151
|
+
}).strict().optional(),
|
|
152
|
+
height: z.number().int().positive().max(2048),
|
|
153
|
+
icon: z.string().max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/u),
|
|
154
|
+
overlayIndex: z.number().int().min(0).max(23),
|
|
155
|
+
width: z.number().int().positive().max(2048)
|
|
156
|
+
}).strict().superRefine((icon, context) => {
|
|
157
|
+
const layout = icon.layout;
|
|
158
|
+
if (!layout) return;
|
|
159
|
+
let valid = Object.values(layout).some((value) => value !== void 0);
|
|
160
|
+
const content = layout.content;
|
|
161
|
+
if (content)
|
|
162
|
+
valid &&= content[0] < content[2] && content[1] < content[3] && content[2] <= icon.width && content[3] <= icon.height;
|
|
163
|
+
for (const [axis, bound, low, high] of [
|
|
164
|
+
["stretchX", icon.width, content?.[0], content?.[2]],
|
|
165
|
+
["stretchY", icon.height, content?.[1], content?.[3]]
|
|
166
|
+
]) {
|
|
167
|
+
let end = 0;
|
|
168
|
+
for (const [from, to] of layout[axis] ?? []) {
|
|
169
|
+
valid &&= from >= end && from < to && to <= bound;
|
|
170
|
+
end = to;
|
|
171
|
+
}
|
|
172
|
+
if (layout[axis] && low !== void 0 && high !== void 0)
|
|
173
|
+
valid &&= layout[axis].some(([from, to]) => from < high && to > low);
|
|
174
|
+
}
|
|
175
|
+
if (!valid)
|
|
176
|
+
context.addIssue({
|
|
177
|
+
code: "custom",
|
|
178
|
+
path: ["layout"],
|
|
179
|
+
message: "Invalid icon layout for the resolved sprite dimensions"
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
var staticRenderCompositionSchema = z.object({
|
|
183
|
+
anchors: placementAnchorsSchema,
|
|
184
|
+
icons: z.array(resolvedIconSchema).max(24),
|
|
185
|
+
schemaVersion: z.literal(staticRenderCompositionSchemaVersion)
|
|
186
|
+
}).strict().refine(
|
|
187
|
+
(composition) => composition.icons.every(
|
|
188
|
+
(icon, index) => index === 0 || composition.icons[index - 1].overlayIndex < icon.overlayIndex
|
|
189
|
+
),
|
|
190
|
+
{ message: "Resolved symbol icons must be unique and sorted by overlay index" }
|
|
191
|
+
);
|
|
192
|
+
var staticRenderManifestBaseShape = {
|
|
193
|
+
attribution: staticAttributionPlanSchema,
|
|
194
|
+
autoFit: staticAutoFitPlanSchema.optional(),
|
|
195
|
+
composition: staticRenderCompositionSchema,
|
|
196
|
+
mapId: z.string().trim().min(1).max(128),
|
|
197
|
+
rendererVersion: z.string().trim().min(1).max(64),
|
|
198
|
+
schemaVersion: z.literal(staticRendererSchemaVersion),
|
|
199
|
+
scene: staticSceneSchema,
|
|
200
|
+
styleId: z.string().trim().min(1).max(128).optional(),
|
|
201
|
+
styleRevision: z.string().trim().min(1).max(128),
|
|
202
|
+
styleUrl: z.string().trim().url().max(512).refine(isSafeHttpUrl, {
|
|
203
|
+
message: "Expected an http(s) style URL without credentials or a fragment"
|
|
204
|
+
})
|
|
205
|
+
};
|
|
206
|
+
var staticRenderManifestSchema = z.object(staticRenderManifestBaseShape).strict();
|
|
207
|
+
function validateStaticRenderManifest(input) {
|
|
208
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
209
|
+
return { error: "manifest: Expected an object", ok: false };
|
|
210
|
+
}
|
|
211
|
+
if (input.schemaVersion !== staticRendererSchemaVersion) {
|
|
212
|
+
return { error: "manifest.schemaVersion: Unsupported renderer schema version", ok: false };
|
|
213
|
+
}
|
|
214
|
+
const rawScene = input.scene;
|
|
215
|
+
const sceneValidation = validateStaticScene(rawScene);
|
|
216
|
+
if (!sceneValidation.ok) return sceneValidation;
|
|
217
|
+
const parsed = staticRenderManifestSchema.safeParse({
|
|
218
|
+
...input,
|
|
219
|
+
scene: sceneValidation.scene
|
|
220
|
+
});
|
|
221
|
+
if (!parsed.success) return zodFailure(parsed.error);
|
|
222
|
+
const autoFit = expectedAutoFit(sceneValidation.scene);
|
|
223
|
+
if (autoFit === void 0 !== (parsed.data.autoFit === void 0) || autoFit !== void 0 && stableStringify(autoFit) !== stableStringify(parsed.data.autoFit)) {
|
|
224
|
+
return { error: "manifest.autoFit: Expected the exact plan derived from scene", ok: false };
|
|
225
|
+
}
|
|
226
|
+
if (!attributionMatchesScene(parsed.data.attribution, sceneValidation.scene)) {
|
|
227
|
+
return {
|
|
228
|
+
error: "manifest.attribution: Expected the exact request resolved from scene",
|
|
229
|
+
ok: false
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
if (!compositionMatchesScene(parsed.data.composition, sceneValidation.scene)) {
|
|
233
|
+
return {
|
|
234
|
+
error: "manifest.composition: Expected exact resolved symbol icon references",
|
|
235
|
+
ok: false
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
manifest: {
|
|
240
|
+
...parsed.data,
|
|
241
|
+
...autoFit === void 0 ? {} : { autoFit },
|
|
242
|
+
scene: sceneValidation.scene
|
|
243
|
+
},
|
|
244
|
+
ok: true
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function createRenderManifest(input) {
|
|
248
|
+
const scene = normalizeStaticScene(input.scene);
|
|
249
|
+
const autoFit = expectedAutoFit(scene);
|
|
250
|
+
return staticRenderManifestSchema.parse(
|
|
251
|
+
stripUndefined({
|
|
252
|
+
attribution: input.attribution,
|
|
253
|
+
autoFit,
|
|
254
|
+
composition: input.composition,
|
|
255
|
+
mapId: input.mapId,
|
|
256
|
+
rendererVersion: input.rendererVersion,
|
|
257
|
+
schemaVersion: staticRendererSchemaVersion,
|
|
258
|
+
scene,
|
|
259
|
+
styleId: input.styleId,
|
|
260
|
+
styleRevision: input.styleRevision,
|
|
261
|
+
styleUrl: input.styleUrl
|
|
262
|
+
})
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
async function hashRenderManifest(manifest) {
|
|
266
|
+
const validation = validateStaticRenderManifest(manifest);
|
|
267
|
+
if (!validation.ok) throw new Error(`Invalid Tileflow render manifest: ${validation.error}`);
|
|
268
|
+
return hashStableValue(validation.manifest);
|
|
269
|
+
}
|
|
270
|
+
async function hashStaticSceneRequest(scene) {
|
|
271
|
+
const validation = validateStaticScene(scene);
|
|
272
|
+
if (!validation.ok) throw new Error(`Invalid Tileflow static scene: ${validation.error}`);
|
|
273
|
+
return hashStableValue(validation.scene);
|
|
274
|
+
}
|
|
275
|
+
function attributionMatchesScene(plan, scene) {
|
|
276
|
+
const request = scene.attribution;
|
|
277
|
+
const expectedMode = request?.mode === "external" ? "external" : "embedded";
|
|
278
|
+
const expectedPosition = expectedMode === "external" ? null : request && "position" in request ? request.position ?? "auto" : "auto";
|
|
279
|
+
return plan.mode === expectedMode && plan.position === expectedPosition;
|
|
280
|
+
}
|
|
281
|
+
function compositionMatchesScene(composition, scene) {
|
|
282
|
+
const expected = scene.overlays.flatMap(
|
|
283
|
+
(overlay, overlayIndex) => overlay.type === "symbol" && overlay.icon ? [{ icon: overlay.icon, overlayIndex }] : []
|
|
284
|
+
);
|
|
285
|
+
return expected.length === composition.icons.length && expected.every(
|
|
286
|
+
(icon, index) => composition.icons[index]?.icon === icon.icon && composition.icons[index]?.overlayIndex === icon.overlayIndex
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
function expectedAutoFit(scene) {
|
|
290
|
+
if (scene.camera.type !== "auto") return void 0;
|
|
291
|
+
const analysis = analyzeStaticAutoFit(scene);
|
|
292
|
+
if (!analysis.ok) throw new Error(`Invalid Tileflow auto-fit scene: ${analysis.error}`);
|
|
293
|
+
return analysis.plan;
|
|
294
|
+
}
|
|
295
|
+
function anchorsHaveTerminalNulls(anchors) {
|
|
296
|
+
let sawNull = false;
|
|
297
|
+
for (const placement of staticOverlayPlacements) {
|
|
298
|
+
const anchor = anchors[placement];
|
|
299
|
+
if (anchor === null) sawNull = true;
|
|
300
|
+
else if (sawNull) return false;
|
|
301
|
+
}
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
function hasNoControlCharacters(value) {
|
|
305
|
+
return !Array.from(value).some((character) => {
|
|
306
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
307
|
+
return codePoint <= 31 || codePoint === 127;
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
function isUniqueSortedSources(values) {
|
|
311
|
+
return values.every(
|
|
312
|
+
(value, index) => index === 0 || compareCodeUnits(values[index - 1].sourceId, value.sourceId) < 0
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
function compareCodeUnits(left, right) {
|
|
316
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
317
|
+
}
|
|
318
|
+
function zodFailure(error) {
|
|
319
|
+
return {
|
|
320
|
+
error: error.issues.map((issue) => `${issue.path.join(".") || "manifest"}: ${issue.message}`).join("; "),
|
|
321
|
+
ok: false
|
|
322
|
+
};
|
|
323
|
+
}
|
|
19
324
|
export {
|
|
20
325
|
createRenderManifest,
|
|
21
326
|
hashRenderManifest,
|
package/dist/overlays.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
2
|
+
import { c as circleOverlaySchema, b as StaticOverlay, l as lineOverlaySchema, m as markerOverlaySchema, p as polygonOverlaySchema, s as symbolOverlaySchema } from './scene-contract-NFnIcQtt.js';
|
|
3
|
+
export { d as StaticOverlayInput, e as staticOverlaySchema } from './scene-contract-NFnIcQtt.js';
|
|
4
4
|
|
|
5
5
|
declare function line(input: Omit<z.input<typeof lineOverlaySchema>, 'type'>): StaticOverlay;
|
|
6
6
|
declare function circle(input: Omit<z.input<typeof circleOverlaySchema>, 'type'>): StaticOverlay;
|
package/dist/overlays.js
CHANGED
|
@@ -1,14 +1,170 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
line,
|
|
5
|
-
marker,
|
|
6
|
-
polygon,
|
|
7
|
-
symbol
|
|
8
|
-
} from "./chunk-HVVIAOBE.js";
|
|
9
|
-
import {
|
|
2
|
+
normalizeStaticOverlay,
|
|
3
|
+
roundNumber,
|
|
10
4
|
staticOverlaySchema
|
|
11
5
|
} from "./chunk-6DWVCK64.js";
|
|
6
|
+
|
|
7
|
+
// src/overlays.ts
|
|
8
|
+
function line(input) {
|
|
9
|
+
return normalizeStaticOverlay({ ...input, type: "line" });
|
|
10
|
+
}
|
|
11
|
+
function circle(input) {
|
|
12
|
+
return normalizeStaticOverlay({ ...input, type: "circle" });
|
|
13
|
+
}
|
|
14
|
+
function marker(input) {
|
|
15
|
+
return normalizeStaticOverlay({ ...input, type: "marker" });
|
|
16
|
+
}
|
|
17
|
+
function polygon(input) {
|
|
18
|
+
return normalizeStaticOverlay({ ...input, type: "polygon" });
|
|
19
|
+
}
|
|
20
|
+
function symbol(input) {
|
|
21
|
+
return normalizeStaticOverlay({ ...input, type: "symbol" });
|
|
22
|
+
}
|
|
23
|
+
function compileStaticOverlays(overlays, options = {}) {
|
|
24
|
+
if (options.longitudeOffsets !== void 0 && (options.longitudeOffsets.length !== overlays.length || options.longitudeOffsets.some(
|
|
25
|
+
(offset) => !Number.isInteger(offset) || Math.abs(offset) > 360 || offset % 360 !== 0
|
|
26
|
+
))) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
"Static overlay longitude offsets must contain one -360, 0, or 360 per overlay"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const sources = {};
|
|
32
|
+
const layers = [];
|
|
33
|
+
const placements = {};
|
|
34
|
+
const symbols = [];
|
|
35
|
+
const pushLayer = (layer, overlay) => {
|
|
36
|
+
const layerId = String(layer.id);
|
|
37
|
+
layers.push(layer);
|
|
38
|
+
placements[layerId] = overlay.placement ?? "above-labels";
|
|
39
|
+
};
|
|
40
|
+
for (const [index, overlay] of overlays.entries()) {
|
|
41
|
+
const longitudeOffset = options.longitudeOffsets?.[index] ?? 0;
|
|
42
|
+
const id = safeLayerId(`tileflow-static-overlay-${index + 1}-${overlay.id ?? overlay.type}`);
|
|
43
|
+
const sourceId = `${id}-source`;
|
|
44
|
+
if (overlay.type === "line") {
|
|
45
|
+
sources[sourceId] = {
|
|
46
|
+
data: feature("LineString", shiftLongitudes(overlay.coordinates, longitudeOffset)),
|
|
47
|
+
type: "geojson"
|
|
48
|
+
};
|
|
49
|
+
pushLayer(
|
|
50
|
+
{
|
|
51
|
+
id,
|
|
52
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
53
|
+
paint: {
|
|
54
|
+
"line-color": overlay.color,
|
|
55
|
+
"line-opacity": overlay.opacity,
|
|
56
|
+
"line-width": overlay.width
|
|
57
|
+
},
|
|
58
|
+
source: sourceId,
|
|
59
|
+
type: "line"
|
|
60
|
+
},
|
|
61
|
+
overlay
|
|
62
|
+
);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (overlay.type === "polygon") {
|
|
66
|
+
sources[sourceId] = {
|
|
67
|
+
data: feature("Polygon", shiftLongitudes(overlay.coordinates, longitudeOffset)),
|
|
68
|
+
type: "geojson"
|
|
69
|
+
};
|
|
70
|
+
pushLayer(
|
|
71
|
+
{
|
|
72
|
+
id,
|
|
73
|
+
paint: {
|
|
74
|
+
"fill-color": overlay.fill,
|
|
75
|
+
"fill-opacity": overlay.opacity
|
|
76
|
+
},
|
|
77
|
+
source: sourceId,
|
|
78
|
+
type: "fill"
|
|
79
|
+
},
|
|
80
|
+
overlay
|
|
81
|
+
);
|
|
82
|
+
if (overlay.stroke && overlay.strokeWidth > 0) {
|
|
83
|
+
pushLayer(
|
|
84
|
+
{
|
|
85
|
+
id: `${id}-stroke`,
|
|
86
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
87
|
+
paint: {
|
|
88
|
+
"line-color": overlay.stroke,
|
|
89
|
+
"line-width": overlay.strokeWidth
|
|
90
|
+
},
|
|
91
|
+
source: sourceId,
|
|
92
|
+
type: "line"
|
|
93
|
+
},
|
|
94
|
+
overlay
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
sources[sourceId] = {
|
|
100
|
+
data: feature("Point", shiftLongitudes(overlay.coordinate, longitudeOffset)),
|
|
101
|
+
type: "geojson"
|
|
102
|
+
};
|
|
103
|
+
if (overlay.type === "symbol") {
|
|
104
|
+
const composed = overlay.label !== void 0;
|
|
105
|
+
const imageId = composed ? safeLayerId(`__tileflow-static-symbol-${index + 1}-${overlay.id}`) : overlay.icon;
|
|
106
|
+
const alwaysVisible = overlay.collision === "always-visible";
|
|
107
|
+
const iconSize = composed ? 1 : overlay.scale;
|
|
108
|
+
const iconOffset = composed ? overlay.offset : overlay.offset.map((value) => roundNumber(value / overlay.scale));
|
|
109
|
+
pushLayer(
|
|
110
|
+
{
|
|
111
|
+
id,
|
|
112
|
+
layout: {
|
|
113
|
+
"icon-allow-overlap": alwaysVisible,
|
|
114
|
+
"icon-anchor": overlay.anchor,
|
|
115
|
+
"icon-ignore-placement": alwaysVisible,
|
|
116
|
+
"icon-image": imageId,
|
|
117
|
+
"icon-offset": iconOffset,
|
|
118
|
+
"icon-pitch-alignment": "viewport",
|
|
119
|
+
"icon-rotation-alignment": "viewport",
|
|
120
|
+
"icon-size": iconSize,
|
|
121
|
+
"symbol-placement": "point",
|
|
122
|
+
"symbol-z-order": "source"
|
|
123
|
+
},
|
|
124
|
+
paint: { "icon-opacity": overlay.opacity },
|
|
125
|
+
source: sourceId,
|
|
126
|
+
type: "symbol"
|
|
127
|
+
},
|
|
128
|
+
overlay
|
|
129
|
+
);
|
|
130
|
+
symbols.push({ imageId, overlayIndex: index });
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
pushLayer(
|
|
134
|
+
{
|
|
135
|
+
id,
|
|
136
|
+
paint: {
|
|
137
|
+
"circle-color": overlay.color,
|
|
138
|
+
"circle-opacity": overlay.type === "circle" ? overlay.opacity : 1,
|
|
139
|
+
"circle-radius": overlay.radius,
|
|
140
|
+
"circle-stroke-color": overlay.strokeColor ?? overlay.color,
|
|
141
|
+
"circle-stroke-width": overlay.strokeWidth
|
|
142
|
+
},
|
|
143
|
+
source: sourceId,
|
|
144
|
+
type: "circle"
|
|
145
|
+
},
|
|
146
|
+
overlay
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
return { layers, placements, sources, symbols };
|
|
150
|
+
}
|
|
151
|
+
function shiftLongitudes(value, offset) {
|
|
152
|
+
if (!Array.isArray(value)) return value;
|
|
153
|
+
if (value.length === 2 && typeof value[0] === "number" && typeof value[1] === "number") {
|
|
154
|
+
return [roundNumber(value[0] + offset), value[1]];
|
|
155
|
+
}
|
|
156
|
+
return value.map((entry) => shiftLongitudes(entry, offset));
|
|
157
|
+
}
|
|
158
|
+
function feature(type, coordinates) {
|
|
159
|
+
return {
|
|
160
|
+
geometry: { coordinates, type },
|
|
161
|
+
properties: {},
|
|
162
|
+
type: "Feature"
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function safeLayerId(value) {
|
|
166
|
+
return value.replace(/[^a-zA-Z0-9_-]/g, "-").slice(0, 80);
|
|
167
|
+
}
|
|
12
168
|
export {
|
|
13
169
|
circle,
|
|
14
170
|
compileStaticOverlays,
|
|
@@ -198,8 +198,8 @@ declare const symbolOverlaySchema: z.ZodObject<{
|
|
|
198
198
|
haloColor: string;
|
|
199
199
|
haloWidth: number;
|
|
200
200
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
201
|
-
text: string;
|
|
202
201
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
202
|
+
text: string;
|
|
203
203
|
} | {
|
|
204
204
|
appearance: "badge";
|
|
205
205
|
backgroundColor: string;
|
|
@@ -214,8 +214,8 @@ declare const symbolOverlaySchema: z.ZodObject<{
|
|
|
214
214
|
x: number;
|
|
215
215
|
y: number;
|
|
216
216
|
};
|
|
217
|
-
text: string;
|
|
218
217
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
218
|
+
text: string;
|
|
219
219
|
}, string | {
|
|
220
220
|
appearance: "plain";
|
|
221
221
|
color: string;
|
|
@@ -224,8 +224,8 @@ declare const symbolOverlaySchema: z.ZodObject<{
|
|
|
224
224
|
haloColor: string;
|
|
225
225
|
haloWidth: number;
|
|
226
226
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
227
|
-
text: string;
|
|
228
227
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
228
|
+
text: string;
|
|
229
229
|
} | {
|
|
230
230
|
appearance: "badge";
|
|
231
231
|
backgroundColor: string;
|
|
@@ -240,8 +240,8 @@ declare const symbolOverlaySchema: z.ZodObject<{
|
|
|
240
240
|
x: number;
|
|
241
241
|
y: number;
|
|
242
242
|
};
|
|
243
|
-
text: string;
|
|
244
243
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
244
|
+
text: string;
|
|
245
245
|
}>>>;
|
|
246
246
|
offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
247
247
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
@@ -403,8 +403,8 @@ declare const staticOverlaySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
403
403
|
haloColor: string;
|
|
404
404
|
haloWidth: number;
|
|
405
405
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
406
|
-
text: string;
|
|
407
406
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
407
|
+
text: string;
|
|
408
408
|
} | {
|
|
409
409
|
appearance: "badge";
|
|
410
410
|
backgroundColor: string;
|
|
@@ -419,8 +419,8 @@ declare const staticOverlaySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
419
419
|
x: number;
|
|
420
420
|
y: number;
|
|
421
421
|
};
|
|
422
|
-
text: string;
|
|
423
422
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
423
|
+
text: string;
|
|
424
424
|
}, string | {
|
|
425
425
|
appearance: "plain";
|
|
426
426
|
color: string;
|
|
@@ -429,8 +429,8 @@ declare const staticOverlaySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
429
429
|
haloColor: string;
|
|
430
430
|
haloWidth: number;
|
|
431
431
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
432
|
-
text: string;
|
|
433
432
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
433
|
+
text: string;
|
|
434
434
|
} | {
|
|
435
435
|
appearance: "badge";
|
|
436
436
|
backgroundColor: string;
|
|
@@ -445,8 +445,8 @@ declare const staticOverlaySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
445
445
|
x: number;
|
|
446
446
|
y: number;
|
|
447
447
|
};
|
|
448
|
-
text: string;
|
|
449
448
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
449
|
+
text: string;
|
|
450
450
|
}>>>;
|
|
451
451
|
offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
452
452
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
@@ -648,8 +648,8 @@ declare const staticSceneSchema: z.ZodObject<{
|
|
|
648
648
|
haloColor: string;
|
|
649
649
|
haloWidth: number;
|
|
650
650
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
651
|
-
text: string;
|
|
652
651
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
652
|
+
text: string;
|
|
653
653
|
} | {
|
|
654
654
|
appearance: "badge";
|
|
655
655
|
backgroundColor: string;
|
|
@@ -664,8 +664,8 @@ declare const staticSceneSchema: z.ZodObject<{
|
|
|
664
664
|
x: number;
|
|
665
665
|
y: number;
|
|
666
666
|
};
|
|
667
|
-
text: string;
|
|
668
667
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
668
|
+
text: string;
|
|
669
669
|
}, string | {
|
|
670
670
|
appearance: "plain";
|
|
671
671
|
color: string;
|
|
@@ -674,8 +674,8 @@ declare const staticSceneSchema: z.ZodObject<{
|
|
|
674
674
|
haloColor: string;
|
|
675
675
|
haloWidth: number;
|
|
676
676
|
language: "ja" | "ko" | "zh-Hans" | "zh-Hant";
|
|
677
|
-
text: string;
|
|
678
677
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
678
|
+
text: string;
|
|
679
679
|
} | {
|
|
680
680
|
appearance: "badge";
|
|
681
681
|
backgroundColor: string;
|
|
@@ -690,8 +690,8 @@ declare const staticSceneSchema: z.ZodObject<{
|
|
|
690
690
|
x: number;
|
|
691
691
|
y: number;
|
|
692
692
|
};
|
|
693
|
-
text: string;
|
|
694
693
|
position?: "above" | "above-left" | "above-right" | "below" | "below-left" | "below-right" | "center" | "left" | "right" | undefined;
|
|
694
|
+
text: string;
|
|
695
695
|
}>>>;
|
|
696
696
|
offset: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
697
697
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
@@ -731,4 +731,4 @@ type StaticSymbolLabelAppearance = (typeof staticSymbolLabelAppearances)[number]
|
|
|
731
731
|
type StaticSymbolLabelPosition = (typeof staticSymbolLabelPositions)[number];
|
|
732
732
|
declare function isSupportedStaticSymbolCodePoint(codePoint: number): boolean;
|
|
733
733
|
|
|
734
|
-
export {
|
|
734
|
+
export { staticSceneSchema as A, staticSceneSchemaVersion as B, staticSymbolAnchors as C, staticSymbolCollisions as D, staticSymbolLabelAppearances as E, staticSymbolLabelPositions as F, staticSymbolLanguages as G, MAX_OVERLAY_LATITUDE as M, type StaticAttributionPosition as S, type StaticSceneInput as a, type StaticOverlay as b, circleOverlaySchema as c, type StaticOverlayInput as d, staticOverlaySchema as e, type StaticScene as f, type StaticAttributionMode as g, type StaticAttributionRequest as h, type StaticCoordinate as i, type StaticMapFormat as j, type StaticOverlayPlacement as k, lineOverlaySchema as l, markerOverlaySchema as m, type StaticPadding as n, type StaticSymbolAnchor as o, polygonOverlaySchema as p, type StaticSymbolCollision as q, type StaticSymbolLabelAppearance as r, symbolOverlaySchema as s, type StaticSymbolLabelPosition as t, type StaticSymbolLanguage as u, isSupportedStaticSymbolCodePoint as v, staticAttributionPositionSchema as w, staticAttributionRequestSchema as x, staticOverlayPlacements as y, staticSceneLimits as z };
|