2013/08/07

Google Geocoding API 透過地址查詢經緯度

Google Geocoding API有提供『地理編碼』,地理編碼就是透過地址轉換成地理座標。相對的也可以透過經緯度轉換為地址

Google Geocoding API 有查詢限制,每天最多發出 2,500 個地理位置要求 ,如果是Google Maps API for Business 使用者每天最多可執行 100,000 個要求

Google Geocoding API又提供JSON以及XML的資料型態,我在這邊的範例是選擇用JSON來做講解

Google Geocoding API又有他自己的格式,如果是用JSON的朋友就用以下的語法

http://maps.googleapis.com/maps/api/geocode/json?

如果是選擇XML的朋友就使用以下的語法

http://maps.googleapis.com/maps/api/geocode/xml?

因為我們要透過地址去查詢取得一個JSON檔案,所以我們將語法改成如下

http://maps.googleapis.com/maps/api/geocode/json?address=台灣高雄市三民區建國二路318號&sensor=false

把該語法貼到網址列,就會得到一個JSON
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "318",
               "short_name" : "318",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Jiànguó 2nd Road",
               "short_name" : "Jiànguó 2nd Road",
               "types" : [ "route" ]
            },
            {
               "long_name" : "港西里",
               "short_name" : "港西里",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "Sanmin District",
               "short_name" : "Sanmin District",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Kaohsiung City",
               "short_name" : "Kaohsiung City",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Taiwan",
               "short_name" : "TW",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "807",
               "short_name" : "807",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "No. 318, Jiànguó 2nd Road, Sanmin District, Kaohsiung City, Taiwan 807",
         "geometry" : {
            "location" : {
               "lat" : 22.63961980,
               "lng" : 120.30211060
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 22.64096878029150,
                  "lng" : 120.3034595802915
               },
               "southwest" : {
                  "lat" : 22.63827081970850,
                  "lng" : 120.3007616197085
               }
            }
         },
         "partial_match" : true,
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}

這樣就能取得Google Map的JSON,在透過location去取得經緯度。
不過要注意最下面有一個status,status狀態是『OK』才算是取得,其他的可以參考『狀態碼



接著,我要講解我的程式碼了


index.html使用了jQuery.jsGoogle Maps JavaScript API,還使用自定義的Script.js以及test.css檔案,分別在標頭內用外部連接方式套用到index.html

Body內有包涵了兩個div,map及panel。map是用來顯示地圖的,panel只是用來包住input及button
Body在載入時呼叫Script.js內的initialize()函式,該函式只是將初始位置設定在樹德科技大學,並且將id為map的元件設定為Google Map而已

點擊button元件,則會呼叫Script.js內的btnClick()函式。
該函式是先判斷是否有將資料填寫完全,在透過jQuery.ajax()的方法由Google Geocoding API語法得到一個JSON,取得之後先判斷地圖是否可以使用。地址如果正確,就可以將地圖位置移至新地圖

HTML:
<!DOCTYPE html>
<html lang="zh-tw">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css"  href="./css/test.css">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=Key number&sensor=false&region=zh-tw"></script>
    <script type="text/javascript" src="./js/Script.js"></script>
  </head>
  <body onload = "initialize()" >
    <div id="map"></div>
      <div id = "panel">
        <input id="address" value="高雄市燕巢區橫山路59號">
        <button onclick="btnClick()">Button</button>
      </div>
  </body>
</html>

Javascript:
function initialize() {

     var mapOptions = {
         zoom: 20,
         center: new google.maps.LatLng(22.76758770, 120.37921390),
         mapTypeId: google.maps.MapTypeId.ROADMAP
     }

     var map = new google.maps.Map(document.getElementById("map"),
                   mapOptions);
};

 function btnClick(){
     if (address.value.length >= 1)
     {
         $.ajax({
             type: "post",
             dataType: "json",
             url: "https://maps.googleapis.com/maps/api/geocode/json?address=" + address.value + "&sensor=false&language=zh-tw",
             success: function (data)
             {

                 if (data.status == "OK")
                 {
                     var mapOptions = {
                         zoom: 16,
                         center: new google.maps.LatLng(data.results[0].geometry.location.lat,
                      data.results[0].geometry.location.lng),
                         mapTypeId: google.maps.MapTypeId.ROADMAP
                     }

                     var map = new google.maps.Map(document.getElementById("map"),
                   mapOptions);
                 }
                 else
                 {
                     alert("沒有地圖資料");
                 }
             },
             error: function ()
             {
                 alert("資料錯誤");
             }
         });
     }
     else
     {
         alert("請輸入正確地址");
         document.getElementById('#address').focus()
     }
};


CSS:
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map { height: 95% ; width: 100% }
#address { width:40%  }


以下為執行結果:

查詢後的結果:

參考資料:
https://developers.google.com/maps/documentation/javascript/basics?hl=zh-tw
https://developers.google.com/maps/documentation/javascript/tutorial?hl=zh-tw
https://developers.google.com/maps/documentation/geocoding/?hl=zh-tw
https://developers.google.com/maps/documentation/geocoding/?hl=zh-tw#StatusCodes
http://api.jquery.com/jQuery.ajax/
http://writecodepeople.blogspot.tw/2013/07/google-maps-api-v3-api-key.html
http://www.json.org/json-zh.html
http://j796160836.pixnet.net/blog/post/30530326
你不可不知的 JSON 基本介紹
http://blog.darkthread.net/post-2012-06-15-geocoding-api.aspx