简体   繁体   中英

How to draw arrows with Mapbox

With the Mapbox Android SDK and Annotation plugin, is there anyway to add arrows to lines? If not, is there any way to suggest the direction of a line? Ideally, I would like to have two markers with an arrow between them so the user knows which direction to travel.

Thanks

Mapbox doesn't support arrows out-of-the-box, but you can experiment with the Line#setPattern which takes as an argument a name of the image added to the map with the Style#addImage / MapboxMap#addImage . You can read more about the requirements of that pattern image here . Otherwise, you'll need to roll out a custom solution by correctly positioning and rotating the arrow graphic (a Symbol ) on the map. You can set that up with symbol-placement and icon-rotation-alignment style properties and exposed SymbolManager methods .

Unfortunately, Mapbox Lines do not support this functionality. However, using the new Mapbox API v7 and the Annotations Plugin you can do the following to get exactly what you need.
1. Draw a Line on the Mapview using a LineManager
2. Calculate the bearing of the Line in degrees
3. Rotate a drawable arrow by the calculated degrees (The drawable can be an arrow pointing up)
4. Draw a Symbol on the Mapview using a SymbolManager. This symbol will be placed in the middle of the line and use as an image the rotated drawable

Just put this code anywhere in your Mapview activity

public void createLineAndArrow(){  

  //Declare the coordinates of the two points of the line
  float latitude1  = 34.1f;
  float longitude1 = 33.2f;
  float latitude2  = 35f;
  float longitude2 = 34.5f;

  //Calculate bearing of line
  double lat1Rad = Math.toRadians(latitude1);
  double lat2Rad = Math.toRadians(latitude2);
  double deltaLonRad = Math.toRadians(longitude2 - longitude1);
  double y = Math.sin(deltaLonRad) * Math.cos(lat2Rad);
  double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * 
             Math.cos(lat2Rad) * Math.cos(deltaLonRad);
  double bearing =  (Math.toDegrees(Math.atan2(y,x))+360)%360;

  //Draw the Line
  List<LatLng> lineVertices = new ArrayList<>();
  lineVertices.add(new LatLng(latitude1,longitude1));
  lineVertices.add(new LatLng(latitude2,longitude2));
  LineOptions lineOptions = new LineOptions().withLatLngs(lineVertices)
                        .withLineColor(ColorUtils.colorToRgbaString(Color.MAGENTA))
                        .withLineWidth(3f);
  LineManager lineManager = new LineManager(mapView, mapboxMap,mapboxMap.getStyle());
  lineManager.create(lineOptions);

  //Rotate the drawable
  Bitmap bmapOriginal = BitmapFactory.decodeResource(getResources(), 
                        R.drawable.arrowup);
  final Bitmap bmap = bmapOriginal.copy(Bitmap.Config.ARGB_8888, true);
  Matrix matrix = new Matrix();
  matrix.postRotate((float)bearing);
  Bitmap rotatedBitmap = Bitmap.createBitmap(bmap , 0, 0, bmap.getWidth(), 
                         bmap.getHeight(), matrix, true);
  Drawable d = new BitmapDrawable(getResources(), rotatedBitmap);

  //Add the drawable to the selected mapbox style
  mapboxMap.getStyle().addImage("rotatedImage",
                        BitmapUtils.getBitmapFromDrawable(d),
                        true);

 //Draw the Symbol in the middle of the Line
 SymbolOptions symbolOptions = new SymbolOptions().withIconImage("rotatedImage")
                          .withGeometry(Point.fromLngLat((longitude2+longitude1)/2, 
                          (latitude2+latitude1)/2));

 SymbolManager symbolManager = new SymbolManager(mapView, mapboxMap, 
                               mapboxMap.getStyle());
 symbolManager.create(symbolOptions);

}  

Image - The above code draws this on a mapview

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM