GoogleAPI進行地址解析和反向地址解析

Google Geocoding API    http://code.google.com/intl/zh-CN/apis/maps/documentation/geocoding/

地址解析請求

Google Geocoding API 請求必須採用以下形式:

http://maps.google.com/maps/api/geocode/output?parameters

其中,output 可以是以下值之一:

  • json(建議)表示以 JavaScript 對象表示法 (JSON) 的形式輸出
  • xml 表示以 XML 的形式輸出

有些參數是必需的,有些是可選的。根據網址的標準,所有參數均使用字符 & (&) 分隔。下面枚舉了這些參數及其可能的值。

Google Geocoding API 使用以下網址參數定義地址解析請求:

  • address(必需)- 您要進行地址解析的地址。*

         或者

  • latlng(必需)- 您希望獲取的、距離最近的、可人工讀取地址的緯度/經度文本值。*
  • bounds(可選)- 要在其中更顯著地偏移地址解析結果的可視區域的邊框。(有關詳細信息,請參見下文的可視區域偏向。)
  • region(可選)- 區域代碼,指定爲 ccTLD(“頂級域”)雙字符值。(有關詳細信息,請參見下文的區域偏向。)
  • language(可選)- 傳回結果時所使用的語言。請參見支持的區域語言列表。請注意,我們會經常更新支持的語言,因此該列表可能並不詳盡。如果未提供language,地址解析器將嘗試儘可能使用發送請求的區域的本地語言。
  • sensor(必需)- 指示地址解析請求是否來自裝有位置傳感器的設備。該值必須爲 true 或 false

* 請注意:您可以傳遞 address 或 latlng 進行查找。(如果傳遞 latlng,則地址解析器執行反向地址解析。有關詳細信息,請參閱反向地址解析。)

bounds 和 region 參數只會影響地址解析器返回的結果,但不能對其進行完全限制。

地址解析響應

地址解析響應將以網址請求路徑中的 output 標記所指示的格式傳回。

JSON 輸出格式

在此示例中,Google Geocoding API 爲針對“1600 Amphitheatre Parkway, Mountain View, CA”的查詢請求一個 json 響應:

http://maps.google.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false

在此示例中,我們將 sensor 參數設爲變量“true_or_false”以強調您必須將該值顯式設置爲 true 或 false

此請求傳回的 JSON 如下所示。請注意,實際的 JSON 可能包含較少的空白。您不應假定請求之間的空白的數量或格式。

{
  "status": "OK",
  "results": [ {
    "types": [ "street_address" ],
    "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
    "address_components": [ {
      "long_name": "1600",
      "short_name": "1600",
      "types": [ "street_number" ]
    }, {
      "long_name": "Amphitheatre Pkwy",
      "short_name": "Amphitheatre Pkwy",
      "types": [ "route" ]
    }, {
      "long_name": "Mountain View",
      "short_name": "Mountain View",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "California",
      "short_name": "CA",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "United States",
      "short_name": "US",
      "types": [ "country", "political" ]
    }, {
      "long_name": "94043",
      "short_name": "94043",
      "types": [ "postal_code" ]
    } ],
    "geometry": {
      "location": {
        "lat": 37.4219720,
        "lng": -122.0841430
      },
      "location_type": "ROOFTOP",
      "viewport": {
        "southwest": {
          "lat": 37.4188244,
          "lng": -122.0872906
        },
        "northeast": {
          "lat": 37.4251196,
          "lng": -122.0809954
        }
      }
    }
  } ]
}

請注意,JSON 響應包含兩個根元素:

  • "status" 包含請求中的元數據。請參見下文的狀態代碼
  • "results" 包含一個經過地址解析的地址信息和幾何圖形信息的數組。

通常,對於地址查詢,只會在 "results" 數組中傳回一個條目,但在進行模糊地址查詢時,地址解析器可能會傳回多個結果。

請注意,如果您希望從結果中提取值,則這些結果通常需要進行解析。解析 JSON 相對來說較容易。有關一些設計模式建議,請參見解析 JSON

