📜 ⬆️ ⬇️

Path with direction signs on a map using Yandex Map Kit for Android

Hello!

In this post we will consider:
  1. Embedding the Yandex Map Kit Android library into the project
  2. Creating an extension for the Overlay class in order to map paths with direction indicators and map onClick events


image

1. Embed a library in a project (Eclipse, Windows)


Load the archive with the library from here and get the API key .
Create a project in Eclipse, copy the \ yandexmapkit-library \ res and \ yandexmapkit-library \ libs folders from the downloaded archive into the folder of our project with the replacement of the folder.
In the project settings, add a link to yandexmapkit-android.jar from the libs folder of our project (Build Path-> Configure Buil Path-> Libraries-> Add External JARs)
Add permissions to our project manifest
')
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 

Change the activity markup

  <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/RelativeLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ru.yandex.yandexmapkit.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey=" " /> </RelativeLayout> 

2. Creating an extension for the Overlay class in order to map paths with direction indicators and onClick event handling on the map


To draw a path, we need to extend the OverlayIRender class, which implements the IRender interface.

 public class MyOverlayIRender extends OverlayIRender { Overlay mOverlay; public MyOverlayIRender(Overlay overlay) { super(); mOverlay = overlay; } @Override public void draw(Canvas canvas, OverlayItem arg1) { super.draw(canvas, arg1); List<OverlayItem> oi = mOverlay.getOverlayItems(); if (oi.size() < 2) return; Paint mPaint = new Paint(); mPaint.setDither(true); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(2); mPaint.setAntiAlias(true); for (int i = 0; i < oi.size() - 1; i++) { Path path = new Path(); ScreenPoint p1 = mOverlay.getMapController().getScreenPoint( oi.get(i).getGeoPoint()); ScreenPoint p2 = mOverlay.getMapController().getScreenPoint( oi.get(i + 1).getGeoPoint()); float angle = (float) (Math.atan2(p2.getY() - p1.getY(), p2.getX()- p1.getX()) * 180 / 3.14); path.moveTo(p2.getX(), p2.getY()); path.lineTo(p1.getX(), p1.getY()); canvas.drawPath(path, mPaint); canvas.save(); canvas.rotate(angle + 90, p2.getX(), p2.getY()); Path path2 = new Path(); path2.moveTo(p2.getX(), p2.getY()); path2.lineTo(p2.getX() + 5, p2.getY() + 8.66f); path2.lineTo(p2.getX() - 5, p2.getY() + 8.66f); path2.close(); canvas.drawPath(path2, mPaint); canvas.restore(); } } } 

If the number of points added to our path is greater than 1, then the segments and the direction arrows are drawn in the cycle.
Now you need to create a successor to Overlay MyPathOverLay, assign it MyOverlayIRender for rendering.

 public class MyPathOverLay extends Overlay { MapView mMmapView; public MyPathOverLay(MapController arg0, MapView mapView) { super(arg0); mMmapView = mapView; this.setIRender(new MyOverlayIRender(this)); } @Override public int compareTo(Object arg0) { return 0; } @Override public boolean onLongPress(float x, float y) { OverlayItem m = new OverlayItem( this.c.getGeoPoint(new ScreenPoint(x, y)), BitmapFactory.decodeResource( this.c.getContext().getResources(), R.drawable.flag2leftred)); m.setOffsetY(-23); this.addOverlayItem(m); this.c.setPositionNoAnimationTo(this.c .getGeoPoint(new ScreenPoint(x, y))); return true; } } 

In the overridden onLongPress method, we will add intermediate points for our path by long pressing the map.
R.drawable.flag2leftred - a picture for a point,
m.setOffsetY (-23); - the offset that you need to pick up, if you want to shift the picture relative to the point of clicking on the map, by default, the center of the picture is combined with the point of pressing.
It remains to add our Overlay to the map and test

 public class BlogYandexActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); MapView mMap = (MapView) findViewById(R.id.map); MapController mMapController = mMap.getMapController(); OverlayManager mOverlayManager = mMapController.getOverlayManager(); mOverlayManager.addOverlay(new MyPathOverLay(mMapController, mMap)); mMap.showBuiltInScreenButtons(true); mOverlayManager.getMyLocation().setEnabled(false); } } 

Result

image

Source: https://habr.com/ru/post/150068/


All Articles