@deck.gl/carto 8.8.0-alpha.2 → 8.8.0-alpha.3
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/dist.dev.js +1479 -1085
- package/dist/es5/api/layer-map.js +17 -5
- package/dist/es5/api/layer-map.js.map +1 -1
- package/dist/es5/api/maps-api-common.js +1 -0
- package/dist/es5/api/maps-api-common.js.map +1 -1
- package/dist/es5/api/parseMap.js +14 -3
- package/dist/es5/api/parseMap.js.map +1 -1
- package/dist/es5/index.js +16 -0
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/layers/carto-layer.js +13 -0
- package/dist/es5/layers/carto-layer.js.map +1 -1
- package/dist/es5/layers/h3-tile-layer.js +96 -0
- package/dist/es5/layers/h3-tile-layer.js.map +1 -0
- package/dist/es5/layers/h3-tileset-2d.js +165 -0
- package/dist/es5/layers/h3-tileset-2d.js.map +1 -0
- package/dist/es5/layers/quadkey-tile-layer.js +97 -0
- package/dist/es5/layers/quadkey-tile-layer.js.map +1 -0
- package/dist/es5/layers/quadkey-tileset-2d.js +89 -0
- package/dist/es5/layers/quadkey-tileset-2d.js.map +1 -0
- package/dist/esm/api/layer-map.js +12 -4
- package/dist/esm/api/layer-map.js.map +1 -1
- package/dist/esm/api/maps-api-common.js +1 -0
- package/dist/esm/api/maps-api-common.js.map +1 -1
- package/dist/esm/api/parseMap.js +15 -4
- package/dist/esm/api/parseMap.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/layers/carto-layer.js +12 -1
- package/dist/esm/layers/carto-layer.js.map +1 -1
- package/dist/esm/layers/h3-tile-layer.js +61 -0
- package/dist/esm/layers/h3-tile-layer.js.map +1 -0
- package/dist/esm/layers/h3-tileset-2d.js +103 -0
- package/dist/esm/layers/h3-tileset-2d.js.map +1 -0
- package/dist/esm/layers/quadkey-tile-layer.js +61 -0
- package/dist/esm/layers/quadkey-tile-layer.js.map +1 -0
- package/dist/esm/layers/quadkey-tileset-2d.js +48 -0
- package/dist/esm/layers/quadkey-tileset-2d.js.map +1 -0
- package/dist.min.js +14 -14
- package/package.json +2 -2
- package/src/api/layer-map.ts +14 -4
- package/src/api/maps-api-common.ts +1 -0
- package/src/api/parseMap.ts +20 -5
- package/src/index.ts +2 -0
- package/src/layers/carto-layer.ts +9 -1
- package/src/layers/h3-tile-layer.js +44 -0
- package/src/layers/h3-tileset-2d.js +82 -0
- package/src/layers/quadkey-tile-layer.js +42 -0
- package/src/layers/quadkey-tileset-2d.js +36 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@deck.gl/carto",
|
|
3
3
|
"description": "CARTO official integration with Deck.gl. Build geospatial applications using CARTO and Deck.gl.",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "8.8.0-alpha.
|
|
5
|
+
"version": "8.8.0-alpha.3",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"@deck.gl/layers": "^8.0.0",
|
|
59
59
|
"@loaders.gl/core": "^3.0.0"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "edad7cf75b75a137d63ec89d2d644727d3082e25"
|
|
62
62
|
}
|
package/src/api/layer-map.ts
CHANGED
|
@@ -42,6 +42,12 @@ export const AGGREGATION = {
|
|
|
42
42
|
sum: 'SUM'
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
export const OPACITY_MAP = {
|
|
46
|
+
getFillColor: 'opacity',
|
|
47
|
+
getLineColor: 'strokeOpacity',
|
|
48
|
+
getTextColor: 'opacity'
|
|
49
|
+
};
|
|
50
|
+
|
|
45
51
|
const AGGREGATION_FUNC = {
|
|
46
52
|
'count unique': (values, accessor) => groupSort(values, v => v.length, accessor).length,
|
|
47
53
|
median,
|
|
@@ -71,7 +77,6 @@ const sharedPropMap = {
|
|
|
71
77
|
enable3d: 'extruded',
|
|
72
78
|
elevationScale: 'elevationScale',
|
|
73
79
|
filled: 'filled',
|
|
74
|
-
opacity: 'opacity',
|
|
75
80
|
strokeColor: 'getLineColor',
|
|
76
81
|
stroked: 'stroked',
|
|
77
82
|
thickness: 'getLineWidth',
|
|
@@ -225,6 +230,10 @@ function normalizeAccessor(accessor, data) {
|
|
|
225
230
|
return accessor;
|
|
226
231
|
}
|
|
227
232
|
|
|
233
|
+
export function opacityToAlpha(opacity) {
|
|
234
|
+
return opacity !== undefined ? Math.round(255 * Math.pow(opacity, 1 / 2.2)) : 255;
|
|
235
|
+
}
|
|
236
|
+
|
|
228
237
|
export function getColorValueAccessor({name}, colorAggregation, data: any) {
|
|
229
238
|
const aggregator = AGGREGATION_FUNC[colorAggregation];
|
|
230
239
|
const accessor = values => aggregator(values, p => p[name]);
|
|
@@ -259,11 +268,12 @@ export function getColorAccessor(
|
|
|
259
268
|
scale.domain(domain);
|
|
260
269
|
scale.range(scaleColor);
|
|
261
270
|
scale.unknown(UNKNOWN_COLOR);
|
|
262
|
-
const alpha =
|
|
271
|
+
const alpha = opacityToAlpha(opacity);
|
|
263
272
|
|
|
264
273
|
const accessor = properties => {
|
|
265
|
-
const
|
|
266
|
-
|
|
274
|
+
const propertyValue = properties[name];
|
|
275
|
+
const {r, g, b} = rgb(scale(propertyValue));
|
|
276
|
+
return [r, g, b, propertyValue === null ? 0 : alpha];
|
|
267
277
|
};
|
|
268
278
|
return normalizeAccessor(accessor, data);
|
|
269
279
|
}
|
package/src/api/parseMap.ts
CHANGED
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
getColorValueAccessor,
|
|
7
7
|
getSizeAccessor,
|
|
8
8
|
getTextAccessor,
|
|
9
|
-
getTextPixelOffsetAccessor
|
|
9
|
+
getTextPixelOffsetAccessor,
|
|
10
|
+
OPACITY_MAP,
|
|
11
|
+
opacityToAlpha
|
|
10
12
|
} from './layer-map';
|
|
11
13
|
import {_flatten as flatten, log} from '@deck.gl/core';
|
|
12
14
|
import {assert} from '../utils';
|
|
@@ -131,10 +133,21 @@ function createStyleProps(config, mapping) {
|
|
|
131
133
|
mapProps(config, result, mapping);
|
|
132
134
|
|
|
133
135
|
// Kepler format sometimes omits strokeColor. TODO: remove once we can rely on
|
|
134
|
-
// `strokeColor` always being
|
|
136
|
+
// `strokeColor` always being set when `stroke: true`.
|
|
135
137
|
if (result.stroked && !result.getLineColor) {
|
|
136
138
|
result.getLineColor = result.getFillColor;
|
|
137
139
|
}
|
|
140
|
+
|
|
141
|
+
for (const colorAccessor in OPACITY_MAP) {
|
|
142
|
+
if (Array.isArray(result[colorAccessor])) {
|
|
143
|
+
const color = [...result[colorAccessor]];
|
|
144
|
+
const opacityKey = OPACITY_MAP[colorAccessor];
|
|
145
|
+
const opacity = config.visConfig[opacityKey];
|
|
146
|
+
color[3] = opacityToAlpha(opacity);
|
|
147
|
+
result[colorAccessor] = color;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
138
151
|
result.highlightColor = config.visConfig.enable3d ? [255, 255, 255, 60] : [252, 242, 26, 255];
|
|
139
152
|
return result;
|
|
140
153
|
}
|
|
@@ -159,7 +172,7 @@ function createChannelProps(visualChannels, type, config, data) {
|
|
|
159
172
|
if (!AGGREGATION[colorAggregation]) {
|
|
160
173
|
result.getColorValue = getColorValueAccessor(colorField, colorAggregation, data);
|
|
161
174
|
} else {
|
|
162
|
-
result.getColorWeight = d => [colorField.name];
|
|
175
|
+
result.getColorWeight = d => d[colorField.name];
|
|
163
176
|
}
|
|
164
177
|
}
|
|
165
178
|
} else if (colorField) {
|
|
@@ -167,13 +180,15 @@ function createChannelProps(visualChannels, type, config, data) {
|
|
|
167
180
|
colorField,
|
|
168
181
|
colorScale,
|
|
169
182
|
visConfig.colorRange,
|
|
170
|
-
|
|
183
|
+
visConfig.opacity,
|
|
171
184
|
data
|
|
172
185
|
);
|
|
173
186
|
}
|
|
174
187
|
|
|
175
188
|
if (strokeColorField) {
|
|
176
|
-
const
|
|
189
|
+
const fallbackOpacity = type === 'point' ? visConfig.opacity : 1;
|
|
190
|
+
const opacity =
|
|
191
|
+
visConfig.strokeOpacity !== undefined ? visConfig.strokeOpacity : fallbackOpacity;
|
|
177
192
|
result.getLineColor = getColorAccessor(
|
|
178
193
|
strokeColorField,
|
|
179
194
|
strokeColorScale,
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export {getDefaultCredentials, setDefaultCredentials} from './config';
|
|
2
2
|
export {default as CartoLayer} from './layers/carto-layer';
|
|
3
3
|
export {default as _CartoTileLayer} from './layers/carto-tile-layer';
|
|
4
|
+
export {default as _H3TileLayer} from './layers/h3-tile-layer';
|
|
5
|
+
export {default as _QuadkeyTileLayer} from './layers/quadkey-tile-layer';
|
|
4
6
|
export {default as BASEMAP} from './basemap';
|
|
5
7
|
export {default as colorBins} from './style/color-bins-style';
|
|
6
8
|
export {default as colorCategories} from './style/color-categories-style';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {CompositeLayer, Layer, log} from '@deck.gl/core';
|
|
2
2
|
import CartoTileLayer from './carto-tile-layer';
|
|
3
|
+
import H3TileLayer from './h3-tile-layer';
|
|
4
|
+
import QuadkeyTileLayer from './quadkey-tile-layer';
|
|
3
5
|
import {MVTLayer} from '@deck.gl/geo-layers';
|
|
4
6
|
import {GeoJsonLayer} from '@deck.gl/layers';
|
|
5
7
|
import {fetchLayerData, getDataV2, API_VERSIONS} from '../api';
|
|
@@ -240,7 +242,7 @@ export default class CartoLayer<DataT = any> extends CompositeLayer<CartoLayerPr
|
|
|
240
242
|
source,
|
|
241
243
|
clientId,
|
|
242
244
|
credentials: credentials as CloudNativeCredentials,
|
|
243
|
-
connection
|
|
245
|
+
connection,
|
|
244
246
|
...rest
|
|
245
247
|
});
|
|
246
248
|
}
|
|
@@ -283,6 +285,12 @@ export default class CartoLayer<DataT = any> extends CompositeLayer<CartoLayerPr
|
|
|
283
285
|
(tileUrl.searchParams.get('formatTiles') as TileFormat) ||
|
|
284
286
|
TILE_FORMATS.MVT;
|
|
285
287
|
|
|
288
|
+
if (data.scheme === 'h3') {
|
|
289
|
+
return [H3TileLayer, props];
|
|
290
|
+
}
|
|
291
|
+
if (data.scheme === 'quadkey') {
|
|
292
|
+
return [QuadkeyTileLayer, props];
|
|
293
|
+
}
|
|
286
294
|
return props.formatTiles === TILE_FORMATS.MVT ? [MVTLayer, props] : [CartoTileLayer, props];
|
|
287
295
|
}
|
|
288
296
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {CompositeLayer} from '@deck.gl/core';
|
|
2
|
+
import {H3HexagonLayer, TileLayer} from '@deck.gl/geo-layers';
|
|
3
|
+
import H3Tileset2D from './h3-tileset-2d';
|
|
4
|
+
|
|
5
|
+
const renderSubLayers = props => {
|
|
6
|
+
const {data} = props;
|
|
7
|
+
const {index} = props.tile;
|
|
8
|
+
if (!data || !data.length) return null;
|
|
9
|
+
|
|
10
|
+
return new H3HexagonLayer(props, {
|
|
11
|
+
centerHexagon: index,
|
|
12
|
+
highPrecision: true
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default class H3TileLayer extends CompositeLayer {
|
|
17
|
+
initializeState() {
|
|
18
|
+
this.setState({data: null, tileJSON: null});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
updateState({props, oldProps, context, changeFlags}) {
|
|
22
|
+
if (changeFlags.dataChanged) {
|
|
23
|
+
let {data} = this.props;
|
|
24
|
+
const tileJSON = data;
|
|
25
|
+
data = tileJSON.tiles;
|
|
26
|
+
this.setState({data, tileJSON});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
renderLayers() {
|
|
31
|
+
const {data} = this.state;
|
|
32
|
+
return [
|
|
33
|
+
new TileLayer(this.props, {
|
|
34
|
+
id: 'h3-tile-layer',
|
|
35
|
+
data,
|
|
36
|
+
getHexagon: d => d.id,
|
|
37
|
+
TilesetClass: H3Tileset2D,
|
|
38
|
+
renderSubLayers
|
|
39
|
+
})
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
H3TileLayer.layerName = 'H3TileLayer';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {_Tileset2D as Tileset2D} from '@deck.gl/geo-layers';
|
|
2
|
+
import {polyfill, getRes0Indexes, h3GetResolution, h3ToGeoBoundary, h3ToParent} from 'h3-js';
|
|
3
|
+
|
|
4
|
+
export function getHexagonsInBoundingBox({west, north, east, south}, resolution) {
|
|
5
|
+
if (resolution === 0) {
|
|
6
|
+
return getRes0Indexes();
|
|
7
|
+
}
|
|
8
|
+
if (east - west > 180) {
|
|
9
|
+
// This is a known issue in h3-js: polyfill does not work correctly
|
|
10
|
+
// when longitude span is larger than 180 degrees.
|
|
11
|
+
return getHexagonsInBoundingBox({west, north, east: 0, south}, resolution).concat(
|
|
12
|
+
getHexagonsInBoundingBox({west: 0, north, east, south}, resolution)
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// `polyfill()` fills based on hexagon center, which means tiles vanish
|
|
17
|
+
// prematurely. Get more accurate coverage by oversampling
|
|
18
|
+
const oversample = 1;
|
|
19
|
+
const h3Indices = polyfill(
|
|
20
|
+
[
|
|
21
|
+
[
|
|
22
|
+
[west, north],
|
|
23
|
+
[west, south],
|
|
24
|
+
[east, south],
|
|
25
|
+
[east, north],
|
|
26
|
+
[west, north]
|
|
27
|
+
]
|
|
28
|
+
],
|
|
29
|
+
resolution + oversample,
|
|
30
|
+
true
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return oversample ? [...new Set(h3Indices.map(i => h3ToParent(i, resolution)))] : h3Indices;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function tileToBoundingBox(index) {
|
|
37
|
+
const coordinates = h3ToGeoBoundary(index);
|
|
38
|
+
const latitudes = coordinates.map(c => c[0]);
|
|
39
|
+
const longitudes = coordinates.map(c => c[1]);
|
|
40
|
+
const west = Math.min(...longitudes);
|
|
41
|
+
const south = Math.min(...latitudes);
|
|
42
|
+
const east = Math.max(...longitudes);
|
|
43
|
+
const north = Math.max(...latitudes);
|
|
44
|
+
return {west, south, east, north};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default class H3Tileset2D extends Tileset2D {
|
|
48
|
+
getTileIndices({viewport, minZoom, maxZoom}) {
|
|
49
|
+
const [east, south, west, north] = viewport.getBounds();
|
|
50
|
+
|
|
51
|
+
// TODO ignores extent
|
|
52
|
+
let z = viewport.zoom;
|
|
53
|
+
if (typeof minZoom === 'number' && Number.isFinite(minZoom) && z < minZoom) {
|
|
54
|
+
z = minZoom;
|
|
55
|
+
}
|
|
56
|
+
if (typeof maxZoom === 'number' && Number.isFinite(maxZoom) && z > maxZoom) {
|
|
57
|
+
z = maxZoom;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Heuristic to get h3 resolution
|
|
61
|
+
const resolution = Math.max(0, Math.floor((2 * z) / 3) - 2);
|
|
62
|
+
return getHexagonsInBoundingBox({west, north, east, south}, resolution).map(i => ({i}));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getTileId({i}) {
|
|
66
|
+
return i;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getTileMetadata({i}) {
|
|
70
|
+
return {bbox: tileToBoundingBox(i)};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getTileZoom({i}) {
|
|
74
|
+
return h3GetResolution(i);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getParentIndex(index) {
|
|
78
|
+
const resolution = h3GetResolution(index.i);
|
|
79
|
+
const i = h3ToParent(index.i, resolution - 1);
|
|
80
|
+
return {i};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {CompositeLayer} from '@deck.gl/core';
|
|
2
|
+
import {QuadkeyLayer, TileLayer} from '@deck.gl/geo-layers';
|
|
3
|
+
import QuadkeyTileset2D from './quadkey-tileset-2d';
|
|
4
|
+
|
|
5
|
+
const renderSubLayers = props => {
|
|
6
|
+
const {data} = props;
|
|
7
|
+
if (!data || !data.length) return null;
|
|
8
|
+
return new QuadkeyLayer(props);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default class QuadkeyTileLayer extends CompositeLayer {
|
|
12
|
+
initializeState() {
|
|
13
|
+
this.setState({data: null, tileJSON: null});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
updateState({props, oldProps, context, changeFlags}) {
|
|
17
|
+
if (changeFlags.dataChanged) {
|
|
18
|
+
let {data} = this.props;
|
|
19
|
+
const tileJSON = data;
|
|
20
|
+
data = tileJSON.tiles;
|
|
21
|
+
this.setState({data, tileJSON});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
renderLayers() {
|
|
26
|
+
const {data, tileJSON} = this.state;
|
|
27
|
+
const {maxresolution} = tileJSON;
|
|
28
|
+
const maxZoom = maxresolution - this.props.aggregationResLevel;
|
|
29
|
+
return [
|
|
30
|
+
new TileLayer(this.props, {
|
|
31
|
+
id: 'quadkey-tile-layer',
|
|
32
|
+
data,
|
|
33
|
+
getQuadkey: d => d.id,
|
|
34
|
+
TilesetClass: QuadkeyTileset2D,
|
|
35
|
+
renderSubLayers,
|
|
36
|
+
maxZoom
|
|
37
|
+
})
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
QuadkeyTileLayer.layerName = 'QuadkeyTileLayer';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {_Tileset2D as Tileset2D} from '@deck.gl/geo-layers';
|
|
2
|
+
|
|
3
|
+
function tileToQuadkey(tile) {
|
|
4
|
+
let index = '';
|
|
5
|
+
for (let z = tile.z; z > 0; z--) {
|
|
6
|
+
let b = 0;
|
|
7
|
+
const mask = 1 << (z - 1);
|
|
8
|
+
if ((tile.x & mask) !== 0) b++;
|
|
9
|
+
if ((tile.y & mask) !== 0) b += 2;
|
|
10
|
+
index += b.toString();
|
|
11
|
+
}
|
|
12
|
+
return {i: index};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default class QuadkeyTileset2D extends Tileset2D {
|
|
16
|
+
getTileIndices(opts) {
|
|
17
|
+
return super.getTileIndices(opts).map(tileToQuadkey);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getTileId({i}) {
|
|
21
|
+
return i;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getTileMetadata() {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getTileZoom({i}) {
|
|
29
|
+
return i.length;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getParentIndex(index) {
|
|
33
|
+
const i = index.i.slice(0, -1);
|
|
34
|
+
return {i};
|
|
35
|
+
}
|
|
36
|
+
}
|