@tileflow/core 0.1.0-alpha.12 → 0.1.0-alpha.13

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 CHANGED
@@ -51,7 +51,7 @@ export default defineTileflow({
51
51
  icons: 'brand',
52
52
  theme: 'light',
53
53
  modules: [
54
- labels({roads: 'minimal'}),
54
+ labels({roads: 'major'}),
55
55
  poi({categories: ['food', 'coffee', 'culture', 'transit'], icons: 'essential'}),
56
56
  roads({detail: 'streets', hierarchy: 'clear', outline: 'subtle', weight: 'regular'}),
57
57
  ],
@@ -113,7 +113,28 @@ Without options, `roads()` uses `detail: 'streets'`, `hierarchy: 'clear'`,
113
113
  `weight: 'regular'`, `outline: 'subtle'`, and all extras disabled. Named visual recipes belong
114
114
  in examples rather than the runtime API, so the resolved behavior is always visible in config.
115
115
 
116
- Colors never belong in `roads()`. Put common colors in `theme.colors` and granular road colors in `theme.modules.roads`. Road-label density remains a `labels({roads: ...})` concern.
116
+ Colors never belong in `roads()`. Put common colors in `theme.colors` and granular road colors in `theme.modules.roads`. Road-label detail remains a `labels({roads: ...})` concern.
117
+
118
+ ## Labels module
119
+
120
+ Control label families independently without a preset:
121
+
122
+ ```ts
123
+ labels({
124
+ language: 'auto',
125
+ places: 'major',
126
+ roads: 'major',
127
+ water: 'major',
128
+ });
129
+ ```
130
+
131
+ `places`, `roads`, and `water` accept `none`, `major`, or `all`. Each value is progressive:
132
+ `major` keeps the important labels for orientation and `all` adds local or secondary labels at
133
+ their natural zoom. Road labels are automatically limited to road classes currently visible through
134
+ `roads({detail})`. `language` accepts `auto`, `local`, or a language code such as `en` or `es`.
135
+
136
+ Without options, `labels()` uses `language: 'auto'` and `major` for all three label families.
137
+ Label colors remain in `theme.modules.labels`; font family and weight remain in `typography`.
117
138
 
118
139
  ## Public API
119
140
 
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ type TileflowDensity = 'clean' | 'balanced' | 'dense';
4
4
  type TileflowRoads = 'hidden' | 'soft' | 'standard' | 'detailed';
5
5
  type TileflowLabels = 'none' | 'essential' | 'balanced' | 'full';
6
6
  type TileflowPoi = 'none' | 'minimal' | 'balanced' | 'full';
7
- type TileflowLabelDensity = 'none' | 'minimal' | 'balanced' | 'detailed';
7
+ type TileflowLabelDetail = 'none' | 'major' | 'all';
8
8
  type TileflowLabelLanguage = 'auto' | 'local' | 'en' | (string & {});
9
9
  type TileflowPoiCategory = 'food' | 'coffee' | 'culture' | 'transit' | 'shopping' | 'lodging' | 'health' | 'education' | 'services' | (string & {});
10
10
  type TileflowPoiIcons = boolean | 'essential' | 'full';
@@ -151,7 +151,10 @@ type TileflowSourceLayers = {
151
151
  landuse?: string;
152
152
  park?: string;
153
153
  water?: string;
154
+ waterName?: string;
155
+ waterway?: string;
154
156
  road?: string;
157
+ roadName?: string;
155
158
  building?: string;
156
159
  boundary?: string;
157
160
  place?: string;
@@ -212,10 +215,9 @@ type TileflowRoadsModuleOptions = Omit<TileflowRoadsModuleConfig, 'type'>;
212
215
  type TileflowLabelsModuleConfig = {
213
216
  type: 'labels';
214
217
  language?: TileflowLabelLanguage;
215
- places?: TileflowLabelDensity;
216
- preset?: TileflowLabels;
217
- roads?: TileflowLabelDensity;
218
- water?: TileflowLabelDensity;
218
+ places?: TileflowLabelDetail;
219
+ roads?: TileflowLabelDetail;
220
+ water?: TileflowLabelDetail;
219
221
  };
220
222
  type TileflowLabelsModuleOptions = Omit<TileflowLabelsModuleConfig, 'type'>;
221
223
  type TileflowPoiModuleConfig = {
@@ -543,7 +545,10 @@ declare const tileflowMapSchema: z.ZodObject<{
543
545
  landuse: z.ZodOptional<z.ZodString>;
544
546
  park: z.ZodOptional<z.ZodString>;
545
547
  water: z.ZodOptional<z.ZodString>;
548
+ waterName: z.ZodOptional<z.ZodString>;
549
+ waterway: z.ZodOptional<z.ZodString>;
546
550
  road: z.ZodOptional<z.ZodString>;
551
+ roadName: z.ZodOptional<z.ZodString>;
547
552
  building: z.ZodOptional<z.ZodString>;
548
553
  boundary: z.ZodOptional<z.ZodString>;
549
554
  place: z.ZodOptional<z.ZodString>;
@@ -752,28 +757,19 @@ declare const tileflowMapSchema: z.ZodObject<{
752
757
  type: z.ZodLiteral<"labels">;
753
758
  language: z.ZodOptional<z.ZodString>;
754
759
  places: z.ZodOptional<z.ZodEnum<{
755
- balanced: "balanced";
756
760
  none: "none";
757
- minimal: "minimal";
758
- detailed: "detailed";
759
- }>>;
760
- preset: z.ZodOptional<z.ZodEnum<{
761
- balanced: "balanced";
762
- none: "none";
763
- essential: "essential";
764
- full: "full";
761
+ major: "major";
762
+ all: "all";
765
763
  }>>;
766
764
  roads: z.ZodOptional<z.ZodEnum<{
767
- balanced: "balanced";
768
765
  none: "none";
769
- minimal: "minimal";
770
- detailed: "detailed";
766
+ major: "major";
767
+ all: "all";
771
768
  }>>;
772
769
  water: z.ZodOptional<z.ZodEnum<{
773
- balanced: "balanced";
774
770
  none: "none";
775
- minimal: "minimal";
776
- detailed: "detailed";
771
+ major: "major";
772
+ all: "all";
777
773
  }>>;
778
774
  }, z.core.$strict>, z.ZodObject<{
779
775
  type: z.ZodLiteral<"poi">;
@@ -1015,7 +1011,10 @@ declare const tileflowMapSchema: z.ZodObject<{
1015
1011
  landuse: z.ZodOptional<z.ZodString>;
1016
1012
  park: z.ZodOptional<z.ZodString>;
1017
1013
  water: z.ZodOptional<z.ZodString>;
1014
+ waterName: z.ZodOptional<z.ZodString>;
1015
+ waterway: z.ZodOptional<z.ZodString>;
1018
1016
  road: z.ZodOptional<z.ZodString>;
1017
+ roadName: z.ZodOptional<z.ZodString>;
1019
1018
  building: z.ZodOptional<z.ZodString>;
1020
1019
  boundary: z.ZodOptional<z.ZodString>;
1021
1020
  place: z.ZodOptional<z.ZodString>;
@@ -1039,7 +1038,10 @@ declare const configSchema: z.ZodObject<{
1039
1038
  landuse: z.ZodOptional<z.ZodString>;
1040
1039
  park: z.ZodOptional<z.ZodString>;
1041
1040
  water: z.ZodOptional<z.ZodString>;
1041
+ waterName: z.ZodOptional<z.ZodString>;
1042
+ waterway: z.ZodOptional<z.ZodString>;
1042
1043
  road: z.ZodOptional<z.ZodString>;
1044
+ roadName: z.ZodOptional<z.ZodString>;
1043
1045
  building: z.ZodOptional<z.ZodString>;
1044
1046
  boundary: z.ZodOptional<z.ZodString>;
1045
1047
  place: z.ZodOptional<z.ZodString>;
@@ -1248,28 +1250,19 @@ declare const configSchema: z.ZodObject<{
1248
1250
  type: z.ZodLiteral<"labels">;
1249
1251
  language: z.ZodOptional<z.ZodString>;
1250
1252
  places: z.ZodOptional<z.ZodEnum<{
1251
- balanced: "balanced";
1252
- none: "none";
1253
- minimal: "minimal";
1254
- detailed: "detailed";
1255
- }>>;
1256
- preset: z.ZodOptional<z.ZodEnum<{
1257
- balanced: "balanced";
1258
1253
  none: "none";
1259
- essential: "essential";
1260
- full: "full";
1254
+ major: "major";
1255
+ all: "all";
1261
1256
  }>>;
1262
1257
  roads: z.ZodOptional<z.ZodEnum<{
1263
- balanced: "balanced";
1264
1258
  none: "none";
1265
- minimal: "minimal";
1266
- detailed: "detailed";
1259
+ major: "major";
1260
+ all: "all";
1267
1261
  }>>;
1268
1262
  water: z.ZodOptional<z.ZodEnum<{
1269
- balanced: "balanced";
1270
1263
  none: "none";
1271
- minimal: "minimal";
1272
- detailed: "detailed";
1264
+ major: "major";
1265
+ all: "all";
1273
1266
  }>>;
1274
1267
  }, z.core.$strict>, z.ZodObject<{
1275
1268
  type: z.ZodLiteral<"poi">;
@@ -1511,7 +1504,10 @@ declare const configSchema: z.ZodObject<{
1511
1504
  landuse: z.ZodOptional<z.ZodString>;
1512
1505
  park: z.ZodOptional<z.ZodString>;
1513
1506
  water: z.ZodOptional<z.ZodString>;
1507
+ waterName: z.ZodOptional<z.ZodString>;
1508
+ waterway: z.ZodOptional<z.ZodString>;
1514
1509
  road: z.ZodOptional<z.ZodString>;
1510
+ roadName: z.ZodOptional<z.ZodString>;
1515
1511
  building: z.ZodOptional<z.ZodString>;
1516
1512
  boundary: z.ZodOptional<z.ZodString>;
1517
1513
  place: z.ZodOptional<z.ZodString>;
@@ -1728,7 +1724,10 @@ declare const tileflowProjectSchema: z.ZodObject<{
1728
1724
  landuse: z.ZodOptional<z.ZodString>;
1729
1725
  park: z.ZodOptional<z.ZodString>;
1730
1726
  water: z.ZodOptional<z.ZodString>;
1727
+ waterName: z.ZodOptional<z.ZodString>;
1728
+ waterway: z.ZodOptional<z.ZodString>;
1731
1729
  road: z.ZodOptional<z.ZodString>;
1730
+ roadName: z.ZodOptional<z.ZodString>;
1732
1731
  building: z.ZodOptional<z.ZodString>;
1733
1732
  boundary: z.ZodOptional<z.ZodString>;
1734
1733
  place: z.ZodOptional<z.ZodString>;
@@ -1745,7 +1744,10 @@ declare const tileflowProjectSchema: z.ZodObject<{
1745
1744
  landuse: z.ZodOptional<z.ZodString>;
1746
1745
  park: z.ZodOptional<z.ZodString>;
1747
1746
  water: z.ZodOptional<z.ZodString>;
1747
+ waterName: z.ZodOptional<z.ZodString>;
1748
+ waterway: z.ZodOptional<z.ZodString>;
1748
1749
  road: z.ZodOptional<z.ZodString>;
1750
+ roadName: z.ZodOptional<z.ZodString>;
1749
1751
  building: z.ZodOptional<z.ZodString>;
1750
1752
  boundary: z.ZodOptional<z.ZodString>;
1751
1753
  place: z.ZodOptional<z.ZodString>;
@@ -1954,28 +1956,19 @@ declare const tileflowProjectSchema: z.ZodObject<{
1954
1956
  type: z.ZodLiteral<"labels">;
1955
1957
  language: z.ZodOptional<z.ZodString>;
1956
1958
  places: z.ZodOptional<z.ZodEnum<{
1957
- balanced: "balanced";
1958
- none: "none";
1959
- minimal: "minimal";
1960
- detailed: "detailed";
1961
- }>>;
1962
- preset: z.ZodOptional<z.ZodEnum<{
1963
- balanced: "balanced";
1964
1959
  none: "none";
1965
- essential: "essential";
1966
- full: "full";
1960
+ major: "major";
1961
+ all: "all";
1967
1962
  }>>;
1968
1963
  roads: z.ZodOptional<z.ZodEnum<{
1969
- balanced: "balanced";
1970
1964
  none: "none";
1971
- minimal: "minimal";
1972
- detailed: "detailed";
1965
+ major: "major";
1966
+ all: "all";
1973
1967
  }>>;
1974
1968
  water: z.ZodOptional<z.ZodEnum<{
1975
- balanced: "balanced";
1976
1969
  none: "none";
1977
- minimal: "minimal";
1978
- detailed: "detailed";
1970
+ major: "major";
1971
+ all: "all";
1979
1972
  }>>;
1980
1973
  }, z.core.$strict>, z.ZodObject<{
1981
1974
  type: z.ZodLiteral<"poi">;
@@ -2217,7 +2210,10 @@ declare const tileflowProjectSchema: z.ZodObject<{
2217
2210
  landuse: z.ZodOptional<z.ZodString>;
2218
2211
  park: z.ZodOptional<z.ZodString>;
2219
2212
  water: z.ZodOptional<z.ZodString>;
2213
+ waterName: z.ZodOptional<z.ZodString>;
2214
+ waterway: z.ZodOptional<z.ZodString>;
2220
2215
  road: z.ZodOptional<z.ZodString>;
2216
+ roadName: z.ZodOptional<z.ZodString>;
2221
2217
  building: z.ZodOptional<z.ZodString>;
2222
2218
  boundary: z.ZodOptional<z.ZodString>;
2223
2219
  place: z.ZodOptional<z.ZodString>;
@@ -2241,12 +2237,12 @@ declare function defineTileflow<const TConfig extends TileflowProjectConfig>(con
2241
2237
 
2242
2238
  declare function osm(options?: TileflowOsmBasemapOptions): TileflowOsmBasemapConfig;
2243
2239
 
2240
+ declare function roads(options?: TileflowRoadsModuleOptions): TileflowRoadsModuleConfig;
2241
+
2244
2242
  declare function labels(options?: TileflowLabelsModuleOptions): TileflowLabelsModuleConfig;
2245
2243
 
2246
2244
  declare function poi(options?: TileflowPoiModuleOptions): TileflowPoiModuleConfig;
2247
2245
 
2248
- declare function roads(options?: TileflowRoadsModuleOptions): TileflowRoadsModuleConfig;
2249
-
2250
2246
  declare function styleOverride(options?: TileflowStyleOverrideOptions): TileflowStyleOverrideModuleConfig;
2251
2247
 
2252
2248
  declare const defaultTileflowManifestUrl = "/tileflow/manifest.json";
@@ -2357,4 +2353,4 @@ declare function normalizeTileflowStaticImageSize(input: {
2357
2353
  };
2358
2354
  declare function inferTileflowAnalyticsFromStyleUrl(styleUrl: string): TileflowAnalytics | undefined;
2359
2355
 
2360
- export { type MapLibreSprite, type MapLibreStyle, type TileflowAdvancedColorConfig, type TileflowAnalytics, type TileflowBaseColors, type TileflowBasemapConfig, type TileflowBoundaryColorConfig, type TileflowBuildingColorConfig, type TileflowBuildings, type TileflowColor, type TileflowColorConfig, type TileflowColors, type TileflowConfig, type TileflowDensity, type TileflowFontWeight, type TileflowFonts, type TileflowHydroColorConfig, type TileflowIconSet, type TileflowIconSetConfig, type TileflowLabelColorConfig, type TileflowLabelDensity, type TileflowLabelLanguage, type TileflowLabels, type TileflowLabelsModuleConfig, type TileflowLabelsModuleOptions, type TileflowLandcoverColorConfig, type TileflowLanduseColorConfig, type TileflowManifest, type TileflowManifestLoadOptions, type TileflowMapConfig, type TileflowMapMarker, type TileflowMapMode, type TileflowMapModeOptions, type TileflowModuleConfig, type TileflowOsmBasemapConfig, type TileflowOsmBasemapOptions, type TileflowPoi, type TileflowPoiCategory, type TileflowPoiColorConfig, type TileflowPoiIcons, type TileflowPoiLabels, type TileflowPoiModuleConfig, type TileflowPoiModuleOptions, type TileflowProjectConfig, type TileflowProjectIconSets, type TileflowProjectThemes, type TileflowRenderer, type TileflowRoadColorConfig, type TileflowRoadDetail, type TileflowRoadExtras, type TileflowRoadHierarchy, type TileflowRoadOutline, type TileflowRoadWeight, type TileflowRoads, type TileflowRoadsModuleConfig, type TileflowRoadsModuleOptions, type TileflowRuntimeManifest, type TileflowRuntimeManifestMap, type TileflowRuntimeManifestMapEntry, type TileflowRuntimeStyle, type TileflowRuntimeStyleOptions, type TileflowSourceLayers, type TileflowStyleLayerOverride, type TileflowStyleOptions, type TileflowStyleOverrideModuleConfig, type TileflowStyleOverrideOptions, type TileflowTerrain, type TileflowTerrainConfig, type TileflowTerrainEncoding, type TileflowTerrainMode, type TileflowTheme, type TileflowThemeConfig, type TileflowThemeMode, type TileflowThemeModulesConfig, type TileflowThemeName, type TileflowTiles, type TileflowTilesetConfig, type TileflowTypography, type TileflowViewConfig, type ValidationMessage, type ValidationResult, configSchema, createManifest, createStyle, createStyleFromProject, createTileflowSessionId, defaultTileflowManifestUrl, defaultTileflowStyleBaseUrl, defineTileflow, getDefaultColors, getDefaultTileflowStyleBaseUrl, getTileflowAnalyticsApiUrl, inferTileflowAnalyticsFromStyleUrl, isTileflowLocalDevHost, labels, loadTileflowManifest, mergeTileflowAnalytics, normalizeTileflowStaticImageSize, normalizeTileflowUrl, osm, parseTileflowMap, parseTileflowProject, poi, resolveTileflowAnalyticsRequestUrl, resolveTileflowManifestMap, resolveTileflowMapMode, resolveTileflowRuntimeStyle, resolveTileflowStaticImageUrl, resolveTileflowStyleUrl, roads, shouldLoadTileflowManifest, startTileflowSession, styleOverride, tileflowMapSchema, tileflowProjectSchema, tileflowThemeSchema, validateConfig, validateTileflowConfig };
2356
+ export { type MapLibreSprite, type MapLibreStyle, type TileflowAdvancedColorConfig, type TileflowAnalytics, type TileflowBaseColors, type TileflowBasemapConfig, type TileflowBoundaryColorConfig, type TileflowBuildingColorConfig, type TileflowBuildings, type TileflowColor, type TileflowColorConfig, type TileflowColors, type TileflowConfig, type TileflowDensity, type TileflowFontWeight, type TileflowFonts, type TileflowHydroColorConfig, type TileflowIconSet, type TileflowIconSetConfig, type TileflowLabelColorConfig, type TileflowLabelDetail, type TileflowLabelLanguage, type TileflowLabels, type TileflowLabelsModuleConfig, type TileflowLabelsModuleOptions, type TileflowLandcoverColorConfig, type TileflowLanduseColorConfig, type TileflowManifest, type TileflowManifestLoadOptions, type TileflowMapConfig, type TileflowMapMarker, type TileflowMapMode, type TileflowMapModeOptions, type TileflowModuleConfig, type TileflowOsmBasemapConfig, type TileflowOsmBasemapOptions, type TileflowPoi, type TileflowPoiCategory, type TileflowPoiColorConfig, type TileflowPoiIcons, type TileflowPoiLabels, type TileflowPoiModuleConfig, type TileflowPoiModuleOptions, type TileflowProjectConfig, type TileflowProjectIconSets, type TileflowProjectThemes, type TileflowRenderer, type TileflowRoadColorConfig, type TileflowRoadDetail, type TileflowRoadExtras, type TileflowRoadHierarchy, type TileflowRoadOutline, type TileflowRoadWeight, type TileflowRoads, type TileflowRoadsModuleConfig, type TileflowRoadsModuleOptions, type TileflowRuntimeManifest, type TileflowRuntimeManifestMap, type TileflowRuntimeManifestMapEntry, type TileflowRuntimeStyle, type TileflowRuntimeStyleOptions, type TileflowSourceLayers, type TileflowStyleLayerOverride, type TileflowStyleOptions, type TileflowStyleOverrideModuleConfig, type TileflowStyleOverrideOptions, type TileflowTerrain, type TileflowTerrainConfig, type TileflowTerrainEncoding, type TileflowTerrainMode, type TileflowTheme, type TileflowThemeConfig, type TileflowThemeMode, type TileflowThemeModulesConfig, type TileflowThemeName, type TileflowTiles, type TileflowTilesetConfig, type TileflowTypography, type TileflowViewConfig, type ValidationMessage, type ValidationResult, configSchema, createManifest, createStyle, createStyleFromProject, createTileflowSessionId, defaultTileflowManifestUrl, defaultTileflowStyleBaseUrl, defineTileflow, getDefaultColors, getDefaultTileflowStyleBaseUrl, getTileflowAnalyticsApiUrl, inferTileflowAnalyticsFromStyleUrl, isTileflowLocalDevHost, labels, loadTileflowManifest, mergeTileflowAnalytics, normalizeTileflowStaticImageSize, normalizeTileflowUrl, osm, parseTileflowMap, parseTileflowProject, poi, resolveTileflowAnalyticsRequestUrl, resolveTileflowManifestMap, resolveTileflowMapMode, resolveTileflowRuntimeStyle, resolveTileflowStaticImageUrl, resolveTileflowStyleUrl, roads, shouldLoadTileflowManifest, startTileflowSession, styleOverride, tileflowMapSchema, tileflowProjectSchema, tileflowThemeSchema, validateConfig, validateTileflowConfig };
package/dist/index.js CHANGED
@@ -513,40 +513,75 @@ function rgbToHex(r, g, b) {
513
513
  }
514
514
 
515
515
  // src/modules/labels/index.ts
516
+ var moduleLabelDefaults = {
517
+ language: "auto",
518
+ places: "major",
519
+ roads: "major",
520
+ water: "major"
521
+ };
522
+ var majorPlaceClasses = ["continent", "country", "state", "city", "town"];
523
+ var highwayRoadClasses = ["motorway", "trunk"];
524
+ var arterialRoadClasses = ["primary", "secondary", "tertiary"];
525
+ var majorRoadClasses = [...highwayRoadClasses, ...arterialRoadClasses];
526
+ var majorRoadClassSet = new Set(majorRoadClasses);
527
+ var streetRoadClasses = ["minor"];
528
+ var serviceRoadClasses = ["service", "track"];
529
+ var majorWaterClasses = ["ocean", "sea", "lake"];
530
+ var majorWaterwayClasses = ["river"];
516
531
  function labels(options = {}) {
517
532
  return {
518
533
  type: "labels",
519
534
  ...options.language ? { language: options.language } : {},
520
535
  ...options.places ? { places: options.places } : {},
521
- ...options.preset ? { preset: options.preset } : {},
522
536
  ...options.roads ? { roads: options.roads } : {},
523
537
  ...options.water ? { water: options.water } : {}
524
538
  };
525
539
  }
526
540
  function resolveLabels(legacyLabels, moduleConfig, fallback) {
527
- const mode = moduleConfig?.preset ?? legacyLabels ?? fallback;
528
- const density = labelDensityFromMode(mode);
541
+ const fallbackMode = legacyLabels ?? fallback;
542
+ const defaults = moduleConfig ? moduleLabelDefaults : labelDefaultsFromLegacyMode(fallbackMode);
543
+ const resolved = {
544
+ language: moduleConfig?.language ?? defaults.language,
545
+ places: moduleConfig?.places ?? defaults.places,
546
+ roads: moduleConfig?.roads ?? defaults.roads,
547
+ water: moduleConfig?.water ?? defaults.water
548
+ };
529
549
  return {
530
- language: moduleConfig?.language ?? "auto",
531
- mode,
532
- places: moduleConfig?.places ?? density,
533
- roads: moduleConfig?.roads ?? density,
534
- water: moduleConfig?.water ?? density
550
+ ...resolved,
551
+ mode: moduleConfig ? legacyModeFromResolvedLabels(resolved) : fallbackMode
535
552
  };
536
553
  }
537
- function labelLayers(source, sourceLayer, colors, labelsConfig, typography) {
538
- if (labelsConfig.mode === "none" || labelsConfig.places === "none") {
539
- return [];
540
- }
541
- const maxRank = labelsConfig.places === "minimal" ? 3 : labelsConfig.places === "balanced" ? 7 : 12;
554
+ function labelLayers(source, sourceLayers, colors, labelsConfig, roadsConfig, typography) {
555
+ return [
556
+ ...placeLabelLayers(source, sourceLayers.place, colors, labelsConfig, typography),
557
+ ...roadLabelLayers(
558
+ source,
559
+ sourceLayers.roadName,
560
+ colors,
561
+ labelsConfig,
562
+ roadsConfig,
563
+ typography
564
+ ),
565
+ ...waterLabelLayers(
566
+ source,
567
+ sourceLayers.waterName,
568
+ sourceLayers.waterway,
569
+ colors,
570
+ labelsConfig,
571
+ typography
572
+ )
573
+ ];
574
+ }
575
+ function placeLabelLayers(source, sourceLayer, colors, labelsConfig, typography) {
576
+ if (labelsConfig.places === "none") return [];
542
577
  return [
543
578
  {
544
579
  id: "place-labels",
545
580
  type: "symbol",
546
581
  source,
547
582
  "source-layer": sourceLayer,
548
- minzoom: 3,
549
- filter: ["<=", ["coalesce", ["get", "rank"], 10], maxRank],
583
+ minzoom: 0,
584
+ filter: labelsConfig.places === "major" ? ["all", ["has", "name"], classFilter(majorPlaceClasses)] : ["has", "name"],
550
585
  layout: {
551
586
  "text-field": labelTextField(labelsConfig.language),
552
587
  "text-font": textFont(typography),
@@ -562,12 +597,160 @@ function labelLayers(source, sourceLayer, colors, labelsConfig, typography) {
562
597
  }
563
598
  ];
564
599
  }
565
- function labelDensityFromMode(mode) {
566
- if (mode === "none") return "none";
567
- if (mode === "essential") return "minimal";
568
- if (mode === "full") return "detailed";
600
+ function roadLabelLayers(source, sourceLayer, colors, labelsConfig, roadsConfig, typography) {
601
+ const classes = visibleRoadLabelClasses(labelsConfig.roads, roadsConfig);
602
+ const majorClasses = classes.filter((roadClass) => majorRoadClassSet.has(roadClass));
603
+ const minorClasses = classes.filter((roadClass) => !majorRoadClassSet.has(roadClass));
604
+ if (classes.length === 0) return [];
605
+ const layers = [];
606
+ const sharedLayout = {
607
+ "symbol-placement": "line",
608
+ "text-field": labelTextField(labelsConfig.language),
609
+ "text-font": textFont(typography),
610
+ "text-rotation-alignment": "map",
611
+ "text-size": ["interpolate", ["linear"], ["zoom"], 11, 11, 14, 13, 17, 15]
612
+ };
613
+ const sharedPaint = {
614
+ "text-color": colors.labels.road,
615
+ "text-halo-color": colors.labels.halo,
616
+ "text-halo-width": 1
617
+ };
618
+ if (majorClasses.length > 0) {
619
+ const namedMajorClasses = majorClasses.filter((roadClass) => roadClass !== "motorway");
620
+ layers.push({
621
+ id: "road-shields",
622
+ type: "symbol",
623
+ source,
624
+ "source-layer": sourceLayer,
625
+ minzoom: 8,
626
+ filter: ["all", ["has", "ref"], classFilter(majorClasses)],
627
+ layout: {
628
+ "symbol-placement": "line",
629
+ "symbol-spacing": 240,
630
+ "text-field": ["get", "ref"],
631
+ "text-font": textFont(typography),
632
+ "text-rotation-alignment": "viewport",
633
+ "text-size": 10
634
+ },
635
+ paint: sharedPaint
636
+ });
637
+ if (namedMajorClasses.length > 0) {
638
+ layers.unshift({
639
+ id: "road-labels-major",
640
+ type: "symbol",
641
+ source,
642
+ "source-layer": sourceLayer,
643
+ minzoom: 10,
644
+ filter: ["all", ["has", "name"], classFilter(namedMajorClasses)],
645
+ layout: sharedLayout,
646
+ paint: sharedPaint
647
+ });
648
+ }
649
+ }
650
+ if (minorClasses.length > 0) {
651
+ layers.push({
652
+ id: "road-labels-minor",
653
+ type: "symbol",
654
+ source,
655
+ "source-layer": sourceLayer,
656
+ minzoom: 14,
657
+ filter: ["all", ["has", "name"], classFilter(minorClasses)],
658
+ layout: sharedLayout,
659
+ paint: sharedPaint
660
+ });
661
+ }
662
+ return layers;
663
+ }
664
+ function waterLabelLayers(source, waterNameSourceLayer, waterwaySourceLayer, colors, labelsConfig, typography) {
665
+ if (labelsConfig.water === "none") return [];
666
+ const waterFilter = labelsConfig.water === "major" ? ["all", ["has", "name"], classFilter(majorWaterClasses)] : ["has", "name"];
667
+ const waterwayFilter = labelsConfig.water === "major" ? ["all", ["has", "name"], classFilter(majorWaterwayClasses)] : ["has", "name"];
668
+ const paint = {
669
+ "text-color": colors.labels.water,
670
+ "text-halo-color": colors.labels.halo,
671
+ "text-halo-width": 1
672
+ };
673
+ return [
674
+ {
675
+ id: "water-labels",
676
+ type: "symbol",
677
+ source,
678
+ "source-layer": waterNameSourceLayer,
679
+ minzoom: 3,
680
+ filter: ["all", ["==", ["geometry-type"], "Point"], waterFilter],
681
+ layout: {
682
+ "text-field": labelTextField(labelsConfig.language),
683
+ "text-font": textFont(typography),
684
+ "text-size": ["interpolate", ["linear"], ["zoom"], 3, 11, 8, 14]
685
+ },
686
+ paint
687
+ },
688
+ {
689
+ id: "water-line-labels",
690
+ type: "symbol",
691
+ source,
692
+ "source-layer": waterNameSourceLayer,
693
+ minzoom: 5,
694
+ filter: ["all", ["==", ["geometry-type"], "LineString"], waterFilter],
695
+ layout: {
696
+ "symbol-placement": "line",
697
+ "text-field": labelTextField(labelsConfig.language),
698
+ "text-font": textFont(typography),
699
+ "text-size": 13
700
+ },
701
+ paint
702
+ },
703
+ {
704
+ id: "waterway-labels",
705
+ type: "symbol",
706
+ source,
707
+ "source-layer": waterwaySourceLayer,
708
+ minzoom: 10,
709
+ filter: ["all", ["==", ["geometry-type"], "LineString"], waterwayFilter],
710
+ layout: {
711
+ "symbol-placement": "line",
712
+ "symbol-spacing": 320,
713
+ "text-field": labelTextField(labelsConfig.language),
714
+ "text-font": textFont(typography),
715
+ "text-size": 12
716
+ },
717
+ paint
718
+ }
719
+ ];
720
+ }
721
+ function visibleRoadLabelClasses(detail, roadsConfig) {
722
+ if (detail === "none" || roadsConfig.detail === "none") return [];
723
+ const visibleRoadClasses = roadsConfig.detail === "highways" ? [...highwayRoadClasses] : [
724
+ ...majorRoadClasses,
725
+ ...roadsConfig.detail === "streets" || roadsConfig.detail === "all" ? streetRoadClasses : [],
726
+ ...roadsConfig.detail === "all" ? serviceRoadClasses : [],
727
+ ...roadsConfig.extras.paths ? ["path"] : []
728
+ ];
729
+ const requestedClasses = detail === "major" ? [...majorRoadClasses] : [...majorRoadClasses, ...streetRoadClasses, ...serviceRoadClasses, "path"];
730
+ const visible = new Set(visibleRoadClasses);
731
+ return requestedClasses.filter((roadClass) => visible.has(roadClass));
732
+ }
733
+ function labelDefaultsFromLegacyMode(mode) {
734
+ if (mode === "none") {
735
+ return { language: "auto", places: "none", roads: "none", water: "none" };
736
+ }
737
+ if (mode === "essential") {
738
+ return { language: "auto", places: "major", roads: "major", water: "major" };
739
+ }
740
+ return { language: "auto", places: "all", roads: "all", water: "all" };
741
+ }
742
+ function legacyModeFromResolvedLabels(options) {
743
+ if (options.places === "none" && options.roads === "none" && options.water === "none") {
744
+ return "none";
745
+ }
746
+ if (options.places === "major" && options.roads === "major" && options.water === "major") {
747
+ return "essential";
748
+ }
569
749
  return "balanced";
570
750
  }
751
+ function classFilter(classes) {
752
+ return ["match", ["get", "class"], classes, true, false];
753
+ }
571
754
  function labelTextField(language) {
572
755
  if (language === "local") {
573
756
  return ["coalesce", ["get", "name"], ["get", "name:latin"], ["get", "name:en"]];
@@ -759,11 +942,11 @@ var moduleRoadDefaults = {
759
942
  outline: "subtle",
760
943
  weight: "regular"
761
944
  };
762
- var highwayRoadClasses = ["motorway", "trunk"];
763
- var arterialRoadClasses = ["primary", "secondary", "tertiary"];
764
- var majorRoadClasses = [...highwayRoadClasses, ...arterialRoadClasses];
765
- var streetRoadClasses = ["minor"];
766
- var serviceRoadClasses = ["service", "track"];
945
+ var highwayRoadClasses2 = ["motorway", "trunk"];
946
+ var arterialRoadClasses2 = ["primary", "secondary", "tertiary"];
947
+ var majorRoadClasses2 = [...highwayRoadClasses2, ...arterialRoadClasses2];
948
+ var streetRoadClasses2 = ["minor"];
949
+ var serviceRoadClasses2 = ["service", "track"];
767
950
  function roads(options = {}) {
768
951
  return {
769
952
  type: "roads",
@@ -835,13 +1018,13 @@ function roadLayers(source, sourceLayer, colors, options) {
835
1018
  return [];
836
1019
  }
837
1020
  const metrics = roadStyleMetrics(options);
838
- const selectedMajorRoadClasses = options.detail === "highways" ? [...highwayRoadClasses] : [...majorRoadClasses];
1021
+ const selectedMajorRoadClasses = options.detail === "highways" ? [...highwayRoadClasses2] : [...majorRoadClasses2];
839
1022
  const showsStreetRoads = options.detail === "streets" || options.detail === "all";
840
1023
  const showsServiceRoads = options.detail === "all";
841
1024
  const roadClasses = [
842
1025
  ...selectedMajorRoadClasses,
843
- ...showsStreetRoads ? streetRoadClasses : [],
844
- ...showsServiceRoads ? serviceRoadClasses : []
1026
+ ...showsStreetRoads ? streetRoadClasses2 : [],
1027
+ ...showsServiceRoads ? serviceRoadClasses2 : []
845
1028
  ];
846
1029
  const transportClasses = [
847
1030
  ...roadClasses,
@@ -851,11 +1034,11 @@ function roadLayers(source, sourceLayer, colors, options) {
851
1034
  ];
852
1035
  const roadClassColor = roadClassColorExpression(colors);
853
1036
  const nonTunnelRoadFilter = ["!=", ["get", "brunnel"], "tunnel"];
854
- const majorFilter = classFilter(selectedMajorRoadClasses);
855
- const streetFilter = classFilter(streetRoadClasses);
856
- const serviceFilter = classFilter(serviceRoadClasses);
857
- const roadFilter = classFilter(roadClasses);
858
- const transportFilter = classFilter(transportClasses);
1037
+ const majorFilter = classFilter2(selectedMajorRoadClasses);
1038
+ const streetFilter = classFilter2(streetRoadClasses2);
1039
+ const serviceFilter = classFilter2(serviceRoadClasses2);
1040
+ const roadFilter = classFilter2(roadClasses);
1041
+ const transportFilter = classFilter2(transportClasses);
859
1042
  const layers = [];
860
1043
  if (options.outline !== "none") {
861
1044
  layers.push({
@@ -936,7 +1119,7 @@ function roadLayers(source, sourceLayer, colors, options) {
936
1119
  source,
937
1120
  "source-layer": sourceLayer,
938
1121
  minzoom: 5,
939
- filter: ["all", nonTunnelRoadFilter, classFilter(["ferry"])],
1122
+ filter: ["all", nonTunnelRoadFilter, classFilter2(["ferry"])],
940
1123
  paint: {
941
1124
  "line-color": colors.roads.ferry,
942
1125
  "line-dasharray": [1.2, 1.1],
@@ -959,7 +1142,7 @@ function roadLayers(source, sourceLayer, colors, options) {
959
1142
  source,
960
1143
  "source-layer": sourceLayer,
961
1144
  minzoom: 10,
962
- filter: ["all", nonTunnelRoadFilter, classFilter(["path"])],
1145
+ filter: ["all", nonTunnelRoadFilter, classFilter2(["path"])],
963
1146
  paint: {
964
1147
  "line-color": colors.roads.path,
965
1148
  "line-dasharray": [0.7, 0.7],
@@ -982,7 +1165,7 @@ function roadLayers(source, sourceLayer, colors, options) {
982
1165
  source,
983
1166
  "source-layer": sourceLayer,
984
1167
  minzoom: 7,
985
- filter: ["all", nonTunnelRoadFilter, classFilter(["rail", "transit"])],
1168
+ filter: ["all", nonTunnelRoadFilter, classFilter2(["rail", "transit"])],
986
1169
  paint: {
987
1170
  "line-color": colors.roads.rail,
988
1171
  "line-opacity": metrics.minorOpacity * 0.65,
@@ -1125,17 +1308,17 @@ function legacyModeFromResolvedRoads(options) {
1125
1308
  if (options.hierarchy === "strong" || options.detail === "all") return "detailed";
1126
1309
  return "standard";
1127
1310
  }
1128
- function classFilter(classes) {
1311
+ function classFilter2(classes) {
1129
1312
  return ["match", ["get", "class"], classes, true, false];
1130
1313
  }
1131
1314
  function roadOpacityExpression(majorOpacity, minorOpacity) {
1132
1315
  return [
1133
1316
  "case",
1134
- classFilter(majorRoadClasses),
1317
+ classFilter2(majorRoadClasses2),
1135
1318
  majorOpacity,
1136
- classFilter(streetRoadClasses),
1319
+ classFilter2(streetRoadClasses2),
1137
1320
  ["step", ["zoom"], 0, 12, minorOpacity],
1138
- classFilter(serviceRoadClasses),
1321
+ classFilter2(serviceRoadClasses2),
1139
1322
  ["step", ["zoom"], 0, 14, minorOpacity],
1140
1323
  minorOpacity
1141
1324
  ];
@@ -1143,7 +1326,7 @@ function roadOpacityExpression(majorOpacity, minorOpacity) {
1143
1326
  function roadWidthExpression(stops, metrics) {
1144
1327
  return [
1145
1328
  "case",
1146
- classFilter(majorRoadClasses),
1329
+ classFilter2(majorRoadClasses2),
1147
1330
  zoomWidth(stops, metrics.weightScale * metrics.majorWidthScale),
1148
1331
  zoomWidth(stops, metrics.weightScale * metrics.minorWidthScale)
1149
1332
  ];
@@ -1204,7 +1387,7 @@ function openMapTilesLayers(source, sourceLayers, colors, options) {
1204
1387
  ...buildingLayers(source, sourceLayers.building, colors, options.density, options.buildings),
1205
1388
  ...roadLayers(source, sourceLayers.road, colors, options.roads),
1206
1389
  ...boundaryLayers(source, sourceLayers.boundary, colors),
1207
- ...labelLayers(source, sourceLayers.place, colors, options.labels, options.typography),
1390
+ ...labelLayers(source, sourceLayers, colors, options.labels, options.roads, options.typography),
1208
1391
  ...poiLayers(
1209
1392
  source,
1210
1393
  sourceLayers.poi,
@@ -1568,7 +1751,10 @@ var sourceLayersSchema = z.object({
1568
1751
  landuse: z.string().optional(),
1569
1752
  park: z.string().optional(),
1570
1753
  water: z.string().optional(),
1754
+ waterName: z.string().optional(),
1755
+ waterway: z.string().optional(),
1571
1756
  road: z.string().optional(),
1757
+ roadName: z.string().optional(),
1572
1758
  building: z.string().optional(),
1573
1759
  boundary: z.string().optional(),
1574
1760
  place: z.string().optional(),
@@ -1596,14 +1782,13 @@ var roadsModuleSchema = z.object({
1596
1782
  outline: z.enum(["none", "subtle", "strong"]).optional(),
1597
1783
  weight: z.enum(["thin", "regular", "bold"]).optional()
1598
1784
  }).strict();
1599
- var labelDensitySchema = z.enum(["none", "minimal", "balanced", "detailed"]);
1785
+ var labelDetailSchema = z.enum(["none", "major", "all"]);
1600
1786
  var labelsModuleSchema = z.object({
1601
1787
  type: z.literal("labels"),
1602
1788
  language: z.string().trim().min(1).optional(),
1603
- places: labelDensitySchema.optional(),
1604
- preset: z.enum(["none", "essential", "balanced", "full"]).optional(),
1605
- roads: labelDensitySchema.optional(),
1606
- water: labelDensitySchema.optional()
1789
+ places: labelDetailSchema.optional(),
1790
+ roads: labelDetailSchema.optional(),
1791
+ water: labelDetailSchema.optional()
1607
1792
  }).strict();
1608
1793
  var poiModuleSchema = z.object({
1609
1794
  type: z.literal("poi"),
@@ -1956,7 +2141,7 @@ function applyOsmBrightControls(layers, options) {
1956
2141
  );
1957
2142
  }
1958
2143
  if (isLabelLayer(id, sourceLayer)) {
1959
- return applyLabelLayerControls(layer, options.labels);
2144
+ return applyLabelLayerControls(layer, options.labels, options.roads);
1960
2145
  }
1961
2146
  return layer;
1962
2147
  });
@@ -2043,12 +2228,12 @@ function scaleStyleValue(value, scale, fallback) {
2043
2228
  }
2044
2229
  return fallback * scale;
2045
2230
  }
2046
- function applyLabelLayerControls(layer, labels2) {
2231
+ function applyLabelLayerControls(layer, labels2, roads2) {
2047
2232
  const id = stringValue(layer.id);
2048
2233
  const sourceLayer = stringValue(layer["source-layer"]);
2049
2234
  const group = labelGroup(id, sourceLayer);
2050
- const density = labelGroupDensity(labels2, group);
2051
- if (labels2.mode === "none" || density === "none") {
2235
+ const detail = labelGroupDetail(labels2, group);
2236
+ if (detail === "none" || detail === "major" && isMinorLabelLayer(id, group)) {
2052
2237
  return setLayerVisibility(layer, "none");
2053
2238
  }
2054
2239
  const nextLayer = setLayerVisibility(layer, "visible");
@@ -2056,13 +2241,20 @@ function applyLabelLayerControls(layer, labels2) {
2056
2241
  if ("text-field" in layout && !isHighwayShieldLayer(id)) {
2057
2242
  layout["text-field"] = labelTextField(labels2.language);
2058
2243
  }
2059
- if (density === "minimal") {
2060
- nextLayer.minzoom = Math.max(numberValue(nextLayer.minzoom) ?? 0, minimalMinZoom(group));
2244
+ if (group === "roads" && roads2) {
2245
+ const allowedClasses = visibleRoadLabelClasses(detail, roads2).filter(
2246
+ (roadClass) => roadLabelLayerClasses(id).includes(roadClass)
2247
+ );
2248
+ if (allowedClasses.length === 0) {
2249
+ return setLayerVisibility(layer, "none");
2250
+ }
2251
+ nextLayer.filter = combineFilters(nextLayer.filter, ["in", "class", ...allowedClasses]);
2061
2252
  }
2062
- if (density === "detailed") {
2063
- const currentMinZoom = numberValue(nextLayer.minzoom);
2064
- if (currentMinZoom !== void 0) {
2065
- nextLayer.minzoom = Math.max(0, currentMinZoom - 1);
2253
+ if (group === "water" && detail === "major") {
2254
+ if (sourceLayer === "waterway") {
2255
+ nextLayer.filter = combineFilters(nextLayer.filter, ["==", "class", "river"]);
2256
+ } else if (id === "water-name-other") {
2257
+ nextLayer.filter = combineFilters(nextLayer.filter, ["in", "class", "sea", "lake"]);
2066
2258
  }
2067
2259
  }
2068
2260
  nextLayer.layout = layout;
@@ -2092,7 +2284,7 @@ function applyPoiLayerControls(layer, poi2, customIconSpriteId2, customIconMappi
2092
2284
  nextLayer.layout = layout;
2093
2285
  return nextLayer;
2094
2286
  }
2095
- function labelGroupDensity(labels2, group) {
2287
+ function labelGroupDetail(labels2, group) {
2096
2288
  if (group === "roads") return labels2.roads;
2097
2289
  if (group === "water") return labels2.water;
2098
2290
  return labels2.places;
@@ -2106,10 +2298,15 @@ function labelGroup(id, sourceLayer) {
2106
2298
  }
2107
2299
  return "places";
2108
2300
  }
2109
- function minimalMinZoom(group) {
2110
- if (group === "roads") return 13;
2111
- if (group === "water") return 5;
2112
- return 4;
2301
+ function isMinorLabelLayer(id, group) {
2302
+ if (group === "places") return id === "place-other" || id === "place-village";
2303
+ if (group === "roads") return id.includes("path") || id.includes("minor");
2304
+ return false;
2305
+ }
2306
+ function roadLabelLayerClasses(id) {
2307
+ if (id.includes("path")) return ["path"];
2308
+ if (id.includes("minor")) return ["minor", "service", "track"];
2309
+ return ["motorway", "trunk", "primary", "secondary", "tertiary"];
2113
2310
  }
2114
2311
  function isLabelLayer(id, sourceLayer) {
2115
2312
  return sourceLayer === "place" || sourceLayer === "transportation_name" || sourceLayer === "water_name" || sourceLayer === "waterway" || id.includes("highway-name") || id.includes("highway-shield") || id.includes("water-name");
@@ -5041,7 +5238,10 @@ var defaultSourceLayers = {
5041
5238
  landuse: "landuse",
5042
5239
  park: "park",
5043
5240
  water: "water",
5241
+ waterName: "water_name",
5242
+ waterway: "waterway",
5044
5243
  road: "transportation",
5244
+ roadName: "transportation_name",
5045
5245
  building: "building",
5046
5246
  boundary: "boundary",
5047
5247
  place: "place",
@@ -5105,8 +5305,9 @@ function createStyle(input = {}, options = {}) {
5105
5305
  labelsModule,
5106
5306
  theme.preset.labels ?? defaultConfig.labels
5107
5307
  );
5308
+ const { mode: resolvedLabelsMode, ...resolvedLabelsModule } = resolvedLabels;
5108
5309
  const resolvedPoi = resolvePoi(config.poi, poiModule, theme.preset.poi ?? defaultConfig.poi);
5109
- const labels2 = resolvedLabels.mode;
5310
+ const labels2 = resolvedLabelsMode;
5110
5311
  const poi2 = resolvedPoi.mode;
5111
5312
  const buildings = config.buildings ?? "flat";
5112
5313
  const colors = resolveColors(config.colors, theme.colors, {}, theme.modules);
@@ -5139,7 +5340,7 @@ function createStyle(input = {}, options = {}) {
5139
5340
  "tileflow:roads": resolvedRoadMode,
5140
5341
  "tileflow:roadsModule": roadModule ? resolvedRoadModule : void 0,
5141
5342
  "tileflow:labels": labels2,
5142
- "tileflow:labelsModule": labelsModule,
5343
+ "tileflow:labelsModule": labelsModule ? resolvedLabelsModule : void 0,
5143
5344
  "tileflow:poi": poi2,
5144
5345
  "tileflow:poiModule": poiModule,
5145
5346
  "tileflow:icons": iconSet ? {
@@ -5177,7 +5378,6 @@ function createStyle(input = {}, options = {}) {
5177
5378
  theme,
5178
5379
  tilesUrl,
5179
5380
  typography,
5180
- labels: labels2,
5181
5381
  labelsModule: resolvedLabels,
5182
5382
  poi: poi2,
5183
5383
  poiModule: resolvedPoi,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tileflow/core",
3
- "version": "0.1.0-alpha.12",
3
+ "version": "0.1.0-alpha.13",
4
4
  "description": "Typed Tileflow config and MapLibre style compiler.",
5
5
  "type": "module",
6
6
  "sideEffects": false,