Skip to content

Commit

Permalink
Update doc based on suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
Xintong Xia committed May 22, 2019
1 parent 7c6201c commit 8cc0f44
Showing 1 changed file with 35 additions and 43 deletions.
78 changes: 35 additions & 43 deletions dev-docs/RFCs/v1.0/react-map-gl-draw.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
react-map-gl currently does not support drawing functions. However, we have got a couple of [users](https://github.com/uber/react-map-gl/issues/725) interested in this capability. Also it is one of P0 features on Kepler.gl 2019 [roadmap](https://github.com/uber/kepler.gl/wiki/Kepler.gl-2019-Roadmap#allow-drawing-on-map-to-create-paths-and-polygons--).

Although [Mapbox/mapbox-gl-draw](https://github.com/mapbox/mapbox-gl-draw) provides quite nice drawing and editing features, because of its manipulating internal states, it cannot work well with React / Redux framework and therefore cannot be integrated with `react-map-gl`.
[vis.gl](http://vis.gl/) offers another geo editing library [Nebula.gl](http://neb.gl), but it is an overkill while adding heavy dependencies such as deck.gl.
[Nebula.gl](http://neb.gl) provides geo editing functionality, however it heavily depends on `deck.gl`.

## Proposal

`react-map-gl` can provide a `EditorModes`, starts from simple functions like the following.
`react-map-gl-draw` is a react based geo editing library, providing functions like the following.

### Options
- `MapContextProvider` (React.Component, required) - A [Context.Provider](https://reactjs.org/docs/context.html#contextprovider) component. If supplied, will be rendered as the ancestor to all children. The passed through context contains the following values:
- `viewport` ([Viewport](/docs/api-reference/viewport.md)) - the current viewport
- `eventManager` ([EventManager](https://github.com/uber-web/mjolnir.js/blob/master/docs/api-reference/event-manager.md))

- `mode` (String, Optional) - `react-map-gl` is stateless, user has complete control of the `mode`.
- `EditorModes.READ_ONLY` - Not interactive. This is the default mode.
Expand All @@ -22,37 +25,33 @@ Although [Mapbox/mapbox-gl-draw](https://github.com/mapbox/mapbox-gl-draw) provi
- `EditorModes.DRAW_POINT` - Lets you draw a Point feature.
- `EditorModes.DRAW_RECTANGLE` - Lets you draw a Rectangle feature.

- `getStyle` (Function, Optional) : Object
- `getFeatureStyle` (Function, Optional) : Object - A function to style features, function parameters are
- `feature`: feature to style
- `featureState`: one of `SELECTED`, `HOVERED`, `INACTIVE`, `UNCOMMITTED`

A function to style features, function parameters are
Return is a map of [style objects](https://reactjs.org/docs/dom-elements.html#style) passed to SVG `circle` or `rect` elements.

- `feature`: feature to style
- `featureState`: one of `SELECTED`, `HOVERED`, `INACTIVE`, `UNCOMMITTED`
- `vertexId`: id of vertex to style
- `getVertexStyle` (Function, Optional) : Object
- `vertexIndex`: index of vertex to style
- `vertexState`: one of `SELECTED`, `HOVERED`, `INACTIVE`, `UNCOMMITTED`

Return is a map of [style objects](https://reactjs.org/docs/dom-elements.html#style) passed to SVG `path` elements.

Return is a map of [style objects](https://reactjs.org/docs/dom-elements.html#style) passed to DOM elements. The following keys are supported.
- `vertex` (Object, Optional)
- `shape` - `rect` or `circle`
- `clickRadius` (Number, optional) - Radius to detect features around a hovered or clicked point. fall back to radius. Default value is `0`
- any style which could be applied to SVG `circle|rect`.
- `line` (Object, Optional):
- `clickRadius`: (Number, Optional) - Radius to detect features around a hovered or clicked point line. Default is `0`
- any style which could be applied to SVG `path`
- `vertexShape` (String, Optional): `rect` or `circle`.
- `clickRadius` (Number, optional) - Radius to detect features around a hovered or clicked point. fall back to radius. Default value is `0`

- `features` (Array, Optional) - A list of Point, LineString, or Polygon features.
- `selectedId` (String, Optional) - id of the selected feature. `EditorModes` assigns a unique id to each feature which is stored in `feature.properties.id`.
- `selectedFeatureId` (String, Optional) - id of the selected feature. `EditorModes` assigns a unique id to each feature which is stored in `feature.properties.id`.

- `onSelect` (Function, Required) - callback when a feature is selected. Receives an object containing `{selectedId}`.
- `onUpdate` (Function, Required) - callback when anything is updated. Receives one argument `features` that is the updated list of GeoJSON features.
- `onAdd` (Function, Optional) - callback when a new feature is finished drawing. Receives one argument `featureId`.
- `onDelete` (Function, Optional) - callback when a feature is being deleted. Receives one argument `featureId`.


### Code Example
```js
import React, { Component } from "react";
import MapGL from 'react-map-gl';
import { Editor, EditorModes } from 'react-map-gl-draw';
import React, { Component } from 'react';
import MapGL, {_MapContext as MapContext} from 'react-map-gl';
import MapGLDraw, { EditorModes } from 'react-map-gl-draw';

const MODES = [
{ id: EditorModes.EDIT_VERTEX, text: 'Select and Edit Feature'},
Expand All @@ -77,7 +76,6 @@ class App extends Component {
features: [],
selectedFeatureId: null
};
this._mapRef = null;
}

_updateViewport = (viewport) => {
Expand Down Expand Up @@ -112,19 +110,17 @@ class App extends Component {
);
}

_getStyle = ({feature, featureState, vertexId, vertexState}) => {
_getVertexStyle = ({feature, featureState, vertexId, vertexState}) => {
return {
vertex: {
clickRadius: 12,
shape: `rect`,
fill: vertexState === `SELECTED` ? '#000' : '#aaa'
},
line: {
clickRadius: 12,
shape: `rect`,
fill: featureState === `SELECTED` ? '#080' : 'none',
fillOpacity: 0.8
}
fill: vertexState === `SELECTED` ? '#000' : '#aaa',
stroke: vertexState === `SELECTED` ? '#000' : 'none'
}
}

_getFeatureStyle = (feature, featureState) => {
return {
fill: featureState === `SELECTED` ? '#080' : 'none',
fillOpacity: 0.8
}
}

Expand All @@ -133,32 +129,28 @@ class App extends Component {
return (
<MapGL
{...viewport}
ref={_ => (this._mapRef = _)}
width="100%"
height="100%"
mapStyle="mapbox://styles/uberdata/cive48w2e001a2imn5mcu2vrs"
onViewportChange={this._updateViewport}
>
<Editor
viewport={viewport}
eventManager={this._mapRef && this._mapRef._eventManager}
width="100%"
height="100%"
<MapGLDraw
MapContextProvider={MapContext.Provider}
mode={selectedMode}
features={features}
selectedFeatureId={selectedFeatureId}
onSelect={this._onSelect}
onUpdate={this._onUpdate}
getStyle={this._getStyle}
/>
{this._renderToolbar()}
{this._renderControlPanel()}
</MapGL>
);
}
}
```

## Compare with `mapbox-gl-draw`
- `EditorModes` is a stateless component. To manipulate the features, simply change the `features` prop. This is different from calling the class methods of `MapboxDraw`.
- `EditorModes` does not contain UI for mode selection, giving user application the flexibility to control their user experience.
- react-map-gl-draw a stateless component. To manipulate the features, simply change the `features` prop. This is different from calling the class methods of `MapboxDraw`.
- react-map-gl-draw does not contain UI for mode selection, giving user application the flexibility to control their user experience.
- Features of `MapboxDraw` that are not planned for the initial release of `EditorModes`: keyboard navigation, box select.

0 comments on commit 8cc0f44

Please sign in to comment.