XML 輸出格式

在此示例中,Google Geocoding API 爲上面所示的相同查詢(針對“1600 Amphitheatre Parkway, Mountain View, CA”)請求一個 xml 響應:

http://maps.google.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false

此請求傳回的 XML 如下所示:

<GeocodeResponse> 
 <status>OK</status> 
 <result> 
  <type>street_address</type> 
  <formatted_address>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA</formatted_address> 
  <address_component> 
   <long_name>1600</long_name> 
   <short_name>1600</short_name> 
   <type>street_number</type> 
  </address_component> 
  <address_component> 
   <long_name>Amphitheatre Pkwy</long_name> 
   <short_name>Amphitheatre Pkwy</short_name> 
   <type>route</type> 
  </address_component> 
  <address_component> 
   <long_name>Mountain View</long_name> 
   <short_name>Mountain View</short_name> 
   <type>locality</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>San Jose</long_name> 
   <short_name>San Jose</short_name> 
   <type>administrative_area_level_3</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>Santa Clara</long_name> 
   <short_name>Santa Clara</short_name> 
   <type>administrative_area_level_2</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>California</long_name> 
   <short_name>CA</short_name> 
   <type>administrative_area_level_1</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>United States</long_name> 
   <short_name>US</short_name> 
   <type>country</type> 
   <type>political</type> 
  </address_component> 
  <address_component> 
   <long_name>94043</long_name> 
   <short_name>94043</short_name> 
   <type>postal_code</type> 
  </address_component> 
  <geometry> 
   <location> 
    <lat>37.4217550</lat> 
    <lng>-122.0846330</lng> 
   </location> 
   <location_type>ROOFTOP</location_type> 
   <viewport> 
    <southwest> 
     <lat>37.4188514</lat> 
     <lng>-122.0874526</lng> 
    </southwest> 
    <northeast> 
     <lat>37.4251466</lat> 
     <lng>-122.0811574</lng> 
    </northeast> 
   </viewport> 
  </geometry> 
 </result> 
</GeocodeResponse> 

請注意,XML 響應包含一個 <GeocodeResponse> 和兩個頂級元素:

  • <status> 包含請求中的元數據。請參見下文的狀態代碼
  • 零或多個 <result> 元素,每個元素都包含單獨的一組地址解析地址信息和幾何圖形信息。

請注意,此響應要比 JSON 響應長很多。有鑑於此,我們建議您使用 json 作爲首選輸出標記,除非您的服務由於某種原因要求使用 xml。此外,在處理 XML 樹時要小心,確保引用正確的節點和元素。有關用於輸出處理的一些建議設計模式,請參見使用 XPath 解析 XML

本文檔的其餘部分將使用 JSON 語法。在大多數情況下,對於說明本文檔中的概念或字段名稱,輸出格式並不是很重要。不過,請注意以下細微差別:

  • XML 結果封裝在一個根 <GeocodeResponse> 元素中。
  • JSON 通過複數形式的數組 (types) 表示多個元素的條目,而 XML 使用多個單數形式的元素 (<type>) 表示這些條目。
  • 空白元素在 JSON 中通過空數組表示,而在 XML 中通過不存在此類元素來表示。例如,在 JSON 中,未生成任何結果的響應將傳回一個空 results 數組,但在 XML 中則不含 <result> 元素。

狀態代碼

地址解析響應對象中的 "status" 字段包含請求的狀態,並且可能包含調試信息,以幫助您追溯地址解析未正常工作的原因。"status" 字段可能包含以下值:

  • "OK" 表示未發生錯誤;地址成功進行了解析並且至少傳回了一個地址解析結果。
  • "ZERO_RESULTS" 表示地址解析成功,但未返回結果。如果地址解析過程中傳遞的偏遠位置 address 或 latlng 並不存在,則會出現 種情況。
  • "OVER_QUERY_LIMIT" 表示您超出了配額。
  • "REQUEST_DENIED" 表示您的請求被拒絕,通常是由於缺少 sensor 參數。
  • "INVALID_REQUEST" 通常表示缺少查詢參數(address 或 latlng)。

