@carto/api-client 0.5.16 → 0.5.18-alpha.colormapfix-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/CHANGELOG.md +8 -0
- package/build/api-client.cjs +979 -151
- package/build/api-client.cjs.map +1 -1
- package/build/api-client.d.cts +152 -29
- package/build/api-client.d.ts +152 -29
- package/build/api-client.js +965 -149
- package/build/api-client.js.map +1 -1
- package/package.json +4 -2
- package/src/fetch-map/basemap-styles.ts +1 -1
- package/src/fetch-map/index.ts +6 -1
- package/src/fetch-map/layer-map.ts +130 -38
- package/src/fetch-map/parse-map.ts +284 -165
- package/src/fetch-map/raster-layer.ts +536 -0
- package/src/fetch-map/types.ts +21 -7
- package/src/fetch-map/utils.ts +56 -0
- package/src/fetch-map/vec-expr-evaluator.ts +374 -0
- package/src/index.ts +7 -1
- package/src/sources/types.ts +52 -11
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"homepage": "https://github.com/CartoDB/carto-api-client#readme",
|
|
9
9
|
"author": "Don McCurdy <donmccurdy@carto.com>",
|
|
10
10
|
"packageManager": "yarn@4.3.1",
|
|
11
|
-
"version": "0.5.
|
|
11
|
+
"version": "0.5.18-alpha.colormapfix-1",
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"publishConfig": {
|
|
14
14
|
"access": "public"
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"d3-format": "^3.1.0",
|
|
72
72
|
"d3-scale": "^4.0.2",
|
|
73
73
|
"h3-js": "^4.1.0",
|
|
74
|
+
"jsep": "^1.4.0",
|
|
74
75
|
"quadbin": "^0.4.1-alpha.0"
|
|
75
76
|
},
|
|
76
77
|
"devDependencies": {
|
|
@@ -131,5 +132,6 @@
|
|
|
131
132
|
"resolutions": {
|
|
132
133
|
"@carto/api-client": "portal:./",
|
|
133
134
|
"rollup": "^4.20.0"
|
|
134
|
-
}
|
|
135
|
+
},
|
|
136
|
+
"stableVersion": "0.5.17"
|
|
135
137
|
}
|
|
@@ -92,7 +92,7 @@ export const STYLE_LAYER_GROUPS: StyleLayerGroup[] = [
|
|
|
92
92
|
];
|
|
93
93
|
|
|
94
94
|
export function applyLayerGroupFilters(
|
|
95
|
-
style: any,
|
|
95
|
+
style: any, // this Maplibre/Mapbox style, we don't want to add a dependency on Maplibre
|
|
96
96
|
visibleLayerGroups: Record<StyleLayerGroupSlug, boolean>
|
|
97
97
|
) {
|
|
98
98
|
if (!Array.isArray(style?.layers)) {
|
package/src/fetch-map/index.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
default as BASEMAP,
|
|
3
|
+
applyLayerGroupFilters as _applyLayerGroupFilters,
|
|
4
|
+
} from './basemap-styles.js';
|
|
5
|
+
export {getRasterTileLayerStyleProps as _getRasterTileLayerStyleProps} from './raster-layer.js';
|
|
2
6
|
export {fetchMap} from './fetch-map.js';
|
|
3
7
|
export type {FetchMapOptions, FetchMapResult} from './fetch-map.js';
|
|
4
8
|
export type {
|
|
@@ -11,3 +15,4 @@ export type {
|
|
|
11
15
|
export * from './basemap.js';
|
|
12
16
|
export * from './layer-map.js';
|
|
13
17
|
export * from './parse-map.js';
|
|
18
|
+
export {getLog10ScaleSteps as _getLog10ScaleSteps} from './utils.js';
|
|
@@ -25,9 +25,11 @@ import {
|
|
|
25
25
|
createBinaryProxy,
|
|
26
26
|
formatDate,
|
|
27
27
|
formatTimestamp,
|
|
28
|
+
getLog10ScaleSteps,
|
|
28
29
|
scaleIdentity,
|
|
29
30
|
} from './utils.js';
|
|
30
31
|
import type {
|
|
32
|
+
ColorRange,
|
|
31
33
|
CustomMarkersRange,
|
|
32
34
|
Dataset,
|
|
33
35
|
MapLayerConfig,
|
|
@@ -38,6 +40,7 @@ import type {
|
|
|
38
40
|
import type {ProviderType, SchemaField} from '../types.js';
|
|
39
41
|
import {DEFAULT_AGGREGATION_EXP_ALIAS} from '../constants-internal.js';
|
|
40
42
|
import {AggregationTypes} from '../constants.js';
|
|
43
|
+
import type {Attribute, TilejsonResult} from '../sources/types.js';
|
|
41
44
|
|
|
42
45
|
export type D3Scale = {
|
|
43
46
|
domain: (d?: any) => any[];
|
|
@@ -72,7 +75,21 @@ function identity<T>(v: T): T {
|
|
|
72
75
|
return v;
|
|
73
76
|
}
|
|
74
77
|
|
|
78
|
+
const hexToRGB = (c: any) => {
|
|
79
|
+
const {r, g, b} = rgb(c);
|
|
80
|
+
return [r, g, b];
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const rgbToHex = (c: number[]) => {
|
|
84
|
+
const [r, g, b] = c;
|
|
85
|
+
const rStr = r.toString(16).padStart(2, '0');
|
|
86
|
+
const gStr = g.toString(16).padStart(2, '0');
|
|
87
|
+
const bStr = b.toString(16).padStart(2, '0');
|
|
88
|
+
return `#${rStr}${gStr}${bStr}`.toUpperCase();
|
|
89
|
+
};
|
|
90
|
+
|
|
75
91
|
const UNKNOWN_COLOR = '#868d91';
|
|
92
|
+
const UNKNOWN_COLOR_RGB = hexToRGB(UNKNOWN_COLOR);
|
|
76
93
|
|
|
77
94
|
export const OPACITY_MAP: Record<string, string> = {
|
|
78
95
|
getFillColor: 'opacity',
|
|
@@ -113,6 +130,13 @@ const sharedPropMap = {
|
|
|
113
130
|
},
|
|
114
131
|
};
|
|
115
132
|
|
|
133
|
+
const rasterPropsMap = {
|
|
134
|
+
isVisible: 'visible',
|
|
135
|
+
visConfig: {
|
|
136
|
+
opacity: 'opacity',
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
116
140
|
const customMarkersPropsMap = {
|
|
117
141
|
color: 'getIconColor',
|
|
118
142
|
visConfig: {
|
|
@@ -174,6 +198,13 @@ export function getLayerProps(
|
|
|
174
198
|
);
|
|
175
199
|
}
|
|
176
200
|
|
|
201
|
+
if (type === 'raster') {
|
|
202
|
+
return {
|
|
203
|
+
propMap: rasterPropsMap,
|
|
204
|
+
defaultProps: {},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
177
208
|
let basePropMap: any = sharedPropMap;
|
|
178
209
|
if (config.visConfig?.customMarkers) {
|
|
179
210
|
basePropMap = mergePropMaps(basePropMap, customMarkersPropsMap);
|
|
@@ -195,18 +226,21 @@ export function getLayerProps(
|
|
|
195
226
|
}
|
|
196
227
|
|
|
197
228
|
function domainFromAttribute(
|
|
198
|
-
attribute:
|
|
229
|
+
attribute: Attribute,
|
|
199
230
|
scaleType: ScaleType,
|
|
200
231
|
scaleLength: number
|
|
201
|
-
) {
|
|
232
|
+
): number[] | string[] {
|
|
202
233
|
if (scaleType === 'ordinal' || scaleType === 'point') {
|
|
234
|
+
if (!attribute.categories) {
|
|
235
|
+
return [0, 1];
|
|
236
|
+
}
|
|
203
237
|
return attribute.categories
|
|
204
238
|
.map((c: any) => c.category)
|
|
205
239
|
.filter((c: any) => c !== undefined && c !== null);
|
|
206
240
|
}
|
|
207
241
|
|
|
208
242
|
if (scaleType === 'quantile' && attribute.quantiles) {
|
|
209
|
-
return attribute.quantiles
|
|
243
|
+
return 'global' in attribute.quantiles
|
|
210
244
|
? attribute.quantiles.global[scaleLength]
|
|
211
245
|
: attribute.quantiles[scaleLength];
|
|
212
246
|
}
|
|
@@ -215,7 +249,7 @@ function domainFromAttribute(
|
|
|
215
249
|
if (scaleType === 'log' && min === 0) {
|
|
216
250
|
min = 1e-5;
|
|
217
251
|
}
|
|
218
|
-
return [min, attribute.max];
|
|
252
|
+
return [min ?? 0, attribute.max ?? 1];
|
|
219
253
|
}
|
|
220
254
|
|
|
221
255
|
function domainFromValues(values: any, scaleType: ScaleType) {
|
|
@@ -235,8 +269,8 @@ function domainFromValues(values: any, scaleType: ScaleType) {
|
|
|
235
269
|
}
|
|
236
270
|
|
|
237
271
|
function calculateDomain(
|
|
238
|
-
data:
|
|
239
|
-
name:
|
|
272
|
+
data: TilejsonResult,
|
|
273
|
+
name: string,
|
|
240
274
|
scaleType: ScaleType,
|
|
241
275
|
scaleLength?: number
|
|
242
276
|
) {
|
|
@@ -244,14 +278,16 @@ function calculateDomain(
|
|
|
244
278
|
// Tileset data type
|
|
245
279
|
const {attributes} = data.tilestats.layers[0];
|
|
246
280
|
const attribute = attributes.find((a: any) => a.attribute === name);
|
|
247
|
-
|
|
281
|
+
if (attribute) {
|
|
282
|
+
return domainFromAttribute(attribute, scaleType, scaleLength as number);
|
|
283
|
+
}
|
|
248
284
|
}
|
|
249
285
|
|
|
250
286
|
return [0, 1];
|
|
251
287
|
}
|
|
252
288
|
|
|
253
289
|
function normalizeAccessor(accessor: any, data: any) {
|
|
254
|
-
if (data.features || data.tilestats) {
|
|
290
|
+
if (data.features || data.tilestats || data.raster_metadata) {
|
|
255
291
|
return (object: any, info: any) => {
|
|
256
292
|
if (object) {
|
|
257
293
|
return accessor(object.properties || object.__source.object.properties);
|
|
@@ -297,61 +333,103 @@ function findAccessorKey(keys: string[], properties: any): string[] {
|
|
|
297
333
|
export function getColorAccessor(
|
|
298
334
|
{name, colorColumn}: VisualChannelField,
|
|
299
335
|
scaleType: ScaleType,
|
|
300
|
-
{aggregation, range}: {aggregation
|
|
336
|
+
{aggregation, range}: {aggregation?: string; range: ColorRange},
|
|
301
337
|
opacity: number | undefined,
|
|
302
|
-
data:
|
|
303
|
-
): {
|
|
304
|
-
|
|
338
|
+
data: TilejsonResult
|
|
339
|
+
): {
|
|
340
|
+
accessor: any;
|
|
341
|
+
domain: number[] | string[];
|
|
342
|
+
scaleDomain: number[] | string[];
|
|
343
|
+
range: string[];
|
|
344
|
+
} {
|
|
345
|
+
const {scale, domain} = calculateLayerScale(
|
|
305
346
|
colorColumn || name,
|
|
306
|
-
scaleType,
|
|
347
|
+
colorColumn ? 'identity' : scaleType,
|
|
307
348
|
range,
|
|
308
349
|
data
|
|
309
350
|
);
|
|
310
351
|
const alpha = opacityToAlpha(opacity);
|
|
311
352
|
|
|
312
|
-
let accessorKeys = getAccessorKeys(name, aggregation);
|
|
353
|
+
let accessorKeys = getAccessorKeys(colorColumn || name, aggregation);
|
|
313
354
|
const accessor = (properties: any) => {
|
|
314
355
|
if (!(accessorKeys[0] in properties)) {
|
|
315
356
|
accessorKeys = findAccessorKey(accessorKeys, properties);
|
|
316
357
|
}
|
|
317
358
|
const propertyValue = properties[accessorKeys[0]];
|
|
318
|
-
const
|
|
319
|
-
|
|
359
|
+
const scaled = scale(propertyValue);
|
|
360
|
+
const rgb = typeof scaled === 'string' ? hexToRGB(scaled) : scaled;
|
|
361
|
+
return [...rgb, propertyValue === null ? 0 : alpha];
|
|
362
|
+
};
|
|
363
|
+
return {
|
|
364
|
+
accessor: normalizeAccessor(accessor, data),
|
|
365
|
+
scaleDomain: scale.domain(),
|
|
366
|
+
domain,
|
|
367
|
+
range: (scale.range() || []).map(rgbToHex),
|
|
320
368
|
};
|
|
321
|
-
return {accessor: normalizeAccessor(accessor, data), scale};
|
|
322
369
|
}
|
|
323
370
|
|
|
324
|
-
function calculateLayerScale(
|
|
325
|
-
name:
|
|
371
|
+
export function calculateLayerScale(
|
|
372
|
+
name: string,
|
|
326
373
|
scaleType: ScaleType,
|
|
327
|
-
range:
|
|
328
|
-
data:
|
|
329
|
-
) {
|
|
330
|
-
|
|
331
|
-
let
|
|
374
|
+
range: ColorRange,
|
|
375
|
+
data: TilejsonResult
|
|
376
|
+
): {scale: D3Scale; domain: string[] | number[]} {
|
|
377
|
+
let domain: string[] | number[] = [];
|
|
378
|
+
let scaleDomain: number[] | string[] | undefined;
|
|
332
379
|
let scaleColor: string[] = [];
|
|
380
|
+
const {colors} = range;
|
|
333
381
|
|
|
334
382
|
if (scaleType !== 'identity') {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
383
|
+
if (range.colorMap) {
|
|
384
|
+
const {colorMap} = range;
|
|
385
|
+
scaleDomain = [];
|
|
338
386
|
colorMap.forEach(([value, color]) => {
|
|
339
|
-
|
|
387
|
+
(scaleDomain as any[]).push(value);
|
|
340
388
|
scaleColor.push(color);
|
|
341
389
|
});
|
|
390
|
+
domain = scaleDomain;
|
|
342
391
|
} else {
|
|
343
|
-
|
|
344
|
-
|
|
392
|
+
if (scaleType === 'custom' && range.uiCustomScaleType === 'logarithmic') {
|
|
393
|
+
domain = calculateDomain(data, name, scaleType, colors.length);
|
|
394
|
+
const [min, max] = domain as number[];
|
|
395
|
+
scaleDomain = getLog10ScaleSteps({
|
|
396
|
+
min,
|
|
397
|
+
max,
|
|
398
|
+
steps: colors.length,
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
scaleColor = colors;
|
|
402
|
+
} else {
|
|
403
|
+
domain = calculateDomain(data, name, scaleType, colors.length);
|
|
404
|
+
scaleColor = colors;
|
|
405
|
+
}
|
|
345
406
|
}
|
|
346
407
|
|
|
347
408
|
if (scaleType === 'ordinal') {
|
|
348
409
|
domain = domain.slice(0, scaleColor.length);
|
|
349
410
|
}
|
|
350
411
|
}
|
|
412
|
+
return {
|
|
413
|
+
scale: createColorScale(
|
|
414
|
+
scaleType,
|
|
415
|
+
scaleDomain || domain,
|
|
416
|
+
scaleColor.map(hexToRGB),
|
|
417
|
+
UNKNOWN_COLOR_RGB
|
|
418
|
+
),
|
|
419
|
+
domain,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
351
422
|
|
|
423
|
+
export function createColorScale<T>(
|
|
424
|
+
scaleType: ScaleType,
|
|
425
|
+
domain: string[] | number[],
|
|
426
|
+
range: T[],
|
|
427
|
+
unknown: T
|
|
428
|
+
) {
|
|
429
|
+
const scale = SCALE_FUNCS[scaleType]();
|
|
352
430
|
scale.domain(domain);
|
|
353
|
-
scale.range(
|
|
354
|
-
scale.unknown!(
|
|
431
|
+
scale.range(range);
|
|
432
|
+
scale.unknown!(unknown as any);
|
|
355
433
|
|
|
356
434
|
return scale;
|
|
357
435
|
}
|
|
@@ -427,13 +505,22 @@ export function getSizeAccessor(
|
|
|
427
505
|
{name}: VisualChannelField,
|
|
428
506
|
scaleType: ScaleType | undefined,
|
|
429
507
|
aggregation: string | null | undefined,
|
|
430
|
-
range:
|
|
431
|
-
data:
|
|
432
|
-
): {
|
|
508
|
+
range: number[] | undefined,
|
|
509
|
+
data: TilejsonResult
|
|
510
|
+
): {
|
|
511
|
+
accessor: any;
|
|
512
|
+
domain: number[];
|
|
513
|
+
scaleDomain: number[];
|
|
514
|
+
range: number[] | undefined;
|
|
515
|
+
} {
|
|
433
516
|
const scale = scaleType ? SCALE_FUNCS[scaleType]() : identity;
|
|
434
|
-
|
|
517
|
+
let domain: number[] = [];
|
|
518
|
+
if (scaleType && range) {
|
|
435
519
|
if (aggregation !== AggregationTypes.Count) {
|
|
436
|
-
|
|
520
|
+
domain = calculateDomain(data, name, scaleType) as number[];
|
|
521
|
+
(scale as D3Scale).domain(domain);
|
|
522
|
+
} else {
|
|
523
|
+
domain = (scale as D3Scale).domain();
|
|
437
524
|
}
|
|
438
525
|
(scale as D3Scale).range(range);
|
|
439
526
|
}
|
|
@@ -446,7 +533,12 @@ export function getSizeAccessor(
|
|
|
446
533
|
const propertyValue = properties[accessorKeys[0]];
|
|
447
534
|
return scale(propertyValue);
|
|
448
535
|
};
|
|
449
|
-
return {
|
|
536
|
+
return {
|
|
537
|
+
accessor: normalizeAccessor(accessor, data),
|
|
538
|
+
domain,
|
|
539
|
+
scaleDomain: domain,
|
|
540
|
+
range,
|
|
541
|
+
};
|
|
450
542
|
}
|
|
451
543
|
|
|
452
544
|
const FORMATS: Record<string, (value: any) => string> = {
|