Маршруты на картах Google в вашем Android-приложении

в 1:21, , рубрики: android, Google Maps, KML, маршруты, Разработка под android, метки: , , ,

Не так давно мне понадобилось написать приложение, которое бы показывало на карте маршрут между двумя заданными точками. В качестве инструмента были выбраны карты от Google. После непродолжительных поисков были найдены статьи про интеграцию карт в приложение, про фильтрацию пинов, про маршруты. Однако статьи, в которой бы описывалось как делать подобные маршруты в Android-приложении, не было и я решил исправить данное упущение (для новоиспечённых разработчиков под Android пригодится). Добро пожаловать под хабракат.

Предположим, что мы уже прочитали статью про интеграцию, получили API-Key и написали приложение с картой, на которой отмечены две точки. Поэтому нам осталось только проложить маршрут между двумя данными точками.

Получение маршрута

Прежде всего необходимо отправить запрос и получить файл с данными о маршруте. Для этого нам потребуется открыть соединение по указанной ссылке (широта и долгота в ссылке задаются через запятую) и получить данные в виде XML. Вытаскивать точки маршрута из файла мы будем DOM парсером, для чего создаем объект Document.

String urlString = "http://maps.google.com/maps?f=d&hl=en&saddr=" + startGeoPoint + "&daddr=" + stopGeoPoint + "&ie=UTF8&0&om=0&output=kml";
Document document = null;
HttpURLConnection urlConnection = null;
URL url = null;
try {
url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
DocumentBuilderFactory documentBuildFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuildFactory.newDocumentBuilder();
document = documentBuilder.parse(urlConnection.getInputStream());
} catch (Exception e) { }

Следуя документации по KML маршрут состоит из более мелких отрезков, поэтому нам предстоит создать массив из точек, через которые будет проходить наш маршрут. Подробности о разборе XML файла можно найти в этой статье. Стоит отметить, что точки находятся в теле тега «coordinates», который, в свою очередь, находится внутри «LineString».

String points = null;
NodeList nodeList = document.getElementsByTagName("LineString");
points = nodeList.item(0).getFirstChild().getFirstChild().getNodeValue();
String[] finalArray = points.split(" ");

На этом получение координат, по которым будет строиться маршрут закончено. Переходим к рисованию самой линии.

Overlay линии маршрута

Данный класс наследует Overlay и представляет из себя (грубо говоря) графический уровень, который будет отображаться на карте. В данном классе мы создадим конструктор, через который будем задавать точки начала и конца линии, и допишем метод draw, который будет рисовать данную линию.

private GeoPoint start;
private GeoPoint stop;
public MapOverlay(GeoPoint start, GeoPoint stop) {
this.start = start;
this.stop = stop;
}

@Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
// TODO Auto-generated method stub
Projection projection = mapView.getProjection();
if (shadow == false) {
Paint paint = new Paint();
paint.setAntiAlias(true);
Point point = new Point();
projection.toPixels(start, point);
paint.setColor(Color.BLUE);
Point point2 = new Point();
projection.toPixels(stop, point2);
paint.setStrokeWidth(2);
canvas.drawLine((float) point.x, (float) point.y, (float) point2.x, (float) point2.y, paint);
}
return super.draw(canvas, mapView, shadow, when);
}

А теперь нам необходимо написать метод, который будет добавлять точки на этот уровень, создавая наш маршрут.

Создание маршрута

Если вы дошли до этого момента, то, скорее всего, знаете, что в GeoPoint сначала указывается широта, потом долгота, однако называются координаты наоборот, что продемонстрировано в KML файле.

String coords = finalArray[0].split(",");
GeoPoint start = new GeoPoint((int) (Double.parseDouble(coords[1]) * 1E6), (int) (Double.parseDouble(coords[0]) * 1E6));
//Первую и последнюю точку маршрута добавляю отдельно потому, что мне проще написать так, однако вы можете написать свой цикл, в который данные точки будут включены
mapView.getOverlays().add(new MapOverlay(start, start));
GeoPoint geoPoint1;
GeoPoint geoPoint2 = start;
for (int i = 1; i < finalArray.length; i++) {
coords = finalArray[i].split(",");
geoPoint1 = geoPoint2;
geoPoint2 = new GeoPoint((int) (Double.parseDouble(coords[1]) * 1E6), (int) (Double.parseDouble(coords[0]) * 1E6));
mapView.getOverlays().add(new MapOverlay(geoPoint1, geoPoint2));
}
mapView.getOverlays().add(new MapOverlay(geoPoint2, geoPoint2));

На этом создание маршрута завершено. Спасибо за внимание. В качестве примера приведу скриншот того, что получилось у меня.

Маршруты на картах Google в вашем Android приложении

P.S. Это моя первая статья, поэтому не судите, пожалуйста, строго, так как большого опыта написания статей не имею, а код объяснял только словами и на пальцах.

Автор: daniilmann

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js