@maplibre/maplibre-react-native 10.0.0-alpha.21 → 10.0.0-alpha.23

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.
Files changed (49) hide show
  1. package/.eslintrc.js +5 -0
  2. package/.git-blame-ignore-revs +3 -0
  3. package/CHANGELOG.md +21 -0
  4. package/CONTRIBUTING.md +20 -14
  5. package/README.md +12 -13
  6. package/android/install.md +3 -2
  7. package/app.plugin.js +1 -1
  8. package/babel.config.js +6 -3
  9. package/docs/Camera.md +1 -1
  10. package/docs/GettingStarted.md +3 -4
  11. package/docs/MapView.md +1 -1
  12. package/docs/ShapeSource.md +3 -3
  13. package/docs/docs.json +15 -15
  14. package/ios/RCTMLN.xcodeproj/project.pbxproj +1 -775
  15. package/ios/install.md +1 -1
  16. package/javascript/components/Camera.tsx +8 -8
  17. package/javascript/components/MapView.tsx +4 -6
  18. package/javascript/components/MarkerView.tsx +2 -2
  19. package/javascript/components/PointAnnotation.tsx +2 -2
  20. package/javascript/components/ShapeSource.tsx +29 -28
  21. package/javascript/components/Style.tsx +1 -1
  22. package/javascript/modules/offline/OfflineCreatePackOptions.ts +2 -9
  23. package/javascript/modules/snapshot/SnapshotOptions.ts +4 -5
  24. package/javascript/utils/StyleValue.ts +3 -1
  25. package/javascript/utils/makeNativeBounds.ts +5 -0
  26. package/jest-setup.ts +113 -0
  27. package/jest.config.js +8 -0
  28. package/maplibre-react-native.podspec +7 -7
  29. package/package.json +30 -73
  30. package/plugin/build/withMapLibre.js +16 -1
  31. package/plugin/install.md +1 -8
  32. package/react-native.config.js +1 -1
  33. package/scripts/.eslintrc.js +3 -0
  34. package/scripts/{autogenerate.js → generate-docs.js} +144 -137
  35. package/scripts/templates/MaplibreStyles.ts.ejs +5 -5
  36. package/scripts/templates/RCTMLNStyle.h.ejs +2 -2
  37. package/scripts/templates/RCTMLNStyle.m.ejs +6 -6
  38. package/scripts/templates/RCTMLNStyleFactory.java.ejs +8 -8
  39. package/scripts/{autogenHelpers → utils}/DocJSONBuilder.js +70 -70
  40. package/scripts/{autogenHelpers → utils}/JSDocNodeTree.js +33 -30
  41. package/scripts/utils/MarkdownBuilder.js +37 -0
  42. package/scripts/utils/template-globals.js +528 -0
  43. package/style-spec/v8.json +32 -1
  44. package/tsconfig.json +2 -2
  45. package/assets/mapbox_logo.png +0 -0
  46. package/javascript/utils/geoUtils.ts +0 -79
  47. package/scripts/autogenHelpers/MarkdownBuilder.js +0 -29
  48. package/scripts/autogenHelpers/globals.js +0 -508
  49. package/setup-jest.js +0 -108