結果

當地址解析器傳回結果時,它會將其放在一個 (JSON) results 數組中。即使地址解析器未傳回任何結果(例如地址不存在),它仍會傳回一個空 results 數組。(XML 響應包含零或多個 <result> 元素。)

一個典型的結果由以下字段組成:

  • types[] 數組指示傳回結果的類型。此數組包含一個或多個標籤,這些標籤標識結果中返回的特徵的類型。例如,對“Chicago”的地址解析返回“locality”,表示“Chicago”是一個城市;同時返回“political”,表示它是一個政治實體。

  • formatted_address 是一個字符串,包含此位置的人類可讀地址。通常該地址相當於“郵政地址”,有時會因不同國家/地區而存在差異。(請注意,部分國家/地區會有許可限制,禁止發佈真實的郵政地址,如英國。)此地址通常由一個或多個地址部分組成。例如,地址“111 8th Avenue, New York, NY”包含四個地址組成部分,即“111”(街道門牌號)、“8th Avenue”(街道地址)、“New York”(城市)和“NY”(美國的一個州)。這些地址組成部分包含附加信息,如下面所述。

  • address_components[] 是一個包含多個地址組成部分(如上文所述)的數組。每個 address_component 通常包含以下幾個組成部分:

    • types[] 是一個數組,表示地址組成部分的類型。
    • long_name 是地址解析器傳回的完整文本說明或地址組成部分的名稱。
    • short_name 是地址組成部分的縮寫文本名稱(如果有)。例如,阿拉斯加州的地址組成部分可能具有 long_name“Alaska”和 short_name“AK”(使用 2 個字母的郵政縮寫)。

    請注意,address_components[] 包含的地址組成部分可能多於 formatted_address 中所註明的地址組成部分。

  • geometry 包含以下信息:

    • location 包含地址解析生成的緯度值和經度值。對於常規地址查詢,此字段通常是最重要的。
    • location_type 存儲有關指定位置的附加數據。當前支持以下值:

      • "ROOFTOP" 表示傳回的結果是一個精確的地址解析值,我們可獲得精確到街道地址的位置信息。
      • "RANGE_INTERPOLATED" 表示返回的結果是一個近似值(通常表示某條道路上的地址),該地址處於兩個精確點(如十字路口)之間。當無法對街道地址進行精確的地址解析時,通常會返回近似結果。
      • "GEOMETRIC_CENTER" 表示返回的結果是折線(如街道)或多邊形(區域)等內容的幾何中心。
      • "APPROXIMATE" 表示返回的結果是一個近似值。
    • viewport 包含用於顯示傳回結果的建議可視區域,並被指定爲兩個緯度/經度值,分別定義可視區域邊框的 southwest 和 northeast 角。通常,該可視區域用於在將結果顯示給用戶時作爲結果的框架。
    • bounds(可選擇傳回)存儲可完全包含傳回結果的邊框。請注意,這些邊界可能與建議的可視區域不相符。(例如,舊金山包含費拉隆島。該島實際上是舊金山市的一部分,但不應該在可視區域內傳回。)

由於我們無法保證針對 Google Geocoding API 請求的各個響應的確切格式,因此您絕對不能假定元素位於絕對位置。(尤其是,Google Geocoding API 請求中的address_components 數會基於所請求的地址而變化,並會隨時間改變。)相反,您應當對響應進行解析並通過表達式選擇相應值。有關詳細信息,請參見解析網絡服務響應

地址組成部分的類型

返回結果中的 types[] 數組表示地址類型。address_components[] 數組中也可能返回這些類型,以表示特定地址組成部分的類型。地址解析器中的地址可能有多種類型,這些類型也可以視爲“標籤”。例如,許多城市都帶有 political 和 locality 類型的標籤。

