android和ios GoogleMap画导航线路图 路径规划(Directions)

本文适合 【Android iOS】下的google Map 开发

转自:http://blog.csdn.NET/mad1989/article/details/9734667

1.0 GoogleMap路径规划

Google Mapandroid版和IOS版的SDK都没有集成路径规划的相关API,若要实现,只能通过http链接请求URL,携带起点终点经纬度,得到返回集合,在地图中展示。

 Google Directions API :https://developers.google.com/maps/documentation/directions/#Waypoints

 Directions Service:https://developers.google.com/maps/documentation/javascript/directions#DirectionsRequests


1.1 请求链接

举个例子: 

https://maps.googleapis.com/maps/api/directions/json?origin=39.99709957757345,116.31184045225382&destination=39.949158391497214,116.4154639095068&sensor=false&mode=driving

origin=起点经纬度 destination=终点经纬度 


返回的json数据(网页打开):


1.2 android实例

1.2.1 getDestinationURL

代码:
  1. /** 
  2.  * 通过起点终点,组合成url 
  3.  *  
  4.  * @param origin 
  5.  * @param dest 
  6.  * @return 
  7.  */  
  8. private String getDirectionsUrl(LatLng origin, LatLng dest) {  
  9.   
  10.     // Origin of route  
  11.     String str_origin = "origin=" + origin.latitude + ","  
  12.             + origin.longitude;  
  13.   
  14.     // Destination of route  
  15.     String str_dest = "destination=" + dest.latitude + "," + dest.longitude;  
  16.   
  17.     // Sensor enabled  
  18.     String sensor = "sensor=false";  
  19.   
  20.     // Travelling Mode  
  21.     String mode = "mode=driving";  
  22.       
  23.     //waypoints,116.32885,40.036675  
  24.     String waypointLatLng = "waypoints="+"40.036675"+","+"116.32885";  
  25.   
  26.     // Building the parameters to the web service  
  27.     String parameters = str_origin + "&" + str_dest + "&" + sensor + "&"  
  28.             + mode+"&"+waypointLatLng;  
  29.   
  30.     // Output format  
  31.     String output = "json";  
  32.   
  33.     // Building the url to the web service  
  34.     String url = "https://maps.googleapis.com/maps/api/directions/"  
  35.             + output + "?" + parameters;  
  36.     System.out.println("getDerectionsURL--->: " + url);  
  37.     return url;  
  38. }  
该方法传递了起点,终点的经纬度,然后组合成了网页请求时用到的URL

1.2.2downloadUrl

【本文是以json格式作为result结果,如果想要以xml形式为Result结果,请步:

源码:
  1. /** A method to download json data from url */  
  2. private String downloadUrl(String strUrl) throws IOException {  
  3.     String data = "";  
  4.     InputStream iStream = null;  
  5.     HttpURLConnection urlConnection = null;  
  6.     try {  
  7.         URL url = new URL(strUrl);  
  8.   
  9.         // Creating an http connection to communicate with url  
  10.         urlConnection = (HttpURLConnection) url.openConnection();  
  11.   
  12.         // Connecting to url  
  13.         urlConnection.connect();  
  14.   
  15.         // Reading data from url  
  16.         iStream = urlConnection.getInputStream();  
  17.   
  18.         BufferedReader br = new BufferedReader(new InputStreamReader(  
  19.                 iStream));  
  20.   
  21.         StringBuffer sb = new StringBuffer();  
  22.   
  23.         String line = "";  
  24.         while ((line = br.readLine()) != null) {  
  25.             sb.append(line);  
  26.         }  
  27.   
  28.         data = sb.toString();  
  29.   
  30.         br.close();  
  31.   
  32.     } catch (Exception e) {  
  33.         Log.d("Exception while downloading url", e.toString());  
  34.     } finally {  
  35.         iStream.close();  
  36.         urlConnection.disconnect();  
  37.     }  
  38.     System.out.println("url:" + strUrl + "---->   downloadurl:" + data);  
  39.     return data;  
  40. }  

该方法通过携带经纬度的url请求得到json数据

1.2.3downloadTask

  1. // Fetches data from url passed  
  2. private class DownloadTask extends AsyncTask<String, Void, String> {  
  3.   
  4.     // Downloading data in non-ui thread  
  5.     @Override  
  6.     protected String doInBackground(String... url) {  
  7.   
  8.         // For storing data from web service  
  9.         String data = "";  
  10.   
  11.         try {  
  12.             // Fetching the data from web service  
  13.             data = downloadUrl(url[0]);  
  14.         } catch (Exception e) {  
  15.             Log.d("Background Task", e.toString());  
  16.         }  
  17.         return data;  
  18.     }  
  19.   
  20.     // Executes in UI thread, after the execution of  
  21.     // doInBackground()  
  22.     @Override  
  23.     protected void onPostExecute(String result) {  
  24.         super.onPostExecute(result);  
  25.   
  26.         ParserTask parserTask = new ParserTask();  
  27.   
  28.         // Invokes the thread for parsing the JSON data  
  29.         parserTask.execute(result);  
  30.     }  
  31. }  