@@ -0,0 +1,528 @@
1
+ const iosPropNameOverrides = {};
2
+
3
+ const iosSpecOverrides = {
4
+ "icon-allow-overlap": "icon-allows-overlap",
5
+ "icon-image": "icon-image-name",
6
+ "icon-ignore-placement": "icon-ignores-placement",
7
+ "icon-keep-upright": "keeps-icon-upright",
8
+ "icon-rotate": "icon-rotation",
9
+ "icon-size": "icon-scale",
10
+ "symbol-avoid-edges": "symbol-avoids-edges",
11
+ "text-allow-overlap": "text-allows-overlap",
12
+ "text-field": "text",
13
+ "text-font": "text-font-names",
14
+ "text-ignore-placement": "text-ignores-placement",
15
+ "text-justify": "text-justification",
16
+ "text-keep-upright": "keeps-text-upright",
17
+ "text-max-angle": "maximum-text-angle",
18
+ "text-max-width": "maximum-text-width",
19
+ "text-rotate": "text-rotation",
20
+ "text-size": "text-font-size",
21
+ "circle-pitch-scale": "circle-scale-alignment",
22
+ "circle-translate": "circle-translation",
23
+ "circle-translate-anchor": "circle-translation-anchor",
24
+ "fill-antialias": "fill-antialiased",
25
+ "fill-translate": "fill-translation",
26
+ "fill-translate-anchor": "fill-translation-anchor",
27
+ "fill-extrusion-translate": "fill-extrusion-translation",
28
+ "fill-extrusion-translate-anchor": "fill-extrusion-translation-anchor",
29
+ "raster-brightness-min": "minimum-raster-brightness",
30
+ "raster-brightness-max": "maximum-raster-brightness",
31
+ "raster-hue-rotate": "raster-hue-rotation",
32
+ "line-dasharray": "line-dash-pattern",
33
+ "line-translate": "line-translation",
34
+ "line-translate-anchor": "line-translation-anchor",
35
+ "icon-translate": "icon-translation",
36
+ "icon-translate-anchor": "icon-translation-anchor",
37
+ "text-translate": "text-translation",
38
+ "text-translate-anchor": "text-translation-anchor",
39
+ "raster-resampling": "raster-resampling-mode",
40
+ "text-writing-mode": "text-writing-modes",
41
+ };
42
+
43
+ function exists(value) {
44
+ return typeof value !== "undefined" && value !== null;
45
+ }
46
+ global.exists = exists;
47
+
48
+ global.getValue = function (value, defaultValue) {
49
+ if (!exists(value) || value === "") {
50
+ return defaultValue;
51
+ }
52
+ return value;
53
+ };
54
+
55
+ function camelCase(str, delimiter = "-") {
56
+ const parts = str.split(delimiter);
57
+ return parts
58
+ .map((part, index) => {
59
+ if (index === 0) {
60
+ return part;
61
+ }
62
+ return part.charAt(0).toUpperCase() + part.substring(1);
63
+ })
64
+ .join("");
65
+ }
66
+ global.camelCase = camelCase;
67
+
68
+ function pascalCase(str, delimiter = "-") {
69
+ const parts = str.split(delimiter);
70
+ return parts
71
+ .map((part) => {
72
+ return part.charAt(0).toUpperCase() + part.substring(1);
73
+ })
74
+ .join("");
75
+ }
76
+ global.pascalCase = pascalCase;
77
+
78
+ global.setLayerMethodName = function (layer, platform) {
79
+ if (platform === "ios") {
80
+ return `${camelCase(layer.name)}Layer`;
81
+ }
82
+ return `set${pascalCase(layer.name)}LayerStyle`;
83
+ };
84
+
85
+ global.getLayerType = function (layer, platform) {
86
+ const isIOS = platform === "ios";
87
+
88
+ switch (layer.name) {
89
+ case "fill":
90
+ return isIOS ? "MLNFillStyleLayer" : "FillLayer";
91
+ case "fill-extrusion":
92
+ return isIOS ? "MLNFillExtrusionStyleLayer" : "FillExtrusionLayer";
93
+ case "line":
94
+ return isIOS ? "MLNLineStyleLayer" : "LineLayer";
95
+ case "symbol":
96
+ return isIOS ? "MLNSymbolStyleLayer" : "SymbolLayer";
97
+ case "circle":
98
+ return isIOS ? "MLNCircleStyleLayer" : "CircleLayer";
99
+ case "background":
100
+ return isIOS ? "MLNBackgroundStyleLayer" : "BackgroundLayer";
101
+ case "raster":
102
+ return isIOS ? "MLNRasterStyleLayer" : "RasterLayer";
103
+ case "heatmap":
104
+ return isIOS ? "MLNHeatmapStyleLayer" : "HeatmapLayer";
105
+ case "hillshade":
106
+ return isIOS ? "MLNHillshadeStyleLayer" : "HillshadeLayer";
107
+ case "light":
108
+ return isIOS ? "MLNLight" : "Light";
109
+ default:
110
+ throw new Error(
111
+ `Is ${layer.name} a new layer? We should add support for it!`,
112
+ );
113
+ }
114
+ };
115
+
116
+ global.ifOrElseIf = function (index) {
117
+ if (index === 0) {
118
+ return "if";
119
+ }
120
+ return "} else if";
121
+ };
122
+
123
+ global.iosStringArrayLiteral = function (arr) {
124
+ return `@[@${arr.map((item) => `"${item}"`).join(", @")}]`;
125
+ };
126
+
127
+ function iosPropName(name) {
128
+ if (name.indexOf("visibility") !== -1) {
129
+ return "visible";
130
+ }
131
+ if (name === "fillExtrusionVerticalGradient") {
132
+ return "fillExtrusionHasVerticalGradient";
133
+ }
134
+ if (iosPropNameOverrides[name]) {
135
+ return iosPropNameOverrides[name];
136
+ }
137
+ return name;
138
+ }
139
+
140
+ global.iosPropName = iosPropName;
141
+
142
+ global.iosMapLibrePropName = function (name) {
143
+ const result = iosPropName(name);
144
+ if (result === "fillExtrusionVerticalGradient") {
145
+ return "fillExtrusionHasVerticalGradient";
146
+ }
147
+ return undefined;
148
+ };
149
+
150
+ global.iosPropMethodName = function (layer, name) {
151
+ if (name.indexOf("Visibility") !== -1) {
152
+ return pascalCase(layer.name) + "StyleLayer" + name;
153
+ }
154
+ return name;
155
+ };
156
+
157
+ function androidInputType(type, value) {
158
+ if (type === "array" && value) {
159
+ return `${androidInputType(value)}[]`;
160
+ }
161
+
162
+ switch (type) {
163
+ case "color":
164
+ return "Integer";
165
+ case "boolean":
166
+ return "Boolean";
167
+ case "number":
168
+ return "Float";
169
+ default:
170
+ return "String";
171
+ }
172
+ }
173
+
174
+ global.androidInputType = androidInputType;
175
+
176
+ function androidOutputType(type, value) {
177
+ if (type === "array" && value) {
178
+ return `${androidOutputType(value)}[]`;
179
+ }
180
+
181
+ switch (type) {
182
+ case "color":
183
+ return "String";
184
+ case "boolean":
185
+ return "Boolean";
186
+ case "number":
187
+ return "Float";
188
+ default:
189
+ return "String";
190
+ }
191
+ }
192
+
193
+ global.androidOutputType = androidOutputType;
194
+
195
+ global.androidGetConfigType = function (androidType, prop) {
196
+ switch (androidType) {
197
+ case "Integer":
198
+ return "styleValue.getInt(VALUE_KEY)";
199
+ case "Float":
200
+ return "styleValue.getFloat(VALUE_KEY)";
201
+ case "Boolean":
202
+ return "styleValue.getBoolean(VALUE_KEY)";
203
+ case "Float[]":
204
+ return "styleValue.getFloatArray(VALUE_KEY)";
205
+ case "String[]":
206
+ return "styleValue.getStringArray(VALUE_KEY)";
207
+ default:
208
+ if (prop && prop.image) {
209
+ return "styleValue.getImageURI()";
210
+ } else {
211
+ return "styleValue.getString(VALUE_KEY)";
212
+ }
213
+ }
214
+ };
215
+
216
+ global.jsStyleType = function (prop) {
217
+ if (prop.type === "color") {
218
+ return "StyleTypes.Color";
219
+ }
220
+
221
+ if (prop.type === "enum") {
222
+ return "StyleTypes.Enum";
223
+ }
224
+
225
+ if (prop.type === "string" && prop.image) {
226
+ return "StyleTypes.Image";
227
+ }
228
+
229
+ if (prop.type === "resolvedImage") {
230
+ return "StyleTypes.Image";
231
+ }
232
+
233
+ if (prop.name.indexOf("Translate") !== -1) {
234
+ return "StyleTypes.Translation";
235
+ }
236
+
237
+ return "StyleTypes.Constant";
238
+ };
239
+
240
+ global.jsDocPropRequires = function (prop) {
241
+ if (!prop.doc.requires) {
242
+ return;
243
+ }
244
+
245
+ let desc = "";
246
+ for (const item of prop.doc.requires) {
247
+ if (typeof item === "string") {
248
+ desc += item + ", ";
249
+ }
250
+ }
251
+
252
+ return desc;
253
+ };
254
+
255
+ global.getEnums = function (layers) {
256
+ const result = {};
257
+
258
+ layers.forEach((layer) => {
259
+ layer.properties.forEach((property) => {
260
+ if (
261
+ property.type === "enum" ||
262
+ (property.type === "array" && property.value === "enum")
263
+ ) {
264
+ result[property.name] = {
265
+ values: property.doc.values,
266
+ name: property.name,
267
+ };
268
+ }
269
+ });
270
+ });
271
+ return Object.values(result);
272
+ };
273
+
274
+ global.dtsInterfaceType = function (prop) {
275
+ const propTypes = [];
276
+
277
+ if (prop.name.indexOf("Translate") !== -1 && prop.type !== "enum") {
278
+ propTypes.push("Translation");
279
+ } else if (prop.type === "color") {
280
+ propTypes.push("string");
281
+ // propTypes.push('ConstantPropType');
282
+ } else if (prop.type === "array") {
283
+ switch (prop.value) {
284
+ case "number":
285
+ propTypes.push("number[]");
286
+ break;
287
+ case "boolean":
288
+ propTypes.push("boolean[]");
289
+ break;
290
+ case "string":
291
+ propTypes.push("string[]");
292
+ break;
293
+ case "enum":
294
+ propTypes.push(
295
+ `Enum<${pascalCase(prop.name)}Enum, ${pascalCase(
296
+ prop.name,
297
+ )}EnumValues>[]`,
298
+ );
299
+ break;
300
+ }
301
+ // propTypes.push('ConstantPropType');
302
+ } else if (prop.type === "number") {
303
+ propTypes.push("number");
304
+ } else if (prop.type === "enum") {
305
+ propTypes.push(
306
+ `Enum<${pascalCase(prop.name)}Enum, ${pascalCase(prop.name)}EnumValues>`,
307
+ );
308
+ } else if (prop.type === "boolean") {
309
+ propTypes.push("boolean");
310
+ } else if (prop.type === "resolvedImage") {
311
+ propTypes.push("ResolvedImageType");
312
+ } else if (prop.type === "formatted") {
313
+ propTypes.push("FormattedString");
314
+ } else if (prop.type === "string") {
315
+ propTypes.push("string");
316
+ } else {
317
+ console.error("Unexpected type:", prop.type);
318
+ throw new Error(`Unexpected type: ${prop.type} for ${prop.name}`);
319
+ }
320
+
321
+ /*
322
+ if (prop.allowedFunctionTypes && prop.allowedFunctionTypes.length > 0) {
323
+ propTypes.push('StyleFunctionProps');
324
+ }
325
+ */
326
+
327
+ if (propTypes.length > 1) {
328
+ return `${propTypes.map((p) => startAtSpace(4, p)).join(" | ")},
329
+ ${startAtSpace(2, "")}`;
330
+ } else {
331
+ if (prop.expressionSupported) {
332
+ let params = "";
333
+ if (prop.expression && prop.expression.parameters) {
334
+ params = `,[${prop.expression.parameters
335
+ .map((v) => `'${v}'`)
336
+ .join(",")}]`;
337
+ }
338
+ return `Value<${propTypes[0]}${params}>`;
339
+ } else {
340
+ return propTypes[0];
341
+ }
342
+ }
343
+ };
344
+
345
+ global.jsDocReactProp = function (prop) {
346
+ const propTypes = [];
347
+
348
+ if (prop.type === "color") {
349
+ propTypes.push("PropTypes.string");
350
+ } else if (prop.type === "array") {
351
+ switch (prop.value) {
352
+ case "number":
353
+ propTypes.push("PropTypes.arrayOf(PropTypes.number)");
354
+ break;
355
+ case "boolean":
356
+ propTypes.push("PropTypes.arrayOf(PropTypes.bool)");
357
+ break;
358
+ case "string":
359
+ propTypes.push("PropTypes.arrayOf(PropTypes.string)");
360
+ break;
361
+ default:
362
+ propTypes.push("PropTypes.array");
363
+ }
364
+ } else if (prop.type === "number") {
365
+ propTypes.push("PropTypes.number");
366
+ } else if (prop.type === "boolean") {
367
+ propTypes.push("PropTypes.bool");
368
+ } else if (prop.type === "enum") {
369
+ if (prop.doc.values) {
370
+ propTypes.push(
371
+ `PropTypes.oneOf([${Object.keys(prop.doc.values)
372
+ .map((v) => `'${v}'`)
373
+ .join(", ")}])`,
374
+ );
375
+ } else {
376
+ propTypes.push("PropTypes.any");
377
+ }
378
+ } else {
379
+ // images can be required which result in a number
380
+ if (prop.image) {
381
+ propTypes.push("PropTypes.number");
382
+ }
383
+ propTypes.push("PropTypes.string");
384
+ }
385
+
386
+ if (prop.expressionSupported && !propTypes.includes("PropTypes.array")) {
387
+ propTypes.push("PropTypes.array");
388
+ }
389
+
390
+ if (propTypes.length > 1) {
391
+ return `PropTypes.oneOfType([
392
+ ${propTypes.map((p) => startAtSpace(4, p)).join(",\n")},
393
+ ${startAtSpace(2, "])")}`;
394
+ } else {
395
+ return propTypes[0];
396
+ }
397
+ };
398
+
399
+ function startAtSpace(spaceCount, str) {
400
+ let value = "";
401
+
402
+ for (let i = 0; i < spaceCount; i++) {
403
+ value += " ";
404
+ }
405
+
406
+ return `${value}${str}`;
407
+ }
408
+
409
+ global.startAtSpace = startAtSpace;
410
+
411
+ function replaceNewLine(str) {
412
+ if (str === undefined) {
413
+ return undefined;
414
+ }
415
+ if (str === null) {
416
+ return null;
417
+ }
418
+ return str.replace(/\n/g, "<br/>");
419
+ }
420
+
421
+ global.replaceNewLine = replaceNewLine;
422
+
423
+ global.styleMarkdownTableRow = function (style) {
424
+ return `| \`${style.name}\` | \`${style.type}\` | \`${
425
+ style.requires.join(", ") || "none"
426
+ }\` | \`${style.disabledBy.join(", ") || "none"}\` | ${replaceNewLine(
427
+ style.description,
428
+ )} |`;
429
+ };
430
+
431
+ global.methodMarkdownTableRow = function (method) {
432
+ return method.params
433
+ .map((param) => {
434
+ return `| \`${param.name}\` | \`${
435
+ (param.type && param.type.name) || "n/a"
436
+ }\` | \`${param.optional ? "No" : "Yes"}\` | ${replaceNewLine(
437
+ param.description,
438
+ )} |`;
439
+ })
440
+ .join("\n");
441
+ };
442
+
443
+ function _propMarkdownTableRows(props, prefix = "") {
444
+ return props
445
+ .map((prop) => {
446
+ let { type } = prop;
447
+ if (typeof type === "object") {
448
+ type = type.name;
449
+ }
450
+ const defaultValue = prop.default || "";
451
+ const { description = "" } = prop;
452
+ let result = `| ${prefix}${
453
+ prop.name
454
+ } | \`${type}\` | \`${defaultValue}\` | \`${
455
+ prop.required
456
+ }\` | ${replaceNewLine(description)} |`;
457
+ if (type === "shape") {
458
+ result = `${result}\n${_propMarkdownTableRows(
459
+ prop.type.value,
460
+ `&nbsp;&nbsp;${prefix}`,
461
+ )}`;
462
+ }
463
+ return result;
464
+ })
465
+ .join("\n");
466
+ }
467
+
468
+ global.propMarkdownTableRows = function (component) {
469
+ return _propMarkdownTableRows(component.props, "");
470
+ };
471
+
472
+ global.getMarkdownMethodSignature = function (method) {
473
+ const params = method.params
474
+ .map((param, i) => {
475
+ const isOptional = param.optional;
476
+
477
+ let name = "";
478
+
479
+ if (i !== 0) {
480
+ name += ", ";
481
+ }
482
+
483
+ name += param.name;
484
+ return isOptional ? `[${name}]` : name;
485
+ })
486
+ .join("");
487
+
488
+ return `${method.name}(${params})`;
489
+ };
490
+
491
+ global.getMarkdownMethodExamples = function (method) {
492
+ if (method.examples == null) {
493
+ return null;
494
+ }
495
+ return method.examples
496
+ .map((example) => {
497
+ return `
498
+
499
+ \`\`\`javascript
500
+ ${example.trim()}
501
+ \`\`\`
502
+
503
+ `;
504
+ })
505
+ .join("");
506
+ };
507
+
508
+ global.getStyleDefaultValue = function (style) {
509
+ if (style.type === "string" && style.default === "") {
510
+ return "empty string";
511
+ } else if (style.type.includes("array")) {
512
+ return `[${style.default}]`;
513
+ } else {
514
+ return style.default;
515
+ }
516
+ };
517
+
518
+ Object.keys(iosSpecOverrides).forEach((propName) => {
519
+ const camelCasePropName = camelCase(propName);
520
+ iosPropNameOverrides[camelCasePropName] = camelCase(
521
+ iosSpecOverrides[propName],
522
+ );
523
+ });
524
+
525
+ module.exports = {
526
+ camelCase,
527
+ pascalCase,
528
+ };
@@ -52,7 +52,38 @@
52
52
  "default": 0,
