Все готово!

Прежде чем приступить к разработке, ознакомьтесь с документацией для разработчиков.

Активировать Google Maps Roads API

Чтобы помочь вам освоиться, мы покажем, как выполнить некоторые необходимые действия в консоли разработчика Google:

  1. Создание или выбор проекта
  2. Активировать Google Maps Roads API
  3. Создание соответствующих ключей

Перспективные идеи

Примечание. В приведенных ниже примерах используется Google Maps Roads API в Java Client for Google Maps Services. Вы можете применить эти идеи к выбранному вами языку. Python Client, Go Client и Node.js Client также доступны на веб-сайте GitHub.

Получение данных

Существует множество способов получить собранные данные о местоположении. Здесь описаны два способа получения данных для функции привязки к дорогам, представленной в Google Maps Roads API.

GPX

GPX – это открытый формат на основе XML, предназначенный для обмена маршрутами, записями пути и промежуточными точками, получаемыми устройствами GPS. В данном примере используется XML-обработчик XmlPull, поскольку он имеет небольшой размер и доступен для сервера Java и мобильных сред.

/**
 * Parses the waypoint (wpt tags) data into native objects from a GPX stream.
 */
private List<LatLng> loadGpxData(XmlPullParser parser, InputStream gpxIn)
        throws XmlPullParserException, IOException {
    // We use a List<> as we need subList for paging later
    List<LatLng> latLngs = new ArrayList<>();
    parser.setInput(gpxIn, null);
    parser.nextTag();

    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }

        if (parser.getName().equals("wpt")) {
            // Save the discovered latitude/longitude attributes in each <wpt>.
            latLngs.add(new LatLng(
                    Double.valueOf(parser.getAttributeValue(null, "lat")),
                    Double.valueOf(parser.getAttributeValue(null, "lon"))));
        }
        // Otherwise, skip irrelevant data
    }

    return latLngs;
}

Вот пример необработанных данных GPX, загруженных на карту.

Необработанные данные GPX на карте

Службы определения местоположения для Android

Оптимальный способ получения GPS-данных с устройства Android зависит от конкретного случая использования. Просмотрите учебные материалы Android по функции Получение обновленных данных о местоположении, а также Примеры местоположений Google Play на веб-сайте GitHub.

Обработка длинных маршрутов

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

Чтобы обрабатывать индивидуальные запросы как один длинный маршрут, необходимо включить пересечение; например, конечные точки предыдущего запроса должны быть включены в качестве первых точек в следующий запрос. Количество включаемых точек зависит от точности данных. Для запросов с низкой точностью следует указывать больше точек.

В данном примере используется Java Client for Google Maps Services для отправки "страничных" запросов и повторного объединения данных, включая интерполированные точки, в полученный список.

/**
 * Snaps the points to their most likely position on roads using the Roads API.
 */
private List<SnappedPoint> snapToRoads(GeoApiContext context) throws Exception {
    List<SnappedPoint> snappedPoints = new ArrayList<>();

    int offset = 0;
    while (offset < mCapturedLocations.size()) {
        // Calculate which points to include in this request. We can't exceed the API's
        // maximum and we want to ensure some overlap so the API can infer a good location for
        // the first few points in each request.
        if (offset > 0) {
            offset -= PAGINATION_OVERLAP;   // Rewind to include some previous points.
        }
        int lowerBound = offset;
        int upperBound = Math.min(offset + PAGE_SIZE_LIMIT, mCapturedLocations.size());

        // Get the data we need for this page.
        LatLng[] page = mCapturedLocations
                .subList(lowerBound, upperBound)
                .toArray(new LatLng[upperBound - lowerBound]);

        // Perform the request. Because we have interpolate=true, we will get extra data points
        // between our originally requested path. To ensure we can concatenate these points, we
        // only start adding once we've hit the first new point (that is, skip the overlap).
        SnappedPoint[] points = RoadsApi.snapToRoads(context, true, page).await();
        boolean passedOverlap = false;
        for (SnappedPoint point : points) {
            if (offset == 0 || point.originalIndex >= PAGINATION_OVERLAP - 1) {
                passedOverlap = true;
            }
            if (passedOverlap) {
                snappedPoints.add(point);
            }
        }

        offset = upperBound;
    }

    return snappedPoints;
}