使用异步操作AsynTask实现downurl json 数据

1.2.4ParserTask

  1. /** A class to parse the Google Places in JSON format */  
  2. private class ParserTask extends  
  3.         AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {  
  4.   
  5.     // Parsing the data in non-ui thread  
  6.     @Override  
  7.     protected List<List<HashMap<String, String>>> doInBackground(  
  8.             String... jsonData) {  
  9.   
  10.         JSONObject jObject;  
  11.         List<List<HashMap<String, String>>> routes = null;  
  12.   
  13.         try {  
  14.             jObject = new JSONObject(jsonData[0]);  
  15.             DirectionsJSONParser parser = new DirectionsJSONParser();  
  16.   
  17.             // Starts parsing data  
  18.             routes = parser.parse(jObject);  
  19.             System.out.println("do in background:" + routes);  
  20.         } catch (Exception e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.         return routes;  
  24.     }  
  25.   
  26.     // Executes in UI thread, after the parsing process  
  27.     @Override  
  28.     protected void onPostExecute(List<List<HashMap<String, String>>> result) {  
  29.         ArrayList<LatLng> points = null;  
  30.         PolylineOptions lineOptions = null;  
  31.         MarkerOptions markerOptions = new MarkerOptions();  
  32.   
  33.         // Traversing through all the routes  
  34.         for (int i = 0; i < result.size(); i++) {  
  35.             points = new ArrayList<LatLng>();  
  36.             lineOptions = new PolylineOptions();  
  37.   
  38.             // Fetching i-th route  
  39.             List<HashMap<String, String>> path = result.get(i);  
  40.   
  41.             // Fetching all the points in i-th route  
  42.             for (int j = 0; j < path.size(); j++) {  
  43.                 HashMap<String, String> point = path.get(j);  
  44.   
  45.                 double lat = Double.parseDouble(point.get("lat"));  
  46.                 double lng = Double.parseDouble(point.get("lng"));  
  47.                 LatLng position = new LatLng(lat, lng);  
  48.   
  49.                 points.add(position);  
  50.             }  
  51.   
  52.             // Adding all the points in the route to LineOptions  
  53.             lineOptions.addAll(points);  
  54.             lineOptions.width(3);  
  55.   
  56.             // Changing the color polyline according to the mode  
  57.             lineOptions.color(Color.BLUE);  
  58.         }  
  59.   
  60.         // Drawing polyline in the Google Map for the i-th route  
  61.         mGoogleMap.addPolyline(lineOptions);  
  62.     }  
  63. }  
异步操作,转换得到的 Google Place json数据,然后显示在google map上。

1.2.5 DirectionsJSONParser

  1. public class DirectionsJSONParser {  
  2.     /** 
  3.      * Receives a JSONObject and returns a list of lists containing latitude and 
  4.      * longitude 
  5.      */  
  6.     public List<List<HashMap<String, String>>> parse(JSONObject jObject) {  
  7.   
  8.         List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String, String>>>();  
  9.         JSONArray jRoutes = null;  
  10.         JSONArray jLegs = null;  
  11.         JSONArray jSteps = null;  
  12.   
  13.         try {  
  14.   
  15.             jRoutes = jObject.getJSONArray("routes");  
  16.   
  17.             /** Traversing all routes */  
  18.             for (int i = 0; i < jRoutes.length(); i++) {  
  19.                 jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");  
  20.                 List path = new ArrayList<HashMap<String, String>>();  
  21.   
  22.                 /** Traversing all legs */  
  23.                 for (int j = 0; j < jLegs.length(); j++) {  
  24.                     jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");  
  25.   
  26.                     /** Traversing all steps */  
  27.                     for (int k = 0; k < jSteps.length(); k++) {  
  28.                         String polyline = "";  
  29.                         polyline = (String) ((JSONObject) ((JSONObject) jSteps  
  30.                                 .get(k)).get("polyline")).get("points");  
  31.                         List<LatLng> list = decodePoly(polyline);  
  32.   
  33.                         /** Traversing all points */  
  34.                         for (int l = 0; l < list.size(); l++) {  
  35.                             HashMap<String, String> hm = new HashMap<String, String>();  
  36.                             hm.put("lat",  
  37.                                     Double.toString(((LatLng) list.get(l)).latitude));  
  38.                             hm.put("lng",  
  39.                                     Double.toString(((LatLng) list.get(l)).longitude));  
  40.                             path.add(hm);  
  41.                         }  
  42.                     }  
  43.                     routes.add(path);  
  44.                 }  
  45.             }  
  46.         } catch (JSONException e) {  
  47.             e.printStackTrace();  
  48.         } catch (Exception e) {  
  49.         }  
  50.         return routes;  
  51.     }  
  52.   
  53.     /** 
  54.      * Method to decode polyline points Courtesy : 
  55.      * jeffreysambells.com/2010/05/27 
  56.      * /decoding-polylines-from-google-maps-direction-api-with-java 
  57.      * */  
  58.     private List<LatLng> decodePoly(String encoded) {  
  59.   
  60.         List<LatLng> poly = new ArrayList<LatLng>();  
  61.         int index = 0, len = encoded.length();  
  62.         int lat = 0, lng = 0;  
  63.   
  64.         while (index < len) {  
  65.             int b, shift = 0, result = 0;  
  66.             do {  
  67.                 b = encoded.charAt(index++) - 63;  
  68.                 result |= (b & 0x1f) << shift;  
  69.                 shift += 5;  
  70.             } while (b >= 0x20);  
  71.             int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));  
  72.             lat += dlat;  
  73.   
  74.             shift = 0;  
  75.             result = 0;  
  76.             do {  
  77.                 b = encoded.charAt(index++) - 63;  
  78.                 result |= (b & 0x1f) << shift;  
  79.                 shift += 5;  
  80.             } while (b >= 0x20);  
  81.             int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));  
  82.             lng += dlng;  
  83.   
  84.             LatLng p = new LatLng((((double) lat / 1E5)),  
  85.                     (((double) lng / 1E5)));  
  86.             poly.add(p);  
  87.         }  
  88.         return poly;  
  89.     }  
  90. }  