53
53
  "units": "degrees",
54
54
  "doc": "Default pitch, in degrees. Zero is perpendicular to the surface, for a look straight down at the map, while a greater value like 60 looks ahead towards the horizon. The style pitch will be used only if the map has not been positioned by other means (e.g. map options or user interaction).",
55
- "example": 50
55
+ "example": 50,
56
+ "sdk-support": {
57
+ "0-60 degrees": {
58
+ "js": "0.8.0",
59
+ "android": "1.0.0",
60
+ "ios": "1.0.0"
61
+ },
62
+ "0-85 degrees": {
63
+ "js": "2.0.0",
64
+ "android": "https://github.com/maplibre/maplibre-native/issues/1909",
65
+ "ios": "https://github.com/maplibre/maplibre-native/issues/1909"
66
+ },
67
+ "0-180 degrees": {
68
+ "js": "5.0.0",
69
+ "android": "https://github.com/maplibre/maplibre-native/issues/1909",
70
+ "ios": "https://github.com/maplibre/maplibre-native/issues/1909"
71
+ }
72
+ }
73
+ },
74
+ "roll": {
75
+ "type": "number",
76
+ "default": 0,
77
+ "units": "degrees",
78
+ "doc": "Default roll, in degrees. The roll angle is measured counterclockwise about the camera boresight. The style roll will be used only if the map has not been positioned by other means (e.g. map options or user interaction).",
79
+ "example": 45,
80
+ "sdk-support": {
81
+ "basic functionality": {
82
+ "js": "5.0.0",
83
+ "android": "https://github.com/maplibre/maplibre-native/issues/2941",
84
+ "ios": "https://github.com/maplibre/maplibre-native/issues/2941"
85
+ }
86
+ }
56
87
  },
