在寫這一篇之前應該會有三篇關於Facebook在Android與iOS上的應用
但我只寫到一半,因為Facebook的SDK使用上有幾個很重要的經驗
需要花一點時間截圖說明,但我最近一直都沒有時間去完成他
所以看官們對Facebook在Android與iOS應用有興趣的需要再等會,我先寫這一篇比較簡單的。
本文開始前,先了解一下什麼是Geocoding,其實說穿的就是google提供把住址轉換成經緯度的API
至於能做什麼應用就見仁見智。
其中要注意的我歸納有以下幾點
1. 2500筆的限制:google為了避免有人濫用 Geocoding API 和 (或) 將其用在其他目的,限制非Google Maps API Premier 使用者,每天只能要求 2,500 個地理位置,經實測結果的確在2600多筆之後回傳的經緯度就都是(0, 0)了,但這只是防君子不防小人的鳥策略。
2.請求速度不能太快:如果你程式一執行就讓他一直向Google要求住址轉換成經緯度,你會發現每隔幾筆請求會回傳經緯度是(0, 0)
3.使用http GET的方式請求:台灣是中文語系的國家,所以請求前最好指定一下為UTF-8編碼格式
4.回傳的結果可以是XML或JSON的呈現方式:我只測試JSON的部分,因此使用的第三方的套件來解析json-simple
以下是原始碼:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.DataOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URL; import java.net.URLEncoder; import org.json.JSONArray; import org.json.JSONObject; public class GeoCoding { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { //設定要讀取轉換地址的文字檔與寫入轉換後經緯度的文字檔 BufferedReader addressIn = new BufferedReader(new FileReader("address_in.txt")); BufferedWriter addressOut = new BufferedWriter(new FileWriter("address_out.txt")); String strIn; String strOut; double AddrXY[] = { 0, 0 }; int queryCount = 0; while ((strIn = addressIn.readLine()) != null) { Thread.sleep(500); //這裡就是我說的如果不休息個幾毫秒,一直傳送請求會有些無法取到經緯度 queryCount++; AddrXY = getAdressXY(strIn); //取得經緯度 if (queryCount == 2500){ //用來防君子不防小人的方式,2500筆的時候重新連線取得新IP Runtime.getRuntime().exec("cmd /k start PPPoE.bat"); //執行我寫的重新連線bat檔 Thread.sleep(7000); //怕還沒撥接完,所以停7秒再繼續(其實不需要這麼久) InetAddress myIP = InetAddress.getLocalHost() ; System.out.println(myIP.getHostAddress()); queryCount = 0; } strOut = strIn + ";" + AddrXY[1] + ";" + AddrXY[0]; System.out.println(strOut); addressOut.write(strOut); addressOut.newLine(); } addressIn.close(); addressOut.close(); } catch (Exception e) { // TODO Auto-generated catch block //e.printStackTrace(); System.out.println("Main Exception" + e.toString()); } } public static double[] getAdressXY(String Address) { URL url; double retXY[] = { 0, 0 }; try { Address = URLEncoder.encode(Address, "utf-8"); String actionUrl = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=" + Address; url = new URL(actionUrl); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setDoOutput(true); con.setDoInput(true); con.setRequestMethod("GET"); con.setUseCaches(false); con.setReadTimeout(3000); con.setConnectTimeout(3000); con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "utf-8"); con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); DataOutputStream ds = new DataOutputStream(con.getOutputStream()); /* 取得Response內容 */ int retCode = con.getResponseCode(); // System.out.println("JsonUtil retCode" + retCode); String inputLine = null; if (retCode == 200) { BufferedReader reader = new BufferedReader(new InputStreamReader( con.getInputStream(), "utf-8")); String strResult = ""; while (((inputLine = reader.readLine()) != null)) { strResult = strResult + inputLine; } //System.out.println("strResult="+strResult); reader.close(); //解析JSON回傳結果 JSONObject obj = new JSONObject(strResult); JSONArray jsonArray = obj.getJSONArray("results"); for (int i = 0; i < jsonArray.length(); i++) { JSONObject obj2 = jsonArray.getJSONObject(i); JSONObject obj3 = obj2.getJSONObject("geometry"); JSONObject obj4 = obj3.getJSONObject("location"); //retString[0] = obj4.getString("lat"); //retString[1] = obj4.getString("lng"); retXY[0] = obj4.getDouble("lat"); retXY[1] = obj4.getDouble("lng"); //System.out.println("lat(經度):"+retXY[0]); //System.out.println("lng(緯度):"+retXY[1]); } } con.disconnect(); } catch (Exception e) { // TODO Auto-generated catch block //e.printStackTrace(); System.out.println("getAdressXY Exception" + e.toString()); } return retXY; } }
讀入的address_in.txt文字檔內容如下
台東縣台東市永安街97號
台東縣台東市漢中街128號
台東縣鹿野鄉高台路42巷2號
台東縣台東市新生路772號
台東縣台東市傳廣路257號
寫入的address_out.txt文字黨內容如下
台東縣台東市永安街97號;121.1220152;22.7829546
台東縣台東市漢中街128號;121.1374301;22.7582271
台東縣鹿野鄉高台路42巷2號;121.1197793;22.9141254
台東縣台東市新生路772號;121.1341475;22.7654438
台東縣台東市傳廣路257號;121.1439304;22.7629646
另外其中有一段用來防君子不防小人的做法
就是在請求2500筆後,重新撥接ADSL取得新IP
if (queryCount == 2500){ //用來防君子不防小人的方式,2500筆的時候重新連線取得新IP Runtime.getRuntime().exec("cmd /k start PPPoE.bat"); //執行我寫的重新連線bat檔 Thread.sleep(7000); //怕還沒撥接完,所以停7秒再繼續(其實不需要這麼久) InetAddress myIP = InetAddress.getLocalHost() ; System.out.println(myIP.getHostAddress()); queryCount = 0; }
PPPoE.bat的內容如下:
rasdial /disconnect
rasdial 連線名稱 12345678@hinet.net password
Place your comment