Ниже приведены данные, полученные после выполнения запросов к службе привязки к дорогам. Красной линией обозначены необработанные данные, а синей – привязанные к дорогам данные.

Пример данных, которые были привязаны к дорогам

Эффективное использование квоты

Ответ на запрос к службе привязки к дорогам включает в себя список идентификаторов мест, соответствующих указанным на карте точкам, а также дополнительным точками, если установлено interpolate=true.

Чтобы более эффективно использовать доступную квоту для запроса ограничения скорости, необходимо запрашивать только уникальные идентификаторы мест. В данном примере Java Client for Google Maps Services используется для запроса сведений об ограничениях скорости из списка идентификаторов мест.

/**
 * Retrieves speed limits for the previously-snapped points. This method is efficient in terms
 * of quota usage as it will only query for unique places.
 *
 * Note: Speed limit data is only available for requests using an API key enabled for a
 * Google Maps APIs Premium Plan license.
 */
private Map<String, SpeedLimit> getSpeedLimits(GeoApiContext context, List<SnappedPoint> points)
        throws Exception {
    Map<String, SpeedLimit> placeSpeeds = new HashMap<>();

    // Pro tip: Save on quota by filtering to unique place IDs.
    for (SnappedPoint point : points) {
        placeSpeeds.put(point.placeId, null);
    }

    String[] uniquePlaceIds =
            placeSpeeds.keySet().toArray(new String[placeSpeeds.keySet().size()]);

    // Loop through the places, one page (API request) at a time.
    for (int i = 0; i < uniquePlaceIds.length; i += PAGE_SIZE_LIMIT) {
        String[] page = Arrays.copyOfRange(uniquePlaceIds, i,
                Math.min(i + PAGE_SIZE_LIMIT, uniquePlaceIds.length));

        // Execute!
        SpeedLimit[] placeLimits = RoadsApi.speedLimits(context, page).await();
        for (SpeedLimit sl : placeLimits) {
            placeSpeeds.put(sl.placeId, sl);
        }
    }

    return placeSpeeds;
}

Ниже приведены данные с отмеченными ограничениями скорости для каждого уникального идентификатора места.

Знаки ограничения скорости на карте

Взаимодействие с другими API

Одним из преимуществ использования идентификаторов мест в качестве результатов функции привязки к дорогам является возможность их применения со множеством других интерфейсов Google Maps API. В данном примере Java Client for Google Maps Services используется для геокодирования места, полученного в результате запроса службы привязки к дорогам, приведенного выше.

/**
 * Geocodes a snapped point using the place ID.
 */
private GeocodingResult geocodeSnappedPoint(GeoApiContext context, SnappedPoint point) throws Exception {
    GeocodingResult[] results = GeocodingApi.newRequest(context)
            .place(point.placeId)
            .await();

    if (results.length > 0) {
        return results[0];
    }
    return null;
}

Ниже приведен маркер ограничения скорости с адресом из Google Maps Geocoding API.

Геокодированный адрес, показанный в маркере

Пример кода

Рекомендации

Программный код, указанный в данной статье, предоставлен как приложение Android исключительно в демонстрационных целях. На практике вы не должны распространять серверные ключи API в приложении Android, поскольку в этом случае не удастся обеспечить защиту ключа от несанкционированного доступа со стороны третьих лиц. Для защиты ключей необходимо выполнять развертывание кода API как серверного прокси и настроить отправку запросов приложением Android через прокси для обеспечения авторизации запросов.

Загрузка

Загрузить код из GitHub.

Оставить отзыв о...

Текущей странице
Google Maps Roads API
Google Maps Roads API
Нужна помощь? Обратитесь в службу поддержки.