效果图

红色的线为驾车线路

蓝色的线为步行线路




1.3 URL解析

导航的路径信息可以通过Http获取也可以通过Https获取;两者的url是相同的,不同的是https比http安全而已。


下面是获取的uil的格式:http://maps.googleapis.com/maps/api/directions/[json|xml]?[params];


有两种输出格式分别是json和xml;

params如下:
origin(必要)您要计算导航路径的起始位置,可以是地址或经纬度。

destination (必要)您要计算导航路径的终止位置,可以是地址或经纬度。

mode(选用,默认值:driving)指定计算导航时使用的交通模式。

driving表示使用标准行车导航。

walking 要求使用人行道及行人步行导航。

bicycling 要求使用自行车导航。(只适用于美国)

waypoints (选用) 指定导航路径要经过的地点。地点可以指定为经纬度坐标或可进行地理编码的地址。

alternatives (选用)true 时,表示请求导航的回应中提供一个以上的路线。这个可能延长服务器的请求耗时。

avoid(选用) 表示导航路径要避开的地点。这个参数可以是下面的2个值︰

tolls 表示路径避开收费站。

highways 表示路径避开高速公路。

units (选用)指定显示的单位。

metric 使用标准单位,公里和公尺。

imperial 使用英式单位,英里和英尺。

region (选用)将区域代码指定为ccTLD([顶层网域])的两位字元值。

language (选用)路径传回时使用的语言。如果系统不支持设置的语言,那么系统会使用浏览器设置的语言进行返回。
zh-CN 简体汉语
en-US 英语

sensor (必要) 指出导航的请求设备是否附有位置感应器。这个值必须是 true 或 false。

以下是Google Directions API提供的2个URL的示例供参考:

http://maps.googleapis.com/maps/api/directions/json?origin=Boston,MA&destination=Concord,MA&waypoints=Charlestown,MA|Lexington,MA&sensor=false
http://maps.googleapis.com/maps/api/directions/json?origin=Adelaide,SA&destination=Adelaide,SA&waypoints=optimize:true|Barossa+Valley,SA|Clare,SA|Connawarra,SA|McLaren+Vale,SA&sensor=false
 
以上的例子是根据地点名称来获取导航路径的方式,下面说明如何使用经纬度的方式来获取导航路径:

示例:http://maps.googleapis.com/maps/api/directions/json?origin=37.458060333333336%2c118.49971400000001&destination=37.458260333333336%2c118.50971400000001&sensor=false

1.4 携带waypoints的轨迹对比图

如果我们的导航路线希望通过地图中的某几个地方,则在url中添加一个parmas名称为 waypoints,waypoints只能携带8个。该属性我已经在上边的java代码中添加,可以自己查看。
https://maps.googleapis.com/maps/api/directions/json?origin=39.99709957757345,116.31184045225382&destination=39.949158391497214,116.4154639095068&sensor=false&mode=driving&waypoints=40.036675,116.32885

效果图:


1.5综述

目前来看,循环添加2(或多个)个点的方法,可以减小误差的情况,不过得设置定时器,当上一此循环返回结果后再进行下一次循环(异步回调),这样轨迹查询可能就会耗时一些。Google map 在国内的环境下,路径规划请求的URL有些慢,偶尔timeout还得不到结果。


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值