Skip to content

Commit

Permalink
Draw polygon by dragging mode (#362)
Browse files Browse the repository at this point in the history
  • Loading branch information
keller-mark committed Mar 23, 2020
1 parent eb8328d commit 42547d4
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 1 deletion.
11 changes: 11 additions & 0 deletions docs/api-reference/modes/overview.md
Expand Up @@ -91,6 +91,17 @@ User can draw a new `Polygon` feature by clicking positions to add then closing

User can draw a new `Polygon` feature with 90 degree corners (right angle) by clicking positions to add then closing the polygon (or double-clicking). After clicking the 2 points, the draw mode guides/allows to have right angle polygon.

## [DrawPolygonByDraggingMode](https://github.com/uber/nebula.gl/blob/master/modules/edit-modes/src/lib/draw-polygon-by-dragging-mode.js)

User can draw a new `Polygon` feature by dragging (similar to the lasso tool commonly found in photo editing software).

### ModeConfig

The following options can be provided in the `modeConfig` object:

* `throttleMs` (optional): `number`
* If provided, the dragging function will be throttled by the specified number of milliseconds.

## [DrawRectangleMode](https://github.com/uber/nebula.gl/blob/master/modules/edit-modes/src/lib/draw-rectangle-mode.js)

User can draw a new rectangular `Polygon` feature by clicking two opposing corners of the rectangle.
Expand Down
8 changes: 8 additions & 0 deletions examples/advanced/example.js
Expand Up @@ -32,6 +32,7 @@ import {
DrawEllipseUsingThreePointsMode,
DrawRectangleUsingThreePointsMode,
Draw90DegreePolygonMode,
DrawPolygonByDraggingMode,
MeasureDistanceMode,
MeasureAreaMode,
MeasureAngleMode,
Expand Down Expand Up @@ -96,6 +97,7 @@ const ALL_MODES = [
{ label: 'Draw LineString', mode: DrawLineStringMode },
{ label: 'Draw Polygon', mode: DrawPolygonMode },
{ label: 'Draw 90° Polygon', mode: Draw90DegreePolygonMode },
{ label: 'Draw Polygon By Dragging', mode: DrawPolygonByDraggingMode },
{ label: 'Draw Rectangle', mode: DrawRectangleMode },
{ label: 'Draw Rectangle Using 3 Points', mode: DrawRectangleUsingThreePointsMode },
{ label: 'Draw Circle From Center', mode: DrawCircleFromCenterMode },
Expand Down Expand Up @@ -127,6 +129,7 @@ const ALL_MODES = [
const POLYGON_DRAWING_MODES = [
DrawPolygonMode,
Draw90DegreePolygonMode,
DrawPolygonByDraggingMode,
DrawRectangleMode,
DrawRectangleUsingThreePointsMode,
DrawCircleFromCenterMode,
Expand Down Expand Up @@ -878,6 +881,11 @@ export default class Example extends Component<
}
]
};
} else if (mode === DrawPolygonByDraggingMode) {
modeConfig = {
...modeConfig,
throttleMs: 100
};
}

// Demonstrate how to override sub layer properties
Expand Down
1 change: 1 addition & 0 deletions modules/edit-modes/package.json
Expand Up @@ -67,6 +67,7 @@
"@turf/transform-scale": ">=4.0.0",
"@turf/transform-translate": ">=4.0.0",
"@turf/union": ">=4.0.0",
"lodash.throttle": "^4.1.1",
"viewport-mercator-project": ">=6.0.0"
}
}
1 change: 1 addition & 0 deletions modules/edit-modes/src/index.js
Expand Up @@ -24,6 +24,7 @@ export { DrawEllipseByBoundingBoxMode } from './lib/draw-ellipse-by-bounding-box
export { DrawEllipseUsingThreePointsMode } from './lib/draw-ellipse-using-three-points-mode.js';
export { DrawRectangleUsingThreePointsMode } from './lib/draw-rectangle-using-three-points-mode.js';
export { Draw90DegreePolygonMode } from './lib/draw-90degree-polygon-mode.js';
export { DrawPolygonByDraggingMode } from './lib/draw-polygon-by-dragging-mode.js';
export { ImmutableFeatureCollection } from './lib/immutable-feature-collection.js';

