Google Haritalar Platformu web hizmetleri, harita hizmetleriniz için coğrafi veriler sağlayan, Google hizmetlerine yönelik HTTP arayüzleri koleksiyonudur.
Bu kılavuzda, web hizmeti isteklerinizi ayarlamak ve hizmet yanıtlarını işlemek için sık kullanılan bazı uygulamalar açıklanmaktadır. DISTANCE Matrix API'nin tüm dokümanları için geliştirici kılavuzuna bakın.
Web hizmeti nedir?
Google Haritalar Platformu web hizmetleri, harici hizmetlerden Maps API verileri istemek ve Haritalar uygulamalarınızda kullanmak için kullanılan bir arayüzdür. Bu hizmetler, Google Haritalar Platformu Hizmet Şartları'ndaki Lisans Kısıtlamaları uyarınca, bir haritayla birlikte kullanılmak üzere tasarlanmıştır.
Maps API web hizmetleri, belirli URL'lere yapılan HTTP(S) isteklerini kullanarak URL parametrelerini ve/veya JSON biçimli POST verilerini hizmetlerin bağımsız değişkeni olarak iletir. Genellikle bu hizmetler, HTTP(S) isteğinde uygulamanızın ayrıştırılması ve/veya işlenmesi için JSON ya da XML olarak veri döndürür.
Tipik bir Mesafe Matrisi API isteği genellikle aşağıdaki biçimdedir:
https://maps.googleapis.com/maps/api/distancematrix/output?parameters
burada output
, yanıt biçimini (genellikle json
veya xml
) belirtir.
Not: Tüm Mesafe Matrisi API uygulamaları için kimlik doğrulama gerekir. Kimlik doğrulama kimlik bilgileri hakkında daha fazla bilgi edinin.
SSL/TLS Erişimi
API anahtarları kullanan veya kullanıcı verileri içeren tüm Google Haritalar Platformu istekleri için HTTPS gereklidir. Hassas veri içeren HTTP üzerinden yapılan istekler reddedilebilir.
Geçerli bir URL oluşturma
"Geçerli" bir URL'nin çok bariz bir şekilde belirgin olduğunu düşünebilirsiniz, ancak tam olarak doğru değildir. Örneğin, tarayıcıdaki bir adres çubuğuna girilen bir URL özel karakterler (ör."上海+中國"
) içerebilir. Aktarma işleminden önce tarayıcının bu karakterleri dahili olarak farklı bir kodlamaya dönüştürmesi gerekir.
Aynı şekilde, UTF-8 girişi oluşturan veya kabul eden tüm kodlar, UTF-8 karakterlerine sahip URL'leri "geçerli" olarak işleyebilir, ancak bunları bir web sunucusuna göndermeden önce çevirmeleri gerekir.
Bu işleme
URL kodlaması veya yüzde kodlama adı verilir.
Özel karakterler
Tüm URL'lerin Tek Tip Kaynak Tanımlayıcısı (URI) spesifikasyonunda belirtilen söz dizimine uyması gerektiğinden özel karakterleri çevirmemiz gerekir. Bu, URL'lerin yalnızca ASCII karakterlerin özel bir alt kümesini içermesi gerektiği anlamına gelir: alfanümerik semboller ve URL'lerde kontrol karakteri olarak kullanılacak bazı ayrılmış karakterler. Bu tabloda şu karakterler özetlenmiştir:
Ayarla | olabilir | URL kullanımı |
---|---|---|
Alfanümerik | a b c d e f n g h i j l m n n o p q r s u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 | Metin dizeleri, şema kullanımı (http ), bağlantı noktası (8080 ) vb. |
Ayrılmamış | - _ . ~ | Metin dizeleri |
Rezervasyon yapıldı | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | Kontrol karakterleri ve/veya Metin Dizeleri |
Geçerli bir URL oluştururken, URL'nin yalnızca Geçerli URL Karakterlerinin Özeti tablosunda gösterilen karakterleri içerdiğinden emin olun. Bu karakter kümesini kullanmak için bir URL oluşturmak, genellikle bir sorunu ve eksik olanı olmak üzere iki soruna yol açar:
- Sevmek istediğiniz karakterler, yukarıda belirtilen grubun dışında var. Örneğin,
上海+中國
gibi yabancı dillerdeki karakterlerin yukarıdaki karakterler kullanılarak kodlanması gerekir. Genel kurala göre, URL'lerde izin verilmeyen boşluklar genellikle'+'
karakteriyle de gösterilir. - Yukarıdaki karakterler içinde, ayrılmış karakterler olarak ayarlanmış karakterler vardır, ancak gerçek anlamda kullanılması gerekir.
Örneğin,
?
, sorgu dizesinin başlangıcını belirtmek için URL'lerde kullanılır. "&"; Gizemler" dizesini kullanmak isterseniz'?'
karakterini kodlamanız gerekir.
URL kodlamalı tüm karakterler, bir '%'
karakteri ve UTF-8 karakterlerine karşılık gelen iki karakterlik onaltılık bir değer kullanılarak kodlanır. Örneğin, UTF-8'deki 上海+中國
, %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B
olarak URL olarak kodlanır. ? and the Mysterians
dizesi %3F+and+the+Mysterians
veya %3F%20and%20the%20Mysterians
olarak URL olarak kodlanır.
Kodlanması gereken yaygın karakterler
Kodlanması gereken bazı yaygın karakterler şunlardır:
Güvenli olmayan karakter | Kodlanmış değer |
---|---|
Boşluk tuşu | %20 |
" | %22 |
< | %3C |
> | %3E |
# | %23 |
% | %25 |
| | %7C |
Kullanıcı girişinden aldığınız bir URL'yi dönüştürmek bazen zor bir süreçtir. Örneğin, bir kullanıcı "5.&";Ana St.&"; Genel olarak, tüm kullanıcı girişlerini düz karakter olarak değerlendirerek URL'nizi parçalarından oluşturmanız gerekir.
Ayrıca URL'ler, tüm Google Haritalar Platformu web hizmetleri ve statik web API'leri için 8.192 karakterle sınırlıdır. Çoğu hizmette bu karakter sınırına nadiren yaklaşılır. Bununla birlikte, belirli hizmetlerin uzun URL'lere neden olabilecek birkaç parametresi olduğunu unutmayın.
Google API'lerinin Kibarca Kullanımı
Kötü tasarlanmış API istemcileri, hem internet hem de Google sunucuları için gerekenden daha fazla yük yükleyebilir. Bu bölümde, API'lerin müşterileri için bazı en iyi uygulamalar yer almaktadır. Buradaki en iyi uygulamaları izlemek, uygulamanızın API'lerin kötüye kullanımını engellemesini önlemeye yardımcı olabilir.
Üstel Geri Alma
Nadiren de olsa isteğiniz yerine getirilirken bir sorun yaşanabilir. 4XX veya 5XX HTTP yanıt kodu alabilirsiniz ya da TCP bağlantısı istemciniz ile Google'ın sunucusu arasında bir yerde başarısız olabilir. Orijinal istek başarısız olduğunda takip isteği başarılı olabileceği için genellikle isteği yeniden denemeye değer. Ancak Google sunucularına tekrar tekrar istekte bulunmak yalnızca önemli değildir. Bu döngü davranışı, istemciniz ile Google arasındaki ağa aşırı yük yüklenmesine neden olarak birçok taraf için soruna yol açabilir.
Denemeler arasında gecikmeleri artırarak yeniden denemek daha iyi bir yaklaşımdır. Genellikle gecikme, her girişimde çarpımsal bir faktörle artırılır. Bu yaklaşım, Üstel Geri Çekme olarak bilinir.
Örneğin, Time Zone API'ye istekte bulunmak isteyen bir uygulamayı düşünün:
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=1331161200&key=YOUR_API_KEY
Aşağıdaki Python örneği, eksponansiyel geri yükleme ile nasıl istekte bulunulacağını göstermektedir:
import json import time import urllib.error import urllib.parse import urllib.request # The maps_key defined below isn't a valid Google Maps API key. # You need to get your own API key. # See https://developers.google.com/maps/documentation/timezone/get-api-key API_KEY = "YOUR_KEY_HERE" TIMEZONE_BASE_URL = "https://maps.googleapis.com/maps/api/timezone/json" def timezone(lat, lng, timestamp): # Join the parts of the URL together into one string. params = urllib.parse.urlencode( {"location": f"{lat},{lng}", "timestamp": timestamp, "key": API_KEY,} ) url = f"{TIMEZONE_BASE_URL}?{params}" current_delay = 0.1 # Set the initial retry delay to 100ms. max_delay = 5 # Set the maximum retry delay to 5 seconds. while True: try: # Get the API response. response = urllib.request.urlopen(url) except urllib.error.URLError: pass # Fall through to the retry loop. else: # If we didn't get an IOError then parse the result. result = json.load(response) if result["status"] == "OK": return result["timeZoneId"] elif result["status"] != "UNKNOWN_ERROR": # Many API errors cannot be fixed by a retry, e.g. INVALID_REQUEST or # ZERO_RESULTS. There is no point retrying these requests. raise Exception(result["error_message"]) if current_delay > max_delay: raise Exception("Too many retry attempts.") print("Waiting", current_delay, "seconds before retrying.") time.sleep(current_delay) current_delay *= 2 # Increase the delay each time we retry. if __name__ == "__main__": tz = timezone(39.6034810, -119.6822510, 1331161200) print(f"Timezone: {tz}")
Ayrıca, başvuru çağrı zincirinde daha yüksek bir düzeyde bir yeniden deneme kodu olduğundan ve bu işlemin çok sayıda kez tekrar eden isteklere yol açtığından emin olmanız gerekir.
Senkronize Talepler
Google’a ait API'lere senkronize edilen çok sayıda istek, Google altyapısına bir Dağıtılmış Hizmet Reddi (DDoS) saldırısı gibi görünebilir ve buna uygun şekilde işlenir. Bunu önlemek için API isteklerinin istemciler arasında senkronize edilmediğinden emin olmanız gerekir.
Örneğin, geçerli saat diliminde saati görüntüleyen bir uygulamayı ele alalım. Bu uygulama muhtemelen istemci işletim sisteminde bir alarm ayarlar ve görüntülenen saatin güncellenebilmesi için dakika başında uyandırır. Uygulama, söz konusu alarmla ilişkilendirilen işleme kapsamında API çağrısı yapmamalıdır.
Sabit bir alarma yanıt olarak API çağrıları yapmak kötü bir şekilde yapılır. Bunun nedeni, API çağrılarının farklı cihazlar arasında bile olsa, zamanın eşit olarak dağıtılması yerine dakikanın başına senkronize edilmesidir. Kötü tasarlanmış bir uygulama, her dakikanın başında normal seviyelerin altmış katı bir trafik artışı sağlar.
Bunun yerine iyi bir tasarım, ikinci bir alarmın rastgele seçilen bir zamana ayarlanmasıdır. Bu ikinci alarm etkinleştirildiğinde uygulama, ihtiyacı olan tüm API'leri çağırır ve sonuçları depolar. Uygulama, görünümünü dakikanın başında güncellemek istediğinde API'yi tekrar çağırmak yerine, önceden depolanan sonuçları kullanır. Bu yaklaşımda API çağrıları zaman içinde eşit olarak yayılır. Dahası, API çağrıları, ekran güncellendiğinde oluşturma işlemini geciktirmez.
Dakikanın başı dışında, hedeflememeniz gereken sırasıyla diğer yaygın senkronizasyon zamanları bir saat başında ve her günün gece yarısı başlar.
Yanıtlar İşleme
Bu bölümde, bu değerlerin web hizmeti yanıtlarından dinamik olarak nasıl alınacağı açıklanmaktadır.
Google Haritalar web hizmetleri, anlaşılması kolay ancak kullanıcı dostu olmayan yanıtlar sağlar. Bir sorgu gerçekleştirirken veri kümesi göstermek yerine belirli değerleri çıkarmak isteyebilirsiniz. Genellikle, web hizmetinden gelen yanıtları ayrıştırır ve yalnızca sizi ilgilendiren değerleri ayıklarsınız.
Kullandığınız ayrıştırma şeması, çıkışı XML veya JSON biçiminde döndürüp döndürmediğinize bağlıdır. Daha önce JavaScript nesneleri biçiminde olan JSON yanıtları, istemcinin üzerinde JavaScript'in içinde işlenebilir. XML yanıtları, XML biçimindeki öğeleri ele almak için bir XML işlemci ve XML sorgu dili kullanılarak işlenmelidir. XML işleme kitaplıklarında yaygın olarak desteklendiğinden, aşağıdaki örneklerde XPath'i kullanıyoruz.
XML, XPath ile işleniyor
XML, veri değişimi için kullanılan, nispeten olgun bir yapılandırılmış bilgi biçimidir. JSON kadar hafif olmasa da XML daha fazla dil desteği ve daha güçlü araçlar sağlar. Örneğin, Java'da XML işleme kodu javax.xml
paketlerinde yer alır.
XML yanıtlarını işlerken, öğelerin XML işaretlemesi içindeki mutlak konumlarda olduğunu kabul etmek yerine XML dokümanındaki düğümleri seçmek için uygun bir sorgu dili kullanmanız gerekir. XPath, bir XML dokümanında düğümleri ve öğeleri benzersiz şekilde açıklayan bir dil söz dizimidir. XPath ifadeleri, XML yanıt dokümanındaki belirli içeriği tanımlamanıza olanak tanır.
XPath İfadeleri
XPath'e aşina olmak, güçlü bir ayrıştırma şeması geliştirme konusunda önemli ilerleme sağlayabilir. Bu bölüm, bir XML dokümanındaki öğelerin XPath ile nasıl ele alındığına odaklanarak birden çok öğeyi ele almanıza ve karmaşık sorgular oluşturmanıza olanak tanır.
XPath, bir XML dokümanındaki öğeleri seçmek için, dizin yollarında kullanılana benzer bir söz dizimi kullanarak ifadeleri kullanır. Bu ifadeler, bir XML doküman ağacındaki öğeleri tanımlar. Bu, DOM'unkine benzer bir hiyerarşik ağaçtır. Genelde XPath ifadeleri, belirtilen kriterlerle eşleşen tüm düğümlerle eşleşip eşleşmediklerini gösteren açgözlü bir yöntemdir.
Örneklerimizi açıklamak için aşağıdaki soyut XML'i kullanacağız:
<WebServiceResponse> <status>OK</status> <result> <type>sample</type> <name>Sample XML</name> <location> <lat>37.4217550</lat> <lng>-122.0846330</lng> </location> </result> <result> <message>The secret message</message> </result> </WebServiceResponse>
İfadelerde Düğüm Seçimi
XPath seçimleri, düğümleri seçer. Kök düğüm, tüm dokümanı kapsar. Bu düğümü "/
" özel ifadesini kullanarak seçersiniz. Kök düğüm, XML dokümanınızın en üst düzey düğümü değildir. Aslında, bu üst düzey öğenin bir üst düzeyinde bulunur ve bu düğümü içerir.
Öğe düğümleri, XML doküman ağacındaki çeşitli öğeleri temsil eder. Örneğin bir <WebServiceResponse>
öğesi, yukarıdaki örnek hizmetimizde döndürülen üst düzey öğeyi temsil eder. Düğümleri mutlak veya göreli yollar aracılığıyla tek tek seçersiniz. Bu, önde gelen bir "/
" karakterinin varlığı veya yokluğuyla belirtilir.
- Mutlak yol: "
/WebServiceResponse/result
ifadesi,<WebServiceResponse>
düğümünün alt öğeleri olan tüm<result>
düğümlerini seçer. (Bu öğelerin her ikisinin de kök düğümünden"/
"geldiğine dikkat edin.) - Geçerli bağlamdaki göreli yol: "
result
" ifadesi, geçerli bağlamdaki herhangi bir<result>
öğesiyle eşleşir. Genellikle, web hizmeti sonuçlarını genellikle tek bir ifade aracılığıyla işlediğiniz için bağlam hakkında endişelenmeniz gerekmez.
Bu ifadelerden herhangi biri, çift eğik çizgiyle ("//
") eklenen joker karakter yolu ile artırılabilir.
Bu joker karakter, araya giren yolda sıfır veya daha fazla öğenin eşleşebileceğini belirtir. Örneğin XPath ifadesi ("//formatted_address
"), mevcut dokümanda bu ada sahip tüm düğümlerle eşleşir.
//viewport//lat
ifadesi, <viewport>
olarak üst öğe olarak izleyebilecek tüm <lat>
öğelerini eşleştirir.
Varsayılan olarak, XPath ifadeleri tüm öğelerle eşleşir. Köşeli parantez ([]
) içinde yer alan bir koşul sağlayarak ifadeyi belirli bir öğeyle eşleşecek şekilde kısıtlayabilirsiniz. XPath ifadesi "/GeocodeResponse/result[2]
, her zaman ikinci sonucu döndürür.
İfade Türü | |
---|---|
Root düğüm | XPath İfadesi: "
/ "Seçim:
<WebServiceResponse> <status>OK</status> <result> <type>sample</type> <name>Sample XML</name> <location> <lat>37.4217550</lat> <lng>-122.0846330</lng> </location> </result> <result> <message>The secret message</message> </result> </WebServiceResponse> |
Mutlak Yol | XPath İfadesi: "
/WebServiceResponse/result "Seçim:
<result> <type>sample</type> <name>Sample XML</name> <location> <lat>37.4217550</lat> <lng>-122.0846330</lng> </location> </result> <result> <message>The secret message</message> </result> |
Joker karakterli yol | XPath İfadesi: "
/WebServiceResponse//location "Seçim:
<location> <lat>37.4217550</lat> <lng>-122.0846330</lng> </location> |
Koşullu Yol | XPath İfadesi: "
/WebServiceResponse/result[2]/message "Seçim:
<message>The secret message</message> |
İlk result öğesinin tüm doğrudan alt öğeleri |
XPath İfadesi: "
/WebServiceResponse/result[1]/* "Seçim:
<type>sample</type> <name>Sample XML</name> <location> <lat>37.4217550</lat> <lng>-122.0846330</lng> </location> |
type metni "example" olan bir result için name |
XPath İfadesi: "
/WebServiceResponse/result[type/text()='sample']/name "Seçim:
Sample XML |
Öğeleri seçerken yalnızca bu nesneler içindeki metni değil, düğümleri de seçtiğinizi unutmayın. Genellikle tüm eşleşen düğümleri yinelemek ve metni çıkarmak istersiniz. Metin düğümlerini doğrudan da eşleştirebilirsiniz. Aşağıdaki Metin Düğümleri bölümüne bakın.
XPath'in özellik düğümlerini de desteklediğini unutmayın. Bununla birlikte, tüm Google Haritalar web hizmetleri özellikleri olmadan öğeleri yayınladığından özelliklerin eşleşmesi gerekmez.
İfadelerde Metin Seçimi
XML dokümanındaki metin, XPath ifadelerinde bir metin düğümü operatörü aracılığıyla belirtilir. Bu operatör "text()
", belirtilen düğümden metin çıkarıldığını gösterir. Örneğin, XPath ifadesi "&";//formatted_address/text()
&"; <formatted_address>
öğelerindeki tüm metni döndürür.
İfade Türü | |
---|---|
Tüm metin düğümleri (boşluklar dahil) | XPath İfadesi: "
//text() "Seçim:
sample Sample XML 37.4217550 -122.0846330 The secret message |
Metin Seçimi | XPath İfadesi: "
/WebServiceRequest/result[2]/message/text() "Seçim:
The secret message |
Bağlama Duyarlı Seçim | XPath İfadesi: "
/WebServiceRequest/result[type/text() = 'sample']/name/text() "Seçim:
Sample XML |
Alternatif olarak, bir ifadeyi değerlendirebilir ve bir dizi düğüm döndürüp metni her bir düğümden çıkararak bu "düğüm grubu" üzerinde yineleyebilirsiniz. Bu yaklaşımı aşağıdaki örnekte kullanıyoruz.
XPath hakkında daha fazla bilgi için XPath W3C Spesifikasyonu'na bakın.
Java'da XPath'i değerlendirme
Java'nın XML paketinde ayrıştırma ve javax.xml.xpath.*
paketinde XPath ifadelerini kullanma konusunda geniş bir desteği vardır.
Bu nedenle, bu bölümdeki örnek kodda, XML'nin nasıl işleneceğini göstermek ve XML hizmeti yanıtlarından verileri ayrıştırmak için Java kullanılır.
Java kodunuzda XPath'i kullanmak için önce bir XPathFactory
örneğini örneklemeniz ve bir XPath
nesnesi oluşturmak için bu fabrikada newXPath()
çağrısı yapmanız gerekir. Bu nesne, evaluate()
yöntemini kullanarak iletilen XML ve XPath ifadelerini işleyebilir.
XPath ifadelerini değerlendirirken, döndürülebilecek olası "düğüm kümelerinin" üzerine tekrar ettiğinizden emin olun. Bu sonuçlar Java kodunda DOM düğümleri olarak döndürüldüğü için bir NodeList
nesnesinin içinde birden fazla değeri yakalamanız ve bu düğümlerdeki metinleri ya da değerleri ayıklamak için nesnenin üzerinde tekrarlamanız gerekir.
Aşağıdaki kod, bir XPath
nesnesinin nasıl oluşturulacağını, XML ve XPath ifadesini atayacağını ve ilgili içeriği yazdırmak için ifadeyi değerlendireceğini gösterir.
import org.xml.sax.InputSource; import org.w3c.dom.*; import javax.xml.xpath.*; import java.io.*; public class SimpleParser { public static void main(String[] args) throws IOException { XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); try { System.out.print("Web Service Parser 1.0\n"); // In practice, you'd retrieve your XML via an HTTP request. // Here we simply access an existing file. File xmlFile = new File("XML_FILE"); // The xpath evaluator requires the XML be in the format of an InputSource InputSource inputXml = new InputSource(new FileInputStream(xmlFile)); // Because the evaluator may return multiple entries, we specify that the expression // return a NODESET and place the result in a NodeList. NodeList nodes = (NodeList) xpath.evaluate("XPATH_EXPRESSION", inputXml, XPathConstants.NODESET); // We can then iterate over the NodeList and extract the content via getTextContent(). // NOTE: this will only return text for element nodes at the returned context. for (int i = 0, n = nodes.getLength(); i < n; i++) { String nodeString = nodes.item(i).getTextContent(); System.out.print(nodeString); System.out.print("\n"); } } catch (XPathExpressionException ex) { System.out.print("XPath Error"); } catch (FileNotFoundException ex) { System.out.print("File Error"); } } }