Skip to content

Commit

Permalink
Contour stroke width (#2193)
Browse files Browse the repository at this point in the history
* Contour: add support for per threshold width
* Move Contour layer from experimental-layers to layers
  • Loading branch information
1chandu committed Aug 16, 2018
1 parent 71d6df7 commit 4d9f3e5
Show file tree
Hide file tree
Showing 15 changed files with 90 additions and 50 deletions.
@@ -1,3 +1,10 @@
<!-- INJECT:"GridLayerDemo" -->

<p class="badges">
<img src="https://img.shields.io/badge/64--bit-support-blue.svg?style=flat-square" alt="64-bit" />
</p>


# ContourLayer

## About
Expand All @@ -20,12 +27,11 @@ const App = ({data, viewport}) => {
id: 'contourLayer',
// Three contours are rendered.
contours: [
{threshold: 1, color: [255, 0, 0]},
{threshold: 5, color: [0, 255, 0]},
{threshold: 10, color: [0, 0, 255]},
{threshold: 1, color: [255, 0, 0], strokeWidth: 1},
{threshold: 5, color: [0, 255, 0], strokeWidth: 2},
{threshold: 10, color: [0, 0, 255], strokeWidth: 5}
],
cellSize: 200,
getStrokeWidth: 3
getPosition: d => d.COORDINATES,
});

