İleri Düzey Kavramlar

Koleksiyonlar ile düzeninizi koruyun İçeriği tercihlerinize göre kaydedin ve kategorilere ayırın.

Veri edinme

Toplanan konum verilerini almanın birçok yolu vardır. Roads API ürününün yollara kestirme özelliğiyle kullanılacak veri edinmeye yönelik iki tekniği açıklarız.

GPX

GPX, GPS cihazları tarafından yakalanan rotaları, pistleri ve ara noktaları paylaşmak için kullanılan açık XML tabanlı bir biçimdir. Bu örnekte, hem Java sunucusu hem de mobil ortamlar için 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;
}

İşlenmemiş GPX verileri bir haritaya yüklenir.

Harita üzerinde ham GPX verileri

Android konum hizmetleri

GPS verilerini Android cihazlardan almanın en iyi yolu kullanım alanınıza bağlı olarak farklılık gösterir. Konum Güncellemelerini Alma ile ilgili Android eğitim sınıfının yanı sıra GitHub'daki Google Play Konum örneklerine göz atın.

Uzun yollar işleniyor

Yollara doğru kesilme özelliği, tek tek noktalar yerine konumu tam yola göre tahmin ettiği için uzun yolları işlerken (yani istek başına 100 puanlık sınırı aşan yollar) dikkatli olmanız gerekir.

Bağımsız istekleri tek bir uzun yol olarak değerlendirebilmek için önceki isteğin son noktalarının, sonraki isteğin ilk noktaları olarak ekleneceği şekilde bazı çakışmalar eklemeniz gerekir. Eklenecek noktaların sayısı, verilerinizin doğruluğuna bağlıdır. Düşük doğruluklu istekler için daha fazla puan eklemeniz gerekir.

Bu örnek, sayfalı istekler göndermek üzere Google Haritalar Hizmetleri için Java İstemcisi'ni kullanır ve ardından, ara noktalar da dahil olmak üzere verileri, döndürülen listeye yeniden birleştirir.

/**
 * 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 hızlı geçiş isteklerini çalıştırdıktan sonra yukarıdaki verileri burada görebilirsiniz. Kırmızı çizgi ham veri, mavi çizgi tutturulmuş veridir.

Yollara tutturulmuş veri örneği

Verimli kota kullanımı

Yollara kestirme isteğine verilen yanıt, sağladığınız noktalarla eşlenen yer kimliklerinin bir listesini içerir. interpolate=true özelliğini ayarlarsanız, ek noktalarla eşleştirilmesi olasıdır.

Bir 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 sorgulamanız gerekir. Bu örnekte, yer kimlikleri listesinden hız sınırlarını sorgulamak amacıyla Google Haritalar Hizmetleri için Java İstemcisi kullanılmaktadı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 benzersiz veri türlerinin, her bir yer kimliğinde işaretlenmiş hız sınırları vardır.

Haritadaki hız sınırı işaretleri

Diğer API'lerle etkileşim

Yer kimliklerinin yollara kestirme yanıtlarında döndürülmesinin avantajlarından biri, yer kimliğini Google Haritalar Platformu API'lerinin çoğunda kullanabilmenizdir. Bu örnekte, yukarıdan hızlı geçiş isteğinden döndürülen bir yerin coğrafi kodunu oluşturmak 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çisine Geocoding API'den alınan adresle ek açıklama dahil edilmiştir.

İşaretçide gösterilen coğrafi kodlamalı adres

Örnek kod

Üzerinde düşünme

Bu makaleyi destekleyen kod, açıklama amaçlı tek bir Android uygulaması olarak mevcuttur. Pratikte, anahtarınız bir üçüncü tarafın yetkisiz erişimine karşı korunamayacağı için sunucu tarafında API anahtarlarınızı Android uygulamasında dağıtmamalısınız. Bunun yerine, anahtarlarınızın güvenliğini sağlamak için API'ye yönelik kodu sunucu tarafı proxy olarak dağıtmanız ve isteklerin yetkilendirildiğinden emin olmak üzere Android uygulamanızın proxy üzerinden istek göndermesini sağlamanız gerekir.

İndir

Kodu GitHub'dan indirin.