1 | # React Map GL Draw
|
2 |
|
3 | `react-map-gl-draw` is a react based drawing library tailored for [`react-map-gl`](https://github.com/uber/react-map-gl).
|
4 |
|
5 | ## Options
|
6 | - `mode` (String, Optional)
|
7 | - `EditorModes.READ_ONLY` - Not interactive. This is the default mode.
|
8 | - `EditorModes.SELECT` - Lets you select, delete, and drag features.
|
9 | - `EditorModes.EDITTING` - Lets you select, delete, and drag vertices; and drag features.
|
10 | - `EditorModes.DRAW_PATH` - Lets you draw a GeoJson `LineString` feature.
|
11 | - `EditorModes.DRAW_POLYGON` - Lets you draw a GeoJson `Polygon` feature.
|
12 | - `EditorModes.DRAW_POINT` - Lets you draw a GeoJson `Point` feature.
|
13 | - `EditorModes.DRAW_RECTANGLE` - Lets you draw a `Rectangle` (represented as GeoJson `Polygon` feature).
|
14 |
|
15 | - `features` (Feature[], Optional) - List of features in GeoJson format. If `features` are provided from users, then `react-map-gl-draw` respect the users' input, and therefore ignore any internal `features`. But if `features` are not provided, then `react-map-gl-draw` manages `features` internally, and users can access and manipulate the features by calling `getFeatures`, `addFeatures`, and `deleteFeatures`.
|
16 | - `selectedFeatureIndex` (String, Optional) - Index of the selected feature.
|
17 | - `clickRadius` (Number, Optional) - Radius to detect features around a hovered or clicked point. Default value is `0`
|
18 |
|
19 | - `onSelect` (Function, Optional) - callback when clicking a position under `SELECT` and `EDITTING` mode. Receives an object containing the following parameters
|
20 | - `selectedFeature`: selected feature. `null` if clicked an empty space.
|
21 | - `selectedFeatureIndex`: selected feature index.`null` if clicked an empty space.
|
22 | - `editHandleIndex`: selected editHandle index. `null` if clicked an empty space.
|
23 | - `screenCoords`: screen coordinates of the clicked position.
|
24 | - `mapCoords`: map coordinates of the clicked position.
|
25 |
|
26 | - `onUpdate` (Function, Optional) - callback when anything is updated. Receives an object containing the following parameters
|
27 | - `features` (Feature[]) - the updated list of GeoJSON features.
|
28 | - `editType` (String) - `addFeature`, `addPosition`, `finishMovePosition`
|
29 | - `editContext` (Array) - list of edit objects, depend on `editType`, each object may contain `featureIndexes`, `editHandleIndexes`, `screenCoords`, `mapCoords`.
|
30 |
|
31 | **Feature object structure:**
|
32 | ```js
|
33 | {
|
34 | id, // an unique identified generated inside react-map-gl-draw library
|
35 | geometry: {
|
36 | coordinates, // latitude longitude pairs of the geometry points
|
37 | type // geojson type, one of `Point`, `LineString`, or `Polygon`
|
38 | },
|
39 | properties: {
|
40 | renderType, // Mainly used for styling, one of `Point`, `LineString`, `Polygon`, or `Rectangle`. Different from `geometry.type`. i.e. a rectangle's renderType is `Rectangle`, and `geometry.type` is `Polygon`. An incomplete (not closed) Polygon's renderType is `Polygon`, `geometry.type` is `LineString`
|
41 | ...otherProps // other properties user passed in
|
42 | }
|
43 | }
|
44 | ```
|
45 |
|
46 | ### Styling related options
|
47 | - `featureStyle` (Object|Function, Optional) : Object - Either a [style objects](https://reactjs.org/docs/dom-elements.html#style) or a function to style a feature, function parameters are
|
48 | - `feature`: feature to style.
|
49 | - `index`: index of the feature.
|
50 | - `state`: one of `SELECTED`, `HOVERED`, `INACTIVE`, `UNCOMMITTED`, `CLOSING`.
|
51 |
|
52 | Returns is a map of [style objects](https://reactjs.org/docs/dom-elements.html#style) passed to SVG `path` elements.
|
53 |
|
54 | - `featureShape` (String|Function, Optional): if is a string, should be one of `rect` or `circle`. If is a function, will receive the following parameters
|
55 | - `feature`: feature to style.
|
56 | - `index`: index of the feature.
|
57 | - `state`: one of `SELECTED`, `HOVERED`, `INACTIVE`, `UNCOMMITTED`, `CLOSING`.
|
58 |
|
59 | - `editHandleStyle` (Object|Function, Optional) : Object - Either a [style objects](https://reactjs.org/docs/dom-elements.html#style) or a function to style an `editHandle, function parameters are
|
60 | - `feature`: feature to style.
|
61 | - `index`: index of the editHandle vertex in the feature.
|
62 | - `state`: one of `SELECTED`, `HOVERED`, `INACTIVE`, `UNCOMMITTED`, `CLOSING`.
|
63 | - `shape`: shape resolved from `editHandleShape`.
|
64 |
|
65 | Returns is a map of [style objects](https://reactjs.org/docs/dom-elements.html#style) passed to SVG `circle` or `rect` elements.
|
66 |
|
67 | - `editHandleShape` (String|Function, Optional): if is a string, should be one of `rect` or `circle`. If is a function, will receive the following parameters
|
68 | - `feature`: feature to style.
|
69 | - `index`: index of the editHandle vertex in the feature.
|
70 | - `state`: one of `SELECTED`, `HOVERED`, `INACTIVE`, `UNCOMMITTED`, `CLOSING`.
|
71 |
|
72 | ## Explanations
|
73 | - `Feature`: any drawn shape, one of point, line, polygon or rectangle.
|
74 | - `EditHandle`: vertex of the feature being edited.
|
75 |
|
76 | ### State related concepts:
|
77 | - `INACTIVE`: neither selected nor hovered, default state of a complete `feature` or `editHandle`.
|
78 | - `SELECTED`: being clicked or dragged.
|
79 | - `HOVERED`: hovered over by the mouse pointer.
|
80 | - `UNCOMMITTED`: in the middle of drawing, not yet added to the feature being edited.
|
81 | - `CLOSING`: closing a polygon.
|
82 |
|
83 | ### Styling based on `state`:
|
84 |
|
85 | ![img](https://raw.githubusercontent.com/uber-common/deck.gl-data/master/nebula.gl/react-map-gl-draw.png)
|
86 |
|
87 | As shown in the above image, for the feature currently being edited,
|
88 | - `featureStyle({feature, state: SELECTED})` will be applied to the committed parts of the feature. (Green strokes)
|
89 | - `editHandleStyle({state: SELECTED})` will be applied to the committed editHandle vertices. (Vertices with black stroke)
|
90 | - `featureStyle({feature, state: UNCOMMITTED})` will be applied to the uncommitted parts of the feature. (Gray stroke)
|
91 | - `editHandleStyle({state: UNCOMMITTED})` will be applied to the uncommitted editHandle vertex. (Gray vertex)
|
92 |
|
93 | ## Methods
|
94 |
|
95 | ##### `getFeatures`
|
96 |
|
97 | - Return a list of finished GeoJson features.
|
98 |
|
99 | ##### `addFeatures` (Feature | Feature[])
|
100 |
|
101 | - Add a single or multiple GeoJson features to editor.
|
102 |
|
103 | ##### `deleteDeatures` (Feature | Feature[])
|
104 |
|
105 | - Delete a single or multiple GeoJson features to editor.
|
106 |
|
107 | ## Code Example
|
108 | ```js
|
109 | import React, { Component } from 'react';
|
110 | import MapGL from 'react-map-gl';
|
111 | import { Editor, EditorModes } from 'react-map-gl-draw';
|
112 |
|
113 | const MODES = [
|
114 | { id: EditorModes.EDITING, text: 'Select and Edit Feature'},
|
115 | { id: EditorModes.DRAW_POINT, text: 'Draw Point'},
|
116 | { id: EditorModes.DRAW_PATH, text: 'Draw Polyline'},
|
117 | { id: EditorModes.DRAW_POLYGON, text: 'Draw Polygon'},
|
118 | { id: EditorModes.DRAW_RECTANGLE, text: 'Draw Rectangle'}
|
119 | ];
|
120 |
|
121 | const DEFAULT_VIEWPORT = {
|
122 | width: 800,
|
123 | height: 600,
|
124 | longitude: -122.45,
|
125 | latitude: 37.78,
|
126 | zoom: 14
|
127 | };
|
128 |
|
129 | class App extends Component {
|
130 | state = {
|
131 | // map
|
132 | viewport: DEFAULT_VIEWPORT,
|
133 | // editor
|
134 | selectedMode: EditorModes.READ_ONLY
|
135 | };
|
136 |
|
137 | _switchMode = evt => {
|
138 | const selectedMode = evt.target.id;
|
139 | this.setState({
|
140 | selectedMode: selectedMode === this.state.selectedMode ? null : selectedMode
|
141 | });
|
142 | };
|
143 |
|
144 | _renderToolbar = () => {
|
145 | return (
|
146 | <div style={{position: absolute, top: 0, right: 0, maxWidth: '320px'}}>
|
147 | <select onChange={this._switchMode}>
|
148 | <option value="">--Please choose a mode--</option>
|
149 | {MODES.map(mode => <option value={mode.id}>{mode.text}</option>)}
|
150 | </select>
|
151 | </div>
|
152 | );
|
153 | };
|
154 |
|
155 | render() {
|
156 | const { viewport, selectedMode } = this.state;
|
157 | return (
|
158 | <MapGL
|
159 | {...viewport}
|
160 | width="100%"
|
161 | height="100%"
|
162 | mapStyle={'mapbox://styles/mapbox/light-v9'}
|
163 | onViewportChange={this.setState({ viewport })}
|
164 | >
|
165 | <Editor
|
166 | clickRadius={12}
|
167 | mode={selectedMode}
|
168 | />
|
169 | {this._renderToolbar()}
|
170 | </MapGL>
|
171 | );
|
172 | }
|
173 | }
|
174 | ```
|