Google Maps Android V2 でルート検索
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <fragment android:id="@+id/map" android:layout_width="wrap_content" android:layout_height="wrap_content" class="com.google.android.gms.maps.SupportMapFragment" /> </RelativeLayout>
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONObject; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.OnMapClickListener; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener; import com.google.android.gms.common.GooglePlayServicesUtil; import import android.app.ProgressDialog; public class MainActivity extends FragmentActivity { GoogleMap gMap; private static final int MENU_A = 0; private static final int MENU_B = 1; private static final int MENU_c = 2; public static String posinfo = ""; public static String info_A = ""; public static String info_B = ""; ArrayList<LatLng> markerPoints; public static MarkerOptions options; public ProgressDialog progressDialog; public String travelMode = "driving";//default @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //プログレス progressDialog = new ProgressDialog(this); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setMessage("検索中だす......"); progressDialog.hide(); //初期化 markerPoints = new ArrayList<LatLng>(); SupportMapFragment mapfragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map); gMap = mapfragment.getMap(); //初期位置 LatLng location = new LatLng(34.802556297454004,135.53884506225586); gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 17)); if(gMap!=null){ gMap.setMyLocationEnabled(true); //クリックリスナー gMap.setOnMapClickListener(new OnMapClickListener() { @Override public void onMapClick(LatLng point) { //3度目クリックでスタート地点を再設定 if(markerPoints.size()>1){ markerPoints.clear(); gMap.clear(); } markerPoints.add(point); options = new MarkerOptions(); options.position(point); if(markerPoints.size()==1){ //options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); options.icon(BitmapDescriptorFactory.fromResource(R.drawable.green)); options.title("A"); }else if(markerPoints.size()==2){ //options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); options.icon(BitmapDescriptorFactory.fromResource(R.drawable.red)); options.title("B"); } gMap.addMarker(options); gMap.setOnMarkerClickListener(new OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { // TODO Auto-generated method stub String title = marker.getTitle(); if (title.equals("A")){ marker.setSnippet(info_A); }else if (title.equals("B")){ marker.setSnippet(info_B); } return false; } }); if(markerPoints.size() >= 2){ //ルート検索 routeSearch(); } } }); } } private void routeSearch(){ progressDialog.show(); LatLng origin = markerPoints.get(0); LatLng dest = markerPoints.get(1); String url = getDirectionsUrl(origin, dest); DownloadTask downloadTask = new DownloadTask(); downloadTask.execute(url); } private String getDirectionsUrl(LatLng origin,LatLng dest){ String str_origin = "origin="+origin.latitude+","+origin.longitude; String str_dest = "destination="+dest.latitude+","+dest.longitude; String sensor = "sensor=false"; //パラメータ String parameters = str_origin+"&"+str_dest+"&"+sensor + "&language=ja" + "&mode=" + travelMode; //JSON指定 String output = "json"; String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters; return url; } private String downloadUrl(String strUrl) throws IOException{ String data = ""; InputStream iStream = null; HttpURLConnection urlConnection = null; try{ URL url = new URL(strUrl); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.connect(); iStream = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(iStream)); StringBuffer sb = new StringBuffer(); String line = ""; while( ( line = br.readLine()) != null){ sb.append(line); } data = sb.toString(); br.close(); }catch(Exception e){ Log.d("Exception while downloading url", e.toString()); }finally{ iStream.close(); urlConnection.disconnect(); } return data; } private class DownloadTask extends AsyncTask<String, Void, String>{ //非同期で取得 @Override protected String doInBackground(String... url) { String data = ""; try{ // Fetching the data from web service data = downloadUrl(url[0]); }catch(Exception e){ Log.d("Background Task",e.toString()); } return data; } // doInBackground() @Override protected void onPostExecute(String result) { super.onPostExecute(result); ParserTask parserTask = new ParserTask(); parserTask.execute(result); } } /*parse the Google Places in JSON format */ private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{ @Override protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) { JSONObject jObject; List<List<HashMap<String, String>>> routes = null; try{ jObject = new JSONObject(jsonData[0]); parseJsonpOfDirectionAPI parser = new parseJsonpOfDirectionAPI(); routes = parser.parse(jObject); }catch(Exception e){ e.printStackTrace(); } return routes; } //ルート検索で得た座標を使って経路表示 @Override protected void onPostExecute(List<List<HashMap<String, String>>> result) { ArrayList<LatLng> points = null; PolylineOptions lineOptions = null; MarkerOptions markerOptions = new MarkerOptions(); if(result.size() != 0){ for(int i=0;i<result.size();i++){ points = new ArrayList<LatLng>(); lineOptions = new PolylineOptions(); List<HashMap<String, String>> path = result.get(i); for(int j=0;j<path.size();j++){ HashMap<String,String> point = path.get(j); double lat = Double.parseDouble(point.get("lat")); double lng = Double.parseDouble(point.get("lng")); LatLng position = new LatLng(lat, lng); points.add(position); } //ポリライン lineOptions.addAll(points); lineOptions.width(10); lineOptions.color(0x550000ff); } //描画 gMap.addPolyline(lineOptions); }else{ gMap.clear(); Toast.makeText(MainActivity.this, "ルート情報を取得できませんでした", Toast.LENGTH_LONG).show(); } progressDialog.hide(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. //getMenuInflater().inflate(R.menu.main, menu); menu.add(0, MENU_A, 0, "Info"); menu.add(0, MENU_B, 0, "Legal Notices"); menu.add(0, MENU_c, 0, "Mode"); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch ( item.getItemId() ) { case MENU_A: //show_mapInfo(); return true; case MENU_B: //Legal Notices(免責事項) String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(getApplicationContext()); AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this); LicenseDialog.setTitle("Legal Notices"); LicenseDialog.setMessage(LicenseInfo); LicenseDialog.show(); return true; case MENU_c: //show_settings(); return true; } return false; } //リ・ルート検索 private void re_routeSearch(){ progressDialog.show(); LatLng origin = markerPoints.get(0); LatLng dest = markerPoints.get(1); // gMap.clear(); //マーカー //A options = new MarkerOptions(); options.position(origin); options.icon(BitmapDescriptorFactory.fromResource(R.drawable.green)); options.title("A"); options.draggable(true); gMap.addMarker(options); //B options = new MarkerOptions(); options.position(dest); options.icon(BitmapDescriptorFactory.fromResource(R.drawable.red)); options.title("B"); options.draggable(true); gMap.addMarker(options); String url = getDirectionsUrl(origin, dest); DownloadTask downloadTask = new DownloadTask(); downloadTask.execute(url); } }
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.google.android.gms.maps.model.LatLng; import android.util.Log; public class parseJsonpOfDirectionAPI { MainActivity ma; public List<List<HashMap<String,String>>> parse(JSONObject jObject){ String temp = ""; List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ; JSONArray jsonRoutes = null; JSONArray jsonLegs = null; JSONArray jsonSteps = null; try { jsonRoutes = jObject.getJSONArray("routes"); for(int i=0;i<jsonRoutes.length();i++){ jsonLegs = ( (JSONObject)jsonRoutes.get(i)).getJSONArray("legs"); //スタート地点・住所 String s_address = (String)((JSONObject)(JSONObject)jsonLegs.get(i)).getString("start_address"); ma.info_A = s_address; //到着地点・住所 String e_address = (String)((JSONObject)(JSONObject)jsonLegs.get(i)).getString("end_address"); ma.info_B = e_address; String distance_txt = (String)((JSONObject)((JSONObject)jsonLegs.get(i)).get("distance")).getString("text"); temp += distance_txt + "<br><br>"; String distance_val = (String)((JSONObject)((JSONObject)jsonLegs.get(i)).get("distance")).getString("value"); temp += distance_val + "<br><br>"; List path = new ArrayList<HashMap<String, String>>(); for(int j=0;j<jsonLegs.length();j++){ jsonSteps = ( (JSONObject)jsonLegs.get(j)).getJSONArray("steps"); for(int k=0;k<jsonSteps.length();k++){ String polyline = ""; polyline = (String)((JSONObject)((JSONObject)jsonSteps.get(k)).get("polyline")).get("points"); String instructions = (String)((JSONObject)(JSONObject)jsonSteps.get(k)).getString("html_instructions"); String duration_value = (String)((JSONObject)((JSONObject)jsonSteps.get(k)).get("duration")).getString("value"); String duration_txt = (String)((JSONObject)((JSONObject)jsonSteps.get(k)).get("duration")).getString("text"); temp += instructions + "/" + duration_value + " m /" + duration_txt + "<br><br>"; List<LatLng> list = decodePoly(polyline); for(int l=0;l<list.size();l++){ HashMap<String, String> hm = new HashMap<String, String>(); hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) ); hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) ); path.add(hm); } } //ルート座標 routes.add(path); } //ルート情報 ma.posinfo = temp; } } catch (JSONException e) { e.printStackTrace(); }catch (Exception e){ } return routes; } //座標データをデコード private List<LatLng> decodePoly(String encoded) { List<LatLng> poly = new ArrayList<LatLng>(); int index = 0, len = encoded.length(); int lat = 0, lng = 0; while (index < len) { int b, shift = 0, result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; LatLng p = new LatLng((((double) lat / 1E5)), (((double) lng / 1E5))); poly.add(p); } return poly; } }
{ "status": "OK", "routes": [ { "summary": "I-40 W", "legs": [ { "steps": [ { "travel_mode": "DRIVING", "start_location": { "lat": 41.8507300, "lng": -87.6512600 }, "end_location": { "lat": 41.8525800, "lng": -87.6514100 }, "polyline": { "points": "a~l~Fjk~uOwHJy@P" }, "duration": { "value": 19, "text": "1 min" }, "html_instructions": "Head \u003cb\u003enorth\u003c/b\u003e on \u003cb\u003eS Morgan St\u003c/b\u003e toward \u003cb\u003eW Cermak Rd\u003c/b\u003e", "distance": { "value": 207, "text": "0.1 mi" } }, ... ... additional steps of this leg ... ... additional legs of this route "duration": { "value": 74384, "text": "20 hours 40 mins" }, "distance": { "value": 2137146, "text": "1,328 mi" }, "start_location": { "lat": 35.4675602, "lng": -97.5164276 }, "end_location": { "lat": 34.0522342, "lng": -118.2436849 }, "start_address": "Oklahoma City, OK, USA", "end_address": "Los Angeles, CA, USA" } ], "copyrights": "Map data ©2010 Google, Sanborn", "overview_polyline": { "points": "a~l~Fjk~uOnzh@vlbBtc~@tsE`vnApw{A`dw@~w\\|tNtqf@l{Yd_Fblh@rxo@b}@xxSfytAblk@xxaBeJxlcBb~t@zbh@jc|Bx}C`rv@rw|@rlhA~dVzeo@vrSnc}Axf]fjz@xfFbw~@dz{A~d{A|zOxbrBbdUvpo@`cFp~xBc`Hk@nurDznmFfwMbwz@bbl@lq~@loPpxq@bw_@v|{CbtY~jGqeMb{iF|n\\~mbDzeVh_Wr|Efc\\x`Ij{kE}mAb~uF{cNd}xBjp]fulBiwJpgg@|kHntyArpb@bijCk_Kv~eGyqTj_|@`uV`k|DcsNdwxAott@r}q@_gc@nu`CnvHx`k@dse@j|p@zpiAp|gEicy@`omFvaErfo@igQxnlApqGze~AsyRzrjAb__@ftyB}pIlo_BflmA~yQftNboWzoAlzp@mz`@|}_@fda@jakEitAn{fB_a]lexClshBtmqAdmY_hLxiZd~XtaBndgC" }, "warnings": [ ], "waypoint_order": [ 0, 1 ], "bounds": { "southwest": { "lat": 34.0523600, "lng": -118.2435600 }, "northeast": { "lat": 41.8781100, "lng": -87.6297900 } } } ] }