Layanan Web Google Maps API

Layanan web Google Maps adalah kumpulan antarmuka HTTP untuk layanan Google yang menyediakan data geografis untuk aplikasi peta Anda. Panduan ini hanya berfungsi memperkenalkan layanan web dan informasi host umum untuk semua layanan yang berbeda. Dokumentasi terpisah untuk setiap layanan terdapat di bawah ini:

Mengetahui API yang Anda perlukan

Gunakan API-picker untuk menemukan API yang tepat bagi proyek Anda.

Selengkapnya tentang layanan web

Bagian selebihnya dari panduan ini membahas beberapa teknik untuk menyiapkan permintaan layanan web dan mem-parse respons. Akan tetapi, untuk dokumentasi tertentu setiap layanan, Anda harus membaca dokumentasi yang sesuai.

Apa yang dimaksud dengan layanan web?

Google Maps API menyediakan layanan web ini sebagai antarmuka untuk meminta data Maps API dari layanan eksternal dan menggunakannya dalam aplikasi Anda. Layanan ini didesain untuk digunakan bersama sebuah peta, sesuai dengan Pembatasan Lisensi Ketentuan Layanan Maps API.

Layanan web ini menggunakan permintaan HTTP ke URL tertentu, dengan meneruskan parameter URL sebagai argumen ke layanan. Biasanya, layanan ini mengembalikan data dalam permintaan HTTP baik sebagai JSON maupun XML untuk mem-parse dan/atau memproses melalui aplikasi Anda.

Permintaan layanan web biasanya dengan bentuk berikut:

https://maps.googleapis.com/maps/api/service/output?parameters

dalam hal ini service menunjukkan layanan tertentu yang diminta dan output menunjukkan format respons (biasanya json atau xml).

Dokumentasi lengkap setiap layanan terdapat dalam panduan developer khusus untuk layanan itu. Akan tetapi, panduan ini berfungsi menampung beberapa kebiasaan umum yang berguna untuk menyiapkan permintaan layanan web dan memproses respons layanan web Anda.

Akses SSL

https://maps.googleapis.com/maps/api/service/output?parameters

HTTPS diperlukan untuk semua permintaan layanan web Maps API yang berisi data pengguna atau identifier developer. Permintaan yang dibuat melalui HTTP yang berisi data sensitif dapat ditolak.

Membuat URL yang Valid

Anda mungkin menganggap URL yang "valid" sudah jelas, namun bukan begitu masalahnya. URL yang dimasukkan dalam bilah alamat di browser, misalnya, bisa berisi karakter khusus (misalnya "上海+中國"); browser harus menerjemahkan karakter itu secara internal ke dalam pengkodean berbeda sebelum transmisi. Dengan token yang sama, setiap kode yang menghasilkan atau menerima masukan UTF-8 bisa memperlakukan URL berisi karakter UTF-8 sebagai "valid", namun juga perlu menerjemahkan karakter itu sebelum mengirimnya ke server web. Proses ini disebut pengkodean URL.

Kita perlu menerjemahkan karakter khusus karena semua URL perlu mematuhi sintaks yang ditetapkan oleh spesifikasi W3 Uniform Resource Identifier. Pada dasarnya, ini berarti URL hanya boleh berisi subset karakter ASCII khusus: simbol alfanumerik yang sudah umum, dan beberapa karakter yang khusus digunakan untuk karakter kontrol dalam URL. Tabel di bawah merangkum semua karakter ini:

Rangkuman Karakter URL yang Valid
RangkaiankarakterPenggunaan URL
Alfanumerik 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 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 7 8 9 String teks, penggunaan skema (http), porta (8080), dll.
Belum diperuntukkan - _ . ~ String teks
Sudah diperuntukkan ! * ' ( ) ; : @ & = + $ , / ? % # [ ] Karakter kontrol dan/atau String Teks

Saat membuat URL yang valid, Anda harus memastikannya berisi karakter yang ditampilkan di atas saja. Menyesuaikan URL untuk menggunakan rangkaian karakter ini biasanya menyebabkan dua masalah, yaitu masalah penghilangan dan masalah penggantian:

  • Karakter yang ingin Anda tangani berada di luar rangkaian karakter di atas. Misalnya, karakter dalam bahasa asing seperti 上海+中國 harus dienkode menggunakan karakter di atas. Menurut aturan umum, spasi (yang tidak diperbolehkan dalam URL) sering kali juga dinyatakan menggunakan karakter '+'.
  • Karakter yang ada di atas ditetapkan sebagai karakter yang diperuntukkan, namun harus digunakan secara literal. Misalnya, ? digunakan dalam URL untuk menunjukkan awal dari string kueri; jika Anda ingin menggunakan string "? and the Mysterions," Anda harus mengenkode karakter '?'.

