-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DrawControl #450
Comments
Hey @Warkst , I have this working by doing exactly what you do and I also have Though interestingly enough it appears the new Mapbox v0.44.0 causes some weird issues with drag/pan, so use <0.44.0. Investigating that now, I think the real solution here will be a pure React draw component overlay that does the drawing. |
Hey @rimig , thanks for sharing. Indeed, turning of pointer-events allows the controls to work properly! However, the shapes that are being drawn are rendered behind some other layers (added by deck.gl), so I'm afraid that the only real solution would indeed be a pure React component. |
Yea, you could probably get it to work but you'd have to give up other functionality here and in deck.gl. I agree about the need for a draw component, I'm currently working on such a thing. |
@Warkst @rimig Hi guys, sorry to bother you. Do u have any solutions yet? |
@akiori Yes and no... let me explain. In my original question, I tried to keep the problem description minimal and simple, but my actual problem involved the particular combination of deck.gl as well. If your problem only uses react-map-gl, I think you should be able to craft a working solution. Consider adding a custom control to the map that toggles the app state to "user drawing". When pressing this button, you could add the draw control to the map and simultaneously disable the pointer events, allowing you to draw. In that case, you'll also want a way to toggle back to regular mode, hiding the draw controls and re-enabling the pointer events so the user can pan and zoom. In my case, I re-evaluated the situation and came to the conclusion that I really only needed a subset of the If you want some example code, let me know. |
@akiori - I do something pretty similar to what @Warkst is describing. I have a simple react component which is a For drawing the features passed in as props: It takes the geojson featureCollection as a prop, uses For user drawing: It handles the This repo has some good examples for drawing on an overlay like this: |
@Warkst thanks for your reply. My situation is almost the same with yours. Can I have your example code? I'm really a code newbie at present :) |
Hi @Warkst , sorry to bother you again. Can you show me some example code? |
@akiori Sorry to keep you waiting for so long. I've attached some code from my project regarding the custom map controls. I did not create a minimal runnable example, but I've added the two most important files you need to figure things out. The file "TILESMapControls.js" contains the custom map controls. This is pretty straight forward. It overrides "handleEvent". The behavior depends on the value of a property, "mode". The custom controls class also has a method "setMode" to update the behavior of the map controls. The default behavior ("else" case) is to use the default map controls ("super.handleEvent") - which means panning when dragging, zooming when scrolling, etc. Then there is "Map2.js", which contains a React.Component class. It manages the ReactMapGL instance. In its state, "type" tracks the current mode the app is in. The default mode in my example is "CLEAR". In the constructor, create an instance of the custom map controls. In the "render" method, update these custom map controls by setting its mode to the current app mode and return JFX for ReactMapGL. Additionally, add a layer showing the line if the user is drawing one. Important here, if you want to use GeoJsonLayer, is that you use a WebMercatorViewport (the default), or otherwise the viewport you are using for ReactMapGL, to "unproject" the x,y coordinates on the screen to lng, lat coordinates on the world. I also added a button which sets the mode to DRAWINGCROSSSECTION. After clicking this, the callbacks onPanStart, onPanMove and onPanEnd will start being called by the custom map controls. In my example, onPanStart adds the start coordinates and end coordinates to the state and onPanMove updates the end coordinates in the state. In onPanEnd, you can do something with the coordinates (call the backend, do a computation... whatever), but don't forget to reset the app mode to CLEAR to make sure the behavior is restored to default. If the user wants to draw a new line, he must first click the button again. The attachments are of type "txt" because github does not accept attachments of type "js", but they are actually really js ;) Hope this helps. |
@Warkst Hi, your method works, but there is a small bug. I don't use panstart panmove panend to draw lines, i use click, mousemove, mimic the polygon-selection here http://geojson.io. However, I found that the click event is so slow (if putting a I click on one point, and move my mouse, there should be a dynamic moving line connecting the point and my cursor. however, if my mouse moves too soon after the click, the click hasn't response, so there is a dynamic line connecting my mouse and the previous point Current SolutionI replace |
@akiori Good to hear you were able to make my code work. I too have the same behaviour you described. I will try changing click to mousedown and hope this also speeds it up in my project. Nice find! |
@Warkst by the way, as you can see from http://geojson.io, when you draw a polygon, the vertexes of a polygon are highlighted using circle. currently i plan to implement them as geojson points. what's your opinion? |
@akiori I've changed the event to mousedown as you suggested and indeed, it's much faster. Really nice! I think adding the points is a good idea. There are several ways to do this. You could use two separate layers, but you could also combine them into one large GeoJSON "FeatureCollection" containing a MultiPoint feature (the points) and a LineString feature (the edges of the polygon). Obviously you can also use Polygon instead of LineString if you want to color the area inside the polygon. |
@Warkst Hi! Do you happen to have any news on that?
|
Just stumbled on this - also found https://github.com/amaurymartiny/react-mapbox-gl-draw if anyone else is still looking for a solution. |
This package uses react-mapbox-gl instead of react-map-gl |
@csi0n - Woops my bad, read that project readme too fast. If that's the case I'm going to need to build this for a project I'm working on next week. Will post the package info when done. |
@contra Let me know if you were able to get around and do this. We should add a link to it from the README. |
FWIW - I realize that this is a much more elaborate solution with significantly bigger bundle sizes etc, but just want to make a small plug for nebula.gl. nebula provides a set of geospatial editing layers for deck.gl, and deck and nebula are a "companion frameworks" of react-map-gl, all designed to work seamlessly together. |
@ibgreen Awesome, I hadn't seen that - will definitely use this instead of making something from scratch. |
Uber's package is great and quick/easy to implement but just as a heads up... If anyone else gets stuck here with adding the to react-map-gl i can confirm a quick switch to how to draw polygons with react-mapbox-gl rather than react-map-glPut the following packages in your package.json
|
Thanks @Aid19801. I also added a small note on the README of |
This prop controls if map style should be updated on changes. Also whilst this is true panning is disabled. You might set this to false whilst integrating with mapbox-gl-draw. The work is based off of the following issues: - visgl#725 - @ibgreen pointed out that this sort of prop would make for an easy integration. - visgl#450 - visgl#328
@meghna0593 can you add example of this redraw function? |
I have released a Example code draw-polygon Also here is the sandbox example |
Hi @spiotrowska , Sorry for the late reply. Since the project I am working on is in its first iteration, I have put a static implementation of the no.of sides for the polygon. That is, only 4 sided polygon can be created. The first mousedown event starts the drawing. Second mousedown creates one line, third creates two lines, fourth one joins the first point with the last point. It then colors the polygon. In the redraw function of CanvasOverlay, I am drawing these line segments based on different mouse events. Also, I am projecting the coordinates on the map using project function. I have an if-else condition handling the mousedown states. You can use the function like this-> In _redrawCanvasOverlay function, something like this-> (Haven't included my actual code, this is the gist of it)
I haven't used the new release react-map-gl-draw. I'll probably give it a try soon. Hope this helps. |
Is there a way to add a mapbox-gl-draw control to
<ReactMapGL>
? I was able to get it to appear on the screen by usingref
to get a reference to the react component, which allowed me to access the underlying mapbox withgetMap()
. On that reference was able to successfully calladdControl
and though it appears correctly, it does not seem to be functioning. Is there anyone who has done this before and can help me out? Even if it's not actually by linking mapbox-gl-draw, any way to allow the user to interactively draw polygons/linestrings in a way that emits events that can be subscribed to would solve my problem.Thanks in advance!
The text was updated successfully, but these errors were encountered: