Veri edinme
Toplanan konum verilerini elde etmenin birçok yolu vardır. Burada, Roads API'ın yollara tutturma özelliğiyle kullanmak üzere veri toplamaya ilişkin iki tekniği açıklıyoruz.
GPX
GPX, GPS cihazları tarafından çekilen rotaları, parkurları ve referans noktalarını paylaşmak için kullanılan, XML tabanlı açık 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ı 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, bir haritaya yüklenen bazı ham GPX verilerini görebilirsiniz.
Android konum hizmetleri
Bir Android cihazdan GPS verilerini yakalamanın en iyi yolu, kullanım alanınıza bağlı olarak değişiklik gösterir. Konum Güncellemelerini Alma konulu Android eğitim sınıfına ve GitHub'daki Google Play Konum örneklerine göz atın.
Uzun yollar işleniyor
Yollara tutturma özelliği, konumu tek tek noktalar yerine tüm yola göre tahmin ettiği için uzun yolları (yani istek başına 100 nokta sınırını aşan yolları) işlerken dikkatli olmanız gerekir.
İstekleri tek tek uzun tek bir yol olarak ele almak için bir miktar çakışma eklemeniz gerekir. Böylece önceki istekten gelen son noktalar, sonraki isteğin ilk noktaları olarak dahil edilir. Eklenecek nokta sayısı, verilerinizin doğruluğuna bağlıdır. Doğruluğu düşük olan istekler için daha fazla puan eklemeniz gerekir.
Bu örnekte, sayfalandırılmış istekler göndermek amacıyla Google Haritalar Hizmetleri için Java İstemcisi kullanılmıştır ve ardından ara değer olarak eklenen noktalar da dahil olmak üzere verileri, döndürülen listede 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; }
Yola geçiş istekleri çalıştırıldıktan sonra yukarıdan elde edilen veriler burada sunulmuştur. Kırmızı çizgi ham veri, mavi çizgi ise tutturulmuş veridir.
Kotanın verimli kullanımı
Yollara tutturma isteğine verilen yanıt, sağladığınız noktalarla eşleşen yer kimliklerinin bir listesini ve interpolate=true
ayarlarsanız ek noktalar da içerebilir.
Bir hız sınırları 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, bir yer kimlikleri listesinden hız sınırlarını sorgulamak için Google Haritalar Hizmetleri için Java İstemcisi kullanılmıştı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; }
Aşağıda, her bir benzersiz yer kimliğinde işaretlenmiş hız sınırlarıyla birlikte yukarıdaki veriler verilmiştir.
Diğer API'lerle etkileşim kurma
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 çoğunda kullanabilmenizdir. Bu örnekte, yukarıdaki yol isteğiyle döndürülen bir yerin coğrafi kodlamasını yapmak üzere 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 GeoKodlama API'sinden alınan adres eklenmiştir.
Örnek kod
Üzerinde düşünülecek noktalar
Bu makaleyi destekleyen kod, açıklama amaçlı tek bir Android uygulaması olarak kullanıma sunulmuştur. Pratikte, üçüncü taraflardan yetkisiz erişime karşı anahtarınızın güvenliği sağlanamayacağından, sunucu tarafı API anahtarlarınızı bir 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ında bir proxy olarak dağıtmanız ve Android uygulamanızın proxy üzerinden istek göndermesini sağlayarak isteklerin yetkilendirildiğinden emin olmanız gerekir.
İndirme
GitHub'dan kodu indirin.