Semua karakter yang akan dienkode ke URL dienkode menggunakan karakter '%' dan nilai heksadesimal dua karakter yang sesuai dengan karakter UTF-8. Misalnya, 上海+中國 dalam UTF-8 akan dienkode ke URL menjadi %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B. String ? and the Mysterians akan dienkode ke URL menjadi %3F+and+the+Mysterians.

Beberapa karakter umum yang harus dienkode adalah:

Karakter tidak aman Nilai yang dienkode
Spasi %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

Mengonversi URL yang Anda terima dari masukan pengguna kadang-kadang rumit. Misalnya, seorang pengguna mungkin memasukkan alamat sebagai "5th&Main St." Biasanya, Anda harus membuat URL Anda dari bagian-bagiannya, memperlakukan setiap masukan pengguna sebagai karakter literal.

Selain itu, URL dibatasi hingga 8192 karakter untuk semua layanan web. Untuk sebagian besar layanan, batas karakter ini jarang dipatuhi. Akan tetapi, perhatikan, layanan tertentu memiliki beberapa parameter yang bisa mengakibatkan URL menjadi panjang.

Penggunaan Moderat Google API

Klien API yang tidak dirancang dengan baik bisa membuat beban lebih dari yang diperlukan pada Internet dan server Google. Bagian ini berisi beberapa praktik terbaik untuk klien API. Mengikuti praktik terbaik berikut bisa membantu Anda menghindari aplikasi Anda diblokir karena penyalahgunaan API yang tidak hati-hati.

Backoff Eksponensial

Dalam kasus yang jarang, bisa terjadi sesuatu yang salah saat melayani permintaan Anda; Anda dapat menerima kode respons HTTP 4XX atau 5XX atau koneksi TCP dapat mengalami kegagalan antara klien Anda dan server Google. Sering kali, sebaiknya coba lagi permintaan karena permintaan tindak lanjut bisa jadi berhasil saat permintaan asli gagal. Akan tetapi, penting untuk tidak membuat loop berulang saat membuat permintaan ke server Google. Perilaku loop ini bisa menyebabkan kelebihan beban pada jaringan antara klien Anda dengan Google yang menyebabkan masalah bagi berbagai pihak.

Pendekatan terbaik adalah mencoba ulang dengan meningkatkan waktu tunda antar percobaan. Biasanya, waktu tunda ditingkatkan dengan faktor perkalian pada setiap percobaan, pendekatan ini dikenal sebagai Backoff Eksponensial.

Sebagai contoh, misalkan sebuah aplikasi ingin membuat permintaan ini ke Google Maps Time Zone API:

https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=YOUR_API_KEY

Contoh Python berikut menampilkan cara membuat permintaan dengan backoff eksponensial:

import json
import time
import urllib
import urllib2

def timezone(lat, lng, timestamp):
    # 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
    maps_key = 'YOUR_KEY_HERE'
    timezone_base_url = 'https://maps.googleapis.com/maps/api/timezone/json'

    # This joins the parts of the URL together into one string.
    url = timezone_base_url + '?' + urllib.urlencode({
        'location': "%s,%s" % (lat, lng),
        'timestamp': timestamp,
        'key': maps_key,
    })

    current_delay = 0.1  # Set the initial retry delay to 100ms.
    max_delay = 3600  # Set the maximum retry delay to 1 hour.

    while True:
        try:
            # Get the API response.
            response = str(urllib2.urlopen(url).read())
        except IOError:
            pass  # Fall through to the retry loop.
        else:
            # If we didn't get an IOError then parse the result.
            result = json.loads(response.replace('\\n', ''))
            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.

tz = timezone(39.6034810, -119.6822510, 1331161200)
print 'Timezone:', tz

Anda juga harus berhati-hati bahwa tidak ada percobaan ulang kode yang lebih tinggi di serangkaian panggilan aplikasi yang menyebabkan permintaan berulang dalam urutan yang cepat.

Permintaan yang Disinkronkan

Sejumlah besar permintaan yang disinkronkan ke Google API bisa tampak seperti serangan DDoS (Distributed Denial of Service) pada infrastruktur Google, dan akan diperlakukan sebagai DDoS. Untuk menghindarinya, Anda harus memastikan bahwa permintaan API tidak disinkronkan antara klien.

