Path with direction indicators on the map using Yandex Map Kit for Android

Hello!

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


image

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


We load the archive with the library from here and get the API key .
We create the project in Eclipse, copy it with the replacement of the \ yandexmapkit-library \ res and \ yandexmapkit-library \ libs folders from the downloaded archive to our project 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 the manifest of our project

  <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 markup of activity

  <?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 display paths with direction indicators and processing onClick events on the map


To draw the 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 more than 1, then segments of the path and direction arrows are drawn in the loop.
Now you need to create the Overlay descendant 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 clicking on the map.
R.drawable.flag2leftred - picture for the point,
m.setOffsetY (-23); - the offset to be selected, if you need to shift the picture relative to the point of clicking on the map, by default the center of the picture is aligned 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