Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions docs/api-reference/core/map-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,88 @@ new Deck({

See the `Controller` class [documentation](./controller.md#methods) for the methods that you can use and/or override.

## MapState
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each class is typically documented in their own file, however these classes are meant to always be composited into controllers, so this organization could make sense.

It'd be great to have the custom controller example expanded to include the application of this class and https://deck.gl/docs/api-reference/core/controller#example-implementing-a-custom-controller to mention ViewState


The `MapState` class manages the internal state of the map controller. It provides methods for handling user interactions like panning, rotating, and zooming.

### Usage

```js
import {MapState} from '@deck.gl/core';

// Create a MapState instance
const mapState = new MapState({
width: 800,
height: 600,
latitude: 37.7749,
longitude: -122.4194,
zoom: 11,
bearing: 0,
pitch: 0,
makeViewport: (props) => new WebMercatorViewport(props)
});

// Use MapState methods
const newState = mapState.pan({pos: [100, 100]});
const zoomedState = mapState.zoom({pos: [400, 300], scale: 2});
Comment on lines +73 to +92
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these classes are intended to be used directly like this - rather, they are to be implemented and the Controller uses them. My current understanding is these are for helping users implement extensions of core controllers:

class CustomState extends MapState {

}

class CustomController extends MapController {
  ControllerState = CustomState
}

Usage docs along these lines makes more sense then showing direct function calls

```

### Methods

MapState provides the following interaction methods:

- `panStart({pos})` - Start a pan interaction
- `pan({pos, startPos})` - Pan the map
- `panEnd()` - End a pan interaction
- `rotateStart({pos})` - Start a rotation interaction
- `rotate({pos, deltaAngleX, deltaAngleY})` - Rotate the map
- `rotateEnd()` - End a rotation interaction
- `zoomStart({pos})` - Start a zoom interaction
- `zoom({pos, startPos, scale})` - Zoom the map
- `zoomEnd()` - End a zoom interaction
- `zoomIn(speed)` - Zoom in
- `zoomOut(speed)` - Zoom out
- `moveLeft(speed)`, `moveRight(speed)`, `moveUp(speed)`, `moveDown(speed)` - Move the map
- `rotateLeft(speed)`, `rotateRight(speed)`, `rotateUp(speed)`, `rotateDown(speed)` - Rotate the map

## MapStateProps

The `MapStateProps` type defines the properties for configuring map viewport state.

### Properties

- `width` (number) - The width of the viewport
- `height` (number) - The height of the viewport
- `latitude` (number) - The latitude at the center of the viewport
- `longitude` (number) - The longitude at the center of the viewport
- `zoom` (number) - The tile zoom level of the map
- `bearing` (number, optional) - The bearing of the viewport in degrees. Default `0`
- `pitch` (number, optional) - The pitch of the viewport in degrees. Default `0`
- `altitude` (number, optional) - Specify the altitude of the viewport camera. Unit: map heights. Default `1.5`
- `position` ([number, number, number], optional) - Viewport position. Default `[0, 0, 0]`
- `maxZoom` (number, optional) - Maximum zoom level. Default `20`
- `minZoom` (number, optional) - Minimum zoom level. Default `0`
- `maxPitch` (number, optional) - Maximum pitch in degrees. Default `60`
- `minPitch` (number, optional) - Minimum pitch in degrees. Default `0`
- `normalize` (boolean, optional) - Normalize viewport props to fit map height into viewport. Default `true`

### Usage

```js
import type {MapStateProps} from '@deck.gl/core';

const viewState: MapStateProps = {
width: 800,
height: 600,
latitude: 37.7749,
longitude: -122.4194,
zoom: 11,
bearing: 0,
pitch: 45,
maxZoom: 18,
minZoom: 5
};
```

## Source

Expand Down
13 changes: 13 additions & 0 deletions docs/api-reference/layers/column-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,19 @@ Whether to generate a line wireframe of the column. The outline will have
If `true`, the vertical surfaces of the columns use [flat shading](https://en.wikipedia.org/wiki/Shading#Flat_vs._smooth_shading).
If `false`, use smooth shading. Only effective if `extruded` is `true`.

#### `capShape` (string, optional) {#capshape}

* Default: `'flat'`

The shape of the column's top cap. Available options:
- `'flat'`: Flat top (default)
- `'rounded'`: Dome-shaped top, like a silo
- `'pointy'`: Cone-shaped top, like a missile

Only effective if `extruded` is `true`.

See the [cap shape example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/pure-js/column-cap-shape) for an interactive demonstration.

#### `radiusUnits` (string, optional) {#radiusunits}

* Default: `'meters'`
Expand Down
48 changes: 48 additions & 0 deletions examples/get-started/pure-js/column-cap-shape/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# ColumnLayer Cap Shape Example

This example demonstrates the new `capShape` property for the ColumnLayer, which allows you to customize the top of columns.

## Running this example

To run this example, you need to install dependencies first:

```bash
# From the repository root
cd examples/get-started/pure-js/column-cap-shape
yarn
yarn start
```

Or to use the local development version of deck.gl:

```bash
yarn start-local
```

## Features

The example shows:
- **Cap Shape Selection**: Switch between flat (default), rounded (dome), and pointy (cone) column tops
- **Disk Resolution**: Adjust the number of sides (4-40) to see how it affects geometry smoothness
- **Interactive Controls**: Real-time updates when changing settings
- **3D Visualization**: Rotate and zoom to inspect columns from different angles

## Usage

```javascript
new ColumnLayer({
data: myData,
extruded: true,
capShape: 'rounded', // 'flat' | 'rounded' | 'pointy'
diskResolution: 20,
getPosition: d => d.position,
getElevation: d => d.elevation,
getFillColor: d => d.color
});
```

## Cap Shapes

- **`flat`** (default): Traditional flat top - preserves original behavior
- **`rounded`**: Dome-shaped top, like a silo - uses multiple latitude rings
- **`pointy`**: Cone-shaped top, like a missile - converges to a single apex point
73 changes: 73 additions & 0 deletions examples/get-started/pure-js/column-cap-shape/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// deck.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors

import {Deck} from '@deck.gl/core';
import {ColumnLayer} from '@deck.gl/layers';

// Generate sample data - grid of columns
const data = [];
for (let x = -2; x <= 2; x++) {
for (let y = -2; y <= 2; y++) {
data.push({
position: [-122.4 + x * 0.01, 37.8 + y * 0.01],
elevation: Math.random() * 3000 + 1000,
color: [
Math.floor(Math.random() * 200) + 55,
Math.floor(Math.random() * 200) + 55,
Math.floor(Math.random() * 200) + 55,
255
]
});
}
}

const INITIAL_VIEW_STATE = {
longitude: -122.4,
latitude: 37.8,
zoom: 13,
pitch: 45,
bearing: 0
};

function createLayer(capShape, diskResolution) {
return new ColumnLayer({
id: 'column-layer',
data: data,
diskResolution: diskResolution,
radius: 200,
extruded: true,
capShape: capShape, // NEW: 'flat', 'rounded', or 'pointy'
elevationScale: 1,
getPosition: d => d.position,
getFillColor: d => d.color,
getElevation: d => d.elevation,
pickable: true
});
}

// Initialize deck.gl
const deckgl = new Deck({
initialViewState: INITIAL_VIEW_STATE,
controller: true,
layers: [createLayer('flat', 20)],
getTooltip: ({object}) => object && `Elevation: ${object.elevation.toFixed(0)}m`
});

// Set up controls
const capShapeSelect = document.getElementById('capShape');
const diskResolutionSlider = document.getElementById('diskResolution');
const diskResValueSpan = document.getElementById('diskResValue');

function updateLayers() {
const capShape = capShapeSelect.value;
const diskResolution = parseInt(diskResolutionSlider.value);
diskResValueSpan.textContent = diskResolution;

deckgl.setProps({
layers: [createLayer(capShape, diskResolution)]
});
}

capShapeSelect.addEventListener('change', updateLayers);
diskResolutionSlider.addEventListener('input', updateLayers);
55 changes: 55 additions & 0 deletions examples/get-started/pure-js/column-cap-shape/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>deck.gl ColumnLayer Cap Shape Example</title>
<style>
body {
margin: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
font-family: Arial, sans-serif;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
background: white;
padding: 15px;
border-radius: 5px;
z-index: 1;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.control-group {
margin-bottom: 10px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
select, input {
width: 200px;
}
</style>
</head>
<body>
<div id="controls">
<h3>ColumnLayer Cap Shape</h3>
<div class="control-group">
<label>Cap Shape:</label>
<select id="capShape">
<option value="flat">Flat (Default)</option>
<option value="rounded">Rounded (Dome)</option>
<option value="pointy">Pointy (Cone)</option>
</select>
</div>
<div class="control-group">
<label>Disk Resolution: <span id="diskResValue">20</span></label>
<input type="range" id="diskResolution" min="4" max="40" value="20">
</div>
</div>
</body>
<script type="module" src="app.js"></script>
</html>
18 changes: 18 additions & 0 deletions examples/get-started/pure-js/column-cap-shape/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "deckgl-example-column-cap-shape",
"version": "0.0.0",
"private": true,
"license": "MIT",
"scripts": {
"start": "vite --open",
"start-local": "vite --config ../../../vite.config.local.mjs",
"build": "vite build"
},
"dependencies": {
"@deck.gl/core": "^9.0.0",
"@deck.gl/layers": "^9.0.0"
},
"devDependencies": {
"vite": "^4.0.0"
}
}
3 changes: 2 additions & 1 deletion modules/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export {default as _GlobeView} from './views/globe-view';

// Controllers
export {default as Controller} from './controllers/controller';
export {default as MapController} from './controllers/map-controller';
export {default as MapController, MapState} from './controllers/map-controller';
export {default as _GlobeController} from './controllers/globe-controller';
export {default as FirstPersonController} from './controllers/first-person-controller';
export {default as OrbitController} from './controllers/orbit-controller';
Expand Down Expand Up @@ -143,6 +143,7 @@ export type {
ViewStateChangeParameters,
InteractionState
} from './controllers/controller';
export type {MapStateProps} from './controllers/map-controller';

// INTERNAL, DO NOT USE
// @deprecated internal do not use
Expand Down
Loading