Не так давно мне понадобилось написать приложение, которое бы показывало на карте маршрут между двумя заданными точками. В качестве инструмента были выбраны карты от Google. После непродолжительных поисков были найдены статьи про интеграцию карт в приложение, про фильтрацию пинов, про маршруты. Однако статьи, в которой бы описывалось как делать подобные маршруты в Android-приложении, не было и я решил исправить данное упущение (для новоиспечённых разработчиков под Android пригодится). Добро пожаловать под хабракат.
Предположим, что мы уже прочитали статью про интеграцию, получили API-Key и написали приложение с картой, на которой отмечены две точки. Поэтому нам осталось только проложить маршрут между двумя данными точками.
Прежде всего необходимо отправить запрос и получить файл с данными о маршруте. Для этого нам потребуется открыть соединение по указанной ссылке (широта и долгота в ссылке задаются через запятую) и получить данные в виде XML. Вытаскивать точки маршрута из файла мы будем DOM парсером, для чего создаем объект Document.
Следуя документации по KML маршрут состоит из более мелких отрезков, поэтому нам предстоит создать массив из точек, через которые будет проходить наш маршрут. Подробности о разборе XML файла можно найти в этой статье. Стоит отметить, что точки находятся в теле тега «coordinates», который, в свою очередь, находится внутри «LineString».
На этом получение координат, по которым будет строиться маршрут закончено. Переходим к рисованию самой линии.
Данный класс наследует Overlay и представляет из себя (грубо говоря) графический уровень, который будет отображаться на карте. В данном классе мы создадим конструктор, через который будем задавать точки начала и конца линии, и допишем метод draw, который будет рисовать данную линию.
А теперь нам необходимо написать метод, который будет добавлять точки на этот уровень, создавая наш маршрут.
Если вы дошли до этого момента, то, скорее всего, знаете, что в GeoPoint сначала указывается широта, потом долгота.
На этом создание маршрута завершено. Спасибо за внимание. В качестве примера приведу скриншот того, что получилось у меня.
P.S. Это моя первая статья, поэтому не судите, пожалуйста, строго, так как большого опыта написания статей не имею, а код объяснял только словами и на пальцах.
Предположим, что мы уже прочитали статью про интеграцию, получили 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 сначала указывается широта, потом долгота.
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));
На этом создание маршрута завершено. Спасибо за внимание. В качестве примера приведу скриншот того, что получилось у меня.
P.S. Это моя первая статья, поэтому не судите, пожалуйста, строго, так как большого опыта написания статей не имею, а код объяснял только словами и на пальцах.