Misalnya, pertimbangkan aplikasi yang menampilkan waktu dalam zona waktu saat ini. Aplikasi ini mungkin akan menyetel alarm dalam sistem operasi klien yang membangunkannya saat menit dimulai sehingga waktu yang ditampilkan bisa diperbarui. Aplikasi harus tidak membuat panggilan API sebagai bagian dari pemrosesan yang dikaitkan dengan alarm tersebut.

Membuat panggilan API sebagai respons terhadap alarm tetap dianggap buruk karena menyebabkan panggilan API disinkronkan ke awal menit, bahkan antara perangkat yang berbeda, bukannya didistribusikan secara merata. Aplikasi yang dirancang dengan buruk yang melakukan ini akan menghasilkan lonjakan lalu lintas sebesar enam puluh kali dari tingkat normal di awal setiap menit.

Sebagai gantinya, satu rancangan yang mungkin baik adalah menyetel alarm kedua ke waktu terpilih yang acak. Saat alarm kedua terpicu, aplikasi memanggil API apa pun yang diperlukannya dan menyimpan hasilnya. Saat aplikasi ingin memperbarui tampilannya di awal menit, aplikasi menggunakan hasil yang disimpan sebelumnya, bukan memanggil API kembali. Dengan pendekatan ini, panggilan API tersebar dengan rata. Terlebih lagi, panggilan API tidak menunda rendering saat tampilan sedang diperbarui.

Di samping awal menit, waktu sinkronisasi umum yang harus Anda perhatikan agar tidak ditarget adalah di awal jam, dan awal setiap hari pada tengah malam.

Memproses Respons

Karena format yang tepat dari setiap respons dengan permintaan layanan web tidak dijamin (beberapa elemen mungkin hilang atau ada di beberapa lokasi), Anda tidak boleh menganggap bahwa format yang ditampilkan untuk setiap respons yang diberikan akan sama untuk kueri yang berbeda. Karenanya, Anda harus memproses respons dan memilih nilai yang sesuai melalui ekspresi. Bagian ini membahas cara mengekstrak nilai-nilai ini secara dinamis dari respons layanan web.

Layanan web Google Maps menyediakan respons yang mudah dipahami, namun tidak begitu ramah pengguna. Saat melakukan kueri, dari pada menampilkan satu set data, mungkin lebih baik mengekstrak beberapa nilai tertentu. Biasanya, Anda ingin mem-parse respons dari layanan web dan hanya mengekstrak nilai-nilai yang Anda perlukan.

Skema parsing yang Anda gunakan bergantung apakah Anda mengembalikan keluaran dalam XML atau JSON. Respons JSON, yang sudah siap dalam bentuk objek JavaScript, bisa diprosses di dalam JavaScript itu sendiri di klien; respons XML harus diproses menggunakan prosesor XML dan bahasa kueri XML ke elemen alamat dalam format XML. Kami menggunakan XPath dalam contoh berikut, karena biasanya didukung dalam pustaka pemrosesan XML.

Memproses XML dengan XPath

XML adalah format informasi terstruktur yang relatif matang yang digunakan untuk pertukaran data. Meskipun tidak seringan JSON, XML jelas memberikan dukungan bahasa yang lebih banyak dan alat-alat yang lebih tangguh. Kode untuk memproses XML dalam Java, misalnya, telah disertakan dalam paket javax.xml.

Saat memproses respons XML, Anda harus menggunakan bahasa kueri yang sesuai untuk memilih simpul dalam dokumen XML, daripada menganggap elemen berada pada posisi absolut dalam markup XML. XPath adalah sintaks bahasa untuk menjelaskan simpul dan elemen dalam sebuah dokumen XML secara unik. Ekspresi XPath memungkinkan Anda untuk mengidentifikasi materi tertentu dalam dokumen respons XML.

Ekspresi XPath

Pemahaman tentang XPath tetap ada dalam pengembangan skema parsing yang tangguh. Bagian ini akan berfokus pada cara menangani elemen dalam dokumen XML dengan XPath, yang memungkinkan Anda untuk menangani multielemen dan membangun kueri yang kompleks.

