3

I'm reading the documentation of the Annotation Plugin along with the examples, but still can't quite understand how to work with Lines.

I want to create a Line, which need to be updated frequently with additional coordinates. In Google Maps is easy, since we declare a Polyline object, take the LatLng points and set the new one. Basically, I'm not going to use a lot of customization, only width and color of the line.

So do we need to define a layer, or we could just use the options for this case?

And a second question: (From the documentation, I see a lot of examples with FeatureCollection and GeoJSON) Is this the only way of updating the line?

H.Karatsanov
  • 199
  • 4
  • 16

1 Answers1

2

Tldr; There are two main options and it's basically up to you as to which route to take. Your LatLng coordinates can be used to create a LineString/Line each time you want to update the visual line.

You can use a LineLayer:

can actually just be style.addSource(new GeoJsonSource("line-source", LineString.fromLngLats(routeCoordinates))); .

Updating GeoJSON of the source that's being used by the LineLayer. Create a new LineString each time you want to update:

See second code block in the GeoJSON updates section (source.setGeoJson(), etc.): https://docs.mapbox.com/android/java/overview/geojson/#geojson-updates

You can use a LineManager in the Annotation Plugin:

https://github.com/mapbox/mapbox-plugins-android/blob/master/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/annotation/LineActivity.java#L48

https://github.com/mapbox/mapbox-plugins-android/blob/master/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/annotation/LineActivity.java#L64-L73

Updating the line via LineManager

enter image description here

Create a new Line each time you want to update

langsmith
  • 2,529
  • 1
  • 11
  • 13
  • Thank you for the provided ways. So basically the LineOptions is the actual Line? I've tried ```Line currentLine = new Line()``` but it tells me that Line is private (Although in the docs it's declared as public). So it is either ```LineString + GeoJSON``` or ```LineManager + LineOptions```? – H.Karatsanov May 07 '20 at 21:56
  • 1
    Yep, correct. `lineManager.create(lineOptions);` creates a `Line`. https://github.com/mapbox/mapbox-plugins-android/blob/master/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/annotation/LineChangeActivity.java has `Line` object usage https://github.com/mapbox/mapbox-plugins-android/blob/master/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/annotation/LineChangeActivity.java#L108 – langsmith May 07 '20 at 22:32
  • Nice. One last question: In the both cases we will initialize always new objects. When it is layout, I think we can set no overlapping, but if we use the manager with ```update()``` per default there is no overlapping? – H.Karatsanov May 07 '20 at 22:46
  • Don't think there's any way to avoid line overlapping. There's no way to adjust collisions for lines like you can for symbols –> https://docs.mapbox.com/android/maps/examples/symbol-collision-detection/ There is lineSortKey to set which lines are drawn first https://imgur.com/a/ZtdeWFQ – langsmith May 08 '20 at 00:11
  • I've tried the ```LineManager``` with ```LineOptions```. Parallel with this I display also the current position from the ```LocationComponent``` but the marker stays under the Line. Is there a method to set it on top of the line when using ```LineManager```? – H.Karatsanov May 08 '20 at 16:19
  • https://docs.mapbox.com/android/maps/examples/location-component-options/ uses the `LocationComponentOptions` class. This class` builder has the `.layerBelow()` and `.layerAbove()` methods. Try activating the the `LocationComponent` after you add the lines. See the second code block in https://docs.mapbox.com/android/maps/overview/styling-map/#retrieving-a-map-layer to see how to print all layer ids. This'll print the layer(s) added by the plugin. Pass through the plugin's layer id in the `LocationComponent`'s `layerAbove()` method: https://imgur.com/a/nGQBUKg & https://imgur.com/a/9JVbr95 – langsmith May 08 '20 at 17:52
  • When I open the activity (after accepted permissions and before starting the service) I need to show the user's location on the map (and use ```LocationComponent```). I've implemented the ```LocationComponentOptions``` and detected the layer (basically, every time, when I add a new line, the N in the "mapbox-android-line-layer-N" increments). So after I receive the LatLngs, I increment the number, save the new LatLngs and call ```mapFragment.getMapAsync(this)``` . There I visualize the new line, and after that call the component with the ```layerAbove()``` but it crash the service, why? – H.Karatsanov May 09 '20 at 08:58
  • The first Line ```(mapbox-android-line-layer-1)``` is initialized, and on the second response from the service after ```mapFragment.getMapAsync(this)``` , the following error appear: ```Consumer closed input channel or an error occurred. events=0x9``` – H.Karatsanov May 09 '20 at 10:32
  • 1
    Hard to help without seeing your code, haha. Mapbox Support team could also help https://support.mapbox.com/hc/en-us/requests/new?ticket_form_id=360000291231. My code at https://gist.github.com/langsmith/0ba43a5b7fe7bf7e352ca83aed014e10 creates –> https://imgur.com/a/DjpSkho . I used the Mapbox Android demo app to spin up your goal rather than starting a completely new Android Studio project. – langsmith May 09 '20 at 19:46
  • 1
    In my imgur link, you'll see that the `LocationComponent` is on top of lines like you want. I loop through all map layers and look for `mapbox-android-line-layer-` (without a number ending), so that the id passed through `.layerAbove()` is the latest layer added by the plugin. – langsmith May 09 '20 at 19:49
  • 1
    Can't tell if you're already doing this, but I'd run `LocationComponentOptions` code and other stuff inside of `onMapReady()` callback area rather than before you even run `mapFragment.getMapAsync(this)`. Run map-related stuff once you know the map and style have finished setting up. See https://docs.mapbox.com/android/maps/examples/support-map-fragment/ & https://github.com/mapbox/mapbox-android-demo/blob/master/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/basics/SupportMapFragmentActivity.java#L55-L71 – langsmith May 09 '20 at 19:52
  • I hope the StackOverflow won't kick this conversation, haha. Here is the link of the complete scenario [link](https://imgur.com/a/VSQPGc3). On one of the post I've wrote where the crash appears. What you think? – H.Karatsanov May 10 '20 at 12:23