diff --git a/docs/api-reference/carto/cluster-tile-layer.md b/docs/api-reference/carto/cluster-tile-layer.md
index 47c386b29a8..339defd6ad2 100644
--- a/docs/api-reference/carto/cluster-tile-layer.md
+++ b/docs/api-reference/carto/cluster-tile-layer.md
@@ -1,6 +1,6 @@
-# ClusterTileLayer (Experimental)
+# ClusterTileLayer
-`ClusterTileLayer` is a layer for visualizing point data aggregated using the [Quadbin Spatial Index](https://docs.carto.com/data-and-analysis/analytics-toolbox-for-bigquery/key-concepts/spatial-indexes#quadbin) using clusters.
+`ClusterTileLayer` is a layer for visualizing point data aggregated using the [Quadbin Spatial Index](https://docs.carto.com/data-and-analysis/analytics-toolbox-for-bigquery/key-concepts/spatial-indexes#quadbin) with dynamic clustering. It provides efficient visualization of large point datasets with automatic clustering based on zoom level and customizable aggregation strategies.
## Usage
@@ -105,11 +105,20 @@ The weight of each cell used for clustering.
When using the `GeoJsonLayer` accessors to style the clusters, aggregated values will be passed to the styling accessor functions.
+### Aggregation types
+
The type aggregation is infered based on the property name, for example `population_average` will be aggregated using a (mean) average operation across all the quadbin cells that are present in the cluster, while `age_min` will give the minimum value present in the cluster.
-### Valid aggregation types
+The following suffixes are supported:
-Supported aggregation types are: `any`, `average`, `count`, `min`, `max`, `sum`.
+| Suffix | Operation | Example |
+|--------|-----------|---------|
+| `_average` | Mean | `temperature_average` |
+| `_count` | Count | `point_count` |
+| `_min` | Minimum | `age_min` |
+| `_max` | Maximum | `age_max` |
+| `_sum` | Sum | `population_sum` |
+| `_any` | Any value | `category_any` |
### Global aggregation
diff --git a/docs/api-reference/carto/data-sources.md b/docs/api-reference/carto/data-sources.md
index 4296f1a2950..f3db43360ef 100644
--- a/docs/api-reference/carto/data-sources.md
+++ b/docs/api-reference/carto/data-sources.md
@@ -151,7 +151,7 @@ type QuadbinTilesetSourceOptions = {
};
```
-#### rasterTilesetSource (Experimental)
+#### rasterTilesetSource
```ts
type RasterTilesetSourceOptions = {
@@ -159,9 +159,9 @@ type RasterTilesetSourceOptions = {
};
```
-Boundary sources are experimental sources where both the tileset and the properties props need a specific schema to work. [Read more about Boundaries in the CARTO documentation](https://docs.carto.com/carto-for-developers/guides/use-boundaries-in-your-application).
+Boundary sources are sources where both the tileset and the properties props need a specific schema to work. [Read more about Boundaries in the CARTO documentation](https://docs.carto.com/carto-for-developers/guides/use-boundaries-in-your-application).
-#### boundaryTableSource (Experimental)
+#### boundaryTableSource
```ts
type BoundaryTableSourceOptions = {
@@ -171,7 +171,7 @@ type BoundaryTableSourceOptions = {
};
```
-#### boundaryQuerySource (Experimental)
+#### boundaryQuerySource
```ts
type BoundaryQuerySourceOptions = {
diff --git a/docs/api-reference/carto/h3-tile-layer.md b/docs/api-reference/carto/h3-tile-layer.md
index 372d904249a..cb1d9a50897 100644
--- a/docs/api-reference/carto/h3-tile-layer.md
+++ b/docs/api-reference/carto/h3-tile-layer.md
@@ -58,7 +58,7 @@ new deck.carto.H3TileLayer({});
## Properties
-Inherits all properties from [`H3HexagonLayer`](../geo-layers/h3-hexagon-layer.md) and [`TileLayer`](../geo-layers/tile-layer.md), with exceptions indicated below.
+Inherits all properties from [`H3HexagonLayer`](../geo-layers/h3-hexagon-layer.md) and [`TileLayer`](../geo-layers/tile-layer.md), with exceptions and additions noted below.
#### `data` (TilejsonResult) {#data}
diff --git a/docs/api-reference/carto/heatmap-tile-layer.md b/docs/api-reference/carto/heatmap-tile-layer.md
index 4ab95f16500..ad4f8f9a868 100644
--- a/docs/api-reference/carto/heatmap-tile-layer.md
+++ b/docs/api-reference/carto/heatmap-tile-layer.md
@@ -1,4 +1,4 @@
-# HeatmapTileLayer (Experimental)
+# HeatmapTileLayer
`HeatmapTileLayer` is a layer for visualizing point data aggregated using the [Quadbin Spatial Index](https://docs.carto.com/data-and-analysis/analytics-toolbox-for-bigquery/key-concepts/spatial-indexes#quadbin) using a heatmap.
@@ -17,7 +17,13 @@ function App({viewState}) {
const layer = new HeatmapTileLayer({
data,
- getWeight: d => d.properties.count
+ getWeight: d => d.properties.count,
+ // Customize appearance
+ radiusPixels: 30,
+ intensity: 1.5,
+ colorDomain: [0, 2],
+ // Optional: Track density changes
+ onMaxDensityChange: (density) => console.log('Max density:', density)
})
return ;
@@ -75,8 +81,9 @@ Use one of the following [Data Sources](./data-sources.md) to fetch this from th
#### `radiusPixels` (number, optional) ![transition-enabled](https://img.shields.io/badge/transition-enabled-green.svg?style=flat-square") {#radiuspixels}
* Default: `20`
+* Range: `[0, 100]`
-Radius of the heatmap blur in pixels, to which the weight of a cell is distributed.
+Radius of the heatmap blur in pixels, to which the weight of a cell is distributed. Larger values create a smoother heatmap but may impact performance.
#### `colorDomain` (number[2], optional) ![transition-enabled](https://img.shields.io/badge/transition-enabled-green.svg?style=flat-square") {#colordomain}
@@ -84,19 +91,25 @@ Radius of the heatmap blur in pixels, to which the weight of a cell is distribut
Controls how weight values are mapped to the `colorRange`, as an array of two numbers [`minValue`, `maxValue`]. The values are normalized, with a value of `1` corresponding to the maximum density present in the viewport.
-When `colorDomain` is specified, a pixel with `minValue` is assigned the first color in `colorRange`, a pixel with `maxValue` is assigned the last color in `colorRange`, and any value in between is interpolated. Pixels in the bottom 10% of the range defined by `colorDomain` are gradually faded out by reducing alpha, until 100% transparency at `minValue`. Pixels with weight more than `maxValue` are capped to the last color in `colorRange`.
+When `colorDomain` is specified:
+- Values below `minValue` are gradually faded out (alpha transitions from 0 to 1)
+- Values between `minValue` and `maxValue` are linearly mapped to colors in `colorRange`
+- Values above `maxValue` are capped to the last color in `colorRange`
#### `colorRange` (Color[], optional) {#colorrange}
* Default: [colorbrewer](http://colorbrewer2.org/#type=sequential&scheme=YlOrRd&n=6) `6-class YlOrRd`
-The color palette used in the heatmap, as an array of colors [color1, color2, ...]. Each color is in the format of `[r, g, b]`. Each channel is a number between 0-255.
+The color palette used in the heatmap, as an array of colors [color1, color2, ...]. Each color is in the format of `[r, g, b]` or `[r, g, b, a]`. Each channel is a number between 0-255.
#### `intensity` (number, optional) ![transition-enabled](https://img.shields.io/badge/transition-enabled-green.svg?style=flat-square") {#intensity}
* Default: `1`
-Value that is multiplied with the total weight at a pixel to obtain the final weight. A value larger than `1` biases the output color towards the higher end of the spectrum, and a value less than `1` biases the output color towards the lower end of the spectrum.
+Value that is multiplied with the total weight at a pixel to obtain the final weight:
+- Values > 1 emphasize high-density areas
+- Values < 1 emphasize low-density areas
+- Value of 1 provides linear mapping
### Data Accessors
diff --git a/docs/api-reference/carto/point-label-layer.md b/docs/api-reference/carto/point-label-layer.md
new file mode 100644
index 00000000000..1d5359e4d7b
--- /dev/null
+++ b/docs/api-reference/carto/point-label-layer.md
@@ -0,0 +1,164 @@
+# PointLabelLayer
+
+`PointLabelLayer` is a layer for rendering text labels with optional secondary labels around points. It extends the capabilities of deck.gl's `TextLayer` with features like automatic label positioning, collision detection, and support for dual-label layouts.
+
+## Usage
+
+```tsx
+import DeckGL from '@deck.gl/react';
+import {CollisionFilterExtension} from '@deck.gl/extensions';
+import {PointLabelLayer} from '@deck.gl/carto';
+
+type Airport = {
+ coordinates: [longitude: number, latitude: number];
+ name: string;
+ abbrev: string;
+};
+const AIRPORTS = 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/line/airports.json'
+
+
+function App({viewState}) {
+ const layers = [
+ new ScatterplotLayer({
+ data: AIRPORTS,
+ getPosition: d => d.coordinates,
+ radiusMinPixels: 2
+ }),
+ new PointLabelLayer({
+ data: AIRPORTS,
+ extensions: [new CollisionFilterExtension()],
+ getPosition: d => d.coordinates,
+ getText: d => d.name,
+ getSecondaryText: d => d.abbrev,
+
+ getColor: d => [2, 5, 11],
+ sizeScale: 13,
+ getSecondaryColor: d => [102, 105, 111],
+ secondarySizeScale: 10,
+
+ getTextAnchor: 'start',
+ fontSettings: {sdf: true},
+ outlineColor: [255, 255, 255],
+ outlineWidth: 2
+ }),
+ ];
+
+ return ;
+}
+```
+
+## Installation
+
+To install the dependencies from NPM:
+
+```bash
+npm install deck.gl
+# or
+npm install @deck.gl/core @deck.gl/layers @deck.gl/carto
+```
+
+```js
+import {PointLabelLayer} from '@deck.gl/carto';
+new PointLabelLayer({});
+```
+
+To use pre-bundled scripts:
+
+```html
+
+
+
+
+
+
+
+```
+
+```js
+new deck.carto.PointLabelLayer({});
+```
+
+## Properties
+
+Inherits all properties from [`TextLayer`](../layers/text-layer.md), with additional properties noted below.
+
+### Label Positioning
+
+#### `getRadius` ([Accessor<number>](../../developer-guide/using-layers.md#accessors), optional) {#getradius}
+
+* Default: `1`
+
+The radius around the point where the label should be positioned. This value is used in conjunction with `radiusScale`, `getTextAnchor`, and `getAlignmentBaseline` to determine the final label position.
+
+#### `radiusScale` (Number, optional) {#radiusscale}
+
+* Default: `1`
+
+A multiplier to scale all radii. Useful for adjusting all label positions uniformly.
+
+### Secondary Label Properties
+
+#### `getSecondaryText` ([Accessor<string>](../../developer-guide/using-layers.md#accessors), optional) {#getsecondarytext}
+
+The text to display as a secondary label. If not provided, no secondary label is shown.
+
+#### `getSecondaryColor` ([Accessor<Color>](../../developer-guide/using-layers.md#accessors), optional) {#getsecondarycolor}
+
+* Default: `[0, 0, 0, 255]`
+
+The color of the secondary text, in `[r, g, b, [a]]` format. Each channel is a number between 0-255 and `a` is 255 if not supplied.
+
+#### `secondaryOutlineColor` (Array, optional) {#secondaryoutlinecolor}
+
+* Default: `[0, 0, 0, 255]`
+
+The outline color for the secondary text, in `[r, g, b, [a]]` format. Each channel is a number between 0-255 and `a` is 255 if not supplied.
+
+#### `secondarySizeScale` (Number, optional) {#secondarysizescale}
+
+* Default: `1`
+
+Text size multiplier for the secondary label relative to the primary label size.
+
+### Label Layout
+
+The layer automatically positions labels based on the following properties:
+
+- `getTextAnchor`: Controls horizontal positioning ('start', 'middle', 'end')
+- `getAlignmentBaseline`: Controls vertical positioning ('top', 'center', 'bottom')
+- `getRadius`: Determines distance from the point
+- Background padding is automatically adjusted based on the anchor and alignment
+
+Example layouts:
+```js
+// Right-aligned labels
+{
+ getTextAnchor: 'start',
+ getAlignmentBaseline: 'center'
+}
+
+// Labels above points
+{
+ getTextAnchor: 'middle',
+ getAlignmentBaseline: 'bottom'
+}
+
+// Labels with secondary text below
+{
+ getTextAnchor: 'start',
+ getAlignmentBaseline: 'center',
+ getSecondaryText: d => d.subtitle
+}
+```
+
+### Collision Detection
+
+The layer includes built-in collision detection that:
+- Uses an enhanced background layer for collision testing
+- Only renders visible labels in collision pass
+- Maintains visual hierarchy between primary and secondary labels
+
+
+## Source
+
+[modules/carto/src/layers/point-label-layer.ts](https://github.com/visgl/deck.gl/tree/master/modules/carto/src/layers/point-label-layer.ts)
\ No newline at end of file
diff --git a/docs/api-reference/carto/quadbin-tile-layer.md b/docs/api-reference/carto/quadbin-tile-layer.md
index afae8e36710..0fdd518b4f4 100644
--- a/docs/api-reference/carto/quadbin-tile-layer.md
+++ b/docs/api-reference/carto/quadbin-tile-layer.md
@@ -58,7 +58,7 @@ new deck.carto.QuadbinTileLayer({});
## Properties
-Inherits all properties from [`QuadkeyLayer`](../geo-layers/quadkey-layer.md) and [`TileLayer`](../geo-layers/tile-layer.md), with exceptions indicated below.
+Inherits all properties from [`QuadkeyLayer`](../geo-layers/quadkey-layer.md) and [`TileLayer`](../geo-layers/tile-layer.md), with exceptions and additions noted below.
#### `data` (TilejsonResult) {#data}
diff --git a/docs/api-reference/carto/raster-tile-layer.md b/docs/api-reference/carto/raster-tile-layer.md
index e99a995636f..acc4d2c7f2f 100644
--- a/docs/api-reference/carto/raster-tile-layer.md
+++ b/docs/api-reference/carto/raster-tile-layer.md
@@ -1,4 +1,4 @@
-# RasterTileLayer (Experimental)
+# RasterTileLayer
`RasterTileLayer` is a layer for visualizing tiled raster data.
diff --git a/docs/api-reference/carto/vector-tile-layer.md b/docs/api-reference/carto/vector-tile-layer.md
index 4c15530fd60..133248f3d31 100644
--- a/docs/api-reference/carto/vector-tile-layer.md
+++ b/docs/api-reference/carto/vector-tile-layer.md
@@ -1,6 +1,6 @@
# VectorTileLayer
-`VectorTileLayer` is a layer for visualizing tiled vector data. It inherits all the properties from the [`MVTLayer`](../geo-layers/mvt-layer.md).
+`VectorTileLayer` is a layer for visualizing tiled vector data. It extends the [`MVTLayer`](../geo-layers/mvt-layer.md) with CARTO-specific optimizations for efficient vector tile rendering, including binary data format support and separate geometry/attribute loading.
## Usage
diff --git a/modules/carto/src/index.ts b/modules/carto/src/index.ts
index 093075b370e..2070f530553 100644
--- a/modules/carto/src/index.ts
+++ b/modules/carto/src/index.ts
@@ -6,7 +6,7 @@
import {default as ClusterTileLayer} from './layers/cluster-tile-layer';
import {default as H3TileLayer} from './layers/h3-tile-layer';
import {default as HeatmapTileLayer} from './layers/heatmap-tile-layer';
-import {default as _PointLabelLayer} from './layers/point-label-layer';
+import {default as PointLabelLayer} from './layers/point-label-layer';
import {default as QuadbinTileLayer} from './layers/quadbin-tile-layer';
import {default as RasterTileLayer} from './layers/raster-tile-layer';
import {default as VectorTileLayer} from './layers/vector-tile-layer';
@@ -16,7 +16,7 @@ const CARTO_LAYERS = {
ClusterTileLayer,
H3TileLayer,
HeatmapTileLayer,
- _PointLabelLayer,
+ PointLabelLayer,
QuadbinTileLayer,
RasterTileLayer,
VectorTileLayer
@@ -26,7 +26,7 @@ export {
ClusterTileLayer,
H3TileLayer,
HeatmapTileLayer,
- _PointLabelLayer,
+ PointLabelLayer,
QuadbinTileLayer,
RasterTileLayer,
VectorTileLayer
diff --git a/test/modules/carto/layers/point-label-layer.spec.ts b/test/modules/carto/layers/point-label-layer.spec.ts
index 8f049dfa0fa..defd0206db8 100644
--- a/test/modules/carto/layers/point-label-layer.spec.ts
+++ b/test/modules/carto/layers/point-label-layer.spec.ts
@@ -4,7 +4,7 @@
import test from 'tape-promise/tape';
import {testLayer} from '@deck.gl/test-utils';
-import {_PointLabelLayer as PointLabelLayer} from '@deck.gl/carto';
+import {PointLabelLayer} from '@deck.gl/carto';
import * as FIXTURES from 'deck.gl-test/data';
test('PointLabelLayer', t => {