XPath menggunakan ekspresi untuk memilih elemen dalam sebuah dokumen XML, menggunakan sintaks yang sama dengan yang digunakan untuk jalur direktori. Ekspresi ini mengidentifikasi elemen-elemen dalam struktur hierarki dokumen XML, yang merupakan struktur hierarki serupa dengan DOM. Biasanya, ekspresi XPath termasuk rakus, maksudnya ekspresi tersebut akan cocok dengan semua simpul yang cocok dengan kriteria yang diberikan.

Kami akan menggunakan XML abstrak berikut untuk mengilustrasikan contoh:

<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>

Pilihan Simpul dalam Ekspresi

Pilihan XPath memilih simpul. Simpul akar mencakup keseluruhan dokumen. Anda memilih simpul ini menggunakan ekspresi khusus "/". Perhatikan, simpul akar bukanlah simpul tingkat atas pada dokumen XML Anda; sesungguhnya, simpul ini berada satu tingkat di atas elemen tingkat atas ini dan berisi simpul tersebut.

Simpul elemen menyatakan beragam elemen dalam struktur hierarki dokumen XML. Elemen <WebServiceResponse>, misalnya, menyatakan elemen tingkat atas yang dikembalikan dalam contoh layanan kami di atas. Anda memilih masing-masing simpul baik melalui jalur absolut maupun relatif, yang ditunjukkan dengan ada atau tidak adanya karakter pengarah "/".

  • Jalur absolut: ekspresi "/WebServiceResponse/result" akan memilih semua simpul <result> yang merupakan anak dari simpul <WebServiceResponse>. (Perhatikan, kedua elemen ini pewaris dari simpul akar "/".)
  • Jalur relatif dari konteks saat ini: ekspresi "result" akan cocok dengan setiap elemen <result> dalam konteks saat ini. Biasanya, Anda tidak perlu khawatir tentang konteks, karena Anda biasanya memproses hasil layanan web melalui ekspresi tunggal.

Ekspresi ini bisa ditingkatkan melalui penambahan jalur karakter pengganti, yang ditunjukkan dengan garis miring ganda ("//"). Karakter pengganti ini menunjukkan bahwa nol atau beberapa elemen mungkin cocok dalam jalur intervensi. Ekspresi XPath "//formatted_address," misalnya, akan cocok dengan semua simpul dari nama tersebut dalam dokumen saat ini. Ekspresi //viewport//lat akan cocok dengan semua elemen <lat> yang bisa melacak <viewport> sebagai induk.

Secara default, ekspresi XPath cocok dengan semua elemen. Anda bisa membatasi ekspresi agar cocok dengan elemen tertentu dengan menyediakan predikat, yang ditutup dalam kurung persegi ([]). Misalnya, ekspresi XPath "/GeocodeResponse/result[2] selalu mengembalikan hasil kedua.

Tipe Ekspresi
Simpul akar
Ekspresi XPath:  "/"
Pilihan:
    <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>
    
Jalur Absolut
Ekspresi XPath:  "/WebServiceResponse/result"
Pilihan:
    <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>
    
Jalur dengan Karakter Pengganti
Ekspresi XPath:  "/WebServiceResponse//location"
Pilihan:
    <location>
     <lat>37.4217550</lat>
     <lng>-122.0846330</lng>
    </location>
    
Jalur dengan Predikat
Ekspresi XPath:  "/WebServiceResponse/result[2]/message"
Pilihan:
    <message>The secret message</message>
    
Semua anak langsung dari result pertama
Ekspresi XPath:  "/WebServiceResponse/result[1]/*"
Pilihan:
     <type>sample</type>
     <name>Sample XML</name>
     <location>
      <lat>37.4217550</lat>
      <lng>-122.0846330</lng>
     </location>
    
name dari result dengan type berupa teks adalah "sample".
Ekspresi XPath:  "/WebServiceResponse/result[type/text()='sample']/name"
Pilihan:
    Sample XML
    

Perlu diperhatikan, saat memilih elemen, Anda memilih simpul, bukan hanya teks dalam objek tersebut. Biasanya, Anda perlu mengulangi semua simpul yang cocok dan mengekstrak teks. Anda juga bisa mencocokkan simpul teks secara langsung; lihat Simpul Teks di bawah ini.

Perhatikan, XPath juga mendukung simpul atribut; akan tetapi, semua layanan web Google Maps melayani elemen tanpa atribut, sehingga tidak perlu mencocokkan atribut.

Pemilihan Teks dalam Ekspresi