HTTP 地址解析器支持並返回以下類型:

  • street_address 表示一個精確的街道地址。
  • route 表示一條已命名的路線(如“US 101”)。
  • intersection 表示一個大十字路口,通常由兩條主道交叉形成。
  • political 表示一個政治實體。此類型通常表示代表某個行政管理區的多邊形。
  • country 表示國家政治實體。在地址解析器返回的結果中,該部分通常列在最前面。
  • administrative_area_level_1 表示僅次於國家級別的行政實體。在美國,這類行政實體是指州。並非所有國家都有該行政級別。
  • administrative_area_level_2 表示國家級別下的二級行政實體。在美國,這類行政實體是指縣。並非所有國家都有該行政級別。
  • administrative_area_level_3 表示國家級別下的三級行政實體。此類型表示較小的行政單位。並非所有國家都有該行政級別。
  • colloquial_area 表示實體的通用別名。
  • locality 表示合併的市鎮級別政治實體。
  • sublocality 表示僅次於地區級別的行政實體。
  • neighborhood 表示已命名的鄰近地區。
  • premise 表示已命名的位置,通常是具有常用名稱的建築物或建築羣。
  • subpremise 表示僅次於已命名位置級別的實體,通常是使用常用名稱的建築羣中的某座建築物。
  • postal_code 表示郵政編碼,用於確定相應國家/地區內的信件投遞地址。
  • natural_feature 表示某個明顯的自然特徵。
  • airport 表示機場。
  • park 表示已命名的公園。
  • point_of_interest 表示已命名的興趣點。通常,這些“POI”是一些不易歸入其他類別的比較有名的當地實體,如“帝國大廈”或“自由女神像”。

除此之外,地址組成部分還可以使用以下類型:

  • post_box 表示一個具體的郵筒。
  • street_number 表示精確的街道編號。
  • floor 表示建築物的樓層號。
  • room 表示建築物的房間編號。

反向地址解析(地址查詢)

術語“地址解析”通常是指將人類可讀的地址轉換成地圖上的位置。反之,將地圖上的位置轉換成人類可讀的地址這一過程則稱爲“反向地址解析”。

Google Geocoding API 支持直接使用 latlng 參數進行反向地址解析。例如,下列查詢包含了布魯克林某一位置的緯度/經度值:

http://maps.google.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false

請注意:在傳入 latlng 參數時,請確保緯度值與經度值之間沒有空格。

該查詢返回下列結果:

