Erweiterte Konzepte

Daten abrufen

Es gibt viele Möglichkeiten, um an erfasste Standortdaten zu kommen. Hier beschreiben wir zwei Techniken zum Erfassen von Daten zur Verwendung mit der Funktion An Straßen ausrichten von Roads API.

GPX

GPX ist ein offenes XML-basiertes Format zum Teilen von Routen, Tracks und Wegpunkten. die von GPS-Geräten erfasst wurden. In diesem Beispiel wird der Parser XmlPull verwendet, ein Ein einfacher XML-Parser, der sowohl für Java-Server als auch mobile Umgebungen verfügbar ist.

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

Hier sehen Sie GPX-Rohdaten, die in eine Karte geladen wurden.

GPX-Rohdaten auf einer Karte

Android-Standortdienste

Wie Sie GPS-Daten mit einem Android-Gerät am besten erfassen, hängt von Ihrem für den Anwendungsfall. Sehen Sie sich den Android-Schulungskurs zum Thema Empfang von Standortdaten an. Updates sowie die Google Play-Standortbeispiele auf GitHub

Lange Pfade werden verarbeitet

Da die Funktion An Straßen ausrichten den Standort anhand des vollständigen Pfads ableitet, und nicht einzelne Punkte. Bei der Verarbeitung langer Punkte Pfade (d. h. Pfade über dem Limit von 100 Punkten pro Anfrage).

Um die einzelnen Anfragen als einen langen Pfad zu behandeln, sollten Sie einige Überschneidungen, sodass die letzten Punkte aus dem vorherigen Antrag enthalten sind als ersten Punkt der nachfolgenden Anfrage. Die Anzahl der einzubeziehenden Punkte hängt von der Genauigkeit Ihrer Daten ab. Du solltest mehr Punkte hinzufügen für Anfragen mit niedriger Genauigkeit.

In diesem Beispiel wird der Java-Client für Google Maps-Dienste verwendet, um Paged-Anfragen und führt die Daten einschließlich interpolierter Punkte wieder in der zurückgegebenen Liste zusammen.

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

Hier sind die Daten von oben, nachdem die Anfragen zum Andocken an Straßen ausgeführt wurden. Das Rote die Rohdaten und die blaue Linie die ausgerichteten Daten.

Beispiel für Daten, die an Straßen ausgerichtet wurden

Effiziente Nutzung des Kontingents

Die Antwort auf eine Anfrage zum Andocken an Straßen enthält eine Liste mit Orts-IDs. mit den von Ihnen angegebenen Punkten, möglicherweise mit zusätzlichen Punkten, interpolate=true festlegen.

Um Ihr zulässiges Kontingent für Geschwindigkeitsbegrenzungen effizient zu nutzen, sollten Sie in Ihrer Anfrage nur eindeutige Orts-IDs abfragen. In diesem Beispiel wird den Java-Client für Google Maps-Dienste, um Geschwindigkeitsbegrenzungen anhand einer Liste von Orten abzufragen IDs.

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

Im Folgenden finden Sie die oben aufgeführten Daten mit Geschwindigkeitsbegrenzungen für jede eindeutige Orts-ID.

Geschwindigkeitsbegrenzungen auf einer Karte

Interaktion mit anderen APIs

Einer der Vorteile, wenn Orts-IDs in der Funktion An Straßen ausrichten zurückgegeben werden ist, dass Sie die Orts-ID in vielen der Google Maps Platform APIs In diesem Beispiel wird der Java-Client für Google Maps-Dienste verwendet. , um einen Ort zu geocodieren, der von der obigen Anforderung zum Ausrichten auf eine Straße zurückgegeben wurde.

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

Hier ist die Markierung für die Geschwindigkeitsbegrenzung mit der Adresse aus dem Geocoding API

Geocodierte Adresse, die auf einer Markierung angezeigt wird

Beispielcode

Hinweise

Der Code zur Unterstützung dieses Artikels ist als einzelne Android-App für zur Veranschaulichung. In der Praxis sollten Sie Ihre serverseitigen API-Schlüssel in einer Android-App können nicht gegen Unbefugte gesichert werden. über den Zugriff durch Dritte. Stattdessen sollten Sie zum Sichern Ihrer Schlüssel die Methode API-seitiger Code als serverseitiger Proxy und Anfragen Ihrer Android-App zum Senden von Anfragen über den Proxy und stellt somit sicher, dass Anfragen autorisiert sind.

Herunterladen

Laden Sie den Code von GitHub herunter.