Teks dalam dokumen XML ditetapkan dalam ekspresi XPath melalui operator text node. Operator "text()" ini menunjukkan ekstraksi teks dari simpul yang ditandai. Misalnya, ekspresi XPath "//formatted_address/text()" akan mengembalikan semua teks dalam elemen <formatted_address>.

Tipe Ekspresi
Semua simpul teks (termasuk spasi)
Ekspresi XPath:  "//text()"
Pilihan:
    sample
    Sample XML

    37.4217550
    -122.0846330
    The secret message
    
Pemilihan Teks
Ekspresi XPath:  "/WebServiceRequest/result[2]/message/text()"
Pilihan:
    The secret message
    
Pilihan Sesuai Konteks
Ekspresi XPath:  "/WebServiceRequest/result[type/text() = 'sample']/name/text()"
Pilihan:
    Sample XML
    

Atau, Anda bisa mengevaluasi suatu ekspresi dan mengembalikan satu set simpul kemudian mengulang "set simpul" itu, yang mengekstrak teks dari setiap simpul. Kami menggunakan pendekatan ini dalam contoh di bawah.

Untuk informasi selengkapnya tentang XPath, lihat Spesifikasi W3C untuk XPath.

Mengevaluasi XPath dalam Java

Java memiliki dukungan luas untuk mem-parse XML dan menggunakan ekspresi XPath dalam paket javax.xml.xpath.*. Karena itu, kode contoh di bagian ini menggunakan Java untuk mengilustrasikan cara menangani XML dan mem-parse data dari respons layanan XML.

Untuk menggunakan XPath dalam kode Java, terlebih dahulu Anda perlu membuat instance XPathFactory dan memanggil newXPath() pada factory tersebut untuk membuat objek XPath . Kemudian objek ini bisa memproses ekspresi XML dan XPath yang diteruskan menggunakan metode evaluate().

Saat mengevaluasi ekspresi XPath, pastikan Anda mengulangi pada setiap kemungkinan "rangkaian simpul" yang bisa dikembalikan. Karena hasil ini dikembalikan sebagai simpul DOM dalam kode Java, Anda harus merekam banyak nilai dalam objek NodeList dan mengulangi pada objek itu untuk mengekstrak teks atau nilai dari simpul tersebut.

Kode berikut mengilustrasikan cara membuat objek XPath, memberinya XML dan ekspresi XPath, serta mengevaluasi ekspresi untuk mencetak materi yang relevan.

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");
    }
  }
}

Unduh kode dari js-v2-samples

Memproses JSON dengan JavaScript

JSON (JavaScript Object Notation) jauh lebih menguntungkan daripada XML karena respons yang ringan. Mem-parse hasil seperti itu tidak sulit dalam JavaScript karena formatnya sudah berupa objek JavaScript yang valid. Misalnya, untuk mengekstrak nilai kunci 'formatted_address' dalam objek hasil JSON, cukup mengaksesnya menggunakan kode berikut:

for (i = 0; i < myJSONResult.results.length; i++) {
  myAddress[i] = myJSONResult.results[i].formatted_address;
}

Perhatikan, karena JSON bisa berisi beberapa nilai, ada baiknya untuk mengulanginya sepanjang larik results jika Anda ingin menangkap semua kemungkinan nilainya. Akan tetapi, dalam praktiknya, Anda mungkin hanya perlu mengembalikan hasil pertama (results[0]).

Mem-parse JSON dalam bahasa lain sedikit lebih sulit. Contoh Python berikut misalnya membuat permintaan layanan web Geocoding dan menampilkan semua nilai formatted_address yang dihasilkan kepada pengguna dalam sebuah larik:

import simplejson, urllib

GEOCODE_BASE_URL = 'https://maps.googleapis.com/maps/api/geocode/json'

def geocode(address, **geo_args):
    geo_args.update({
        'address': address
    })

    url = GEOCODE_BASE_URL + '?' + urllib.urlencode(geo_args)
    result = simplejson.load(urllib.urlopen(url))

    print simplejson.dumps([s['formatted_address'] for s in result['results']], indent=2)

if __name__ == '__main__':
    geocode(address="San+Francisco")

Output: [ "San Francisco, CA, USA" ]

Unduh kode dari js-v2-samples

Parameter sensor

Google Maps API sebelumnya mengharuskan Anda menyertakan parameter sensor untuk menunjukkan apakah aplikasi Anda menggunakan sensor untuk menentukan lokasi pengguna. Parameter ini tidak lagi diperlukan.

Kirim masukan tentang...

Google Maps Web Service API
Google Maps Web Service API