@deck.gl-community/basemap-layers 9.3.0-beta.2
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/LICENSE +19 -0
- package/README.md +14 -0
- package/dist/atmosphere-layer.d.ts +11 -0
- package/dist/atmosphere-layer.d.ts.map +1 -0
- package/dist/atmosphere-layer.js +15 -0
- package/dist/atmosphere-layer.js.map +1 -0
- package/dist/basemap-layer.d.ts +67 -0
- package/dist/basemap-layer.d.ts.map +1 -0
- package/dist/basemap-layer.js +115 -0
- package/dist/basemap-layer.js.map +1 -0
- package/dist/globe-layers.d.ts +22 -0
- package/dist/globe-layers.d.ts.map +1 -0
- package/dist/globe-layers.js +451 -0
- package/dist/globe-layers.js.map +1 -0
- package/dist/index.cjs +947 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/map-style-loader.d.ts +49 -0
- package/dist/map-style-loader.d.ts.map +1 -0
- package/dist/map-style-loader.js +35 -0
- package/dist/map-style-loader.js.map +1 -0
- package/dist/map-style-schema.d.ts +71 -0
- package/dist/map-style-schema.d.ts.map +1 -0
- package/dist/map-style-schema.js +45 -0
- package/dist/map-style-schema.js.map +1 -0
- package/dist/map-style.cjs +250 -0
- package/dist/map-style.cjs.map +7 -0
- package/dist/map-style.d.ts +7 -0
- package/dist/map-style.d.ts.map +1 -0
- package/dist/map-style.js +6 -0
- package/dist/map-style.js.map +1 -0
- package/dist/mapbox-style.d.ts +41 -0
- package/dist/mapbox-style.d.ts.map +1 -0
- package/dist/mapbox-style.js +113 -0
- package/dist/mapbox-style.js.map +1 -0
- package/dist/mvt-label-layer.d.ts +8142 -0
- package/dist/mvt-label-layer.d.ts.map +1 -0
- package/dist/mvt-label-layer.js +175 -0
- package/dist/mvt-label-layer.js.map +1 -0
- package/dist/style-resolver.d.ts +88 -0
- package/dist/style-resolver.d.ts.map +1 -0
- package/dist/style-resolver.js +63 -0
- package/dist/style-resolver.js.map +1 -0
- package/dist/util.d.ts +21 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +18 -0
- package/dist/util.js.map +1 -0
- package/package.json +60 -0
- package/src/atmosphere-layer.ts +15 -0
- package/src/basemap-layer.ts +183 -0
- package/src/globe-layers.ts +780 -0
- package/src/index.ts +3 -0
- package/src/map-style-loader.ts +52 -0
- package/src/map-style-schema.ts +54 -0
- package/src/map-style.ts +18 -0
- package/src/mapbox-style.ts +196 -0
- package/src/mvt-label-layer.ts +269 -0
- package/src/style-resolver.ts +173 -0
- package/src/util.ts +38 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {BasemapStyleSchema, ResolvedBasemapStyleSchema} from './map-style-schema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A basemap source entry from a style document.
|
|
5
|
+
*/
|
|
6
|
+
export type BasemapSource = {
|
|
7
|
+
/** Source kind such as `vector` or `raster`. */
|
|
8
|
+
type?: string;
|
|
9
|
+
/** Optional TileJSON URL used to resolve the source metadata. */
|
|
10
|
+
url?: string;
|
|
11
|
+
/** Inline tile templates for the source. */
|
|
12
|
+
tiles?: string[];
|
|
13
|
+
/** Minimum source zoom, when supplied by the style or TileJSON. */
|
|
14
|
+
minzoom?: number;
|
|
15
|
+
/** Maximum source zoom, when supplied by the style or TileJSON. */
|
|
16
|
+
maxzoom?: number;
|
|
17
|
+
/** Tile size in pixels. */
|
|
18
|
+
tileSize?: number;
|
|
19
|
+
/** Additional source properties are preserved verbatim. */
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A style layer entry used by the basemap runtime.
|
|
25
|
+
*/
|
|
26
|
+
export type BasemapStyleLayer = {
|
|
27
|
+
/** Unique layer identifier. */
|
|
28
|
+
id: string;
|
|
29
|
+
/** Style layer type such as `background`, `fill`, `line`, `symbol`, or `raster`. */
|
|
30
|
+
type: string;
|
|
31
|
+
/** Referenced source identifier. */
|
|
32
|
+
source?: string;
|
|
33
|
+
/** Referenced vector source-layer identifier. */
|
|
34
|
+
'source-layer'?: string;
|
|
35
|
+
/** Optional minimum zoom. */
|
|
36
|
+
minzoom?: number;
|
|
37
|
+
/** Optional maximum zoom. */
|
|
38
|
+
maxzoom?: number;
|
|
39
|
+
/** Optional style-spec filter expression. */
|
|
40
|
+
filter?: unknown[];
|
|
41
|
+
/** Paint properties from the source style layer. */
|
|
42
|
+
paint?: Record<string, unknown>;
|
|
43
|
+
/** Layout properties from the source style layer. */
|
|
44
|
+
layout?: Record<string, unknown>;
|
|
45
|
+
/** Additional layer properties are preserved verbatim. */
|
|
46
|
+
[key: string]: unknown;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A MapLibre or Mapbox style document consumed by the basemap runtime.
|
|
51
|
+
*/
|
|
52
|
+
export type BasemapStyle = {
|
|
53
|
+
/** Style-spec version number. */
|
|
54
|
+
version?: number;
|
|
55
|
+
/** Optional style metadata bag. */
|
|
56
|
+
metadata?: Record<string, unknown>;
|
|
57
|
+
/** Named source definitions used by the style. */
|
|
58
|
+
sources?: Record<string, BasemapSource>;
|
|
59
|
+
/** Ordered list of style layers. */
|
|
60
|
+
layers?: BasemapStyleLayer[];
|
|
61
|
+
/** Additional style properties are preserved verbatim. */
|
|
62
|
+
[key: string]: unknown;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A style document after all sources have been normalized and TileJSON-backed
|
|
67
|
+
* sources have been resolved.
|
|
68
|
+
*/
|
|
69
|
+
export type ResolvedBasemapStyle = BasemapStyle & {
|
|
70
|
+
/** Fully resolved source definitions. */
|
|
71
|
+
sources: Record<string, BasemapSource>;
|
|
72
|
+
/** Style layers copied into a mutable array. */
|
|
73
|
+
layers: BasemapStyleLayer[];
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Load options accepted by {@link resolveBasemapStyle}.
|
|
78
|
+
*/
|
|
79
|
+
export type BasemapLoadOptions = {
|
|
80
|
+
/** Base URL used to resolve relative source or tile URLs for in-memory styles. */
|
|
81
|
+
baseUrl?: string;
|
|
82
|
+
/** Optional custom fetch implementation. */
|
|
83
|
+
fetch?: typeof fetch;
|
|
84
|
+
/** Optional init object passed to the selected fetch implementation. */
|
|
85
|
+
fetchOptions?: RequestInit;
|
|
86
|
+
/** Additional loader options are accepted for forward compatibility. */
|
|
87
|
+
[key: string]: unknown;
|
|
88
|
+
} | null;
|
|
89
|
+
|
|
90
|
+
/** Resolves a possibly relative URL against the provided base URL. */
|
|
91
|
+
function normalizeUrl(url: string | undefined, baseUrl?: string) {
|
|
92
|
+
if (!url) {
|
|
93
|
+
return url;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
return decodeURI(new URL(url, baseUrl).toString());
|
|
98
|
+
} catch {
|
|
99
|
+
return url;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Resolves all tile templates in a source against the source base URL. */
|
|
104
|
+
function normalizeTiles(tiles: string[] | undefined, baseUrl?: string) {
|
|
105
|
+
return Array.isArray(tiles) ? tiles.map((tile) => normalizeUrl(tile, baseUrl) || tile) : tiles;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Fetches and parses a JSON resource. */
|
|
109
|
+
async function fetchJson(url: string, loadOptions?: BasemapLoadOptions) {
|
|
110
|
+
const fetchFn = loadOptions?.fetch || fetch;
|
|
111
|
+
const response = await fetchFn(url, loadOptions?.fetchOptions);
|
|
112
|
+
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
throw new Error(`Failed to load basemap resource: ${url} (${response.status})`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return await response.json();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Resolves a single source, including optional TileJSON indirection. */
|
|
121
|
+
async function resolveSource(
|
|
122
|
+
source: BasemapSource | undefined,
|
|
123
|
+
baseUrl: string | undefined,
|
|
124
|
+
loadOptions?: BasemapLoadOptions
|
|
125
|
+
) {
|
|
126
|
+
if (!source) {
|
|
127
|
+
return source;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const resolvedSource: BasemapSource = {...source};
|
|
131
|
+
let sourceBaseUrl = baseUrl;
|
|
132
|
+
|
|
133
|
+
if (resolvedSource.url) {
|
|
134
|
+
const tileJsonUrl = normalizeUrl(resolvedSource.url, baseUrl);
|
|
135
|
+
const tileJson = await fetchJson(tileJsonUrl || resolvedSource.url, loadOptions);
|
|
136
|
+
Object.assign(resolvedSource, tileJson);
|
|
137
|
+
resolvedSource.url = tileJsonUrl;
|
|
138
|
+
sourceBaseUrl = tileJsonUrl;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (resolvedSource.tiles) {
|
|
142
|
+
resolvedSource.tiles = normalizeTiles(resolvedSource.tiles, sourceBaseUrl);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return resolvedSource;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Resolves a basemap style input into a style object whose sources contain
|
|
150
|
+
* directly consumable tile templates and source metadata.
|
|
151
|
+
*/
|
|
152
|
+
export async function resolveBasemapStyle(
|
|
153
|
+
style: string | BasemapStyle,
|
|
154
|
+
loadOptions?: BasemapLoadOptions
|
|
155
|
+
): Promise<ResolvedBasemapStyle> {
|
|
156
|
+
const styleDefinition = BasemapStyleSchema.parse(
|
|
157
|
+
typeof style === 'string' ? await fetchJson(style, loadOptions) : structuredClone(style)
|
|
158
|
+
);
|
|
159
|
+
const baseUrl = typeof style === 'string' ? style : loadOptions?.baseUrl;
|
|
160
|
+
const resolvedSources: Record<string, BasemapSource> = {};
|
|
161
|
+
|
|
162
|
+
await Promise.all(
|
|
163
|
+
Object.entries(styleDefinition.sources || {}).map(async ([sourceId, source]) => {
|
|
164
|
+
resolvedSources[sourceId] = (await resolveSource(source, baseUrl, loadOptions)) || {};
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
return ResolvedBasemapStyleSchema.parse({
|
|
169
|
+
...styleDefinition,
|
|
170
|
+
sources: resolvedSources,
|
|
171
|
+
layers: [...(styleDefinition.layers || [])]
|
|
172
|
+
});
|
|
173
|
+
}
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
type FeatureLike = {
|
|
2
|
+
properties?: Record<string, unknown>;
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Options for {@link featuresArrayToObject}.
|
|
7
|
+
*/
|
|
8
|
+
export type FeaturesArrayToObjectOptions = {
|
|
9
|
+
/** Features to group by the requested layer-name property. */
|
|
10
|
+
features?: FeatureLike[];
|
|
11
|
+
/** Feature property name that contains the source-layer identifier. */
|
|
12
|
+
layerName?: string;
|
|
13
|
+
/** Optional source name wrapper for the returned object. */
|
|
14
|
+
sourceName?: string | null;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Converts an array of GeoJSON-like features into an object keyed by layer
|
|
19
|
+
* name, optionally wrapped by a source identifier.
|
|
20
|
+
*/
|
|
21
|
+
export function featuresArrayToObject(
|
|
22
|
+
options: FeaturesArrayToObjectOptions = {}
|
|
23
|
+
): Record<string, FeatureLike[] | Record<string, FeatureLike[]>> {
|
|
24
|
+
const {features = [], layerName = 'layerName', sourceName = null} = options;
|
|
25
|
+
|
|
26
|
+
const featuresByLayer: Record<string, FeatureLike[]> = {};
|
|
27
|
+
for (const feature of features) {
|
|
28
|
+
const featureLayerName = String(feature.properties?.[layerName] ?? '');
|
|
29
|
+
featuresByLayer[featureLayerName] = featuresByLayer[featureLayerName] || [];
|
|
30
|
+
featuresByLayer[featureLayerName].push(feature);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!sourceName) {
|
|
34
|
+
return featuresByLayer;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {[sourceName]: featuresByLayer};
|
|
38
|
+
}
|