// Other modes
Expand Down
72 changes: 72 additions & 0 deletions modules/edit-modes/src/lib/draw-polygon-by-dragging-mode.js
@@ -0,0 +1,72 @@
// @flow

import throttle from 'lodash.throttle';
import type {
ClickEvent,
StartDraggingEvent,
StopDraggingEvent,
DraggingEvent,
ModeProps
} from '../types.js';
import type { Polygon, FeatureCollection } from '../geojson-types.js';
import { getPickedEditHandle } from '../utils.js';
import { DrawPolygonMode } from './draw-polygon-mode';

type DraggingHandler = (event: DraggingEvent, props: ModeProps<FeatureCollection>) => void;

export class DrawPolygonByDraggingMode extends DrawPolygonMode {
handleDraggingThrottled: ?DraggingHandler = null;

handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
// No-op
}

handleStartDragging(event: StartDraggingEvent, props: ModeProps<FeatureCollection>) {
event.cancelPan();
if (props.modeConfig && props.modeConfig.throttleMs) {
this.handleDraggingThrottled = throttle(this.handleDraggingAux, props.modeConfig.throttleMs);
} else {
this.handleDraggingThrottled = this.handleDraggingAux;
}
}

handleStopDragging(event: StopDraggingEvent, props: ModeProps<FeatureCollection>) {
this.addClickSequence(event);
const clickSequence = this.getClickSequence();

if (this.handleDraggingThrottled && this.handleDraggingThrottled.cancel) {
this.handleDraggingThrottled.cancel();
}

if (clickSequence.length > 2) {
// Complete the polygon.
const polygonToAdd: Polygon = {
type: 'Polygon',
coordinates: [[...clickSequence, clickSequence[0]]]
};

this.resetClickSequence();

const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props);
if (editAction) {
props.onEdit(editAction);
}
}
}

handleDraggingAux(event: DraggingEvent, props: ModeProps<FeatureCollection>) {
const { picks } = event;
const clickedEditHandle = getPickedEditHandle(picks);

if (!clickedEditHandle) {
// Don't add another point right next to an existing one.
this.addClickSequence(event);
}
}

handleDragging(event: DraggingEvent, props: ModeProps<FeatureCollection>) {
if (this.handleDraggingThrottled) {
this.handleDraggingThrottled(event, props);
}
}
}
4 changes: 3 additions & 1 deletion modules/layers/src/layers/editable-geojson-layer.js
Expand Up @@ -23,6 +23,7 @@ import {
DrawRectangleUsingThreePointsMode,
DrawEllipseUsingThreePointsMode,
Draw90DegreePolygonMode,
DrawPolygonByDraggingMode,
SnappableMode,
TransformMode
} from '@nebula.gl/edit-modes';
Expand Down Expand Up @@ -184,7 +185,8 @@ const modeNameMapping = {
drawEllipseByBoundingBox: DrawEllipseByBoundingBoxMode,
drawRectangleUsing3Points: DrawRectangleUsingThreePointsMode,
drawEllipseUsing3Points: DrawEllipseUsingThreePointsMode,
draw90DegreePolygon: Draw90DegreePolygonMode
draw90DegreePolygon: Draw90DegreePolygonMode,
drawPolygonByDragging: DrawPolygonByDraggingMode
};

type Props = {
Expand Down
1 change: 1 addition & 0 deletions modules/main/src/index.js
Expand Up @@ -50,6 +50,7 @@ export { DrawEllipseByBoundingBoxMode } from '@nebula.gl/edit-modes';
export { DrawEllipseUsingThreePointsMode } from '@nebula.gl/edit-modes';
export { DrawRectangleUsingThreePointsMode } from '@nebula.gl/edit-modes';
export { Draw90DegreePolygonMode } from '@nebula.gl/edit-modes';
export { DrawPolygonByDraggingMode } from '@nebula.gl/edit-modes';
export { ImmutableFeatureCollection } from '@nebula.gl/edit-modes';

// Other modes
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 42547d4

Please sign in to comment.