57
88
  "light": {
58
89
  "type": "light",
package/tsconfig.json CHANGED
@@ -10,12 +10,12 @@
10
10
  "isolatedModules": true,
11
11
  "skipLibCheck": true,
12
12
  "strict": true,
13
- "types": ["node", "react-native", "geojson"],
13
+ "types": ["node", "react-native", "geojson", "jest"],
14
14
  "moduleResolution": "node",
15
15
  "allowSyntheticDefaultImports": true,
16
16
  "esModuleInterop": true,
17
17
  "noUnusedLocals": true,
18
- "noImplicitReturns": true,
18
+ "noImplicitReturns": true
19
19
  },
20
20
  "include": [
21
21
  "javascript/**/*", "index.ts"
Binary file
@@ -1,79 +0,0 @@
1
- import geoViewport from "@mapbox/geo-viewport";
2
- import along from "@turf/along";
3
- import distance from "@turf/distance";
4
- import {
5
- featureCollection,
6
- point,
7
- feature,
8
- lineString,
9
- Id,
10
- Properties,
11
- } from "@turf/helpers";
12
-
13
- const VECTOR_TILE_SIZE = 512;
14
-
15
- export const makePoint = point;
16
-
17
- export const makeLineString = lineString;
18
-
19
- export function makeLatLngBounds(
20
- northEastCoordinates: GeoJSON.Position,
21
- southWestCoordinates: GeoJSON.Position,
22
- ): GeoJSON.FeatureCollection {
23
- return featureCollection([
24
- point(northEastCoordinates),
25
- point(southWestCoordinates),
26
- ]);
27
- }
28
-
29
- export const makeFeature = feature;
30
-
31
- export function makeFeatureCollection(
32
- features: GeoJSON.Feature[] = [],
33
- options?: { bbox?: GeoJSON.BBox; id?: Id },
34
- ): GeoJSON.FeatureCollection {
35
- return featureCollection(features, options);
36
- }
37
-
38
- export function addToFeatureCollection<T extends GeoJSON.Geometry>(
39
- newFeatureCollection: GeoJSON.FeatureCollection<T, Properties>,
40
- newFeature: GeoJSON.Feature<T, Properties>,
41
- ): GeoJSON.FeatureCollection<T, Properties> {
42
- return {
43
- ...newFeatureCollection,
44
- features: [...newFeatureCollection.features, newFeature],
45
- };
46
- }
47
-
48
- export const calculateDistance = distance;
49
-
50
- export const pointAlongLine = along;
51
-
52
- export function getOrCalculateVisibleRegion(
53
- coord: [number, number] | { lon: number; lat: number },
54
- zoomLevel: number,
55
- width: number,
56
- height: number,
57
- nativeRegion: { properties: { visibleBounds: [number, number][] } },
58
- ): { ne: [number, number]; sw: [number, number] } {
59
- const region = {
60
- ne: [0, 0] as [number, number],
61
- sw: [0, 0] as [number, number],
62
- };
63
-
64
- if (!nativeRegion || !Array.isArray(nativeRegion.properties.visibleBounds)) {
65
- const bounds = geoViewport.bounds(
66
- coord,
67
- zoomLevel,
68
- [width, height],
69
- VECTOR_TILE_SIZE,
70
- );
71
- region.ne = [bounds[3], bounds[2]];
72
- region.sw = [bounds[1], bounds[0]];
73
- } else {
74
- region.ne = nativeRegion.properties.visibleBounds[0];
75
- region.sw = nativeRegion.properties.visibleBounds[1];
76
- }
77
-
78
- return region;
79
- }
@@ -1,29 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const ejs = require('ejs');
4
-
5
- const TMPL_PATH = path.join(__dirname, '..', 'templates');
6
- const TMPL_FILE = fs.readFileSync(path.join(TMPL_PATH, 'component.md.ejs'), 'utf8');
7
-
8
- class MarkdownBuilder {
9
-
10
- generateComponentFile (docJSON, componentName) {
11
- const tmpl = ejs.compile(TMPL_FILE, { strict: true });
12
- const fileContents = tmpl({ component: docJSON[componentName] });
13
- fs.writeFileSync(path.join(__dirname, '..', '..', 'docs', `${componentName}.md`), fileContents);
14
- }
15
-
16
- generate () {
17
- const docJSONFile = fs.readFileSync(path.join(__dirname, '..', '..', 'docs', 'docs.json'), 'utf8');
18
- const docJSON = JSON.parse(docJSONFile);
19
- const componentPaths = Object.keys(docJSON);
20
-
21
- for (let componentPath of componentPaths) {
22
- this.generateComponentFile(docJSON, componentPath);
23
- }
24
-
25
- console.log('Markdown is finished generating');
26
- }
27
- }
28
-
29
- module.exports = MarkdownBuilder;