Zorgan
Zorgan

Reputation: 9123

How can you draw a straight line between 2 Points on a Mapbox map?

I have loaded a Mapbox map in my Fragment:

xml

<com.mapbox.mapboxsdk.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    mapbox:mapbox_cameraZoomMax="@integer/maxZoom"
    mapbox:mapbox_cameraZoom="@integer/defaultZoom"
    mapbox:mapbox_cameraZoomMin="@integer/minZoom"
    mapbox:mapbox_uiRotateGestures="false"
    mapbox:mapbox_uiTiltGestures="false"
    mapbox:mapbox_uiScrollGestures="false"
    mapbox:mapbox_uiDoubleTapGestures="false" />

Fragment

    /** Initialise Mapbox **/
        mapView = view.findViewById(R.id.mapView)
        mapView?.onCreate(savedInstanceState)
        val destinationMarker = ContextCompat.getDrawable(activity, R.drawable.dest_logo) ?: return
        mapView?.getMapAsync { mapboxMap ->
            this.mapboxMap = mapboxMap
            this.mapboxMap.setStyle(Style.MAPBOX_STREETS) { style ->
                style.addImage("destination", destinationMarker)
                showUserLocation(style)
                resetCamera()
            }
        }

@SuppressWarnings("MissingPermission")
private fun showUserLocation(style: Style){
    // If permissions are granted, show/get user user1location. Else, return to TurnOnLocationActivity
    if (PermissionsManager.areLocationPermissionsGranted(activity)){
        val activity = activity ?: return
        val locationComponentOptions = LocationComponentOptions.builder(activity)
            .bearingTintColor(Color.WHITE)
            .accuracyAlpha(0.1f)
            .build()

        val locationComponentActivationOptions = LocationComponentActivationOptions
            .builder(activity, style)
            .locationComponentOptions(locationComponentOptions)
            .useDefaultLocationEngine(true)
            .build()
        val mapView = mapView ?: return returnToLoginPage()
        if (!style.isFullyLoaded) return returnToLoginPage()
        symbolManager = SymbolManager(mapView, mapboxMap, style)
        locationComponent = mapboxMap.locationComponent
        locationComponent?.activateLocationComponent(locationComponentActivationOptions)
        locationComponent?.isLocationComponentEnabled = true
        locationComponent?.cameraMode = CameraMode.TRACKING
        locationComponent?.renderMode = RenderMode.COMPASS
        return createLocationEngine()
    } else {
        Toast.makeText(context, "Permissions not granted", Toast.LENGTH_LONG).show()
        return returnToLocationPage()
    }

}

@SuppressWarnings("MissingPermission")
private fun createLocationEngine(){
    // Get current user1location
    val activity = activity ?: return
    locationEngine = LocationEngineProvider.getBestLocationEngine(activity)
    // After user1location has been loaded, configure mapBox settings
    mapboxMap.uiSettings.isCompassEnabled = false
}

I would like to draw a straight line between 2 Points on my map. Say I have -37.791890, 145.119387 and -37.790597, 145.116213 as my 2 Points - how would I draw a straight line?

EDIT

FeatureCollection isn't showing up:

/** Initialise Mapbox **/
        mapView = view.findViewById(R.id.mapView)
        mapView?.onCreate(savedInstanceState)
        val destinationMarker = ContextCompat.getDrawable(activity, R.drawable.dest_logo) ?: return
        mapView?.getMapAsync { mapboxMap ->
            this.mapboxMap = mapboxMap
            this.mapboxMap.setStyle(Style.MAPBOX_STREETS) { style ->
                style.addImage("destination", destinationMarker)
                val routeCoordinates: List<Point> = listOf(Point.fromLngLat(145.152088, -37.759647))
                val lineString = LineString.fromLngLats(routeCoordinates)
                val feature = Feature.fromGeometry(lineString)
                val featureCollection = FeatureCollection.fromFeature(feature)
                val geoJsonSource = GeoJsonSource("line-source", featureCollection)
                style.addSource(geoJsonSource)
            }
        }

Upvotes: 2

Views: 1788

Answers (1)

Zohaib Amir
Zohaib Amir

Reputation: 3562

Line is one of the Feature subclass of Mapbox so the process of adding Line is pretty much same as any other feature:

  1. Instantiate a LineString object from Point list. LineString is implementation of GeoJson

  2. Instantiate a Feature using the LineString object

  3. Instantiate a FeatureCollection from the Feature object

  4. Instantiate a GeoJsonSource using FeatureCollection

  5. Add GeoJsonSource to map style

  6. Add a LineLayer to map style

List<Point> routeCoordinates;
...

LineString lineString = LineString.fromLngLats(coordinates);
Feature feature = Feature.fromGeometry(lineString);

FeatureCollection featureCollection = FeatureCollection.fromFeature(feature);
GeoJsonSource geoJsonSource = new GeoJsonSource("line-source", featureCollection);
style.addSource(geoJsonSource);

style.addLayer(new LineLayer("linelayer", "line-source").withProperties(
PropertyFactory.lineDasharray(new Float[] {0.01f, 2f}),
PropertyFactory.lineCap(Property.LINE_CAP_ROUND),
PropertyFactory.lineJoin(Property.LINE_JOIN_ROUND),
PropertyFactory.lineWidth(5f),
PropertyFactory.lineColor(Color.parseColor("#e55e5e"))
));

This can possibly be done inside your map.setStyle() lambda.

Alternatively, if you have a json in following format (LineString uses this format):

 {
   "TYPE": "LineString",
   "coordinates": [
     [100.0, 0.0],
     [101.0, 1.0]
   ]
 }

You can skip to the third step and construct a FeatureCollection from this json:

FeatureCollection.fromJson(stringJson)

Upvotes: 3

Related Questions