@tileflow/core 0.1.0-alpha.6 → 0.1.0-alpha.8
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 +56 -3
- package/dist/index.d.ts +934 -94
- package/dist/index.js +959 -324
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,130 +1,13 @@
|
|
|
1
1
|
// src/basemaps/osm.ts
|
|
2
|
+
var defaultOsmBrightSprite = "https://openmaptiles.github.io/osm-bright-gl-style/sprite";
|
|
2
3
|
function osm(options = {}) {
|
|
3
4
|
return {
|
|
4
5
|
type: "osm",
|
|
6
|
+
sprite: defaultOsmBrightSprite,
|
|
5
7
|
...options
|
|
6
8
|
};
|
|
7
9
|
}
|
|
8
10
|
|
|
9
|
-
// src/modules/roads/index.ts
|
|
10
|
-
function roads(options = {}) {
|
|
11
|
-
return {
|
|
12
|
-
type: "roads",
|
|
13
|
-
preset: options.preset ?? "modern",
|
|
14
|
-
...options.density ? { density: options.density } : {}
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
function resolveRoads(legacyRoads, moduleConfig, fallback) {
|
|
18
|
-
if (!moduleConfig) {
|
|
19
|
-
return legacyRoads ?? fallback;
|
|
20
|
-
}
|
|
21
|
-
if (moduleConfig.preset === "minimal" || moduleConfig.density === "clean") {
|
|
22
|
-
return "soft";
|
|
23
|
-
}
|
|
24
|
-
if (moduleConfig.density === "dense") {
|
|
25
|
-
return "detailed";
|
|
26
|
-
}
|
|
27
|
-
return "standard";
|
|
28
|
-
}
|
|
29
|
-
function roadLayers(source, sourceLayer, colors, roadsMode) {
|
|
30
|
-
if (roadsMode === "hidden") {
|
|
31
|
-
return [];
|
|
32
|
-
}
|
|
33
|
-
const opacity = roadsMode === "soft" ? 0.72 : roadsMode === "standard" ? 0.84 : 0.96;
|
|
34
|
-
const casingOpacity = roadsMode === "detailed" ? 0.3 : 0.16;
|
|
35
|
-
const majorRoadFilter = [
|
|
36
|
-
"match",
|
|
37
|
-
["get", "class"],
|
|
38
|
-
["motorway", "trunk", "primary", "secondary"],
|
|
39
|
-
true,
|
|
40
|
-
false
|
|
41
|
-
];
|
|
42
|
-
const minorRoadFilter = ["!", majorRoadFilter];
|
|
43
|
-
const nonTunnelRoadFilter = ["!=", ["get", "brunnel"], "tunnel"];
|
|
44
|
-
return [
|
|
45
|
-
{
|
|
46
|
-
id: "roads-tunnels-casing",
|
|
47
|
-
type: "line",
|
|
48
|
-
source,
|
|
49
|
-
"source-layer": sourceLayer,
|
|
50
|
-
minzoom: 10,
|
|
51
|
-
filter: ["==", ["get", "brunnel"], "tunnel"],
|
|
52
|
-
paint: {
|
|
53
|
-
"line-color": colors.roads.tunnel,
|
|
54
|
-
"line-dasharray": [0.6, 0.8],
|
|
55
|
-
"line-opacity": 0.28,
|
|
56
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 0.5, 14, 1.7, 16, 3.8]
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
id: "roads-tunnels",
|
|
61
|
-
type: "line",
|
|
62
|
-
source,
|
|
63
|
-
"source-layer": sourceLayer,
|
|
64
|
-
minzoom: 10,
|
|
65
|
-
filter: ["==", ["get", "brunnel"], "tunnel"],
|
|
66
|
-
paint: {
|
|
67
|
-
"line-color": colors.roads.minor,
|
|
68
|
-
"line-dasharray": [0.6, 0.8],
|
|
69
|
-
"line-opacity": 0.2,
|
|
70
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 0.25, 14, 1, 16, 2.4]
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
id: "roads-casing",
|
|
75
|
-
type: "line",
|
|
76
|
-
source,
|
|
77
|
-
"source-layer": sourceLayer,
|
|
78
|
-
minzoom: 6,
|
|
79
|
-
filter: nonTunnelRoadFilter,
|
|
80
|
-
paint: {
|
|
81
|
-
"line-color": colors.roads.casing,
|
|
82
|
-
"line-opacity": casingOpacity,
|
|
83
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 6, 0.4, 12, 1.2, 16, 4]
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
id: "roads-minor",
|
|
88
|
-
type: "line",
|
|
89
|
-
source,
|
|
90
|
-
"source-layer": sourceLayer,
|
|
91
|
-
minzoom: 6,
|
|
92
|
-
filter: ["all", nonTunnelRoadFilter, minorRoadFilter],
|
|
93
|
-
paint: {
|
|
94
|
-
"line-color": colors.roads.minor,
|
|
95
|
-
"line-opacity": opacity * 0.88,
|
|
96
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 6, 0.2, 12, 0.8, 16, 3]
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
id: "roads-major",
|
|
101
|
-
type: "line",
|
|
102
|
-
source,
|
|
103
|
-
"source-layer": sourceLayer,
|
|
104
|
-
minzoom: 5,
|
|
105
|
-
filter: ["all", nonTunnelRoadFilter, majorRoadFilter],
|
|
106
|
-
paint: {
|
|
107
|
-
"line-color": colors.roads.primary,
|
|
108
|
-
"line-opacity": opacity,
|
|
109
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 5, 0.35, 12, 1.2, 16, 4]
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
id: "roads-bridges",
|
|
114
|
-
type: "line",
|
|
115
|
-
source,
|
|
116
|
-
"source-layer": sourceLayer,
|
|
117
|
-
minzoom: 10,
|
|
118
|
-
filter: ["==", ["get", "brunnel"], "bridge"],
|
|
119
|
-
paint: {
|
|
120
|
-
"line-color": colors.roads.bridge,
|
|
121
|
-
"line-opacity": opacity,
|
|
122
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 0.45, 14, 1.6, 16, 4.4]
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
11
|
// src/themes/index.ts
|
|
129
12
|
var defaultColors = {
|
|
130
13
|
background: "#F6F7F3",
|
|
@@ -266,7 +149,8 @@ function resolveColors(overrides = {}, defaults = defaultColors, moduleOverrides
|
|
|
266
149
|
const defaultModules = mergeThemeModules(extractLegacyModuleColors(defaults), moduleDefaults);
|
|
267
150
|
const overrideModules = mergeThemeModules(extractLegacyModuleColors(overrides), moduleOverrides);
|
|
268
151
|
const base = resolveBaseColors(overrideInput, defaultInput);
|
|
269
|
-
const
|
|
152
|
+
const baseRoadCasing = overrideInput.roadCasing ?? defaultInput.roadCasing ?? mix(base.road, base.text, 0.2);
|
|
153
|
+
const roadCasing = overrideModules.roads?.casing ?? defaultModules.roads?.casing ?? baseRoadCasing;
|
|
270
154
|
const baseResolved = {
|
|
271
155
|
...base,
|
|
272
156
|
canvas: base.background,
|
|
@@ -286,18 +170,33 @@ function resolveColors(overrides = {}, defaults = defaultColors, moduleOverrides
|
|
|
286
170
|
rail: base.textMuted,
|
|
287
171
|
secondary: base.roadMajor,
|
|
288
172
|
trunk: base.roadMajor,
|
|
289
|
-
tunnel: mix(
|
|
173
|
+
tunnel: mix(baseRoadCasing, base.background, 0.35)
|
|
290
174
|
};
|
|
291
175
|
const labelDefaults = {
|
|
292
176
|
country: base.text,
|
|
293
177
|
halo: base.textHalo,
|
|
294
178
|
muted: base.textMuted,
|
|
179
|
+
neighborhood: base.textMuted,
|
|
295
180
|
poi: base.textMuted,
|
|
296
181
|
primary: base.text,
|
|
297
182
|
road: base.textMuted,
|
|
298
183
|
settlement: base.text,
|
|
299
184
|
water: mix(base.water, base.text, 0.42)
|
|
300
185
|
};
|
|
186
|
+
const poiDefaults = {
|
|
187
|
+
coffee: mix(base.textMuted, base.roadMajor, 0.24),
|
|
188
|
+
culture: mix(base.textMuted, base.text, 0.18),
|
|
189
|
+
education: mix(base.textMuted, base.water, 0.18),
|
|
190
|
+
food: mix(base.textMuted, base.roadMajor, 0.34),
|
|
191
|
+
halo: labelDefaults.halo,
|
|
192
|
+
health: mix(base.textMuted, "#D45E5E", 0.22),
|
|
193
|
+
icon: labelDefaults.poi,
|
|
194
|
+
label: labelDefaults.poi,
|
|
195
|
+
lodging: mix(base.textMuted, base.water, 0.24),
|
|
196
|
+
services: labelDefaults.poi,
|
|
197
|
+
shopping: mix(base.textMuted, base.park, 0.2),
|
|
198
|
+
transit: labelDefaults.road
|
|
199
|
+
};
|
|
301
200
|
const landuseDefaults = {
|
|
302
201
|
cemetery: mix(base.park, base.land, 0.35),
|
|
303
202
|
civic: mix(base.land, base.textMuted, 0.08),
|
|
@@ -348,6 +247,7 @@ function resolveColors(overrides = {}, defaults = defaultColors, moduleOverrides
|
|
|
348
247
|
landuse: mapColorRecord(
|
|
349
248
|
resolveGroup(landuseDefaults, defaultModules.landuse, overrideModules.landuse)
|
|
350
249
|
),
|
|
250
|
+
poi: mapColorRecord(resolveGroup(poiDefaults, defaultModules.poi, overrideModules.poi)),
|
|
351
251
|
roads: mapColorRecord(resolveGroup(roadDefaults, defaultModules.roads, overrideModules.roads))
|
|
352
252
|
};
|
|
353
253
|
}
|
|
@@ -501,6 +401,7 @@ function stripLegacyModuleColors(colors) {
|
|
|
501
401
|
labels: _labels,
|
|
502
402
|
landcover: _landcover,
|
|
503
403
|
landuse: _landuse,
|
|
404
|
+
poi: _poi,
|
|
504
405
|
roads: _roads,
|
|
505
406
|
...baseColors
|
|
506
407
|
} = colors;
|
|
@@ -517,6 +418,7 @@ function extractLegacyModuleColors(colors) {
|
|
|
517
418
|
...colors.labels ? { labels: colors.labels } : {},
|
|
518
419
|
...colors.landcover ? { landcover: colors.landcover } : {},
|
|
519
420
|
...colors.landuse ? { landuse: colors.landuse } : {},
|
|
421
|
+
...colors.poi ? { poi: colors.poi } : {},
|
|
520
422
|
...colors.roads ? { roads: colors.roads } : {}
|
|
521
423
|
};
|
|
522
424
|
}
|
|
@@ -528,6 +430,7 @@ function mergeThemeModules(defaults = {}, overrides = {}) {
|
|
|
528
430
|
...mergeThemeModuleGroup("labels", defaults, overrides),
|
|
529
431
|
...mergeThemeModuleGroup("landcover", defaults, overrides),
|
|
530
432
|
...mergeThemeModuleGroup("landuse", defaults, overrides),
|
|
433
|
+
...mergeThemeModuleGroup("poi", defaults, overrides),
|
|
531
434
|
...mergeThemeModuleGroup("roads", defaults, overrides)
|
|
532
435
|
};
|
|
533
436
|
}
|
|
@@ -611,6 +514,437 @@ function rgbToHex(r, g, b) {
|
|
|
611
514
|
return `#${[r, g, b].map((value) => value.toString(16).padStart(2, "0")).join("")}`;
|
|
612
515
|
}
|
|
613
516
|
|
|
517
|
+
// src/modules/labels/index.ts
|
|
518
|
+
function labels(options = {}) {
|
|
519
|
+
return {
|
|
520
|
+
type: "labels",
|
|
521
|
+
...options.language ? { language: options.language } : {},
|
|
522
|
+
...options.places ? { places: options.places } : {},
|
|
523
|
+
...options.preset ? { preset: options.preset } : {},
|
|
524
|
+
...options.roads ? { roads: options.roads } : {},
|
|
525
|
+
...options.water ? { water: options.water } : {}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
function resolveLabels(legacyLabels, moduleConfig, fallback) {
|
|
529
|
+
const mode = moduleConfig?.preset ?? legacyLabels ?? fallback;
|
|
530
|
+
const density = labelDensityFromMode(mode);
|
|
531
|
+
return {
|
|
532
|
+
language: moduleConfig?.language ?? "auto",
|
|
533
|
+
mode,
|
|
534
|
+
places: moduleConfig?.places ?? density,
|
|
535
|
+
roads: moduleConfig?.roads ?? density,
|
|
536
|
+
water: moduleConfig?.water ?? density
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
function labelLayers(source, sourceLayer, colors, labelsConfig, typography) {
|
|
540
|
+
if (labelsConfig.mode === "none" || labelsConfig.places === "none") {
|
|
541
|
+
return [];
|
|
542
|
+
}
|
|
543
|
+
const maxRank = labelsConfig.places === "minimal" ? 3 : labelsConfig.places === "balanced" ? 7 : 12;
|
|
544
|
+
return [
|
|
545
|
+
{
|
|
546
|
+
id: "place-labels",
|
|
547
|
+
type: "symbol",
|
|
548
|
+
source,
|
|
549
|
+
"source-layer": sourceLayer,
|
|
550
|
+
minzoom: 3,
|
|
551
|
+
filter: ["<=", ["coalesce", ["get", "rank"], 10], maxRank],
|
|
552
|
+
layout: {
|
|
553
|
+
"text-field": labelTextField(labelsConfig.language),
|
|
554
|
+
"text-font": textFont(typography),
|
|
555
|
+
"text-size": ["interpolate", ["linear"], ["zoom"], 3, 10, 8, 13, 14, 17],
|
|
556
|
+
"text-letter-spacing": 0,
|
|
557
|
+
"text-padding": 4
|
|
558
|
+
},
|
|
559
|
+
paint: {
|
|
560
|
+
"text-color": colors.labels.primary,
|
|
561
|
+
"text-halo-color": colors.labels.halo,
|
|
562
|
+
"text-halo-width": 1.2
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
];
|
|
566
|
+
}
|
|
567
|
+
function labelDensityFromMode(mode) {
|
|
568
|
+
if (mode === "none") return "none";
|
|
569
|
+
if (mode === "essential") return "minimal";
|
|
570
|
+
if (mode === "full") return "detailed";
|
|
571
|
+
return "balanced";
|
|
572
|
+
}
|
|
573
|
+
function labelTextField(language) {
|
|
574
|
+
if (language === "local") {
|
|
575
|
+
return ["coalesce", ["get", "name"], ["get", "name:latin"], ["get", "name:en"]];
|
|
576
|
+
}
|
|
577
|
+
if (language === "auto") {
|
|
578
|
+
return ["coalesce", ["get", "name:latin"], ["get", "name"], ["get", "name:en"]];
|
|
579
|
+
}
|
|
580
|
+
return ["coalesce", ["get", `name:${language}`], ["get", "name:latin"], ["get", "name"]];
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// src/modules/poi/index.ts
|
|
584
|
+
var defaultPoiMinZoom = {
|
|
585
|
+
none: 24,
|
|
586
|
+
minimal: 15,
|
|
587
|
+
balanced: 13,
|
|
588
|
+
full: 11
|
|
589
|
+
};
|
|
590
|
+
function poi(options = {}) {
|
|
591
|
+
return {
|
|
592
|
+
type: "poi",
|
|
593
|
+
...options.categories ? { categories: options.categories } : {},
|
|
594
|
+
...options.icons !== void 0 ? { icons: options.icons } : {},
|
|
595
|
+
...options.labels ? { labels: options.labels } : {},
|
|
596
|
+
...options.minZoom !== void 0 ? { minZoom: options.minZoom } : {},
|
|
597
|
+
...options.preset ? { preset: options.preset } : {}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
function resolvePoi(legacyPoi, moduleConfig, fallback) {
|
|
601
|
+
const mode = moduleConfig?.preset ?? legacyPoi ?? fallback;
|
|
602
|
+
return {
|
|
603
|
+
categories: moduleConfig?.categories,
|
|
604
|
+
icons: moduleConfig?.icons ?? (mode === "none" ? false : "essential"),
|
|
605
|
+
labels: moduleConfig?.labels ?? poiLabelsFromMode(mode),
|
|
606
|
+
minZoom: moduleConfig?.minZoom ?? defaultPoiMinZoom[mode],
|
|
607
|
+
mode
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
function poiLayers(source, sourceLayer, colors, poiConfig, typography, customIconSpriteId2, customIconMapping) {
|
|
611
|
+
if (poiConfig.mode === "none") {
|
|
612
|
+
return [];
|
|
613
|
+
}
|
|
614
|
+
const layout = {
|
|
615
|
+
"text-field": labelTextField("auto"),
|
|
616
|
+
"text-font": textFont(typography),
|
|
617
|
+
"text-size": ["interpolate", ["linear"], ["zoom"], poiConfig.minZoom, 10, 17, 12],
|
|
618
|
+
"text-letter-spacing": 0,
|
|
619
|
+
"text-padding": 2
|
|
620
|
+
};
|
|
621
|
+
if (poiConfig.labels === "none") {
|
|
622
|
+
delete layout["text-field"];
|
|
623
|
+
}
|
|
624
|
+
if (poiConfig.icons) {
|
|
625
|
+
layout["icon-image"] = poiIconImageExpression(customIconSpriteId2, customIconMapping);
|
|
626
|
+
layout["icon-optional"] = true;
|
|
627
|
+
layout["icon-padding"] = 2;
|
|
628
|
+
layout["icon-size"] = ["interpolate", ["linear"], ["zoom"], poiConfig.minZoom, 0.85, 17, 1];
|
|
629
|
+
layout["text-anchor"] = "top";
|
|
630
|
+
layout["text-offset"] = [0, 0.75];
|
|
631
|
+
}
|
|
632
|
+
return [
|
|
633
|
+
{
|
|
634
|
+
id: "poi-labels",
|
|
635
|
+
type: "symbol",
|
|
636
|
+
source,
|
|
637
|
+
"source-layer": sourceLayer,
|
|
638
|
+
minzoom: poiConfig.minZoom,
|
|
639
|
+
...poiConfig.categories ? { filter: poiCategoryFilter(poiConfig.categories) } : {},
|
|
640
|
+
layout,
|
|
641
|
+
paint: {
|
|
642
|
+
"text-color": colors.poi.label,
|
|
643
|
+
"text-halo-color": colors.poi.halo ?? alpha(colors.background, 0.78),
|
|
644
|
+
"text-halo-width": 1
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
];
|
|
648
|
+
}
|
|
649
|
+
function poiLabelsFromMode(mode) {
|
|
650
|
+
if (mode === "none") return "none";
|
|
651
|
+
if (mode === "minimal") return "minimal";
|
|
652
|
+
if (mode === "full") return "full";
|
|
653
|
+
return "balanced";
|
|
654
|
+
}
|
|
655
|
+
function poiCategoryFilter(categories) {
|
|
656
|
+
return ["in", "class", ...categories.flatMap((category) => poiCategoryClasses(category))];
|
|
657
|
+
}
|
|
658
|
+
function poiIconImageExpression(customIconSpriteId2, customIconMapping = {}) {
|
|
659
|
+
const matchParts = [];
|
|
660
|
+
for (const [className, iconName] of Object.entries(poiClassIconNames)) {
|
|
661
|
+
matchParts.push(
|
|
662
|
+
className,
|
|
663
|
+
poiIconImageFallback(iconName, customIconSpriteId2, customIconMapping)
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
return [
|
|
667
|
+
"match",
|
|
668
|
+
["get", "class"],
|
|
669
|
+
...matchParts,
|
|
670
|
+
poiIconImageFallback("default", customIconSpriteId2, customIconMapping)
|
|
671
|
+
];
|
|
672
|
+
}
|
|
673
|
+
function poiCategoryClasses(category) {
|
|
674
|
+
return poiCategoryClassNames[category] ?? [category];
|
|
675
|
+
}
|
|
676
|
+
function poiIconImageFallback(iconName, customIconSpriteId2, customIconMapping) {
|
|
677
|
+
const osmBrightIcon = `${osmBrightIconNameForSemanticIcon(iconName)}_11`;
|
|
678
|
+
const customIconName = customIconMapping[iconName] ?? iconName;
|
|
679
|
+
if (!customIconSpriteId2) {
|
|
680
|
+
return ["coalesce", ["image", customIconName], ["image", osmBrightIcon]];
|
|
681
|
+
}
|
|
682
|
+
return [
|
|
683
|
+
"coalesce",
|
|
684
|
+
["image", `${customIconSpriteId2}:${customIconName}`],
|
|
685
|
+
["image", osmBrightIcon]
|
|
686
|
+
];
|
|
687
|
+
}
|
|
688
|
+
function osmBrightIconNameForSemanticIcon(iconName) {
|
|
689
|
+
return semanticToOsmBrightIconName[iconName] ?? "marker";
|
|
690
|
+
}
|
|
691
|
+
var poiCategoryClassNames = {
|
|
692
|
+
coffee: ["cafe"],
|
|
693
|
+
culture: ["museum", "gallery", "theatre", "cinema", "library", "attraction"],
|
|
694
|
+
education: ["school", "college", "university"],
|
|
695
|
+
food: ["restaurant", "fast_food", "bar", "pub", "biergarten"],
|
|
696
|
+
health: ["hospital", "pharmacy", "doctors", "dentist"],
|
|
697
|
+
lodging: ["hotel", "motel", "hostel", "guest_house"],
|
|
698
|
+
services: ["bank", "post", "toilet", "police", "fire_station", "town_hall"],
|
|
699
|
+
shopping: ["shop", "mall", "supermarket", "marketplace"],
|
|
700
|
+
transit: ["railway", "station", "bus", "bus_stop", "subway", "tram"]
|
|
701
|
+
};
|
|
702
|
+
var poiClassIconNames = {
|
|
703
|
+
attraction: "culture",
|
|
704
|
+
bank: "services",
|
|
705
|
+
bar: "food",
|
|
706
|
+
biergarten: "food",
|
|
707
|
+
bus: "transit",
|
|
708
|
+
bus_stop: "transit",
|
|
709
|
+
cafe: "coffee",
|
|
710
|
+
cinema: "culture",
|
|
711
|
+
college: "education",
|
|
712
|
+
dentist: "health",
|
|
713
|
+
doctors: "health",
|
|
714
|
+
fast_food: "food",
|
|
715
|
+
fire_station: "services",
|
|
716
|
+
gallery: "culture",
|
|
717
|
+
guest_house: "lodging",
|
|
718
|
+
hospital: "health",
|
|
719
|
+
hostel: "lodging",
|
|
720
|
+
hotel: "lodging",
|
|
721
|
+
library: "culture",
|
|
722
|
+
mall: "shopping",
|
|
723
|
+
marketplace: "shopping",
|
|
724
|
+
motel: "lodging",
|
|
725
|
+
museum: "culture",
|
|
726
|
+
pharmacy: "health",
|
|
727
|
+
police: "services",
|
|
728
|
+
post: "services",
|
|
729
|
+
pub: "food",
|
|
730
|
+
railway: "transit",
|
|
731
|
+
restaurant: "food",
|
|
732
|
+
school: "education",
|
|
733
|
+
shop: "shopping",
|
|
734
|
+
station: "transit",
|
|
735
|
+
subway: "transit",
|
|
736
|
+
supermarket: "shopping",
|
|
737
|
+
theatre: "culture",
|
|
738
|
+
toilet: "services",
|
|
739
|
+
town_hall: "services",
|
|
740
|
+
tram: "transit",
|
|
741
|
+
university: "education"
|
|
742
|
+
};
|
|
743
|
+
var semanticToOsmBrightIconName = {
|
|
744
|
+
coffee: "cafe",
|
|
745
|
+
culture: "museum",
|
|
746
|
+
default: "marker",
|
|
747
|
+
education: "school",
|
|
748
|
+
food: "restaurant",
|
|
749
|
+
health: "hospital",
|
|
750
|
+
lodging: "lodging",
|
|
751
|
+
services: "marker",
|
|
752
|
+
shopping: "shop",
|
|
753
|
+
transit: "railway"
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
// src/modules/roads/index.ts
|
|
757
|
+
function roads(options = {}) {
|
|
758
|
+
return {
|
|
759
|
+
type: "roads",
|
|
760
|
+
preset: options.preset ?? "modern",
|
|
761
|
+
...options.density ? { density: options.density } : {}
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
function resolveRoads(legacyRoads, moduleConfig, fallback) {
|
|
765
|
+
if (!moduleConfig) {
|
|
766
|
+
return legacyRoads ?? fallback;
|
|
767
|
+
}
|
|
768
|
+
if (moduleConfig.preset === "minimal" || moduleConfig.density === "clean") {
|
|
769
|
+
return "soft";
|
|
770
|
+
}
|
|
771
|
+
if (moduleConfig.density === "dense") {
|
|
772
|
+
return "detailed";
|
|
773
|
+
}
|
|
774
|
+
return "standard";
|
|
775
|
+
}
|
|
776
|
+
function roadLayers(source, sourceLayer, colors, roadsMode) {
|
|
777
|
+
if (roadsMode === "hidden") {
|
|
778
|
+
return [];
|
|
779
|
+
}
|
|
780
|
+
const opacity = roadsMode === "soft" ? 0.72 : roadsMode === "standard" ? 0.84 : 0.96;
|
|
781
|
+
const casingOpacity = roadsMode === "detailed" ? 0.3 : 0.16;
|
|
782
|
+
const majorRoadFilter = classFilter(["motorway", "trunk", "primary", "secondary"]);
|
|
783
|
+
const ferryFilter = classFilter(["ferry"]);
|
|
784
|
+
const pathFilter = classFilter(["path", "track"]);
|
|
785
|
+
const railFilter = classFilter(["rail", "transit"]);
|
|
786
|
+
const minorRoadFilter = [
|
|
787
|
+
"all",
|
|
788
|
+
["!", majorRoadFilter],
|
|
789
|
+
["!", ferryFilter],
|
|
790
|
+
["!", pathFilter],
|
|
791
|
+
["!", railFilter]
|
|
792
|
+
];
|
|
793
|
+
const nonTunnelRoadFilter = ["!=", ["get", "brunnel"], "tunnel"];
|
|
794
|
+
const roadClassColor = roadClassColorExpression(colors);
|
|
795
|
+
return [
|
|
796
|
+
{
|
|
797
|
+
id: "roads-tunnels-casing",
|
|
798
|
+
type: "line",
|
|
799
|
+
source,
|
|
800
|
+
"source-layer": sourceLayer,
|
|
801
|
+
minzoom: 10,
|
|
802
|
+
filter: ["==", ["get", "brunnel"], "tunnel"],
|
|
803
|
+
paint: {
|
|
804
|
+
"line-color": colors.roads.tunnel,
|
|
805
|
+
"line-dasharray": [0.6, 0.8],
|
|
806
|
+
"line-opacity": 0.28,
|
|
807
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 0.5, 14, 1.7, 16, 3.8]
|
|
808
|
+
}
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
id: "roads-tunnels",
|
|
812
|
+
type: "line",
|
|
813
|
+
source,
|
|
814
|
+
"source-layer": sourceLayer,
|
|
815
|
+
minzoom: 10,
|
|
816
|
+
filter: ["==", ["get", "brunnel"], "tunnel"],
|
|
817
|
+
paint: {
|
|
818
|
+
"line-color": roadClassColor,
|
|
819
|
+
"line-dasharray": [0.6, 0.8],
|
|
820
|
+
"line-opacity": 0.2,
|
|
821
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 0.25, 14, 1, 16, 2.4]
|
|
822
|
+
}
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
id: "roads-casing",
|
|
826
|
+
type: "line",
|
|
827
|
+
source,
|
|
828
|
+
"source-layer": sourceLayer,
|
|
829
|
+
minzoom: 6,
|
|
830
|
+
filter: nonTunnelRoadFilter,
|
|
831
|
+
paint: {
|
|
832
|
+
"line-color": colors.roads.casing,
|
|
833
|
+
"line-opacity": casingOpacity,
|
|
834
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 6, 0.4, 12, 1.2, 16, 4]
|
|
835
|
+
}
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
id: "roads-ferry",
|
|
839
|
+
type: "line",
|
|
840
|
+
source,
|
|
841
|
+
"source-layer": sourceLayer,
|
|
842
|
+
minzoom: 5,
|
|
843
|
+
filter: ["all", nonTunnelRoadFilter, ferryFilter],
|
|
844
|
+
paint: {
|
|
845
|
+
"line-color": colors.roads.ferry,
|
|
846
|
+
"line-dasharray": [1.2, 1.1],
|
|
847
|
+
"line-opacity": opacity * 0.8,
|
|
848
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 5, 0.25, 12, 0.8, 16, 2.6]
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
id: "roads-paths",
|
|
853
|
+
type: "line",
|
|
854
|
+
source,
|
|
855
|
+
"source-layer": sourceLayer,
|
|
856
|
+
minzoom: 10,
|
|
857
|
+
filter: ["all", nonTunnelRoadFilter, pathFilter],
|
|
858
|
+
paint: {
|
|
859
|
+
"line-color": colors.roads.path,
|
|
860
|
+
"line-dasharray": [0.7, 0.7],
|
|
861
|
+
"line-opacity": opacity * 0.68,
|
|
862
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 0.25, 14, 0.8, 16, 2.2]
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
id: "roads-rail",
|
|
867
|
+
type: "line",
|
|
868
|
+
source,
|
|
869
|
+
"source-layer": sourceLayer,
|
|
870
|
+
minzoom: 7,
|
|
871
|
+
filter: ["all", nonTunnelRoadFilter, railFilter],
|
|
872
|
+
paint: {
|
|
873
|
+
"line-color": colors.roads.rail,
|
|
874
|
+
"line-opacity": opacity * 0.58,
|
|
875
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 7, 0.35, 12, 0.9, 16, 2.4]
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
id: "roads-minor",
|
|
880
|
+
type: "line",
|
|
881
|
+
source,
|
|
882
|
+
"source-layer": sourceLayer,
|
|
883
|
+
minzoom: 6,
|
|
884
|
+
filter: ["all", nonTunnelRoadFilter, minorRoadFilter],
|
|
885
|
+
paint: {
|
|
886
|
+
"line-color": colors.roads.minor,
|
|
887
|
+
"line-opacity": opacity * 0.88,
|
|
888
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 6, 0.2, 12, 0.8, 16, 3]
|
|
889
|
+
}
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
id: "roads-major",
|
|
893
|
+
type: "line",
|
|
894
|
+
source,
|
|
895
|
+
"source-layer": sourceLayer,
|
|
896
|
+
minzoom: 5,
|
|
897
|
+
filter: ["all", nonTunnelRoadFilter, majorRoadFilter],
|
|
898
|
+
paint: {
|
|
899
|
+
"line-color": roadClassColor,
|
|
900
|
+
"line-opacity": opacity,
|
|
901
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 5, 0.35, 12, 1.2, 16, 4]
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
id: "roads-bridges",
|
|
906
|
+
type: "line",
|
|
907
|
+
source,
|
|
908
|
+
"source-layer": sourceLayer,
|
|
909
|
+
minzoom: 10,
|
|
910
|
+
filter: ["==", ["get", "brunnel"], "bridge"],
|
|
911
|
+
paint: {
|
|
912
|
+
"line-color": colors.roads.bridge,
|
|
913
|
+
"line-opacity": opacity,
|
|
914
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 0.45, 14, 1.6, 16, 4.4]
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
];
|
|
918
|
+
}
|
|
919
|
+
function classFilter(classes) {
|
|
920
|
+
return ["match", ["get", "class"], classes, true, false];
|
|
921
|
+
}
|
|
922
|
+
function roadClassColorExpression(colors) {
|
|
923
|
+
return [
|
|
924
|
+
"match",
|
|
925
|
+
["get", "class"],
|
|
926
|
+
"motorway",
|
|
927
|
+
colors.roads.motorway,
|
|
928
|
+
"trunk",
|
|
929
|
+
colors.roads.trunk,
|
|
930
|
+
"primary",
|
|
931
|
+
colors.roads.primary,
|
|
932
|
+
"secondary",
|
|
933
|
+
colors.roads.secondary,
|
|
934
|
+
"rail",
|
|
935
|
+
colors.roads.rail,
|
|
936
|
+
"transit",
|
|
937
|
+
colors.roads.rail,
|
|
938
|
+
"ferry",
|
|
939
|
+
colors.roads.ferry,
|
|
940
|
+
"path",
|
|
941
|
+
colors.roads.path,
|
|
942
|
+
"track",
|
|
943
|
+
colors.roads.path,
|
|
944
|
+
colors.roads.minor
|
|
945
|
+
];
|
|
946
|
+
}
|
|
947
|
+
|
|
614
948
|
// src/basemaps/osm/layers.ts
|
|
615
949
|
function openMapTilesLayers(source, sourceLayers, colors, options) {
|
|
616
950
|
return [
|
|
@@ -622,13 +956,27 @@ function openMapTilesLayers(source, sourceLayers, colors, options) {
|
|
|
622
956
|
}
|
|
623
957
|
},
|
|
624
958
|
fillLayer("landuse", source, sourceLayers.landuse, colors.landuse.residential, 0.42),
|
|
625
|
-
fillLayer(
|
|
959
|
+
fillLayer(
|
|
960
|
+
"parks",
|
|
961
|
+
source,
|
|
962
|
+
sourceLayers.park,
|
|
963
|
+
colors.landcover.park,
|
|
964
|
+
parkOpacity(options.density)
|
|
965
|
+
),
|
|
626
966
|
fillLayer("water", source, sourceLayers.water, colors.hydro.water, 1),
|
|
627
967
|
...buildingLayers(source, sourceLayers.building, colors, options.density, options.buildings),
|
|
628
968
|
...roadLayers(source, sourceLayers.road, colors, options.roads),
|
|
629
969
|
...boundaryLayers(source, sourceLayers.boundary, colors),
|
|
630
970
|
...labelLayers(source, sourceLayers.place, colors, options.labels, options.typography),
|
|
631
|
-
...poiLayers(
|
|
971
|
+
...poiLayers(
|
|
972
|
+
source,
|
|
973
|
+
sourceLayers.poi,
|
|
974
|
+
colors,
|
|
975
|
+
options.poi,
|
|
976
|
+
options.typography,
|
|
977
|
+
options.customIconSpriteId,
|
|
978
|
+
options.customIconMapping
|
|
979
|
+
)
|
|
632
980
|
];
|
|
633
981
|
}
|
|
634
982
|
function fillLayer(id, source, sourceLayer, color, opacity) {
|
|
@@ -719,82 +1067,27 @@ function buildingLayers(source, sourceLayer, colors, density, buildings) {
|
|
|
719
1067
|
type: "line",
|
|
720
1068
|
source,
|
|
721
1069
|
"source-layer": sourceLayer,
|
|
722
|
-
minzoom: 15,
|
|
723
|
-
paint: {
|
|
724
|
-
"line-color": colors.buildings.outline,
|
|
725
|
-
"line-opacity": 0.24,
|
|
726
|
-
"line-width": 0.6
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
];
|
|
730
|
-
}
|
|
731
|
-
function boundaryLayers(source, sourceLayer, colors) {
|
|
732
|
-
return [
|
|
733
|
-
{
|
|
734
|
-
id: "boundaries",
|
|
735
|
-
type: "line",
|
|
736
|
-
source,
|
|
737
|
-
"source-layer": sourceLayer,
|
|
738
|
-
minzoom: 2,
|
|
739
|
-
paint: {
|
|
740
|
-
"line-color": colors.boundaries.admin,
|
|
741
|
-
"line-opacity": 0.35,
|
|
742
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 2, 0.35, 8, 0.8]
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
];
|
|
746
|
-
}
|
|
747
|
-
function labelLayers(source, sourceLayer, colors, labels, typography) {
|
|
748
|
-
if (labels === "none") {
|
|
749
|
-
return [];
|
|
750
|
-
}
|
|
751
|
-
const maxRank = labels === "essential" ? 3 : labels === "balanced" ? 7 : 12;
|
|
752
|
-
return [
|
|
753
|
-
{
|
|
754
|
-
id: "place-labels",
|
|
755
|
-
type: "symbol",
|
|
756
|
-
source,
|
|
757
|
-
"source-layer": sourceLayer,
|
|
758
|
-
minzoom: 3,
|
|
759
|
-
filter: ["<=", ["coalesce", ["get", "rank"], 10], maxRank],
|
|
760
|
-
layout: {
|
|
761
|
-
"text-field": ["coalesce", ["get", "name:en"], ["get", "name"]],
|
|
762
|
-
"text-font": textFont(typography),
|
|
763
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 3, 10, 8, 13, 14, 17],
|
|
764
|
-
"text-letter-spacing": 0,
|
|
765
|
-
"text-padding": 4
|
|
766
|
-
},
|
|
1070
|
+
minzoom: 15,
|
|
767
1071
|
paint: {
|
|
768
|
-
"
|
|
769
|
-
"
|
|
770
|
-
"
|
|
1072
|
+
"line-color": colors.buildings.outline,
|
|
1073
|
+
"line-opacity": 0.24,
|
|
1074
|
+
"line-width": 0.6
|
|
771
1075
|
}
|
|
772
1076
|
}
|
|
773
1077
|
];
|
|
774
1078
|
}
|
|
775
|
-
function
|
|
776
|
-
if (poi === "none") {
|
|
777
|
-
return [];
|
|
778
|
-
}
|
|
779
|
-
const minzoom = poi === "minimal" ? 15 : poi === "balanced" ? 13 : 11;
|
|
1079
|
+
function boundaryLayers(source, sourceLayer, colors) {
|
|
780
1080
|
return [
|
|
781
1081
|
{
|
|
782
|
-
id: "
|
|
783
|
-
type: "
|
|
1082
|
+
id: "boundaries",
|
|
1083
|
+
type: "line",
|
|
784
1084
|
source,
|
|
785
1085
|
"source-layer": sourceLayer,
|
|
786
|
-
minzoom,
|
|
787
|
-
layout: {
|
|
788
|
-
"text-field": ["coalesce", ["get", "name:en"], ["get", "name"]],
|
|
789
|
-
"text-font": textFont(typography),
|
|
790
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], minzoom, 10, 17, 12],
|
|
791
|
-
"text-letter-spacing": 0,
|
|
792
|
-
"text-padding": 2
|
|
793
|
-
},
|
|
1086
|
+
minzoom: 2,
|
|
794
1087
|
paint: {
|
|
795
|
-
"
|
|
796
|
-
"
|
|
797
|
-
"
|
|
1088
|
+
"line-color": colors.boundaries.admin,
|
|
1089
|
+
"line-opacity": 0.35,
|
|
1090
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 2, 0.35, 8, 0.8]
|
|
798
1091
|
}
|
|
799
1092
|
}
|
|
800
1093
|
];
|
|
@@ -880,7 +1173,10 @@ var hexColorSchema = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-
|
|
|
880
1173
|
message: "Expected a hex color like #F6F7F3 or #F6F7F3FF"
|
|
881
1174
|
});
|
|
882
1175
|
function colorGroupSchema(keys) {
|
|
883
|
-
|
|
1176
|
+
const shape = Object.fromEntries(
|
|
1177
|
+
keys.map((key) => [key, hexColorSchema.optional()])
|
|
1178
|
+
);
|
|
1179
|
+
return z.object(shape).strict();
|
|
884
1180
|
}
|
|
885
1181
|
var colorConfigSchema = z.object({
|
|
886
1182
|
accent: hexColorSchema.optional(),
|
|
@@ -906,6 +1202,7 @@ var colorConfigSchema = z.object({
|
|
|
906
1202
|
"country",
|
|
907
1203
|
"halo",
|
|
908
1204
|
"muted",
|
|
1205
|
+
"neighborhood",
|
|
909
1206
|
"poi",
|
|
910
1207
|
"primary",
|
|
911
1208
|
"road",
|
|
@@ -920,6 +1217,20 @@ var colorConfigSchema = z.object({
|
|
|
920
1217
|
"industrial",
|
|
921
1218
|
"residential"
|
|
922
1219
|
]).optional(),
|
|
1220
|
+
poi: colorGroupSchema([
|
|
1221
|
+
"coffee",
|
|
1222
|
+
"culture",
|
|
1223
|
+
"education",
|
|
1224
|
+
"food",
|
|
1225
|
+
"halo",
|
|
1226
|
+
"health",
|
|
1227
|
+
"icon",
|
|
1228
|
+
"label",
|
|
1229
|
+
"lodging",
|
|
1230
|
+
"services",
|
|
1231
|
+
"shopping",
|
|
1232
|
+
"transit"
|
|
1233
|
+
]).optional(),
|
|
923
1234
|
roads: colorGroupSchema([
|
|
924
1235
|
"bridge",
|
|
925
1236
|
"casing",
|
|
@@ -942,6 +1253,7 @@ var themeModulesSchema = z.object({
|
|
|
942
1253
|
"country",
|
|
943
1254
|
"halo",
|
|
944
1255
|
"muted",
|
|
1256
|
+
"neighborhood",
|
|
945
1257
|
"poi",
|
|
946
1258
|
"primary",
|
|
947
1259
|
"road",
|
|
@@ -956,6 +1268,20 @@ var themeModulesSchema = z.object({
|
|
|
956
1268
|
"industrial",
|
|
957
1269
|
"residential"
|
|
958
1270
|
]).optional(),
|
|
1271
|
+
poi: colorGroupSchema([
|
|
1272
|
+
"coffee",
|
|
1273
|
+
"culture",
|
|
1274
|
+
"education",
|
|
1275
|
+
"food",
|
|
1276
|
+
"halo",
|
|
1277
|
+
"health",
|
|
1278
|
+
"icon",
|
|
1279
|
+
"label",
|
|
1280
|
+
"lodging",
|
|
1281
|
+
"services",
|
|
1282
|
+
"shopping",
|
|
1283
|
+
"transit"
|
|
1284
|
+
]).optional(),
|
|
959
1285
|
roads: colorGroupSchema([
|
|
960
1286
|
"bridge",
|
|
961
1287
|
"casing",
|
|
@@ -1026,12 +1352,43 @@ var roadsModuleSchema = z.object({
|
|
|
1026
1352
|
density: z.enum(["clean", "balanced", "dense"]).optional(),
|
|
1027
1353
|
preset: z.enum(["modern", "minimal"]).optional()
|
|
1028
1354
|
}).strict();
|
|
1355
|
+
var labelDensitySchema = z.enum(["none", "minimal", "balanced", "detailed"]);
|
|
1356
|
+
var labelsModuleSchema = z.object({
|
|
1357
|
+
type: z.literal("labels"),
|
|
1358
|
+
language: z.string().trim().min(1).optional(),
|
|
1359
|
+
places: labelDensitySchema.optional(),
|
|
1360
|
+
preset: z.enum(["none", "essential", "balanced", "full"]).optional(),
|
|
1361
|
+
roads: labelDensitySchema.optional(),
|
|
1362
|
+
water: labelDensitySchema.optional()
|
|
1363
|
+
}).strict();
|
|
1364
|
+
var poiModuleSchema = z.object({
|
|
1365
|
+
type: z.literal("poi"),
|
|
1366
|
+
categories: z.array(identifierSchema).optional(),
|
|
1367
|
+
icons: z.union([z.boolean(), z.enum(["essential", "full"])]).optional(),
|
|
1368
|
+
labels: z.enum(["none", "minimal", "balanced", "full"]).optional(),
|
|
1369
|
+
minZoom: z.number().finite().min(0).max(24).optional(),
|
|
1370
|
+
preset: z.enum(["none", "minimal", "balanced", "full"]).optional()
|
|
1371
|
+
}).strict();
|
|
1029
1372
|
var styleOverrideModuleSchema = z.object({
|
|
1030
1373
|
type: z.literal("styleOverride"),
|
|
1031
1374
|
layers: z.record(z.string(), styleLayerOverrideSchema).optional(),
|
|
1032
1375
|
removeLayers: z.array(z.string().min(1)).optional()
|
|
1033
1376
|
}).strict();
|
|
1034
|
-
var moduleSchema = z.discriminatedUnion("type", [
|
|
1377
|
+
var moduleSchema = z.discriminatedUnion("type", [
|
|
1378
|
+
labelsModuleSchema,
|
|
1379
|
+
poiModuleSchema,
|
|
1380
|
+
roadsModuleSchema,
|
|
1381
|
+
styleOverrideModuleSchema
|
|
1382
|
+
]);
|
|
1383
|
+
var iconSetSchema = z.union([
|
|
1384
|
+
z.string().trim().min(1),
|
|
1385
|
+
z.object({
|
|
1386
|
+
extends: z.string().trim().min(1).optional(),
|
|
1387
|
+
mapping: z.record(identifierSchema, z.string().trim().min(1)).optional(),
|
|
1388
|
+
source: z.string().trim().min(1).optional(),
|
|
1389
|
+
sprite: z.string().trim().min(1).optional()
|
|
1390
|
+
}).strict()
|
|
1391
|
+
]);
|
|
1035
1392
|
var viewSchema = z.object({
|
|
1036
1393
|
bearing: z.number().finite().min(-180).max(180).optional(),
|
|
1037
1394
|
center: z.tuple([z.number().finite(), z.number().finite()]).refine(([lng, lat]) => lng >= -180 && lng <= 180 && lat >= -90 && lat <= 90, {
|
|
@@ -1071,6 +1428,7 @@ var tileflowMapSchema = z.object({
|
|
|
1071
1428
|
buildings: z.enum(["hidden", "flat", "3d"]).optional(),
|
|
1072
1429
|
terrain: z.union([z.enum(["none", "hillshade", "3d"]), terrainConfigSchema]).optional(),
|
|
1073
1430
|
glyphs: z.string().min(1).optional(),
|
|
1431
|
+
icons: iconSetSchema.optional(),
|
|
1074
1432
|
sprite: z.string().min(1).optional(),
|
|
1075
1433
|
tiles: tilesSchema.optional(),
|
|
1076
1434
|
view: viewSchema.optional(),
|
|
@@ -1084,6 +1442,7 @@ var tilesetConfigSchema = z.object({
|
|
|
1084
1442
|
sourceLayers: sourceLayersSchema.optional()
|
|
1085
1443
|
}).strict();
|
|
1086
1444
|
var tileflowProjectSchema = z.object({
|
|
1445
|
+
icons: z.record(identifierSchema, iconSetSchema).optional(),
|
|
1087
1446
|
themes: z.record(identifierSchema, themeConfigSchema).optional(),
|
|
1088
1447
|
tilesets: z.record(identifierSchema, tilesetConfigSchema).optional(),
|
|
1089
1448
|
maps: z.record(identifierSchema, configSchema).refine((maps) => {
|
|
@@ -1152,10 +1511,11 @@ function isProjectConfigLike(input) {
|
|
|
1152
1511
|
function validateProjectThemeReferences(project) {
|
|
1153
1512
|
const themeNames = new Set(Object.keys(project.themes ?? {}));
|
|
1154
1513
|
const themeMessages = validateThemeExtends(project.themes, themeNames);
|
|
1514
|
+
const iconMessages = validateProjectIconReferences(project);
|
|
1155
1515
|
const mapMessages = Object.entries(project.maps).flatMap(
|
|
1156
1516
|
([mapName, mapConfig]) => validateMapThemeReference(mapConfig, themeNames, `maps.${mapName}.theme`)
|
|
1157
1517
|
);
|
|
1158
|
-
return [...themeMessages, ...mapMessages];
|
|
1518
|
+
return [...themeMessages, ...iconMessages, ...mapMessages];
|
|
1159
1519
|
}
|
|
1160
1520
|
function validateMapThemeReference(config, themeNames, path) {
|
|
1161
1521
|
if (!config.theme) {
|
|
@@ -1220,6 +1580,242 @@ function findThemeCycle(themeName, themes, path) {
|
|
|
1220
1580
|
}
|
|
1221
1581
|
return findThemeCycle(nextThemeName, themes, [...path, themeName]);
|
|
1222
1582
|
}
|
|
1583
|
+
function validateProjectIconReferences(project) {
|
|
1584
|
+
const messages = [];
|
|
1585
|
+
const iconSets = project.icons ?? {};
|
|
1586
|
+
for (const [iconSetName, iconSet] of Object.entries(iconSets)) {
|
|
1587
|
+
const extendedName = iconSetReference(iconSet);
|
|
1588
|
+
if (extendedName && !iconSets[extendedName]) {
|
|
1589
|
+
messages.push({
|
|
1590
|
+
level: "error",
|
|
1591
|
+
path: iconSetExtendsPath(`icons.${iconSetName}`, iconSet),
|
|
1592
|
+
message: `Unknown Tileflow icon set "${extendedName}"`
|
|
1593
|
+
});
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
for (const iconSetName of Object.keys(iconSets)) {
|
|
1597
|
+
const cycle = findIconSetCycle(iconSetName, iconSets, []);
|
|
1598
|
+
if (cycle) {
|
|
1599
|
+
messages.push({
|
|
1600
|
+
level: "error",
|
|
1601
|
+
path: iconSetExtendsPath(`icons.${iconSetName}`, iconSets[iconSetName]),
|
|
1602
|
+
message: `Circular Tileflow icon set extends: ${cycle.join(" -> ")}`
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
for (const [mapName, mapConfig] of Object.entries(project.maps)) {
|
|
1607
|
+
if (!isIconSetObject(mapConfig.icons) || !mapConfig.icons.extends) {
|
|
1608
|
+
continue;
|
|
1609
|
+
}
|
|
1610
|
+
if (!iconSets[mapConfig.icons.extends]) {
|
|
1611
|
+
messages.push({
|
|
1612
|
+
level: "error",
|
|
1613
|
+
path: `maps.${mapName}.icons.extends`,
|
|
1614
|
+
message: `Unknown Tileflow icon set "${mapConfig.icons.extends}"`
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
return messages;
|
|
1619
|
+
}
|
|
1620
|
+
function findIconSetCycle(iconSetName, iconSets, path) {
|
|
1621
|
+
if (path.includes(iconSetName)) {
|
|
1622
|
+
return [...path, iconSetName];
|
|
1623
|
+
}
|
|
1624
|
+
const nextIconSetName = iconSetReference(iconSets?.[iconSetName]);
|
|
1625
|
+
if (!nextIconSetName || !iconSets?.[nextIconSetName]) {
|
|
1626
|
+
return void 0;
|
|
1627
|
+
}
|
|
1628
|
+
return findIconSetCycle(nextIconSetName, iconSets, [...path, iconSetName]);
|
|
1629
|
+
}
|
|
1630
|
+
function iconSetReference(iconSet) {
|
|
1631
|
+
if (typeof iconSet === "string") {
|
|
1632
|
+
return iconSet;
|
|
1633
|
+
}
|
|
1634
|
+
return isIconSetObject(iconSet) ? iconSet.extends : void 0;
|
|
1635
|
+
}
|
|
1636
|
+
function iconSetExtendsPath(basePath, iconSet) {
|
|
1637
|
+
return isIconSetObject(iconSet) ? `${basePath}.extends` : basePath;
|
|
1638
|
+
}
|
|
1639
|
+
function isIconSetObject(value) {
|
|
1640
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
// src/terrain/index.ts
|
|
1644
|
+
function resolveTerrain(terrain, tileBaseUrl) {
|
|
1645
|
+
if (!terrain || terrain === "none") {
|
|
1646
|
+
return void 0;
|
|
1647
|
+
}
|
|
1648
|
+
const terrainConfig = typeof terrain === "string" ? { mode: terrain } : terrain;
|
|
1649
|
+
const mode = terrainConfig.mode ?? "hillshade";
|
|
1650
|
+
if (mode === "none") {
|
|
1651
|
+
return void 0;
|
|
1652
|
+
}
|
|
1653
|
+
const sourceId = terrainConfig.sourceId ?? "tileflow-terrain";
|
|
1654
|
+
const tileset = terrainConfig.tileset ?? "terrain";
|
|
1655
|
+
const url = terrainConfig.url ?? `${tileBaseUrl}/tiles/${tileset}/tiles.json`;
|
|
1656
|
+
const encoding = terrainConfig.encoding ?? "terrarium";
|
|
1657
|
+
return {
|
|
1658
|
+
exaggeration: terrainConfig.exaggeration ?? 1.2,
|
|
1659
|
+
mode,
|
|
1660
|
+
sourceId,
|
|
1661
|
+
source: {
|
|
1662
|
+
...terrainConfig.attribution ? { attribution: terrainConfig.attribution } : {},
|
|
1663
|
+
encoding,
|
|
1664
|
+
type: "raster-dem",
|
|
1665
|
+
url
|
|
1666
|
+
}
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1669
|
+
function withTerrainLayers(layers, terrain) {
|
|
1670
|
+
const hillshadeLayer = {
|
|
1671
|
+
id: "terrain-hillshade",
|
|
1672
|
+
type: "hillshade",
|
|
1673
|
+
source: terrain.sourceId,
|
|
1674
|
+
maxzoom: 15,
|
|
1675
|
+
paint: {
|
|
1676
|
+
"hillshade-accent-color": "rgba(255, 255, 255, 0.18)",
|
|
1677
|
+
"hillshade-exaggeration": terrain.mode === "3d" ? 0.24 : 0.42,
|
|
1678
|
+
"hillshade-highlight-color": "rgba(255, 255, 255, 0.28)",
|
|
1679
|
+
"hillshade-shadow-color": "rgba(38, 44, 50, 0.34)"
|
|
1680
|
+
}
|
|
1681
|
+
};
|
|
1682
|
+
const insertionIndex = layers.findIndex((layer) => layer.id === "water");
|
|
1683
|
+
if (insertionIndex === -1) {
|
|
1684
|
+
return [hillshadeLayer, ...layers];
|
|
1685
|
+
}
|
|
1686
|
+
return [
|
|
1687
|
+
...layers.slice(0, insertionIndex + 1),
|
|
1688
|
+
hillshadeLayer,
|
|
1689
|
+
...layers.slice(insertionIndex + 1)
|
|
1690
|
+
];
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
// src/templates/osm-bright/controls.ts
|
|
1694
|
+
function applyOsmBrightControls(layers, options) {
|
|
1695
|
+
return layers.map((layer) => {
|
|
1696
|
+
const id = stringValue(layer.id);
|
|
1697
|
+
const sourceLayer = stringValue(layer["source-layer"]);
|
|
1698
|
+
const type = stringValue(layer.type);
|
|
1699
|
+
if (type !== "symbol") {
|
|
1700
|
+
return layer;
|
|
1701
|
+
}
|
|
1702
|
+
if (isPoiLayer(id, sourceLayer)) {
|
|
1703
|
+
return applyPoiLayerControls(
|
|
1704
|
+
layer,
|
|
1705
|
+
options.poi,
|
|
1706
|
+
options.customIconSpriteId,
|
|
1707
|
+
options.customIconMapping
|
|
1708
|
+
);
|
|
1709
|
+
}
|
|
1710
|
+
if (isLabelLayer(id, sourceLayer)) {
|
|
1711
|
+
return applyLabelLayerControls(layer, options.labels);
|
|
1712
|
+
}
|
|
1713
|
+
return layer;
|
|
1714
|
+
});
|
|
1715
|
+
}
|
|
1716
|
+
function applyLabelLayerControls(layer, labels2) {
|
|
1717
|
+
const id = stringValue(layer.id);
|
|
1718
|
+
const sourceLayer = stringValue(layer["source-layer"]);
|
|
1719
|
+
const group = labelGroup(id, sourceLayer);
|
|
1720
|
+
const density = labelGroupDensity(labels2, group);
|
|
1721
|
+
if (labels2.mode === "none" || density === "none") {
|
|
1722
|
+
return setLayerVisibility(layer, "none");
|
|
1723
|
+
}
|
|
1724
|
+
const nextLayer = setLayerVisibility(layer, "visible");
|
|
1725
|
+
const layout = isRecord3(nextLayer.layout) ? { ...nextLayer.layout } : {};
|
|
1726
|
+
if ("text-field" in layout && !isHighwayShieldLayer(id)) {
|
|
1727
|
+
layout["text-field"] = labelTextField(labels2.language);
|
|
1728
|
+
}
|
|
1729
|
+
if (density === "minimal") {
|
|
1730
|
+
nextLayer.minzoom = Math.max(numberValue(nextLayer.minzoom) ?? 0, minimalMinZoom(group));
|
|
1731
|
+
}
|
|
1732
|
+
if (density === "detailed") {
|
|
1733
|
+
const currentMinZoom = numberValue(nextLayer.minzoom);
|
|
1734
|
+
if (currentMinZoom !== void 0) {
|
|
1735
|
+
nextLayer.minzoom = Math.max(0, currentMinZoom - 1);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
nextLayer.layout = layout;
|
|
1739
|
+
return nextLayer;
|
|
1740
|
+
}
|
|
1741
|
+
function applyPoiLayerControls(layer, poi2, customIconSpriteId2, customIconMapping) {
|
|
1742
|
+
if (poi2.mode === "none") {
|
|
1743
|
+
return setLayerVisibility(layer, "none");
|
|
1744
|
+
}
|
|
1745
|
+
const nextLayer = setLayerVisibility(layer, "visible");
|
|
1746
|
+
const layout = isRecord3(nextLayer.layout) ? { ...nextLayer.layout } : {};
|
|
1747
|
+
nextLayer.minzoom = Math.max(numberValue(nextLayer.minzoom) ?? 0, poi2.minZoom);
|
|
1748
|
+
if (poi2.categories && sourceLayerValue(nextLayer) === "poi") {
|
|
1749
|
+
nextLayer.filter = combineFilters(nextLayer.filter, poiCategoryFilter(poi2.categories));
|
|
1750
|
+
}
|
|
1751
|
+
if (poi2.labels === "none") {
|
|
1752
|
+
delete layout["text-field"];
|
|
1753
|
+
} else if ("text-field" in layout) {
|
|
1754
|
+
layout["text-field"] = labelTextField("auto");
|
|
1755
|
+
}
|
|
1756
|
+
if (poi2.icons === false) {
|
|
1757
|
+
delete layout["icon-image"];
|
|
1758
|
+
} else if ("icon-image" in layout || customIconSpriteId2) {
|
|
1759
|
+
layout["icon-image"] = poiIconImageExpression(customIconSpriteId2, customIconMapping);
|
|
1760
|
+
layout["icon-optional"] = true;
|
|
1761
|
+
}
|
|
1762
|
+
nextLayer.layout = layout;
|
|
1763
|
+
return nextLayer;
|
|
1764
|
+
}
|
|
1765
|
+
function labelGroupDensity(labels2, group) {
|
|
1766
|
+
if (group === "roads") return labels2.roads;
|
|
1767
|
+
if (group === "water") return labels2.water;
|
|
1768
|
+
return labels2.places;
|
|
1769
|
+
}
|
|
1770
|
+
function labelGroup(id, sourceLayer) {
|
|
1771
|
+
if (sourceLayer === "transportation_name" || id.includes("highway-name") || id.includes("highway-shield")) {
|
|
1772
|
+
return "roads";
|
|
1773
|
+
}
|
|
1774
|
+
if (sourceLayer === "water_name" || sourceLayer === "waterway" || id.includes("water-name")) {
|
|
1775
|
+
return "water";
|
|
1776
|
+
}
|
|
1777
|
+
return "places";
|
|
1778
|
+
}
|
|
1779
|
+
function minimalMinZoom(group) {
|
|
1780
|
+
if (group === "roads") return 13;
|
|
1781
|
+
if (group === "water") return 5;
|
|
1782
|
+
return 4;
|
|
1783
|
+
}
|
|
1784
|
+
function isLabelLayer(id, sourceLayer) {
|
|
1785
|
+
return sourceLayer === "place" || sourceLayer === "transportation_name" || sourceLayer === "water_name" || sourceLayer === "waterway" || id.includes("highway-name") || id.includes("highway-shield") || id.includes("water-name");
|
|
1786
|
+
}
|
|
1787
|
+
function isPoiLayer(id, sourceLayer) {
|
|
1788
|
+
return sourceLayer === "poi" || id.startsWith("poi-");
|
|
1789
|
+
}
|
|
1790
|
+
function isHighwayShieldLayer(id) {
|
|
1791
|
+
return id.includes("highway-shield");
|
|
1792
|
+
}
|
|
1793
|
+
function setLayerVisibility(layer, visibility) {
|
|
1794
|
+
const layout = isRecord3(layer.layout) ? { ...layer.layout } : {};
|
|
1795
|
+
layout.visibility = visibility;
|
|
1796
|
+
return {
|
|
1797
|
+
...layer,
|
|
1798
|
+
layout
|
|
1799
|
+
};
|
|
1800
|
+
}
|
|
1801
|
+
function combineFilters(first, second) {
|
|
1802
|
+
if (!first) {
|
|
1803
|
+
return second;
|
|
1804
|
+
}
|
|
1805
|
+
return ["all", first, second];
|
|
1806
|
+
}
|
|
1807
|
+
function sourceLayerValue(layer) {
|
|
1808
|
+
return stringValue(layer["source-layer"]);
|
|
1809
|
+
}
|
|
1810
|
+
function stringValue(value) {
|
|
1811
|
+
return typeof value === "string" ? value : "";
|
|
1812
|
+
}
|
|
1813
|
+
function numberValue(value) {
|
|
1814
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1815
|
+
}
|
|
1816
|
+
function isRecord3(value) {
|
|
1817
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1818
|
+
}
|
|
1223
1819
|
|
|
1224
1820
|
// src/templates/osm-bright/style.json
|
|
1225
1821
|
var style_default = {
|
|
@@ -3783,68 +4379,18 @@ var style_default = {
|
|
|
3783
4379
|
id: "bright"
|
|
3784
4380
|
};
|
|
3785
4381
|
|
|
3786
|
-
// src/terrain/index.ts
|
|
3787
|
-
function resolveTerrain(terrain, tileBaseUrl) {
|
|
3788
|
-
if (!terrain || terrain === "none") {
|
|
3789
|
-
return void 0;
|
|
3790
|
-
}
|
|
3791
|
-
const terrainConfig = typeof terrain === "string" ? { mode: terrain } : terrain;
|
|
3792
|
-
const mode = terrainConfig.mode ?? "hillshade";
|
|
3793
|
-
if (mode === "none") {
|
|
3794
|
-
return void 0;
|
|
3795
|
-
}
|
|
3796
|
-
const sourceId = terrainConfig.sourceId ?? "tileflow-terrain";
|
|
3797
|
-
const tileset = terrainConfig.tileset ?? "terrain";
|
|
3798
|
-
const url = terrainConfig.url ?? `${tileBaseUrl}/tiles/${tileset}/tiles.json`;
|
|
3799
|
-
const encoding = terrainConfig.encoding ?? "terrarium";
|
|
3800
|
-
return {
|
|
3801
|
-
exaggeration: terrainConfig.exaggeration ?? 1.2,
|
|
3802
|
-
mode,
|
|
3803
|
-
sourceId,
|
|
3804
|
-
source: {
|
|
3805
|
-
...terrainConfig.attribution ? { attribution: terrainConfig.attribution } : {},
|
|
3806
|
-
encoding,
|
|
3807
|
-
type: "raster-dem",
|
|
3808
|
-
url
|
|
3809
|
-
}
|
|
3810
|
-
};
|
|
3811
|
-
}
|
|
3812
|
-
function withTerrainLayers(layers, terrain) {
|
|
3813
|
-
const hillshadeLayer = {
|
|
3814
|
-
id: "terrain-hillshade",
|
|
3815
|
-
type: "hillshade",
|
|
3816
|
-
source: terrain.sourceId,
|
|
3817
|
-
maxzoom: 15,
|
|
3818
|
-
paint: {
|
|
3819
|
-
"hillshade-accent-color": "rgba(255, 255, 255, 0.18)",
|
|
3820
|
-
"hillshade-exaggeration": terrain.mode === "3d" ? 0.24 : 0.42,
|
|
3821
|
-
"hillshade-highlight-color": "rgba(255, 255, 255, 0.28)",
|
|
3822
|
-
"hillshade-shadow-color": "rgba(38, 44, 50, 0.34)"
|
|
3823
|
-
}
|
|
3824
|
-
};
|
|
3825
|
-
const insertionIndex = layers.findIndex((layer) => layer.id === "water");
|
|
3826
|
-
if (insertionIndex === -1) {
|
|
3827
|
-
return [hillshadeLayer, ...layers];
|
|
3828
|
-
}
|
|
3829
|
-
return [
|
|
3830
|
-
...layers.slice(0, insertionIndex + 1),
|
|
3831
|
-
hillshadeLayer,
|
|
3832
|
-
...layers.slice(insertionIndex + 1)
|
|
3833
|
-
];
|
|
3834
|
-
}
|
|
3835
|
-
|
|
3836
4382
|
// src/templates/osm-bright/theme.ts
|
|
3837
4383
|
function applyOsmBrightTheme(layers, colors, theme, typography) {
|
|
3838
4384
|
if (!theme.custom && theme.name === "light") {
|
|
3839
4385
|
return layers;
|
|
3840
4386
|
}
|
|
3841
4387
|
return layers.map((layer) => {
|
|
3842
|
-
const type =
|
|
3843
|
-
const sourceLayer =
|
|
3844
|
-
const id =
|
|
4388
|
+
const type = stringValue2(layer.type);
|
|
4389
|
+
const sourceLayer = stringValue2(layer["source-layer"]);
|
|
4390
|
+
const id = stringValue2(layer.id);
|
|
3845
4391
|
const nextLayer = { ...layer };
|
|
3846
|
-
const paint =
|
|
3847
|
-
const layout =
|
|
4392
|
+
const paint = isRecord4(layer.paint) ? { ...layer.paint } : {};
|
|
4393
|
+
const layout = isRecord4(layer.layout) ? { ...layer.layout } : {};
|
|
3848
4394
|
let paintChanged = false;
|
|
3849
4395
|
let layoutChanged = false;
|
|
3850
4396
|
if (type === "background" && hasBaseColor(theme, ["background", "canvas"])) {
|
|
@@ -3891,43 +4437,40 @@ function applyOsmBrightTheme(layers, colors, theme, typography) {
|
|
|
3891
4437
|
}
|
|
3892
4438
|
function osmBrightFillColor(id, sourceLayer, colors, theme) {
|
|
3893
4439
|
if (sourceLayer === "water" || id.includes("water")) {
|
|
3894
|
-
return
|
|
4440
|
+
return hasBaseColor(theme, ["water"]) || hasNestedModuleColor(theme, "hydro", "water") ? colors.hydro.water : void 0;
|
|
3895
4441
|
}
|
|
3896
4442
|
if (sourceLayer === "building") {
|
|
3897
|
-
return
|
|
4443
|
+
return hasBaseColor(theme, ["building"]) || hasNestedModuleColor(theme, "buildings", "fill") ? colors.buildings.fill : void 0;
|
|
3898
4444
|
}
|
|
3899
4445
|
if (sourceLayer === "landcover" || id.includes("park") || id.includes("wood")) {
|
|
3900
|
-
if (!shouldThemeLandcover(theme)) {
|
|
3901
|
-
return void 0;
|
|
3902
|
-
}
|
|
3903
4446
|
if (id.includes("wood") || id.includes("forest")) {
|
|
3904
|
-
return colors.landcover.wood;
|
|
4447
|
+
return shouldThemeLandcoverColor(theme, "wood") ? colors.landcover.wood : void 0;
|
|
3905
4448
|
}
|
|
3906
4449
|
if (id.includes("grass")) {
|
|
3907
|
-
return colors.landcover.grass;
|
|
4450
|
+
return shouldThemeLandcoverColor(theme, "grass") ? colors.landcover.grass : void 0;
|
|
3908
4451
|
}
|
|
3909
4452
|
if (id.includes("sand") || id.includes("beach")) {
|
|
3910
|
-
return colors.landcover.sand;
|
|
4453
|
+
return shouldThemeLandcoverColor(theme, "sand") ? colors.landcover.sand : void 0;
|
|
3911
4454
|
}
|
|
3912
4455
|
if (id.includes("ice") || id.includes("glacier")) {
|
|
3913
|
-
return colors.landcover.ice;
|
|
4456
|
+
return shouldThemeLandcoverColor(theme, "ice") ? colors.landcover.ice : void 0;
|
|
3914
4457
|
}
|
|
3915
|
-
return colors.landcover.park;
|
|
4458
|
+
return shouldThemeLandcoverColor(theme, "park") ? colors.landcover.park : void 0;
|
|
3916
4459
|
}
|
|
3917
4460
|
if (sourceLayer === "landuse" || id.includes("landuse")) {
|
|
3918
|
-
if (!shouldThemeLanduse(theme)) {
|
|
3919
|
-
return void 0;
|
|
3920
|
-
}
|
|
3921
4461
|
if (id.includes("commercial") || id.includes("retail")) {
|
|
3922
|
-
return colors.landuse.commercial;
|
|
4462
|
+
return shouldThemeLanduseColor(theme, "commercial") ? colors.landuse.commercial : void 0;
|
|
3923
4463
|
}
|
|
3924
4464
|
if (id.includes("industrial")) {
|
|
3925
|
-
return colors.landuse.industrial;
|
|
4465
|
+
return shouldThemeLanduseColor(theme, "industrial") ? colors.landuse.industrial : void 0;
|
|
3926
4466
|
}
|
|
3927
4467
|
if (id.includes("cemetery")) {
|
|
3928
|
-
return colors.landuse.cemetery;
|
|
4468
|
+
return shouldThemeLanduseColor(theme, "cemetery") ? colors.landuse.cemetery : void 0;
|
|
3929
4469
|
}
|
|
3930
|
-
|
|
4470
|
+
if (id.includes("hospital") || id.includes("school") || id.includes("civic")) {
|
|
4471
|
+
return shouldThemeLanduseColor(theme, "civic") ? colors.landuse.civic : void 0;
|
|
4472
|
+
}
|
|
4473
|
+
return shouldThemeLanduseColor(theme, "residential") ? colors.landuse.residential : void 0;
|
|
3931
4474
|
}
|
|
3932
4475
|
return void 0;
|
|
3933
4476
|
}
|
|
@@ -3936,43 +4479,45 @@ function osmBrightLineColor(id, sourceLayer, colors, theme) {
|
|
|
3936
4479
|
return osmBrightRoadLineColor(id, colors, theme);
|
|
3937
4480
|
}
|
|
3938
4481
|
if (sourceLayer === "waterway") {
|
|
3939
|
-
return
|
|
4482
|
+
return hasBaseColor(theme, ["water"]) || hasNestedModuleColor(theme, "hydro", "waterway") ? colors.hydro.waterway : void 0;
|
|
3940
4483
|
}
|
|
3941
4484
|
if (sourceLayer === "boundary") {
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
}
|
|
3945
|
-
return id.includes("country") || id.includes("admin") ? colors.boundaries.major : colors.boundaries.admin;
|
|
4485
|
+
const boundaryKey = boundaryColorKey(id);
|
|
4486
|
+
return hasBaseColor(theme, ["boundary"]) || hasNestedModuleColor(theme, "boundaries", boundaryKey) ? colors.boundaries[boundaryKey] : void 0;
|
|
3946
4487
|
}
|
|
3947
4488
|
return void 0;
|
|
3948
4489
|
}
|
|
3949
4490
|
function osmBrightTextColor(id, sourceLayer, colors, theme) {
|
|
3950
4491
|
if (sourceLayer === "water_name" || id.includes("water")) {
|
|
3951
|
-
|
|
4492
|
+
if (hasNestedModuleColor(theme, "labels", "water")) {
|
|
4493
|
+
return colors.labels.water;
|
|
4494
|
+
}
|
|
4495
|
+
if (hasNestedModuleColor(theme, "hydro", "label")) {
|
|
4496
|
+
return colors.hydro.label;
|
|
4497
|
+
}
|
|
4498
|
+
return hasBaseColor(theme, ["water"]) || shouldThemeLabels(theme) ? colors.labels.water : void 0;
|
|
3952
4499
|
}
|
|
3953
4500
|
if (sourceLayer === "transportation_name") {
|
|
3954
|
-
return
|
|
4501
|
+
return shouldThemeLabelColor(theme, "road") ? colors.labels.road : void 0;
|
|
3955
4502
|
}
|
|
3956
4503
|
if (sourceLayer === "poi" || id.includes("poi")) {
|
|
3957
|
-
|
|
4504
|
+
if (hasNestedModuleColor(theme, "poi", "label")) {
|
|
4505
|
+
return colors.poi.label;
|
|
4506
|
+
}
|
|
4507
|
+
return shouldThemeLabelColor(theme, "poi") ? colors.labels.poi : void 0;
|
|
3958
4508
|
}
|
|
3959
4509
|
if (id.includes("country")) {
|
|
3960
|
-
return
|
|
4510
|
+
return shouldThemeLabelColor(theme, "country") ? colors.labels.country : void 0;
|
|
3961
4511
|
}
|
|
3962
4512
|
if (sourceLayer === "place" || id.includes("place")) {
|
|
3963
|
-
return
|
|
4513
|
+
return shouldThemeLabelColor(theme, "settlement") ? colors.labels.settlement : void 0;
|
|
3964
4514
|
}
|
|
3965
|
-
return
|
|
3966
|
-
}
|
|
3967
|
-
function shouldThemeHydro(theme) {
|
|
3968
|
-
return hasBaseColor(theme, ["water"]) || hasModuleColorGroup(theme, "hydro");
|
|
3969
|
-
}
|
|
3970
|
-
function shouldThemeWaterLabels(theme) {
|
|
3971
|
-
return shouldThemeHydro(theme) || shouldThemeLabels(theme) || hasNestedModuleColor(theme, "labels", "water");
|
|
4515
|
+
return shouldThemeLabelColor(theme, "primary") ? colors.labels.primary : void 0;
|
|
3972
4516
|
}
|
|
3973
4517
|
function osmBrightRoadLineColor(id, colors, theme) {
|
|
3974
|
-
|
|
3975
|
-
|
|
4518
|
+
const moduleColor = osmBrightModuleRoadLineColor(id, colors, theme);
|
|
4519
|
+
if (moduleColor) {
|
|
4520
|
+
return moduleColor;
|
|
3976
4521
|
}
|
|
3977
4522
|
if (isNonRoadThemeTarget(id)) {
|
|
3978
4523
|
return void 0;
|
|
@@ -3991,16 +4536,25 @@ function osmBrightRoadLineColor(id, colors, theme) {
|
|
|
3991
4536
|
function osmBrightModuleRoadLineColor(id, colors, theme) {
|
|
3992
4537
|
const roadColor = (key) => hasNestedModuleColor(theme, "roads", key) ? colors.roads[key] : void 0;
|
|
3993
4538
|
if (isRoadCasing(id)) {
|
|
3994
|
-
|
|
4539
|
+
const casing = roadColor("casing");
|
|
4540
|
+
if (casing) {
|
|
4541
|
+
return casing;
|
|
4542
|
+
}
|
|
3995
4543
|
}
|
|
3996
4544
|
if (id.includes("ferry")) {
|
|
3997
4545
|
return roadColor("ferry");
|
|
3998
4546
|
}
|
|
3999
4547
|
if (id.includes("rail")) {
|
|
4000
|
-
|
|
4548
|
+
const rail = roadColor("rail");
|
|
4549
|
+
if (rail) {
|
|
4550
|
+
return rail;
|
|
4551
|
+
}
|
|
4001
4552
|
}
|
|
4002
4553
|
if (id.includes("path") || id.includes("track") || id.includes("steps")) {
|
|
4003
|
-
|
|
4554
|
+
const path = roadColor("path");
|
|
4555
|
+
if (path) {
|
|
4556
|
+
return path;
|
|
4557
|
+
}
|
|
4004
4558
|
}
|
|
4005
4559
|
if (id.includes("bridge")) {
|
|
4006
4560
|
const bridge = roadColor("bridge");
|
|
@@ -4017,9 +4571,12 @@ function osmBrightModuleRoadLineColor(id, colors, theme) {
|
|
|
4017
4571
|
if (id.includes("motorway")) {
|
|
4018
4572
|
return roadColor("motorway");
|
|
4019
4573
|
}
|
|
4020
|
-
if (id.includes("trunk")) {
|
|
4574
|
+
if (id.includes("trunk-primary")) {
|
|
4021
4575
|
return roadColor("trunk") ?? roadColor("primary");
|
|
4022
4576
|
}
|
|
4577
|
+
if (id.includes("trunk")) {
|
|
4578
|
+
return roadColor("trunk");
|
|
4579
|
+
}
|
|
4023
4580
|
if (id.includes("primary")) {
|
|
4024
4581
|
return roadColor("primary");
|
|
4025
4582
|
}
|
|
@@ -4034,6 +4591,15 @@ function osmBrightModuleRoadLineColor(id, colors, theme) {
|
|
|
4034
4591
|
}
|
|
4035
4592
|
return void 0;
|
|
4036
4593
|
}
|
|
4594
|
+
function boundaryColorKey(id) {
|
|
4595
|
+
if (id.includes("water") || id.includes("maritime")) {
|
|
4596
|
+
return "maritime";
|
|
4597
|
+
}
|
|
4598
|
+
if (id.includes("disputed")) {
|
|
4599
|
+
return "disputed";
|
|
4600
|
+
}
|
|
4601
|
+
return id.includes("country") || id.includes("admin") || id.includes("level-2") ? "major" : "admin";
|
|
4602
|
+
}
|
|
4037
4603
|
function isRoadCasing(id) {
|
|
4038
4604
|
return id.includes("case") || id.includes("casing");
|
|
4039
4605
|
}
|
|
@@ -4046,41 +4612,26 @@ function isMinorRoad(id) {
|
|
|
4046
4612
|
function isNonRoadThemeTarget(id) {
|
|
4047
4613
|
return id.includes("rail") || id.includes("ferry") || id.includes("cablecar") || id.includes("path") || id.includes("steps") || id.includes("pier") || id.includes("area");
|
|
4048
4614
|
}
|
|
4049
|
-
function
|
|
4050
|
-
return hasBaseColor(theme, ["park", "greenspace", "nature"]) ||
|
|
4615
|
+
function shouldThemeLandcoverColor(theme, key) {
|
|
4616
|
+
return hasBaseColor(theme, ["park", "greenspace", "nature"]) || hasNestedModuleColor(theme, "landcover", key);
|
|
4051
4617
|
}
|
|
4052
|
-
function
|
|
4053
|
-
return hasBaseColor(theme, ["land"]) ||
|
|
4054
|
-
}
|
|
4055
|
-
function shouldThemeBuildings(theme) {
|
|
4056
|
-
return hasBaseColor(theme, ["building"]) || hasModuleColorGroup(theme, "buildings");
|
|
4057
|
-
}
|
|
4058
|
-
function shouldThemeBoundaries(theme) {
|
|
4059
|
-
return hasBaseColor(theme, ["boundary"]) || hasModuleColorGroup(theme, "boundaries");
|
|
4618
|
+
function shouldThemeLanduseColor(theme, key) {
|
|
4619
|
+
return hasBaseColor(theme, ["land"]) || hasNestedModuleColor(theme, "landuse", key);
|
|
4060
4620
|
}
|
|
4061
4621
|
function shouldThemeLabels(theme) {
|
|
4062
|
-
return hasBaseColor(theme, ["text", "textMuted"])
|
|
4622
|
+
return hasBaseColor(theme, ["text", "textMuted"]);
|
|
4063
4623
|
}
|
|
4064
4624
|
function shouldThemeLabelHalo(theme) {
|
|
4065
4625
|
return hasBaseColor(theme, ["background", "canvas", "textHalo"]) || hasNestedModuleColor(theme, "labels", "halo");
|
|
4066
4626
|
}
|
|
4067
|
-
function
|
|
4068
|
-
return shouldThemeLabels(theme) || hasNestedModuleColor(theme, "labels",
|
|
4069
|
-
}
|
|
4070
|
-
function shouldThemePoiLabels(theme) {
|
|
4071
|
-
return shouldThemeLabels(theme) || hasNestedModuleColor(theme, "labels", "poi");
|
|
4627
|
+
function shouldThemeLabelColor(theme, key) {
|
|
4628
|
+
return shouldThemeLabels(theme) || hasNestedModuleColor(theme, "labels", key);
|
|
4072
4629
|
}
|
|
4073
4630
|
function hasBaseColor(theme, keys) {
|
|
4074
4631
|
return keys.some(
|
|
4075
4632
|
(key) => typeof theme.colorOverrides[key] === "string"
|
|
4076
4633
|
);
|
|
4077
4634
|
}
|
|
4078
|
-
function hasModuleColorGroup(theme, group) {
|
|
4079
|
-
const value = theme.moduleOverrides[group];
|
|
4080
|
-
return Boolean(
|
|
4081
|
-
value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length > 0
|
|
4082
|
-
);
|
|
4083
|
-
}
|
|
4084
4635
|
function hasNestedModuleColor(theme, group, key) {
|
|
4085
4636
|
const value = theme.moduleOverrides[group];
|
|
4086
4637
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -4088,10 +4639,10 @@ function hasNestedModuleColor(theme, group, key) {
|
|
|
4088
4639
|
}
|
|
4089
4640
|
return typeof value[key] === "string";
|
|
4090
4641
|
}
|
|
4091
|
-
function
|
|
4642
|
+
function isRecord4(value) {
|
|
4092
4643
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
4093
4644
|
}
|
|
4094
|
-
function
|
|
4645
|
+
function stringValue2(value) {
|
|
4095
4646
|
return typeof value === "string" ? value : "";
|
|
4096
4647
|
}
|
|
4097
4648
|
|
|
@@ -4105,7 +4656,13 @@ function createOsmBrightStyle(options) {
|
|
|
4105
4656
|
options.theme,
|
|
4106
4657
|
options.typography
|
|
4107
4658
|
);
|
|
4108
|
-
const
|
|
4659
|
+
const controlledLayers = applyOsmBrightControls(themedLayers, {
|
|
4660
|
+
customIconMapping: options.customIconMapping,
|
|
4661
|
+
customIconSpriteId: options.customIconSpriteId,
|
|
4662
|
+
labels: options.labelsModule,
|
|
4663
|
+
poi: options.poiModule
|
|
4664
|
+
});
|
|
4665
|
+
const resolvedLayers = options.terrain ? withTerrainLayers(controlledLayers, options.terrain) : controlledLayers;
|
|
4109
4666
|
return {
|
|
4110
4667
|
...template,
|
|
4111
4668
|
name: options.name,
|
|
@@ -4167,6 +4724,7 @@ var defaultConfig = {
|
|
|
4167
4724
|
};
|
|
4168
4725
|
var defaultTileBaseUrl = "https://api.tileflow.dev";
|
|
4169
4726
|
var defaultTileset = "world";
|
|
4727
|
+
var customIconSpriteId = "tileflow";
|
|
4170
4728
|
function createStyle(input = {}, options = {}) {
|
|
4171
4729
|
const parsed = configSchema.safeParse(input);
|
|
4172
4730
|
if (!parsed.success) {
|
|
@@ -4199,9 +4757,21 @@ function createStyle(input = {}, options = {}) {
|
|
|
4199
4757
|
const roadModule = config.modules?.find(
|
|
4200
4758
|
(moduleConfig) => moduleConfig.type === "roads"
|
|
4201
4759
|
);
|
|
4760
|
+
const labelsModule = config.modules?.find(
|
|
4761
|
+
(moduleConfig) => moduleConfig.type === "labels"
|
|
4762
|
+
);
|
|
4763
|
+
const poiModule = config.modules?.find(
|
|
4764
|
+
(moduleConfig) => moduleConfig.type === "poi"
|
|
4765
|
+
);
|
|
4202
4766
|
const roads2 = resolveRoads(config.roads, roadModule, theme.preset.roads ?? defaultConfig.roads);
|
|
4203
|
-
const
|
|
4204
|
-
|
|
4767
|
+
const resolvedLabels = resolveLabels(
|
|
4768
|
+
config.labels,
|
|
4769
|
+
labelsModule,
|
|
4770
|
+
theme.preset.labels ?? defaultConfig.labels
|
|
4771
|
+
);
|
|
4772
|
+
const resolvedPoi = resolvePoi(config.poi, poiModule, theme.preset.poi ?? defaultConfig.poi);
|
|
4773
|
+
const labels2 = resolvedLabels.mode;
|
|
4774
|
+
const poi2 = resolvedPoi.mode;
|
|
4205
4775
|
const buildings = config.buildings ?? "flat";
|
|
4206
4776
|
const colors = resolveColors(config.colors, theme.colors, {}, theme.modules);
|
|
4207
4777
|
const sourceId = config.tiles?.sourceId ?? basemap.sourceId ?? "tileflow";
|
|
@@ -4211,7 +4781,10 @@ function createStyle(input = {}, options = {}) {
|
|
|
4211
4781
|
const typography = resolveTypography(config.typography, theme.typography);
|
|
4212
4782
|
const terrain = resolveTerrain(config.terrain, tileBaseUrl);
|
|
4213
4783
|
const glyphs = config.glyphs ?? basemap.glyphs ?? `${tileBaseUrl}/fonts/{fontstack}/{range}.pbf`;
|
|
4214
|
-
const
|
|
4784
|
+
const iconSet = resolveIconSet(config.icons, options.iconSets);
|
|
4785
|
+
const iconSprite = iconSet?.sprite;
|
|
4786
|
+
const sprite = config.sprite ?? resolveSprite(basemap.sprite, iconSprite);
|
|
4787
|
+
const customIconSpriteName = Array.isArray(sprite) && iconSprite ? customIconSpriteId : void 0;
|
|
4215
4788
|
const attribution = config.tiles?.attribution ?? basemap.attribution ?? "\xA9 OpenMapTiles \xA9 OpenStreetMap contributors";
|
|
4216
4789
|
const metadata = {
|
|
4217
4790
|
"tileflow:basemap": basemap.type,
|
|
@@ -4219,8 +4792,15 @@ function createStyle(input = {}, options = {}) {
|
|
|
4219
4792
|
"tileflow:themeMode": theme.mode,
|
|
4220
4793
|
"tileflow:density": density,
|
|
4221
4794
|
"tileflow:roads": roads2,
|
|
4222
|
-
"tileflow:labels":
|
|
4223
|
-
"tileflow:
|
|
4795
|
+
"tileflow:labels": labels2,
|
|
4796
|
+
"tileflow:labelsModule": labelsModule,
|
|
4797
|
+
"tileflow:poi": poi2,
|
|
4798
|
+
"tileflow:poiModule": poiModule,
|
|
4799
|
+
"tileflow:icons": iconSet ? {
|
|
4800
|
+
customSpriteId: customIconSpriteName,
|
|
4801
|
+
mapping: iconSet.mapping,
|
|
4802
|
+
sprite: iconSprite
|
|
4803
|
+
} : void 0,
|
|
4224
4804
|
"tileflow:buildings": buildings,
|
|
4225
4805
|
"tileflow:modules": config.modules?.map((moduleConfig) => moduleConfig.type) ?? [],
|
|
4226
4806
|
"tileflow:themeModules": Object.keys(theme.moduleOverrides),
|
|
@@ -4248,7 +4828,13 @@ function createStyle(input = {}, options = {}) {
|
|
|
4248
4828
|
terrain,
|
|
4249
4829
|
theme,
|
|
4250
4830
|
tilesUrl,
|
|
4251
|
-
typography
|
|
4831
|
+
typography,
|
|
4832
|
+
labels: labels2,
|
|
4833
|
+
labelsModule: resolvedLabels,
|
|
4834
|
+
poi: poi2,
|
|
4835
|
+
poiModule: resolvedPoi,
|
|
4836
|
+
customIconMapping: iconSet?.mapping,
|
|
4837
|
+
customIconSpriteId: customIconSpriteName
|
|
4252
4838
|
});
|
|
4253
4839
|
return {
|
|
4254
4840
|
...style2,
|
|
@@ -4266,10 +4852,12 @@ function createStyle(input = {}, options = {}) {
|
|
|
4266
4852
|
const layers = openMapTilesLayers(sourceId, sourceLayers, colors, {
|
|
4267
4853
|
buildings,
|
|
4268
4854
|
density,
|
|
4269
|
-
labels,
|
|
4270
|
-
poi,
|
|
4855
|
+
labels: resolvedLabels,
|
|
4856
|
+
poi: resolvedPoi,
|
|
4271
4857
|
roads: roads2,
|
|
4272
|
-
typography
|
|
4858
|
+
typography,
|
|
4859
|
+
customIconMapping: iconSet?.mapping,
|
|
4860
|
+
customIconSpriteId: customIconSpriteName
|
|
4273
4861
|
});
|
|
4274
4862
|
const terrainLayers = terrain ? withTerrainLayers(layers, terrain) : layers;
|
|
4275
4863
|
const resolvedLayers = applyStyleOverrides(terrainLayers, styleOverrideModules);
|
|
@@ -4329,6 +4917,7 @@ function createStyleFromProject(projectConfig, mapName, options = {}) {
|
|
|
4329
4917
|
},
|
|
4330
4918
|
{
|
|
4331
4919
|
...options,
|
|
4920
|
+
iconSets: projectConfig.icons,
|
|
4332
4921
|
themes: projectConfig.themes,
|
|
4333
4922
|
tileset: resolvedTileset
|
|
4334
4923
|
}
|
|
@@ -4361,7 +4950,9 @@ function resolveSourceLayers(mapLayers, tilesetLayers) {
|
|
|
4361
4950
|
}
|
|
4362
4951
|
function shouldUseOsmBrightTemplate(config, basemap, theme) {
|
|
4363
4952
|
const templateTheme = theme.custom || theme.name === "light" || theme.name === "dark";
|
|
4364
|
-
return basemap.type === "osm" && templateTheme && !hasEffectiveColorOverrides(config.colors) && !config.typography && !config.density && !config.roads && !config.
|
|
4953
|
+
return basemap.type === "osm" && templateTheme && !hasEffectiveColorOverrides(config.colors) && !config.typography && !config.density && !config.roads && !config.buildings && !config.modules?.some(
|
|
4954
|
+
(moduleConfig) => moduleConfig.type !== "styleOverride" && moduleConfig.type !== "labels" && moduleConfig.type !== "poi"
|
|
4955
|
+
) && !basemap.sourceLayers && !config.tiles?.sourceLayers;
|
|
4365
4956
|
}
|
|
4366
4957
|
function hasEffectiveColorOverrides(colors) {
|
|
4367
4958
|
if (!colors) {
|
|
@@ -4371,13 +4962,13 @@ function hasEffectiveColorOverrides(colors) {
|
|
|
4371
4962
|
if (key === "accent" || value === void 0) {
|
|
4372
4963
|
return false;
|
|
4373
4964
|
}
|
|
4374
|
-
if (
|
|
4965
|
+
if (isRecord5(value)) {
|
|
4375
4966
|
return Object.values(value).some((nestedValue) => typeof nestedValue === "string");
|
|
4376
4967
|
}
|
|
4377
4968
|
return typeof value === "string";
|
|
4378
4969
|
});
|
|
4379
4970
|
}
|
|
4380
|
-
function
|
|
4971
|
+
function isRecord5(value) {
|
|
4381
4972
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
4382
4973
|
}
|
|
4383
4974
|
function normalizeBaseUrl(value) {
|
|
@@ -4389,6 +4980,48 @@ function normalizeStyleBaseUrl(value) {
|
|
|
4389
4980
|
function normalizeUrl(value) {
|
|
4390
4981
|
return value.replace(/\/+$/, "");
|
|
4391
4982
|
}
|
|
4983
|
+
function resolveIconSet(icons, iconSets, path = []) {
|
|
4984
|
+
if (!icons) {
|
|
4985
|
+
return void 0;
|
|
4986
|
+
}
|
|
4987
|
+
if (typeof icons === "string") {
|
|
4988
|
+
const referenced = iconSets?.[icons];
|
|
4989
|
+
if (referenced) {
|
|
4990
|
+
if (path.includes(icons)) {
|
|
4991
|
+
throw new Error(`Circular Tileflow icon set extends: ${[...path, icons].join(" -> ")}`);
|
|
4992
|
+
}
|
|
4993
|
+
return resolveIconSet(referenced, iconSets, [...path, icons]);
|
|
4994
|
+
}
|
|
4995
|
+
if (isSpriteReference(icons)) {
|
|
4996
|
+
return { sprite: icons };
|
|
4997
|
+
}
|
|
4998
|
+
return { source: icons };
|
|
4999
|
+
}
|
|
5000
|
+
const extended = icons.extends ? resolveIconSet(icons.extends, iconSets, path) : void 0;
|
|
5001
|
+
return {
|
|
5002
|
+
...extended,
|
|
5003
|
+
...icons,
|
|
5004
|
+
mapping: {
|
|
5005
|
+
...extended?.mapping,
|
|
5006
|
+
...icons.mapping
|
|
5007
|
+
}
|
|
5008
|
+
};
|
|
5009
|
+
}
|
|
5010
|
+
function resolveSprite(basemapSprite, iconSprite) {
|
|
5011
|
+
if (!basemapSprite) {
|
|
5012
|
+
return iconSprite;
|
|
5013
|
+
}
|
|
5014
|
+
if (!iconSprite || iconSprite === basemapSprite) {
|
|
5015
|
+
return basemapSprite;
|
|
5016
|
+
}
|
|
5017
|
+
return [
|
|
5018
|
+
{ id: "default", url: basemapSprite },
|
|
5019
|
+
{ id: customIconSpriteId, url: iconSprite }
|
|
5020
|
+
];
|
|
5021
|
+
}
|
|
5022
|
+
function isSpriteReference(value) {
|
|
5023
|
+
return value.startsWith("http://") || value.startsWith("https://") || value.startsWith("/") || value.startsWith("data:");
|
|
5024
|
+
}
|
|
4392
5025
|
|
|
4393
5026
|
// src/config.ts
|
|
4394
5027
|
function defineTileflow(config) {
|
|
@@ -4401,9 +5034,11 @@ export {
|
|
|
4401
5034
|
createStyleFromProject,
|
|
4402
5035
|
defineTileflow,
|
|
4403
5036
|
getDefaultColors2 as getDefaultColors,
|
|
5037
|
+
labels,
|
|
4404
5038
|
osm,
|
|
4405
5039
|
parseTileflowMap,
|
|
4406
5040
|
parseTileflowProject,
|
|
5041
|
+
poi,
|
|
4407
5042
|
roads,
|
|
4408
5043
|
styleOverride,
|
|
4409
5044
|
tileflowMapSchema,
|