• 沒有找到結果。

各區域內部資料解析

3.3 臺北市公眾區免費無線上網熱點

3.3.1 各區域內部資料解析

由於台北市政府開放資料平台所提供的資料串接格式多為 JSON 檔案格 式,此格式多以文字為基礎且方便讓使用者閱讀。JSON 與 XML 最大的差異在 於 XML 是屬於一個比較完整的標記語言,而 JSON 不是。使用 XML 在程式判 讀與解析上需要花較多的時間,XML 利用標記語言特性提供較好的延展性,如:

Xpath,在擴充功能與資料儲存上面具有較佳的優勢,反觀 JSON 相對於 XML 來說更加輕巧,更適用於網路資料傳輸。

本研究透過 Http 方式取的 JSON 資料,並在手持裝置上進 JSON 檔案解析與 呈現。圖 3-6 為一個 Http URL 連線並取得 JSON 資料的 Java Class,本研究中系 統解析 JSON 檔案皆是使用此 class 完成,完整內容請參考附錄。

//透過 HTTP 取的 JSON Data try {

DefaultHttpClient httpClient = new DefaultHttpClient();

HttpPost httpPost = new HttpPost(url);

HttpResponse httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity = httpResponse.getEntity();

is = httpEntity.getContent();

} catch (UnsupportedEncodingException e) { e.printStackTrace();

} catch (ClientProtocolException e) { e.printStackTrace();

} catch (IOException e) { e.printStackTrace();

} try {

// utf-8 為編碼方式、8 為 bufferedreadfer size

BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);

StringBuilder sb = new StringBuilder();

String line = null;

while ((line = reader.readLine()) != null) { sb.append(line + "\n");

}

is.close();

json = sb.toString();

} catch (Exception e) { }

try { // 解析 String JSON 物件 jObj = new JSONObject(json);

} catch (JSONException e) { }

return jObj; // 回傳 JSON string }

圖 3- 6 Http 連接 URL 取得 JSON 檔案

如圖 3-7,以 7-ELEVEN 區域為例,Server 端透過 MySQL 語法查詢無線上 網熱點資料庫內容,依據表 3-1 取出所有類別欄位(area)為 7-ELEVEN 的資料並 透過 MySQL 轉 JSON 的 Class 進行格式輸出,再將結果直接透過網頁傳值方式 回傳至使用者手持裝置上進行分析。如圖 3-8,系統中也加入 LocationManager 物件來判斷使用者目前所在位置,並透過 LocationListener 介面取得位置是否更 新的資訊,如圖 3-9。

//載入 json class

include('mysql_to_json.class.php');

mysql_connect('localhost', 'database_user', 'database_password');

mysql_select_db('database');

//資料庫編碼方式

mysql_query("SET NAMES 'UTF8'");

mysql_query("SET CHARACTER SET UTF8");

mysql_query("SET CHARACTER_SET_RESULTS=UTF8'");

//SQL 查詢語法

$query = 'SELECT * FROM senven_eleven';

//建立一個 mysql_to_json instance

$mtj = new mysql_to_json($query);

//顯示 JSON 輸出 echo $mtj->get_json();

$mtj = new mysql_to_json();

echo $mtj->set_query($query)->set_cbfunc('loels')->get_json();

圖 3- 7 將 MySQL 查詢結果輸出成 JSON 格式 // 取得 LocationManager 物件

locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

// 建立 Criteria 物件,求更精準的定位功能 criteria = new Criteria();

criteria.setAccuracy(Criteria.ACCURACY_FINE);

// criteria 回傳最適合的定位名稱, true 代表只回傳目前可提供的定位名稱 String provider = locationManager.getBestProvider(criteria, true);

// 指定的定位名稱取得自己最新位置

Location myLocation = locationManager.getLastKnownLocation(provider);

this.myLocation = myLocation;

圖 3- 8 透過 LocationManager 物件取得目前位置資訊

// listener 物件實作 LocationListener 介面,專門監聽自己位置是否改變 private LocationListener myLocationListener = new LocationListener() {

//若位置改變就更新資訊

public void onLocationChanged(Location location) { myLocation = location;

updateMyLocationInfo(location);

} };

// 判斷自己位置是否改變 protected void onResume() {

super.onResume();

// 當位置改變時讓系統重新擷取最適當的定位方式

String provider = locationManager.getBestProvider(criteria, true);

//透過 LocationListener 來判斷自己位置是否改變,1000=1 秒,10=10 公尺 locationManager.requestLocationUpdates(provider, 1000,

10,myLocationListener);

}

// 畫面切換時即停止更新自己位置 protected void onPause() {

locationManager.removeUpdates(myLocationListener);

super.onPause();

}

圖 3- 9 LocationListener 更新使用者位置

透過 HTTP 取得 JSON Data 資料格式皆屬於字串(String),因此我們必須將 字串格式的經度與緯度轉換成 double 格式,如圖 3-10。因此我們將轉換完成的 值與自己所在位置的經緯度進行距離的計算,並存入陣列中,經由計算完成的數 值單位為公尺,為了方便使用者查詢本系統將此數值轉為公里,如圖 3-11。

double json_lng = Double.parseDouble(lng);

double json_lat = Double.parseDouble(lat);

圖 3- 10 將字串轉換成 double 型態 float[] results = new float[1];

// 計算兩點間的距離(公尺),結果存入 results[0]

Location.distanceBetween(myLocation.getLatitude(), myLocation.getLongitude(), json_lat,json_lng, results);

//將結果公尺除以 1000 轉換成公里

distance = NumberFormat.getInstance().format(results[0]/1000)+"公里";

圖 3- 11 計算兩點之間的距離並換算成公里

當進入單一資料查詢時,畫面會呈現該點位的詳細資料內容並透過 Google String strUri =

"google.streetview:cbll="+wifi_area_latitude+","+wifi_area_longtitude;

//顯示該點位地址

Toast.makeText(SingleTaipeiWifiTrackActivity.this, wifi_area_address, Toast.LENGTH_LONG).show();

//利用 Intent 方式開啟 Google Map 街景圖

Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(strUri));

startActivity(intent);

圖 3- 12 透過 Intent 方式啟動 Google Map 街景圖 // 取得自己位置緯經度

double fromLat = myLocation.getLatitude();

double fromLng = myLocation.getLongitude();

//取的目的地位置經緯度

double toLat = Double.parseDouble(wifi_area_latitude);

double toLng = Double.parseDouble(wifi_area_longtitude);

direct(fromLat, fromLng, toLat, toLng);

// 開啟 Google 地圖應用程式來完成導航

private void direct(double fromLat, double fromLng, double toLat, double toLng) {

// 設定前往的 Uri,saddr-出發地緯經度;daddr-目的地緯經度 String uriStr = String.format(

"http://maps.google.com/maps?saddr=%f,%f&daddr=%f,%f", fromLat, fromLng, toLat, toLng);

Intent intent = new Intent();

// 指定 Google 地圖應用程式

intent.setClassName("com.google.android.apps.maps",

"com.google.android.maps.MapsActivity");

// ACTION_VIEW-呈現資料給使用者觀看

intent.setAction(android.content.Intent.ACTION_VIEW);

// 將 Uri 資訊附加到 Intent 物件上 intent.setData(Uri.parse(uriStr));

startActivity(intent);

}

圖 3- 13 透過 Intent 啟動 Google Map 導航

相關文件