İleri Düzey Kavramlar

Veri edinme

Toplanan konum verilerini elde etmenin birçok yolu vardır. Burada, Roads API'nin yollara yaklaştır özelliğiyle kullanılacak verileri edinmeyle ilgili iki teknik açıklanmaktadır.

GPX

GPX, GPS cihazları tarafından yakalanan rotaları, parkurları ve yol noktalarını paylaşmak için kullanılan açık XML tabanlı bir biçimdir. Bu örnekte, hem Java sunucusu hem de mobil ortamlarda kullanılabilen hafif bir XML ayrıştırıcı olan XmlPull ayrıştırıcısı kullanılmaktadır.

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

Aşağıda, haritaya yüklenen bazı ham GPX verileri gösterilmektedir.

Haritada ham GPX verileri

Android konum hizmetleri

Android cihazdan GPS verilerini yakalamanın en iyi yolu, kullanım alanınıza bağlı olarak değişir. Konum Güncellemeleri Alma konulu Android eğitim sınıfına ve GitHub'daki Google Play konum örneklerine göz atın.

Uzun yolları işleme

Yollara yaklaş özelliği, konumu tek tek noktalar yerine tam yola göre tahmin ettiğinden uzun yolları (ör. istek başına 100'den fazla nokta içeren yollar) işlerken dikkatli olmanız gerekir.

Tek tek istekleri tek bir uzun yol olarak ele almak için bazı çakışmalar eklemeniz gerekir. Örneğin, önceki istekteki son noktalar sonraki isteğinin ilk noktaları olarak eklenir. Eklenecek nokta sayısı, verilerinizin doğruluğuna bağlıdır. Düşük doğruluktaki istekler için daha fazla nokta eklemeniz gerekir.

Bu örnekte, sayfalı istekler göndermek için Google Haritalar Hizmetleri için Java İstemcisi kullanılır ve ardından, noktaların ara değerle doldurulması da dahil olmak üzere veriler döndürülen listeye yeniden katılır.

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

Yollara sabitleme istekleri çalıştırıldıktan sonra yukarıdaki verileri görebilirsiniz. Kırmızı çizgi ham verileri, mavi çizgi ise yakalanan verileri gösterir.

Yollara bağlanmış verileri gösteren örnek

Kotayı verimli bir şekilde kullanma

Yola yaklaş isteğinin yanıtı, sağladığınız noktalarla eşleşen yer kimliklerinin bir listesini içerir. interpolate=true ayarını yaparsanız ek noktalar da yer alabilir.

Hız sınırı isteği için izin verilen kotanızı verimli bir şekilde kullanmak amacıyla isteğinizde yalnızca benzersiz yer kimliklerini sorgulayın. Bu örnekte, yer kimlikleri listesinden hız sınırlarını sorgulamak için Google Haritalar Hizmetleri için Java İstemcisi kullanılır.

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

Yukarıdaki verileri, her benzersiz yer kimliğinde hız sınırlarının işaretlendiği şekilde aşağıda bulabilirsiniz.

Haritadaki hız sınırı tabelaları

Diğer API'lerle etkileşim

Yola yaklaştır yanıtlarında yer kimliklerinin döndürülmesinin avantajlarından biri, yer kimliğini Google Maps Platform API'lerinin çoğunda kullanabilmenizdir. Bu örnekte, yukarıdaki fotoğraftan yola istek gönderme işleminde döndürülen bir yeri coğrafi kodlamak için Google Haritalar Hizmetleri için Java İstemcisi kullanılmaktadır.

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

Burada hız sınırı işaretçisi, Coğrafi Kodlama API'sindeki adresle ek açıklamaya sahiptir.

İşaretçi üzerinde gösterilen coğrafi kodlu adres

Örnek kod

Dikkat edilmesi gereken noktalar

Bu makaleyi destekleyen kod, açıklama amaçlı tek bir Android uygulaması olarak kullanılabilir. Anahtarınız üçüncü tarafların yetkisiz erişimine karşı korunamadığından, sunucu tarafı API anahtarlarınızı Android uygulamasında dağıtmamanız önerilir. Bunun yerine, anahtarlarınızı güvence altına almak için API'ye bakan kodu sunucu tarafı proxy olarak dağıtmanız ve Android uygulamanızın isteklerin yetkilendirilmesini sağlayarak isteklerini proxy üzerinden göndermesini sağlamanız gerekir.

İndir

Kodu GitHub'dan indirin.