@mapbox/mapbox-gl-style-spec 14.29.0 → 14.30.0-rc.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapbox/mapbox-gl-style-spec",
3
- "version": "14.29.0",
3
+ "version": "14.30.0-rc.1",
4
4
  "description": "a specification for mapbox gl styles",
5
5
  "author": "Mapbox",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
package/reference/v8.json CHANGED
@@ -10450,7 +10450,9 @@
10450
10450
  "experimental": true,
10451
10451
  "sdk-support": {
10452
10452
  "basic functionality": {
10453
- "js": "3.29.0"
10453
+ "js": "3.29.0",
10454
+ "android": "11.30.0",
10455
+ "ios": "11.30.0"
10454
10456
  }
10455
10457
  }
10456
10458
  },
@@ -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
 
@@ -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: light[key],
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 = 15;
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 sources`));
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) {