Eso es todo.

Para comenzar a desarrollar, consulta nuestra documentación para desarrolladores.

Activar Google Maps Roads API

Para que puedas comenzar, te proporcionaremos orientación en la consola para desarrolladores de Google a fin de que hagas primero algunas acciones:

  1. Crear o seleccionar un proyecto
  2. Activar Google Maps Roads API
  3. Crear claves correspondientes
Continuar

Conceptos avanzados

Nota: En los ejemplos siguientes se usa la Google Maps Roads API en Java Client for Google Maps Services. Puedes adaptar los conceptos al idioma que prefieras. Python Client, Go Client y Node.js Client también están disponibles en GitHub.

Obtención de datos

Hay muchas formas de obtener datos de ubicación recopilados. En este documento, describimos dos técnicas de adquisición de datos que se usarán con la función ajustar a carreteras de la Google Maps Roads API.

GPX

GPX es un formato abierto basado en XML para compartir rutas, caminos y waypoints capturados por dispositivos GPS. En este ejemplo, se usa el analizador XmlPull, un analizador XML liviano disponible para entornos móviles y de servidor de 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;
}

Aquí te mostramos algunos datos GPX sin procesar cargados en un mapa.

Datos GPX sin procesar en un mapa

Servicios de ubicación de Android

La mejor forma de captar datos de GPS desde un dispositivo Android varía según el caso de uso. Consulta la clase de capacitación de Android sobre Recepción de actualizaciones de ubicación y los ejemplos de ubicación de Google Play en GitHub.

Procesamiento de rutas de acceso extensas

Debido a que la función ajustar a carreteras deduce la ubicación a partir de toda la ruta, en lugar de puntos individuales, debes tener cuidado cuando proceses rutas largas (es decir, rutas que superen el límite de 100 puntos por solicitud).

Para tratar las solicitudes individuales como una ruta larga, debes admitir cierta superposición para que los puntos finales de la solicitud anterior se incluyan como los primeros puntos de la solicitud siguiente. La cantidad de puntos que se incluirán depende de la precisión de tus datos. Para solicitudes de poca precisión, debes incluir más puntos.

En este ejemplo, se usa Java Client for Google Maps Services para enviar solicitudes paginadas y luego volver a unir los datos, incluidos los puntos interpolados, en la lista devuelta.

/**
 * 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;
}

Aquí se muestran los datos anteriores después de ejecutar las solicitudes de ajuste a carreteras. La línea roja corresponde a los datos sin procesar y la azul, a los datos ajustados.

Ejemplo de datos obtenidos de Snap to Roads

Uso eficiente de la cuota

En la respuesta de una solicitud ajustar a carretera se incluye una lista de ID de sitios que se asignan a los puntos que proporcionaste (incluso puntos adicionales si configuraste interpolate=true).

Para usar tu cuota con eficacia en una solicitud de límites de velocidad, solo debes consultar ID de sitios únicos en tu solicitud. En este ejemplo, se usa Java Client for Google Maps Services para consultar límites de velocidad en una lista de ID de sitios.

/**
 * 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;
}

Aquí se muestran los datos anteriores con límites de velocidad marcados en cada ID de sitio único.

Carteles de límite de velocidad en un mapa

Interacción con otras API

Uno de los beneficios de contar con ID de sitios en las respuestas de ajustar a carreteras es que puedes usarlos en varias Google Maps API. En este ejemplo, se usa Java Client for Google Maps Services para realizar la geocodificación de un sitio que mostró la solicitud de ajuste a carreteras anterior.

/**
 * 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;
}

Aquí, el marcador de límite de velocidad tiene el texto de la dirección obtenida de la Google Maps Geocoding API.

Dirección geocodificada en un marcador

Ejemplo de código

Consideraciones

El código de este artículo se encuentra disponible como una sola app de Android para fines ilustrativos. En la práctica, no debes distribuir tus claves de API de servidor en una app de Android, ya que la clave no se puede proteger contra el acceso no autorizado por parte de terceros. En su lugar, para garantizar la seguridad de tus claves, implementa el código visible en la API como un proxy de servidor. A continuación, indícale a tu app que envíe solicitudes a través del proxy y asegúrate de que estas estén autorizadas.

Descarga

Descarga el código desde GitHub.

Enviar comentarios sobre…

Google Maps Roads API
Google Maps Roads API
¿Necesitas ayuda? Visita nuestra página de asistencia.