{
  "status": "OK",
  "results": [ {
    "types": [ "street_address" ],
    "formatted_address": "275-291 Bedford Ave, Brooklyn, NY 11211, USA",
    "address_components": [ {
      "long_name": "275-291",
      "short_name": "275-291",
      "types": [ "street_number" ]
    }, {
      "long_name": "Bedford Ave",
      "short_name": "Bedford Ave",
      "types": [ "route" ]
    }, {
      "long_name": "New York",
      "short_name": "New York",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "Brooklyn",
      "short_name": "Brooklyn",
      "types": [ "administrative_area_level_3", "political" ]
    }, {
      "long_name": "Kings",
      "short_name": "Kings",
      "types": [ "administrative_area_level_2", "political" ]
    }, {
      "long_name": "New York",
      "short_name": "NY",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "United States",
      "short_name": "US",
      "types": [ "country", "political" ]
    }, {
      "long_name": "11211",
      "short_name": "11211",
      "types": [ "postal_code" ]
    } ],
    "geometry": {
      "location": {
        "lat": 40.7142298,
        "lng": -73.9614669
      },
      "location_type": "RANGE_INTERPOLATED",
      "viewport": {
        "southwest": {
          "lat": 40.7110822,
          "lng": -73.9646145
        },
        "northeast": {
          "lat": 40.7173774,
          "lng": -73.9583193
        }
      }
    }
  },
  
  ... Additional results[] ...

請注意,反向地址解析器傳回了多個結果。結果的 "formatted_addresses" 不僅是指通信地址,還包含對位置進行地理命名的所有方式。例如,當對芝加哥市中的一個點進行地址解析時,地址解析的點可標註爲其街道地址、城市(芝加哥)、州(伊利諾斯)或國家(美國)。這些對地址解析器來說都是“地址”。反向地址解析器可將任何這些類型的地址作爲有效結果傳回。

反向地址解析器將匹配政治實體(國家/地區、省、市和鄰近地區)、街道地址和郵政編碼。

前一查詢所傳回的 formatted_address 值的完整列表如下所示。

"formatted_address": "275-291 Bedford Ave, Brooklyn, NY 11211, USA",
"formatted_address": "Williamsburg, NY, USA",
"formatted_address": "New York 11211, USA",
"formatted_address": "Kings, New York, USA",
"formatted_address": "Brooklyn, NY, USA",
"formatted_address": "New York, NY, USA",
"formatted_address": "New York, USA",
"formatted_address": "United States"

通常,地址將按照具體程度由高到低的順序傳回;最確切的地址將作爲最顯著的結果傳回,本例就是如此。請注意,我們傳回了各種不同的地址,從十分具體的街道地址到比較籠統的政治實體,如鄰近地區、市、縣、州/省等。如果您希望匹配更廣泛的地址,可能要檢查傳回的 Placemark 的 "types" 字段(請參見上文的地址組成部分類型)。

注意:反向地址解析給出的是估計結果。地址解析器會試圖在一定的偏差範圍內查找最接近的可尋址位置;如果找不到匹配項,地址解析器通常不會傳回結果。

可視區域偏向

您還可以指示地址解析服務優先在指定可視區域(表現爲邊框)中顯示結果。爲此,您可以在請求網址中設置 bounds 參數。

bounds 參數將定義此邊框的西南角和東北角的緯度/經度座標,並使用豎線 (|) 字符分隔座標。

例如,“Winnetka”的地址解析通常傳回芝加哥近郊地區的地址,具體結果如下:

請求:

http://maps.google.com/maps/api/geocode/json?address=Winnetka&sensor=false

響應:

{
  "status": "OK",
  "results": [ {
    "types": [ "locality", "political" ],
    "formatted_address": "Winnetka, IL, USA",
    "address_components": [ {
      "long_name": "Winnetka",
      "short_name": "Winnetka",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "Illinois",
      "short_name": "IL",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "United States",
      "short_name": "US",
      "types": [ "country", "political" ]
    } ],
    "geometry": {
      "location": {
        "lat": 42.1083080,
        "lng": -87.7417070
      },
      "location_type": "APPROXIMATE",
      "viewport": {
        "southwest": {
          "lat": 42.0917501,
          "lng": -87.7737218
        },
        "northeast": {
          "lat": 42.1248616,
          "lng": -87.7096922
        }
      },
      "bounds": {
        "southwest": {
          "lat": 42.0885320,
          "lng": -87.7715480
        },
        "northeast": {
          "lat": 42.1284090,
          "lng": -87.7110160
        }
      }
    }
  } ]
}

但是,如果添加一個 bounds 參數以定義洛杉磯的聖費爾南多谷的邊框,則地址解析會傳回該位置範圍內鄰近地區(名爲“Winnetka”)的地址:

請求:

http://maps.google.com/maps/api/geocode/json?address=Winnetka&bounds=34.172684,-118.604794|34.236144,-118.500938&sensor=false

響應:

{
  "status": "OK",
  "results": [ {
    "types": [ "sublocality", "political" ],
    "formatted_address": "Winnetka, California, USA",
    "address_components": [ {
      "long_name": "Winnetka",
      "short_name": "Winnetka",
      "types": [ "sublocality", "political" ]
    }, {
      "long_name": "Los Angeles",
      "short_name": "Los Angeles",
      "types": [ "administrative_area_level_3", "political" ]
    }, {
      "long_name": "Los Angeles",
      "short_name": "Los Angeles",
      "types": [ "administrative_area_level_2", "political" ]
    }, {
      "long_name": "California",
      "short_name": "CA",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "United States",
      "short_name": "US",
      "types": [ "country", "political" ]
    } ],
    "geometry": {
      "location": {
        "lat": 34.2131710,
        "lng": -118.5710220
      },
      "location_type": "APPROXIMATE",
      "viewport": {
        "southwest": {
          "lat": 34.1947148,
          "lng": -118.6030368
        },
        "northeast": {
          "lat": 34.2316232,
          "lng": -118.5390072
        }
      },
      "bounds": {
        "southwest": {
          "lat": 34.1791050,
          "lng": -118.5883200
        },
        "northeast": {
          "lat": 34.2353090,
          "lng": -118.5534191
        }
      }
    }
  } ]
}

區域偏向

Google Geocoding API 傳回的結果會受到發送請求的區域(通常是國家/地區)的影響。例如,如果分別從美國境內某個區域和西班牙發送對“San Francisco”的搜索,則會傳回不同的結果。

您可以使用 region 參數,將 Google Geocoding API 設置爲傳回偏向於特定區域的結果。該參數採用指定區域偏向的 ccTLD(國家/地區代碼頂級域)參數。多數 ccTLD 代碼都與 ISO 3166-1 代碼相同,但也有一些需要注意的例外情況。例如,英國的 ccTLD 爲“uk”(.co.uk),而其 ISO 3166-1 代碼爲“gb”(特指“大不列顛及北愛爾蘭聯合王國”)。

對於正式啓動了主 Google Maps 應用程序的每個區域,都可以對地址解析結果進行偏向。

例如,由於 Google Geocoding API 的默認區域設置爲美國,因此,對“Toldeo”的地址解析傳回瞭如下結果:

http://maps.google.com/maps/api/geocode/json?address=Toledo&sensor=false
# Returns:
#
{
  "status": "OK",
  "results": [ {
    "types": [ "locality", "political" ],
    "formatted_address": "Toledo, OH, USA",
    "address_components": [ {
      "long_name": "Toledo",
      "short_name": "Toledo",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "Ohio",
      "short_name": "OH",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "United States",
      "short_name": "US",
      "types": [ "country", "political" ]
    } ],
    "geometry": {
      "location": {
        "lat": 41.6529200,
        "lng": -83.5777820
      },
      "location_type": "APPROXIMATE",
      "viewport": {
        "southwest": {
          "lat": 41.5861889,
          "lng": -83.7058414
        },
        "northeast": {
          "lat": 41.7195821,
          "lng": -83.4497226
        }
      },
      "bounds": {
        "southwest": {
          "lat": 41.5803170,
          "lng": -83.6947540
        },
        "northeast": {
          "lat": 41.7326310,
          "lng": -83.4545660
        }
      }
    }
  } ]
}

而在域爲 region=es(西班牙)的情況下,對“Toldeo”的地址解析將會傳回西班牙的城市:

http://maps.google.com/maps/api/geocode/json?address=Toledo&sensor=false®ion=es
#
# Returns
#
{
  "status": "OK",
  "results": [ {
    "types": [ "locality", "political" ],
    "formatted_address": "Toledo, España",
    "address_components": [ {
      "long_name": "Toledo",
      "short_name": "Toledo",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "Toledo",
      "short_name": "TO",
      "types": [ "administrative_area_level_2", "political" ]
    }, {
      "long_name": "Castilla-La Mancha",
      "short_name": "CM",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "España",
      "short_name": "ES",
      "types": [ "country", "political" ]
    } ],
    "geometry": {
      "location": {
        "lat": 39.8567775,
        "lng": -4.0244759
      },
      "location_type": "APPROXIMATE",
      "viewport": {
        "southwest": {
          "lat": 39.7882200,
          "lng": -4.1525353
        },
        "northeast": {
          "lat": 39.9252666,
          "lng": -3.8964165
        }
      },
      "bounds": {
        "southwest": {
          "lat": 39.8105550,
          "lng": -4.1796354
        },
        "northeast": {
          "lat": 39.9250920,
          "lng": -3.8147915
        }
      }
    }
  } ]
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;


public class Demo {
 public static void main(String[] args) {
  String addr = GetAddr("35.8616600", "104.1953970");
  System.out.println(addr);
  //getCoordinate("中國");
 }

 /**
  * 根據經緯度反向解析地址,有時需要多嘗試幾次
  * 注意:如果在 24 小時時段內收到來自一個 IP 地址超過 2500 個地址解析請求, 或從一個 IP
  * 地址提交的地址解析請求速率過快,Google 地圖 API 編碼器將用 620 狀態代碼開始響應。 如果地址解析器的使用仍然過多,則從該 IP
  * 地址對 Google 地圖 API 地址解析器的訪問可能被永久阻止。
  * 
  * @param latitude
  *            緯度
  * @param longitude
  *            經度
  * @return
  */
 public static String GetAddr(String latitude, String longitude) {
  String addr = "";

  // 也可以是http://maps.google.cn/maps/geo?output=csv&key=abcdef&q=%s,%s,不過解析出來的是英文地址
  // 密鑰可以隨便寫一個key=abc
  // output=csv,也可以是xml或json,不過使用csv返回的數據最簡潔方便解析
  String url = String.format(
    "http://ditu.google.cn/maps/geo?output=csv&key=abcdef&q=%s,%s",
    latitude, longitude);
  URL myURL = null;
  URLConnection httpsConn = null;
  try {
   myURL = new URL(url);
  } catch (MalformedURLException e) {
   e.printStackTrace();
   return null;
  }
  try {
   httpsConn = (URLConnection) myURL.openConnection();
   if (httpsConn != null) {
    InputStreamReader insr = new InputStreamReader(
      httpsConn.getInputStream(), "UTF-8");
    BufferedReader br = new BufferedReader(insr);
    String data = null;
    if ((data = br.readLine()) != null) {
     System.out.println(data);
     String[] retList = data.split(",");
     if (retList.length > 2 && ("200".equals(retList[0]))) {
      addr = retList[2];
      addr = addr.replace("\"", "");
     } else {
      addr = "";
     }
    }
    insr.close();
   }
  } catch (IOException e) {
   e.printStackTrace();
   return null;
  }
  return addr;
 }
 
 public static void getCoordinate(String addr)
 {
  String addrs = "";
     String address = null;
  try {
   address = java.net.URLEncoder.encode(addr,"UTF-8");
  } catch (UnsupportedEncodingException e1) {
   e1.printStackTrace();
  };
        String output = "csv";
        String key = "abc";
        String url = String.format("http://maps.google.com/maps/geo?q=%s&output=%s&key=%s", address, output, key);
        URL myURL = null;
        URLConnection httpsConn = null;
        //進行轉碼
  try {
   myURL = new URL(url);
  } catch (MalformedURLException e) {
   e.printStackTrace();
  }
  
  try {
   httpsConn = (URLConnection) myURL.openConnection();
   if (httpsConn != null) {
    InputStreamReader insr = new InputStreamReader(
      httpsConn.getInputStream(), "UTF-8");
    BufferedReader br = new BufferedReader(insr);
    String data = null;
    if ((data = br.readLine()) != null) {
     System.out.println(data);
     String[] retList = data.split(",");
     /*
              String latitude = retList[2];
              String longitude = retList[3];
              
              System.out.println("緯度"+ latitude);
              System.out.println("經度"+ longitude);
              */

     if (retList.length > 2 && ("200".equals(retList[0]))) {
      addrs = retList[2];
      addrs = addr.replace("\"", "");
     } else {
      addrs = "";
     }
    }
    insr.close();
   }
  } catch (IOException e) {
   e.printStackTrace();
  }      
  System.out.println(addrs);
 }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章