Expand Down Expand Up @@ -55,17 +61,15 @@ NOTE: GPU Aggregation requires WebGL2 support by the browser. When `gpuAggregati

##### `contours` (Array, optional)

* Default: `[{threshold: 1}, color: [255, 255, 255]]`
* Default: `[{threshold: 1}]`

Array of objects with following keys
* `threshold` (Number) : Threshold value to be used in contour generation.
* `color` (Array) : RGB color array to be used to render contour lines.

#### `getStrokeWidth` (Number, optional)
* `threshold` (Number) : Threshold value to be used in contour generation.

* Default: `1`
* `color` (Array, optional) : RGB color array to be used to render contour lines, if not specified a default value of `[255, 255, 255]` is used.

Width of the contour line in pixels. All contours are rendered with same width, but can have different colors using `contours` prop.
* `strokeWidth` (Number, optional) : Width of the contour line in pixels, if not specified a default value of `1` is used.

##### `fp64` (Boolean, optional)

Expand Down
20 changes: 20 additions & 0 deletions examples/layer-browser/src/examples/core-layers.js
Expand Up @@ -14,8 +14,11 @@ import {
PolygonLayer,
PathLayer,
TextLayer
// ContourLayer
} from 'deck.gl';

import ContourLayer from '@deck.gl/layers/contour-layer/contour-layer';

// Demonstrate immutable support
import * as dataSamples from '../data-samples';
import {parseColor, setOpacity} from '../utils/color';
Expand Down Expand Up @@ -238,6 +241,22 @@ const GridCellLayerExample = {
}
};

const ContourLayerExample = {
layer: ContourLayer,
getData: () => dataSamples.points,
props: {
id: 'contourLayer',
cellSize: 200,
getPosition: d => d.COORDINATES,
gpuAggregation: true,
contours: [
{threshold: 1, color: [255, 0, 0], strokeWidth: 4},
{threshold: 5, color: [0, 255, 0], strokeWidth: 2},
{threshold: 15, color: [0, 0, 255]}
]
}
};

function getMean(pts, key) {
const filtered = pts.filter(pt => Number.isFinite(pt[key]));

Expand Down Expand Up @@ -528,6 +547,7 @@ export default {
HexagonCellLayer: HexagonCellLayerExample,
HexagonLayer: HexagonLayerExample,
TextLayer: TextLayerExample,
ContourLayer: ContourLayerExample,
'TextLayer (100K)': TextLayer100KExample
},

Expand Down
21 changes: 2 additions & 19 deletions examples/layer-browser/src/examples/experimental-layers.js
Expand Up @@ -4,7 +4,7 @@ import {
PathMarkerLayer,
AdvancedTextLayer
} from '@deck.gl/experimental-layers';
import {GPUGridLayer, ContourLayer} from '@deck.gl/experimental-layers';
import {GPUGridLayer} from '@deck.gl/experimental-layers';
import {COORDINATE_SYSTEM} from 'deck.gl';
import GL from 'luma.gl/constants';
import {CylinderGeometry} from 'luma.gl';
Expand Down Expand Up @@ -196,22 +196,6 @@ const GPUGridLayerPerfExample = (id, getData) => ({
}
});

const ContourLayerExample = {
layer: ContourLayer,
getData: () => dataSamples.points,
props: {
id: 'contourLayer',
cellSize: 200,
getPosition: d => d.COORDINATES,
gpuAggregation: true,
contours: [
{threshold: 1, color: [255, 0, 0]},
{threshold: 5, color: [0, 255, 0]},
{threshold: 15, color: [0, 0, 255]}
]
}
};

/* eslint-disable quote-props */
export default {
'Experimental Layers': {
Expand All @@ -223,7 +207,6 @@ export default {
AdvancedTextLayer: AdvancedTextLayerExample,
GPUGridLayer: GPUGridLayerExample,
'GPUGridLayer (1M)': GPUGridLayerPerfExample('1M', dataSamples.getPoints1M),
'GPUGridLayer (5M)': GPUGridLayerPerfExample('5M', dataSamples.getPoints5M),
ContourLayer: ContourLayerExample
'GPUGridLayer (5M)': GPUGridLayerPerfExample('5M', dataSamples.getPoints5M)
}
};
4 changes: 2 additions & 2 deletions examples/website/line/app.js
Expand Up @@ -72,7 +72,7 @@ export class App extends Component {
const {
airports = DATA_URL.AIRPORTS,
flightPaths = DATA_URL.FLIGHT_PATHS,
strokeWidth = 3
getStrokeWidth = 3
} = this.props;

return [
Expand All @@ -89,11 +89,11 @@ export class App extends Component {
new LineLayer({
id: 'flight-paths',
data: flightPaths,
strokeWidth,
fp64: false,
getSourcePosition: d => d.start,
getTargetPosition: d => d.end,
getColor,
getStrokeWidth,
pickable: true,
onHover: this._onHover
})
Expand Down
2 changes: 0 additions & 2 deletions modules/experimental-layers/src/index.js
Expand Up @@ -17,6 +17,4 @@ export {default as GPUGridLayer} from './gpu-grid-layer/gpu-grid-layer';

export {default as BitmapLayer} from './bitmap-layer/bitmap-layer';

export {default as ContourLayer} from './contour-layer/contour-layer';

export {default as TripsLayer} from './trips-layer/trips-layer';
Expand Up @@ -28,17 +28,16 @@ import {LineLayer} from '@deck.gl/layers';
import {generateContours} from './contour-utils';

const DEFAULT_COLOR = [255, 255, 255];
const DEFAULT_STROKE_WIDTH = 1;
const DEFAULT_THRESHOLD = 1;

const defaultProps = {
// grid aggregation
cellSize: {type: 'number', min: 0, max: 1000, value: 1000},
getPosition: x => x.position,
// TODO: support for custom weights, defaults to 1

// contour lines
contours: [{threshold: DEFAULT_THRESHOLD, color: DEFAULT_COLOR}],
getStrokeWidth: 1,
contours: [{threshold: DEFAULT_THRESHOLD}],

fp64: false
};
Expand Down Expand Up @@ -76,7 +75,7 @@ export default class ContourLayer extends CompositeLayer {
}

getSubLayerProps() {
const {getStrokeWidth, fp64} = this.props;
const {fp64} = this.props;

return super.getSubLayerProps({
id: 'contour-line-layer',
Expand All @@ -85,7 +84,7 @@ export default class ContourLayer extends CompositeLayer {
getSourcePosition: d => d.start,
getTargetPosition: d => d.end,
getColor: this.onGetSublayerColor.bind(this),
getStrokeWidth
getStrokeWidth: this.onGetSublayerStrokeWidth.bind(this)
});
}

Expand Down Expand Up @@ -147,12 +146,26 @@ export default class ContourLayer extends CompositeLayer {
let color = DEFAULT_COLOR;
contours.forEach(data => {
if (data.threshold === segment.threshold) {
color = data.color;
color = data.color || DEFAULT_COLOR;
}
});
return color;
}

onGetSublayerStrokeWidth(segment) {
const {contours} = this.props;
let strokeWidth = DEFAULT_STROKE_WIDTH;
// Linearly searches the contours, but there should only be few contours
contours.some(contour => {
if (contour.threshold === segment.threshold) {
strokeWidth = contour.strokeWidth || DEFAULT_STROKE_WIDTH;
return true;
}
return false;
});
return strokeWidth;
}

rebuildContours({oldProps, props}) {
if (oldProps.contours.length !== props.contours.length) {
return true;
Expand Down
2 changes: 2 additions & 0 deletions modules/layers/src/index.js
Expand Up @@ -39,6 +39,8 @@ export {default as GeoJsonLayer} from './geojson-layer/geojson-layer';

export {default as TextLayer} from './text-layer/text-layer';

export {default as ContourLayer} from './contour-layer/contour-layer';

// Experimental layer exports
export {default as _SolidPolygonLayer} from './solid-polygon-layer/solid-polygon-layer';
export {default as _MultiIconLayer} from './text-layer/multi-icon-layer/multi-icon-layer';
9 changes: 4 additions & 5 deletions test/apps/svg-interoperability/app.js
Expand Up @@ -3,7 +3,7 @@
import React, {PureComponent} from 'react';
import {render} from 'react-dom';
import DeckGL, {COORDINATE_SYSTEM, ScatterplotLayer, OrthographicView} from 'deck.gl';
import {ContourLayer} from '@deck.gl/experimental-layers';
import ContourLayer from '@deck.gl/layers/contour-layer/contour-layer';

const DEGREE_TO_RADIAN = Math.PI / 180;
const NUM_POINTS = 20000;
Expand Down Expand Up @@ -142,11 +142,10 @@ class Root extends PureComponent {
],
coordinateSystem: COORDINATE_SYSTEM.IDENTITY,
cellSize: 20,
getStrokeWidth: 4,
contours: [
{threshold: 2, color: [0, 250, 250]},
{threshold: 25, color: [0, 150, 150]},
{threshold: 50, color: [0, 100, 100]}
{threshold: 2, color: [0, 250, 250], strokeWidth: 6},
{threshold: 25, color: [0, 150, 150], strokeWidth: 5},
{threshold: 50, color: [0, 100, 100], strokeWidth: 4}
],
gpuAggregation: true
});
Expand Down
@@ -1,5 +1,5 @@
import test from 'tape-catch';
import {getCode, getVertices} from '@deck.gl/experimental-layers/contour-layer/marching-squares';
import {getCode, getVertices} from '@deck.gl/layers/contour-layer/marching-squares';

const GETCODE_TESTS = [
{
Expand Down
Binary file modified test/render/golden-images/contour-lnglat.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 4 additions & 5 deletions test/render/test-cases.js
@@ -1,6 +1,6 @@
import * as dataSamples from '../../examples/layer-browser/src/data-samples';
import {parseColor, setOpacity} from '../../examples/layer-browser/src/utils/color';
import {GPUGridLayer, ContourLayer} from '@deck.gl/experimental-layers';
import {GPUGridLayer} from '@deck.gl/experimental-layers';
import GL from 'luma.gl/constants';
import {OrbitView, OrthographicView} from 'deck.gl';

Expand Down Expand Up @@ -30,6 +30,7 @@ import {
PointCloudLayer,
TextLayer
} from 'deck.gl';
import ContourLayer from '@deck.gl/layers/contour-layer/contour-layer';

const LIGHT_SETTINGS = {
lightsPosition: [-122.45, 37.66, 8000, -122.0, 38.0, 8000],
Expand Down Expand Up @@ -210,7 +211,6 @@ export const TEST_CASES = [
coordinateSystem: COORDINATE_SYSTEM.IDENTITY,
cellSize: 40,
opacity: 1,
getStrokeWidth: 3,
contours: [
{threshold: 1, color: [50, 50, 50]},
{threshold: 2, color: [100, 100, 100]},
Expand Down Expand Up @@ -1146,10 +1146,9 @@ export const TEST_CASES = [
opacity: 1,
getPosition: d => d.COORDINATES,
lightSettings: LIGHT_SETTINGS,
getStrokeWidth: 3,
contours: [
{threshold: 1, color: [255, 0, 0]},
{threshold: 5, color: [0, 255, 0]},
{threshold: 1, color: [255, 0, 0], strokeWidth: 6},
{threshold: 5, color: [0, 255, 0], strokeWidth: 3},
{threshold: 15, color: [0, 0, 255]}
],
gpuAggregation: true
Expand Down
4 changes: 4 additions & 0 deletions website/contents/pages.js
Expand Up @@ -366,6 +366,10 @@ export const docPages = generatePath([
name: 'ArcLayer',
content: getDocUrl('layers/arc-layer.md')
},
{
name: 'ContourLayer',
content: getDocUrl('layers/contour-layer.md')
},
{
name: 'GeoJsonLayer',
content: getDocUrl('layers/geojson-layer.md')
Expand Down
18 changes: 18 additions & 0 deletions website/src/components/demos/layer-demos.js
Expand Up @@ -16,6 +16,7 @@ import {
GeoJsonLayer,
PointCloudLayer
} from 'deck.gl';
import ContourLayer from '@deck.gl/layers/contour-layer/contour-layer';

import {colorToRGBArray} from '../../utils/format-utils';

Expand Down Expand Up @@ -210,3 +211,20 @@ export const TextLayerDemo = createLayerDemoClass({
getAlignmentBaseline: 'center'
}
});

export const ContourLayerDemo = createLayerDemoClass({
Layer: ContourLayer,
dataUrl: `${DATA_URI}/sf-bike-parking.json`,
formatTooltip: d => `${d.position.join(', ')}\nCount: ${d.count}`,
props: {
pickable: true,
cellSize: 200,
elevationScale: 4,
getPosition: d => d.COORDINATES,
contours: [
{threshold: 1, color: [255, 0, 0], strokeWidth: 6},
{threshold: 5, color: [0, 255, 0], strokeWidth: 3},
{threshold: 15, color: [0, 0, 255]}
]
}
});

0 comments on commit 4d9f3e5

Please sign in to comment.