mapbox / mapbox-gl-native

Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
4.35k stars 1.33k forks source link

Dragging AnnotationView and simultaneously updating MGLShapeSource causes flickering #16557

Open jradasaurus opened 3 years ago

jradasaurus commented 3 years ago

Steps to reproduce

  1. Create a draggable AnnotationView
  2. Add an MGLShapeSource with the shape set to a polyline
  3. Drag the AnnotationView and simultaneously while dragging update the MGLShapeSource by mutating the shape
  4. (I happen to be updating the shape coordinates to match the position of the Annotation view but this is irrelevant)

Expected behavior

  1. The AnnotationView position should smoothly drag with gesture position
  2. The shapes mutation should update smoothly without flickering

Actual behavior

  1. The AnnotationView rapidly flickers between the original position and the gesture position
  2. The MGLShapeSource also flickers between the starting & gesture position

Configuration

Mapbox SDK versions: 5.9.0 iOS/macOS versions: iOS 14.1 Device/simulator models: iPhone 8 Xcode version: 12.1

I am attempting to build a "caliper tool" where I add two AnnotationViews and an MGLShapeSource with a polyline (well really just a line) that appears to the user as connecting the two AnnotationViews. I set the isDraggable property of the AnnotationView to true and as the drag event is occurring I also mutate the shape property of the MGLShapeSource. As I update/drag both the line and the annotation flicker rapidly.

I have a create a basic repo with ~150LOC to reproduce this issue: https://github.com/jradasaurus/caliper/blob/main/Caliper/ViewController.swift

You can see during the drag gesture I update the polyline shape: https://github.com/jradasaurus/caliper/blob/main/Caliper/ViewController.swift#L132

I realize this is not the place to ask help questions, but I have paid for the Mapbox $50/mo support contract, and they do not appear to have any other technical implementation approaches. If there are other different ideas on how to approach this I am happy to shift my implementation but to my knowledge the AnnotationView is the only natively draggable element in the SDK. I will be more than happy to replicate this question on SO if I can find an answer but I believe a Mapbox pro could look at this issue and consider it a bug with the library.

out

vmosconecds commented 3 years ago

@jradasaurus Do you received any update on this? We are trying to drag a polygon base on annotations (draggable annotations). We are having the same issue.

jradasaurus commented 3 years ago

After a long drawn out conversation with the paid Mapbox support we determined that you simply cannot have a "live" rendering line and animate at any acceptable framerate, instead you have to draw your own UIView. In my case, while the user was dragging the annotation the connecting line would be a manually placed UIView based on the touch location of the drag. Once the touch was released, I would update the Mapbox line source (so panning/zooming/tilting the map would all have the native feel of a true Mapbox shape source). Trying to update the shape source is simply too slow.

I did view the video upon my initial response. Geo sources are typically slower to update than other sources, so MGLShapeSource will not be as fast to update as you are looking for. I might suggest that instead of you using a line drawn on the map, you switch to some type of overlay or UIView to visualize where the line will be, and then once you stop dragging, you update the MGLShapeSource with the coordinates of the annotations. You could create a rectangular UIView that's just 1-2 pixels tall and rotate and size it to connect the two UIViews. Otherwise, you could render a path by drawing into a CGContext to draw the line as a vector path