İleri Düzey Kavramlar

Veri edinme

Toplanan konum verilerini elde etmenin birçok yolu vardır. Burada, Roads API'ın yollara yaslama özelliğiyle kullanılacak verileri edinmeye yönelik iki teknik açıklanmaktadır.

GPX

GPX, GPS cihazları tarafından kaydedilen rotaları, izleri ve yol noktalarını paylaşmak için kullanılan açık bir XML tabanlı biçimdir. Bu örnekte, hem Java sunucu hem de mobil ortamlar için kullanılabilen hafif bir XML ayrıştırıcısı 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;
}

Haritaya yüklenen bazı ham GPX verilerini burada görebilirsiniz.

Haritada ham GPX verileri

Android konum hizmetleri

Android cihazdan GPS verilerini yakalamanın en iyi yolu, kullanım alanınıza göre değişir. 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şleme

Yollara yaslama özelliği, konumu tek tek noktalar yerine tam yola göre çıkarır. Bu nedenle, uzun yolları (yani istek başına 100 nokta sınırını aşan yollar) işlerken dikkatli olmanız gerekir.

Ayrı istekleri tek bir uzun yol olarak ele almak için bir miktar çakışma eklemeniz gerekir. Böylece, önceki isteğin son noktaları, sonraki isteğin ilk noktaları olarak dahil edilir. Eklenecek nokta sayısı, verilerinizin doğruluğuna bağlıdır. Düşük doğruluklu istekler için daha fazla nokta eklemelisiniz.

Bu örnekte, sayfalandırılmış istekler göndermek için Google Haritalar Hizmetleri için Java İstemcisi kullanılır ve ardından, interpolasyonlu noktalar da dahil olmak üzere veriler döndürülen listeye yeniden eklenir.

/**
 * 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 tutturma istekleri çalıştırıldıktan sonra yukarıdaki veriler şu şekilde görünür: Kırmızı çizgi ham verileri, mavi çizgi ise yakalanan verileri gösterir.

Yollara sabitlenmiş veri örneği

Kotayı verimli kullanma

Yollara yerleştirme isteğine verilen yanıt, sağladığınız noktalara eşlenen yer kimliklerinin listesini içerir. interpolate=true parametresini ayarladıysanız ek noktalar da içerebilir.

Hız sınırları isteği için izin verilen kotanızı verimli bir şekilde kullanmak istiyorsanız isteğinizde yalnızca benzersiz yer kimliklerini sorgulamanız gerekir. Bu örnekte, bir yer kimliği listesinden hız sınırlarını sorgulamak için 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 verilerde, her benzersiz yer kimliğinde hız sınırları işaretlenmiştir.

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

Diğer API'lerle etkileşim

Yollara hızlı geçiş yanıtlarında yer kimliklerinin döndürülmesinin avantajlarından biri, yer kimliğini Google Haritalar Platformu API'lerinin birçoğunda kullanabilmenizdir. Bu örnekte, yukarıdaki snap to road isteğinden döndürülen bir yeri coğrafi olarak kodlamak için Google Haritalar Hizmetleri için Java İstemcisi kullanılı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şaretine Geocoding API'den alınan adresle açıklama eklenmiştir.

Bir işaretçide gösterilen coğrafi kodlu adres

Örnek kod

Dikkat edilmesi gereken noktalar

Bu belgeyi destekleyen kod, açıklama amacıyla tek bir Android uygulaması olarak sunulmaktadır. Uygulamada, sunucu tarafı API anahtarlarınızı bir Android uygulamasında dağıtmamanız gerekir. Çünkü anahtarınız, üçüncü tarafların yetkisiz erişimine karşı güvende olamaz. 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 Android uygulamanızın istekleri proxy kullanarak göndermesini sağlamanız gerekir. Böylece isteklerin yetkilendirildiğinden emin olabilirsiniz.

İndir

Kodu GitHub'dan indirin.