amaury1093 / react-mapbox-gl-draw Goto Github PK
View Code? Open in Web Editor NEWDraw tools for Mapbox with React: πΊοΈ react-mapbox-gl + ποΈ mapbox-gl-draw
License: MIT License
Draw tools for Mapbox with React: πΊοΈ react-mapbox-gl + ποΈ mapbox-gl-draw
License: MIT License
I can show my existing feature in the map, but it has no editable form such as pan, uncombine or etc. which exist in draw control.
actually I can not access
get(featureId: string): ?Feature,
getFeatureIdsAt(point: { x: number, y: number }): Array,
etc
which is existing in mapbox-gl-draw
checkPropTypes.js:19 Warning: Failed context type: The context map
is marked as required in DrawControl
, but its value is undefined
.
this problem occurred during installation
1: create controls state
state =
controls: {
polygon: true,
trash: true,
},
}
controls not hide in jsx.
If a map is initialized with some feature, the drawcontrol doesn't handle them.
To replicate the problem:
import React from "react";
import ReactDOM from "react-dom";
import ReactMapboxGl, {GeoJSONLayer} from "react-mapbox-gl";
import DrawControl from "react-mapbox-gl-draw";
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
import "./styles.css";
const geojsonStyles = {
linePaint: {
"line-color": "#ff11ff",
"line-width": 4,
"line-opacity": 1
}
}
const data = {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': [[-0.23,51.54], [90,0]]
}
}
const Map = ReactMapboxGl({
accessToken:
"pk.eyJ1IjoiZmFrZXVzZXJnaXRodWIiLCJhIjoiY2pwOGlneGI4MDNnaDN1c2J0eW5zb2ZiNyJ9.mALv0tCpbYUPtzT7YysA2g"
});
function App() {
const onDrawCreate = ({ features }) => {
console.log(features);
};
const onDrawUpdate = ({ features }) => {
console.log(features);
};
return (
<div>
<h2>Welcome to react-mapbox-gl-draw</h2>
<Map
style="mapbox://styles/mapbox/streets-v9" // eslint-disable-line
containerStyle={{
height: "600px",
width: "100vw"
}}
>
<DrawControl onDrawCreate={onDrawCreate} onDrawUpdate={onDrawUpdate} />
<GeoJSONLayer {...geojsonStyles} data={data} />
</Map>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
-> the drawcontrol doesn't act on the pre-existing line.
A code sandbox for this behaviour is available at: https://codesandbox.io/s/infallible-poitras-lpwr41
I implemented the example and am getting: Uncaught TypeError: Cannot read property 'addControl' of undefined.
Here is my map component:
`import React, {Component} from 'react';
import ReactMapboxGl from "react-mapbox-gl";
import DrawControl from "react-mapbox-gl-draw";
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
const Map = ReactMapboxGl({
accessToken:
'<my_access_token>'
});
class MapboxMap extends Component {
onDrawCreate = ({ features }) => {
console.log(features);
};
onDrawUpdate = ({ features }) => {
console.log({ features });
};
render(){
return <div style={{
height: '100%',
width: '100%'
}}>
<Map
style="mapbox://styles/mapbox/streets-v9"
containerStyle={{
height: '100%',
width: '100%'
}}>
Here's my package.json
{ "name": "my_app", "version": "0.1.0", "private": true, "dependencies": { "@mapbox/mapbox-gl-draw": "^1.1.1", "@material-ui/core": "^3.9.2", "@material-ui/icons": "^3.0.2", "mapbox-gl": "^0.53.0", "material-ui-icons": "^1.0.0-beta.36", "prop-types": "^15.7.2", "react": "^16.8.2", "react-dom": "^16.8.2", "react-leaflet": "^2.2.0", "react-leaflet-draw": "^0.19.0", "react-mapbox-gl": "^4.2.0", "react-mapbox-gl-draw": "^1.0.5", "react-scripts": "2.1.5", "recharts": "^1.5.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": [ ">0.2%", "not dead", "not ie <= 11", "not op_mini all" ] }
Hi when we add control on state controls object . And try to hide control on button click set-state method controls not hide.
Currently I am using the DrawControl class as
const MapboxDraw = require("react-mapbox-gl-draw"); const DrawControl = MapboxDraw.default;
Is this the correct code to use for ES5? Or is there any other approach.
I am making this thing work in IE11 and since it only reads ES5 code, I need to make DrawControl work in ES5.
This one:
"To learn about overriding styles, see the Styling Draw section below."
I am trying to enter the draw object with react hooks but an error message 'getAll is not function' is displayed
As the correct reference should be made, is its example with react component, as I can replicate it with react hooks, I have used the useRef () but it still does not work
`<Map
style="mapbox://styles/mapbox/streets-v9"
containerStyle={{
height: '100vh',
width: '100vw'
}}>
<DrawControl
ref={(drawControl) => { this.drawControl = drawControl; }}
/>
//...
handleButtonClick() {
this.drawControl.draw.getAll(); // Or any other API method
}`
in hooks
cons drawControl = useRef() ??
`..../node_modules/@mapbox/mapbox-gl-draw/index.js:1
({"Object.":function(module,exports,require,__dirname,__filename,global,jest){import runSetup from './src/setup';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (../react-ui-components/node_modules/react-mapbox-gl-draw/lib/index.js:13:42)`
Test shouldn't fail when importing mapbox-gl-draw
Test fails when importing mapbox-gl-draw
I belive it's related to this issue
"react-mapbox-gl": "^4.7.3",
"react-mapbox-gl-draw": "^2.0.3",
"@mapbox/mapbox-gl-draw": "^1.1.2",
"mapbox-gl": "^1.5.1",
browser: jsdom-fourteen provided by jest
I noticed there is a Static mode available but I am unable to change into it through the changeMode method. Is there a way to access the static mode since I want to turn off editing of shapes at some point for the user. Thanks!
Hi all, I am using react-mapbox-gl 4.5.1
and react-mapbox-gl-draw 2.0.1
. Referencing this issue and this feature, it seems like react-mapbox-gl-draw
is now compatible with react-mapbox-gl
version 4+, but I am running into issues when I try to implement the demo. If it is compatible, I would appreciate any help debugging the following error!
Here's my code, and the error is below:
import DrawControl from 'react-mapbox-gl-draw';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
// imports
// ignore the class instantiation, constructor, all that. It works.
// in the render method:
<Map
onStyleLoad={ el => this.map = el}
style={this.state.style}
containerStyle={{
height: this.state.height,
width: this.state.width
}}
center={[0,0]}
zoom={[2]} >
<DrawControl />
</Map>
And here is the error:
index.js:14 Uncaught TypeError: map.getStyle is not a function
at DrawControl.componentDidMount (index.js:14)
at commitLifeCycles (react-dom.development.js:14361)
at commitAllLifeCycles (react-dom.development.js:15462)
at HTMLUnknownElement.callCallback (react-dom.development.js:100)
at Object.invokeGuardedCallbackDev (react-dom.development.js:138)
at invokeGuardedCallback (react-dom.development.js:187)
at commitRoot (react-dom.development.js:15603)
at completeRoot (react-dom.development.js:16618)
at performWorkOnRoot (react-dom.development.js:16563)
at performWork (react-dom.development.js:16482)
at performSyncWork (react-dom.development.js:16454)
at requestWork (react-dom.development.js:16354)
at scheduleWork$1 (react-dom.development.js:16218)
at Object.enqueueSetState (react-dom.development.js:11299)
at ReactMapboxGl.../../../node_modules/react/cjs/react.development.js.Component.setState (react.development.js:335)
at r.<anonymous> (map.js:119)
at r.Ft.fire (mapbox-gl.js:29)
at r._render (mapbox-gl.js:33)
at mapbox-gl.js:33
Does anyone have an idea as to why my application crashes right before the map mounts? Thanks!
I'm trying to hide the controls until the user presses a button to add points to the map.
At first just doing:
{mapIsEditable &&
<DrawControl
ref={drawControl}
controls={{
point: true,
polygon: true,
trash: true
}}
onDrawCreate={({ features }) => {
console.log('FEATURES: ', features)
}
...
/>;
}
seemed to work well until I try to toggle the controls multiple times, then the onDrawCreate
gets executed the same amount of times I toggled the component.
I've tried using:
<DrawControl
ref={drawControl}
controls={{
point: props.mapIsEditable,
polygon: props.mapIsEditable,
trash: props.mapIsEditable
}}
...
/>;
But this way the controls never show up when I toggle the prop.
Is there a way to toggle these or fix this error?
Hi there,
I'm attempting to create custom buttons to trigger draw effects, but I can't seem to find how to do that...probably missing something simple but any help would be appreciated.
Thanks!
Hello,
How can I attach event listeners?
Thanks
Hi I have used default drawing option I.e line and polygons but I need to do circle thing by using default mode .Can it is possible
I ran into problems with TS compilation and basic example doesn't compile because all props of Draw control are marked as required.
So this code will not compile
<DrawControl
position="top-left"
onDrawCreate={this.onDrawCreate}
onDrawUpdate={this.onDrawUpdate}
/>
Because of this TS error
Error:Error:line (67)TS2740: Type '{ position: "top-left"; onDrawCreate: ({ features }: { features: any; }) => void; onDrawUpdate: ({ features }: { features: any; }) => void; }' is missing the following properties from type 'Pick<Readonly & Readonly<{ children?: ReactNode; }>, "children" | "boxSelect" | "clickBuffer" | "controls" | "default_mode" | "displayControlsDefault" | "keybindings" | "modes" | "touchBuffer" | "touchEnabled" | "styles">': boxSelect, clickBuffer, controls, default_mode, and 6 more.
All props in lib/index.d.ts
should be marked as optional to make basic example work in Typescript or example with all mandatory props should be provided.
Please see title
Thanks!
To reproduce:
Try and unmount a component that contains a map, which contains a draw component.
Throws:
Uncaught TypeError: Cannot read property 'removeLayer' of null at e.removeLayer (.../node_modules/mapbox-gl/dist/mapbox-gl.js:391:11501) at ctx.options.styles.forEach.style (../node_modules/@mapbox/mapbox-gl-draw/src/setup.js:87:17) at Array.forEach (native) at Object.removeLayers (.../node_modules/@mapbox/mapbox-gl-draw/src/setup.js:86:26) at module.exports.onRemove (.../node_modules/@mapbox/mapbox-gl-draw/src/setup.js:12:13) at e.removeControl (.../node_modules/mapbox-gl/dist/mapbox-gl.js:391:3664) at DrawControl.componentWillUnmount (.../node_modules/react-mapbox-gl-draw/lib/index.js:47:24) at .../node_modules/react-dom/lib/ReactCompositeComponent.js:408:25 at measureLifeCyclePerf (.../node_modules/react-dom/lib/ReactCompositeComponent.js:75:12) at ReactCompositeComponentWrapper.unmountComponent (.../node_modules/react-dom/lib/ReactCompositeComponent.js:407:11)
In future, when remounting the component that contains the map, the map is then broken permanently, with this error:
.../node_modules/fbjs/lib/warning.js:35 Warning: performUpdateIfNecessary: Unexpected batch number (current 23, pending 3)
This error indicates that unmounting the draw component actually causes react itself to break.
Since the introduction of the new React Content, the legacy context is deprecated. react-mapbox-gl
v4 has a new API to manage context, so this library should also work with that.
see pr: #347
The app I'm working on is using the ReactMapGL component. I'm having issues with this wrapper when making it a child of ReactMapGL
like so:
return (
<div style={{ height: '100vh' }}>
<ReactMapGL
{...viewport}
ref={(map) => { this.reactMap = map }}
onLoad={this.onReactMapLoad}
interactiveLayerIds={interactiveLayerIds}
onMouseMove={this.onMapMouseMove}
onMouseLeave={this.onMapLayerMouseLeave}
onClick={this.onMapClick}
onContextMenu={this.contextMenu}
width='100%'
height='100%'
mapStyle={style}
onViewportChange={this.onViewportChange}
mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN}
>
<DrawControl
map={this.reactMap}
displayControlsDefault={false}
modes={modes}
defaultMode='static'
controls={{ polygon: true }}
styles={DEFAULT_DRAW_STYLE}
position='bottom-left'
onDrawCreate={(e) => {
const layerIDs = mapMVTLayers.map(l => l.id)
onDrawCreate(e, this.reactMap.getMap(), layerIDs, {
addItemToSideBar,
addGeoQueryResults,
})
}}
onDrawModeChange={(e) => {
onDrawModeChange(e, { setPopDown })
}}
/>
</ReactMapGL>
</div>
Is there something I can do to make this work?
According to this example: https://codesandbox.io/s/7z5qvmvqrq onDrawUpdate should work by passing a call back function like this:
import React, { Component } from 'react';
import ReactMapboxGl, { ZoomControl } from "react-mapbox-gl";
import mapboxStyle from '../../mapStyle/style.json';
import DrawControl from 'react-mapbox-gl-draw';
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
const Map = ReactMapboxGl({
accessToken: MY_KEY
});
class DrawLineMap extends Component {
onDrawUpdate = ({ features }) => {
console.log({ features });
};
render() {
return (
<div>
<Map style={ mapboxStyle } containerStyle={{ height: '300px', width: '100%', borderRadius: '8px' }} center={ [9, 61] }>
<ZoomControl />
<DrawControl
displayControlsDefault={false}
controls={{ line_string: true, trash: true }}
onDrawUpdate={ this.onDrawUpdate } />
</Map>
</div>
)
}
}
export default DrawLineMap;
With the code above the onDrawUpdate function is never triggered.
I want to get data feature from backend, use it to create a feature on the map. After that I want modify this feature and send the the new data to backend. Can I use this package for doing it ?
This tool is great at drawing on decktop/laptop browser, but looks like it only support click to draw on pad devices.
On a pad device, the drag gesture on mapbox is moving map by default, and it can be closed.
Could I add the drag gesture as drawing using react-mapbox-gl-draw when the default gesture of moving map is closed?
Thanks for sharing your work on this, it's been super useful.
I would like to change the styles of features, but it looks to me that I can't set the userProperties
option. From the mapbox-gl-draw API reference:
If
opts.userProperties
is set totrue
the properties of a feature will also be available for styling.
I tried changing the styles of features by calling draw.setFeatureProperties()
but nothing was happening - until I went into lib/index.js
of this package and set userProperties: true
on the MapBoxDraw
instantiation.
Am I missing something here, or is a change needed?
Hello,
First of all a big congratulations for the package it is really great and very useful for my use! :)
I cannot solve a problem, despite the fact that I have read all the documentation several times.
I initiate my DrawControl component this way with a ref to be able to use draw.()
<DrawControl ref={(drawControl) => { this.drawControl = drawControl; }}/>
When my parent component is assembled, in componentDidMount I would like to be able to follow an API call to draw all the features that I have recovered. Like this :
this.drawControl.draw.add(feature);
I get this error (normal):
Unhandled Rejection (TypeError): Cannot read property 'draw' of undefined
How do I know when is the DrawControl component init and the draw function usable?
Thank you very much! Hoping to find an answer :(
I'm trying to add react-mapbox-gl-draw to Mapbox. But it make user cannot click any popup on map.
The example is not running correctly any more.
"example": "yarn build && cd example && webpack-dev-server",
should become:
"example": "yarn build && cd example && webpack serve",
Controls are not shown. The following import is missing:
import 'mapbox-gl/dist/mapbox-gl.css';
when using draggable feature and set the DrawControl component. the feature dragging are very lagy and unusable even when set the feature layer on top of the DrawControl component
<Map
style="mapbox://styles/mapbox/streets-v9"
center={[ 48.51456, 34.79922 ]}
>
<DrawControl
onDrawCreate={this.logDraw}/>
<Layer
type="circle"
id="position-marker"
paint={POSITION_CIRCLE_PAINT}>
<Feature
coordinates={[ 48.51456, 34.79922 ]}
draggable={true}
onDragEnd={this.onDragEnd.bind(this)}/>
</Layer>
</Map>
Dependabot couldn't authenticate with registry.yarnpkg.com.
You can provide authentication details in your Dependabot dashboard by clicking into the account menu (in the top right) and selecting 'Config variables'.
Thanks for providing wrapper to mapbox-gl-draw. To get the example working I needed to copy and rename index.js (exports DrawControl) to examples/src; as CRA does not allow relative imports outwith this folder. From my limited React knowledge, then I could have 'ejected', but at this stage of exploration I did not want to do that. Another user may find a note related to this 'example/README.md' or another solution helpful.
~ npm run build
Creating an optimized production build...
Failed to compile.
Failed to minify the code from this file:
./node_modules/react-mapbox-gl-draw/lib/index.js:6
i can't build my project
I can get features from component with the help of
onDrawCreate
onDrawDelete
onDrawUpdate
etc.but how to do I pass back those features to the component?
For now: a unit test that makes sure we can mount the DrawControl component.
Adding saved ploygon (created use react-mapbox-gl-draw tool) to react-mapbox-gl, the added ploygon in the mode of none. Have to click two times to choose the ploygon.
After adding a Feature in react-mapbox-gl:
<Feature coordinates={[this.props.coords]}
onClick={this.handlePolyClick}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
properties={{active: true, meta: 'feature', mode: 'simple_select'}}
/>
The properties could be read from:
private handlePolyClick = (e: any) => {
const saved = e.feature;
But the ploygon is not in simple_select
mode, and is not been selected. I have to use following code to set the feature been selected:
drawcontrol[0].add(saved)
let firstFeature = drawcontrol[0].getAll().features[0] || {}
drawcontrol[0].changeMode('simple_select', {featureIds:[firstFeature.id]})
The DrawControl properties were set as:
<DrawControl ref={this.mapRef}
controls={controls}
styles={drawStyles}
userProperties={true}
displayControlsDefault={false}
onDrawCreate={this.props.onDrawCreate}
onDrawUpdate={this.props.onDrawUpdate}
onDrawDelete={this.props.onDrawDelete}
onDrawModeChange={this.props.onAction}
onDrawSelectionChange={this.props.onAction}
Am I wrong or there is a bug?
I'm trying to persist a polygon through page loads. I have the coordinate array saved, so when the map renders, i'm trying to programmatically call this.drawControl.draw.add()
with the coordinates
Given
Polygon = {[
{
lat: num,
long: num,
},
{
....
}
]}
when i call
this.drawControl.draw.add({
type: 'Polygon',
coordinates: [polygon.map(coord => Object.values(coord))],
});
nothing happens, but after, i can call
console.log(this.drawControl.draw.getAll());
and i see the feature was added.
I guess the issue is, how can i manually draw a polygon on the map given as set of saved coordinates? I don't think it's a problem with loading, because as a sanity check, I added a 10 second timeout before trying to add the polygon to ensure everything was loaded, and still nothing happened.
Question. Can this be used in react native?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.