@mapbox/mapbox-gl-style-spec 14.29.0 → 14.30.0-alpha.742b92e7a62
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/dist/index.cjs +104 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +74 -2
- package/dist/index.es.js +104 -10
- package/dist/index.es.js.map +1 -1
- package/package.json +1 -1
- package/reference/v8.json +62 -2
- package/types.ts +30 -1
- package/util/geometry_util.ts +24 -3
- package/validate/validate_layer.ts +1 -1
- package/validate/validate_lights.ts +3 -3
- package/validate_mapbox_api_supported.ts +15 -2
package/package.json
CHANGED
package/reference/v8.json
CHANGED
|
@@ -1647,6 +1647,14 @@
|
|
|
1647
1647
|
}
|
|
1648
1648
|
}
|
|
1649
1649
|
},
|
|
1650
|
+
"placement-group": {
|
|
1651
|
+
"doc": "Marks a placement priority group relative to other layers, going from lower to higher priority. Symbols from groups with higher priorities will be placed first",
|
|
1652
|
+
"sdk-support": {
|
|
1653
|
+
"basic functionality": {}
|
|
1654
|
+
},
|
|
1655
|
+
"private": true,
|
|
1656
|
+
"experimental": true
|
|
1657
|
+
},
|
|
1650
1658
|
"clip": {
|
|
1651
1659
|
"doc": "Layer that removes 3D content from map.",
|
|
1652
1660
|
"sdk-support": {
|
|
@@ -1667,7 +1675,7 @@
|
|
|
1667
1675
|
},
|
|
1668
1676
|
"source": {
|
|
1669
1677
|
"type": "string",
|
|
1670
|
-
"doc": "Name of a source description to be used for this layer. Required for all layer types except `background` and `
|
|
1678
|
+
"doc": "Name of a source description to be used for this layer. Required for all layer types except `background`, `slot`, and `placement-group`."
|
|
1671
1679
|
},
|
|
1672
1680
|
"source-layer": {
|
|
1673
1681
|
"type": "string",
|
|
@@ -10316,6 +10324,56 @@
|
|
|
10316
10324
|
]
|
|
10317
10325
|
},
|
|
10318
10326
|
"property-type": "data-driven"
|
|
10327
|
+
},
|
|
10328
|
+
"placement-priority": {
|
|
10329
|
+
"type": "number",
|
|
10330
|
+
"doc": "In-group placement priority. Higher values are placed first within the symbol's placement group.",
|
|
10331
|
+
"default": 0,
|
|
10332
|
+
"minimum": 0,
|
|
10333
|
+
"transition": false,
|
|
10334
|
+
"appearance": true,
|
|
10335
|
+
"expression": {
|
|
10336
|
+
"interpolated": true,
|
|
10337
|
+
"parameters": [
|
|
10338
|
+
"zoom",
|
|
10339
|
+
"pitch",
|
|
10340
|
+
"feature",
|
|
10341
|
+
"feature-state",
|
|
10342
|
+
"measure-light",
|
|
10343
|
+
"distance-from-center"
|
|
10344
|
+
]
|
|
10345
|
+
},
|
|
10346
|
+
"property-type": "data-driven",
|
|
10347
|
+
"sdk-support": {
|
|
10348
|
+
"basic functionality": {},
|
|
10349
|
+
"data-driven styling": {}
|
|
10350
|
+
},
|
|
10351
|
+
"private": true,
|
|
10352
|
+
"experimental": true
|
|
10353
|
+
},
|
|
10354
|
+
"placement-group": {
|
|
10355
|
+
"type": "string",
|
|
10356
|
+
"doc": "Assigns this symbol layer to the specified placement-group layer, placing its symbols as if they were drawn within that group. When unset, the layer's symbols use an implicitly created placement group located at the same position as the symbol layer.",
|
|
10357
|
+
"transition": false,
|
|
10358
|
+
"appearance": true,
|
|
10359
|
+
"expression": {
|
|
10360
|
+
"interpolated": false,
|
|
10361
|
+
"parameters": [
|
|
10362
|
+
"zoom",
|
|
10363
|
+
"pitch",
|
|
10364
|
+
"feature",
|
|
10365
|
+
"feature-state",
|
|
10366
|
+
"measure-light",
|
|
10367
|
+
"distance-from-center"
|
|
10368
|
+
]
|
|
10369
|
+
},
|
|
10370
|
+
"property-type": "data-driven",
|
|
10371
|
+
"sdk-support": {
|
|
10372
|
+
"basic functionality": {},
|
|
10373
|
+
"data-driven styling": {}
|
|
10374
|
+
},
|
|
10375
|
+
"private": true,
|
|
10376
|
+
"experimental": true
|
|
10319
10377
|
}
|
|
10320
10378
|
},
|
|
10321
10379
|
"paint_raster": {
|
|
@@ -10450,7 +10508,9 @@
|
|
|
10450
10508
|
"experimental": true,
|
|
10451
10509
|
"sdk-support": {
|
|
10452
10510
|
"basic functionality": {
|
|
10453
|
-
"js": "3.29.0"
|
|
10511
|
+
"js": "3.29.0",
|
|
10512
|
+
"android": "11.30.0",
|
|
10513
|
+
"ios": "11.30.0"
|
|
10454
10514
|
}
|
|
10455
10515
|
}
|
|
10456
10516
|
},
|
package/types.ts
CHANGED
|
@@ -904,7 +904,15 @@ export type SymbolLayerSpecification = {
|
|
|
904
904
|
"icon-color-brightness-min"?: number | ExpressionSpecification,
|
|
905
905
|
"icon-color-brightness-max"?: number | ExpressionSpecification,
|
|
906
906
|
"symbol-z-offset"?: DataDrivenPropertyValueSpecification<number>,
|
|
907
|
-
"symbol-z-offset-transition"?: TransitionSpecification
|
|
907
|
+
"symbol-z-offset-transition"?: TransitionSpecification,
|
|
908
|
+
/**
|
|
909
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
910
|
+
*/
|
|
911
|
+
"placement-priority"?: DataDrivenPropertyValueSpecification<number>,
|
|
912
|
+
/**
|
|
913
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
914
|
+
*/
|
|
915
|
+
"placement-group"?: DataDrivenPropertyValueSpecification<string>
|
|
908
916
|
},
|
|
909
917
|
"appearances"?: Array<AppearanceSpecification>
|
|
910
918
|
};
|
|
@@ -1524,6 +1532,21 @@ export type SlotLayerSpecification = {
|
|
|
1524
1532
|
"paint"?: never
|
|
1525
1533
|
};
|
|
1526
1534
|
|
|
1535
|
+
export type PlacementGroupLayerSpecification = {
|
|
1536
|
+
"id": string,
|
|
1537
|
+
"type": "placement-group",
|
|
1538
|
+
"metadata"?: unknown,
|
|
1539
|
+
"source"?: never,
|
|
1540
|
+
"source-layer"?: never,
|
|
1541
|
+
"slot"?: string,
|
|
1542
|
+
"minzoom"?: never,
|
|
1543
|
+
"maxzoom"?: never,
|
|
1544
|
+
"filter"?: never,
|
|
1545
|
+
"appearances"?: Array<AppearanceSpecification>,
|
|
1546
|
+
"layout"?: never,
|
|
1547
|
+
"paint"?: never
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1527
1550
|
export type ClipLayerSpecification = {
|
|
1528
1551
|
"id": string,
|
|
1529
1552
|
"type": "clip",
|
|
@@ -1563,6 +1586,7 @@ export type LayerSpecification =
|
|
|
1563
1586
|
| BackgroundLayerSpecification
|
|
1564
1587
|
| SkyLayerSpecification
|
|
1565
1588
|
| SlotLayerSpecification
|
|
1589
|
+
| PlacementGroupLayerSpecification
|
|
1566
1590
|
| ClipLayerSpecification;
|
|
1567
1591
|
|
|
1568
1592
|
export type LayoutSpecification = UnionToIntersection<NonNullable<LayerSpecification['layout']>>;
|
|
@@ -1668,6 +1692,11 @@ export type SkyLayer = SkyLayerSpecification;
|
|
|
1668
1692
|
*/
|
|
1669
1693
|
export type SlotLayer = SlotLayerSpecification;
|
|
1670
1694
|
|
|
1695
|
+
/**
|
|
1696
|
+
* @deprecated Use `PlacementGroupLayerSpecification` instead.
|
|
1697
|
+
*/
|
|
1698
|
+
export type PlacementGroupLayer = PlacementGroupLayerSpecification;
|
|
1699
|
+
|
|
1671
1700
|
/**
|
|
1672
1701
|
* @deprecated Use `ClipLayerSpecification` instead.
|
|
1673
1702
|
*/
|
package/util/geometry_util.ts
CHANGED
|
@@ -25,19 +25,40 @@ function compareAreas(a: Ring, b: Ring): number {
|
|
|
25
25
|
return (b.area!) - (a.area!);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
// Whether every point of the ring lies on a single line, i.e. the ring has no real area
|
|
29
|
+
// regardless of winding
|
|
30
|
+
function isCollinear(ring: Ring): boolean {
|
|
31
|
+
const len = ring.length;
|
|
32
|
+
if (len < 3) return true;
|
|
33
|
+
|
|
34
|
+
const p0 = ring[0]!;
|
|
35
|
+
let dx = 0, dy = 0, i = 1;
|
|
36
|
+
for (; i < len; i++) {
|
|
37
|
+
dx = ring[i]!.x - p0.x;
|
|
38
|
+
dy = ring[i]!.y - p0.y;
|
|
39
|
+
if (dx !== 0 || dy !== 0) break;
|
|
40
|
+
}
|
|
41
|
+
if (i === len) return true; // every point coincides with p0
|
|
42
|
+
|
|
43
|
+
for (; i < len; i++) {
|
|
44
|
+
const px = ring[i]!.x - p0.x;
|
|
45
|
+
const py = ring[i]!.y - p0.y;
|
|
46
|
+
if (dx * py - dy * px !== 0) return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
28
51
|
// classifies an array of rings into polygons with outer rings and holes
|
|
29
52
|
export function classifyRings(rings: Array<Ring>, maxRings: number): Array<Array<Ring>> {
|
|
30
53
|
const len = rings.length;
|
|
31
54
|
|
|
32
|
-
if (len <= 1) return [rings];
|
|
33
|
-
|
|
34
55
|
const polygons: Array<Array<Ring>> = [];
|
|
35
56
|
let polygon: Array<Ring> | undefined,
|
|
36
57
|
ccw: boolean | undefined;
|
|
37
58
|
|
|
38
59
|
for (let i = 0; i < len; i++) {
|
|
39
60
|
const area = calculateSignedArea(rings[i]!);
|
|
40
|
-
if (area === 0) continue;
|
|
61
|
+
if (area === 0 && isCollinear(rings[i]!)) continue;
|
|
41
62
|
|
|
42
63
|
(rings[i]!).area = Math.abs(area);
|
|
43
64
|
|
|
@@ -72,7 +72,7 @@ export default function validateLayer(options: LayerValidatorOptions): Validatio
|
|
|
72
72
|
} else {
|
|
73
73
|
type = unbundle(parent.type) as string;
|
|
74
74
|
}
|
|
75
|
-
} else if (!(type === 'background' || type === 'sky' || type === 'slot')) {
|
|
75
|
+
} else if (!(type === 'background' || type === 'sky' || type === 'slot' || type === 'placement-group')) {
|
|
76
76
|
if (!layer.source) {
|
|
77
77
|
errors.push(new ValidationError(key, layer, 'missing required property "source"'));
|
|
78
78
|
} else if (!isString(layer.source)) {
|
|
@@ -79,7 +79,7 @@ export default function validateLights(options: LightsValidatorOptions): Validat
|
|
|
79
79
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
80
80
|
if (useThemeMatch && lightPropertySpec[useThemeMatch[1]!]) {
|
|
81
81
|
errors = errors.concat(validate({
|
|
82
|
-
key,
|
|
82
|
+
key: propertyKey,
|
|
83
83
|
value: properties[propertyKey],
|
|
84
84
|
valueSpec: {type: 'string'},
|
|
85
85
|
style,
|
|
@@ -88,8 +88,8 @@ export default function validateLights(options: LightsValidatorOptions): Validat
|
|
|
88
88
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
89
89
|
} else if (transitionMatch && lightPropertySpec[transitionMatch[1]!] && lightPropertySpec[transitionMatch[1]!].transition) {
|
|
90
90
|
errors = errors.concat(validate({
|
|
91
|
-
key,
|
|
92
|
-
value:
|
|
91
|
+
key: propertyKey,
|
|
92
|
+
value: properties[propertyKey],
|
|
93
93
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
94
94
|
valueSpec: styleSpec.transition,
|
|
95
95
|
style,
|
|
@@ -24,7 +24,8 @@ type MapboxStyleSpecification = StyleSpecification & {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const SUPPORTED_SPEC_VERSION = 8;
|
|
27
|
-
const MAX_SOURCES_IN_STYLE =
|
|
27
|
+
const MAX_SOURCES_IN_STYLE = 64;
|
|
28
|
+
const MAX_TILESETS_IN_SOURCE = 15;
|
|
28
29
|
|
|
29
30
|
function isValid(value: string | null | undefined, regex: RegExp): boolean {
|
|
30
31
|
if (!value || !isString(value)) return true;
|
|
@@ -78,11 +79,22 @@ function getSourceErrors(source: SourceSpecification, i: number): Array<Validati
|
|
|
78
79
|
function getMaxSourcesErrors(sourcesCount: number): Array<ValidationError> {
|
|
79
80
|
const errors: ValidationError[] = [];
|
|
80
81
|
if (sourcesCount > MAX_SOURCES_IN_STYLE) {
|
|
81
|
-
errors.push(new ValidationError('sources', null, `Styles must contain ${MAX_SOURCES_IN_STYLE} or fewer
|
|
82
|
+
errors.push(new ValidationError('sources', null, `Styles must contain ${MAX_SOURCES_IN_STYLE} or fewer tilesets`));
|
|
82
83
|
}
|
|
83
84
|
return errors;
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
function getMaxTilesetsErrors(sources: SourcesSpecification): Array<ValidationError> {
|
|
88
|
+
const errors: ValidationError[] = [];
|
|
89
|
+
Object.keys(sources).forEach((s: string, i: number) => {
|
|
90
|
+
const source = sources[s]!;
|
|
91
|
+
if (getSourceCount(source) > MAX_TILESETS_IN_SOURCE) {
|
|
92
|
+
errors.push(new ValidationError(`sources[${i}].url`, (source as {url?: string}).url, `Sources must contain ${MAX_TILESETS_IN_SOURCE} or fewer tilesets`));
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return errors;
|
|
96
|
+
}
|
|
97
|
+
|
|
86
98
|
function getSourcesErrors(sources: SourcesSpecification): {
|
|
87
99
|
errors: Array<ValidationError>;
|
|
88
100
|
sourcesCount: number;
|
|
@@ -225,6 +237,7 @@ export default function validateMapboxApiSupported(style: MapboxStyleSpecificati
|
|
|
225
237
|
const sourcesErrors = getSourcesErrors(s.sources);
|
|
226
238
|
sourcesCount += sourcesErrors.sourcesCount;
|
|
227
239
|
errors = errors.concat(sourcesErrors.errors);
|
|
240
|
+
errors = errors.concat(getMaxTilesetsErrors(s.sources));
|
|
228
241
|
}
|
|
229
242
|
|
|
230
243
|
if (s.imports) {
|