Здравствуйте!
В этом сообщении рассмотрим:
- Встраивание библиотеки Yandex Map Kit Android в проект
- Создание расширения для класса Overlay с целью вывода на карту пути с указателями направления и обработки событий «onClick» по карте
1. Встраивание библиотеки в проект (Eclipse, Windows)
Загружаем архив с библиотекой отсюда и получаем API-ключ.
Создаем проект в Eclipse, копируем с заменой папки yandexmapkit-libraryres и yandexmapkit-librarylibs из загруженного архива в папку нашего проекта.
В настройках проекта добавляем ссылку на yandexmapkit-android.jar из папки libs нашего проекта (Build Path->Configure Buil Path->Libraries->Add External JARs)
Добавляем разрешения в манифест нашего проекта
<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"/>
Изменяем разметку 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. Создание расширения для класса Overlay с целью вывода на карту пути с указателями направления и обработки событий «onClick» по карте
Чтобы нарисовать путь, нам потребуется расширить класс OverlayIRender, который реализует интерфейс IRender
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();
}
}
}
Если количество точек добавленных в наш путь больше 1, то в цикле отрисовываются отрезки пути и стрелки направления.
Теперь нужно создать наследника Overlay MyPathOverLay, назначить ему MyOverlayIRender для отрисовки.
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;
}
}
В переопределенном методе onLongPress будем добавлять промежуточные точки для нашего пути долгим нажатием на карту.
R.drawable.flag2leftred — картинка для точки,
m.setOffsetY(-23); — смещение, которое нужно подобрать, если нужно сместить картинку относительно точки нажатия на карту, по-умолчанию центр картинки совмещается с точкой нажатия.
Осталось добавить наш Overlay на карту и протестировать
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);
}
}
Результат
Автор: constv
(Здесь не ясно, когда будет отображен комментарий, в при первой попытке у меня был сбой. Поэтому с этим добавлением посылаю снова – так как просто не увидел нормальной реакции сервиса.)
Тема очень для меня актуальная. Но в Вашем примере пользователь сам себе строит маршрут, просто кликая по карте. В моем же приложении требуется маршрут прокладывать автоматически. Буду делать поддержку множества карт, это точно будут Google карты и Open Street Map, при этом буду использовать Android-движки каждой отдельно – о том, что можно использовать один движок, а подсовывать разные карты, я как-то не догадался, не подумал, но теперь не вижу в этом необходимости – и для гугл-карт, и для Open Street Map у меня есть уже рабочие примеры прокладки маршрута (пока без наворотов вроде маркеров и прочего, но с этим не вижу дальнейших сложностей. Код же для поддержки Яндекс-Карт движком от Open Street Map мне показался излишне сложным, зачем?
Итак, к сути вопроса. Яндекс-карты тоже хочу добавить. Есть ли возможность прокладки маршрута при использовании Yandex Map Kit, рассчитанного не мной лично, а самим Яндексом?