Android谷歌地图绘制两点之间的路径

VLe*_*ovs 1 android google-maps

我想在两点之间绘制一条路径并计算从A移动到B需要多长时间.我认为Google Maps API是一项微不足道的任务.

我找到的所有内容PolyUtil都是文档中的小片段,而不是如何使用它.

我做了什么 ?

MapsActivityonMapReady方法内部我正在尝试创建一个编码路径:

List<LatLng> latLngList = new ArrayList<>();
latLngList.add(new LatLng(56.952503, 24.083719));
latLngList.add(new LatLng(55.877526, 26.533898));

String encodedPath = PolyUtil.encode(latLngList);
Run Code Online (Sandbox Code Playgroud)

但下一步是什么?如何在地图上绘制此路径?如何计算这点之间的车/步行距离?

Al-*_*ari 15

路径是点的序列.其中一个解决方案是向Google maps API发出HTTP请求,将两个位置指定为参数,然后返回JSON,描述在两点之间建立路径所需的点.要求执行此操作的代码如下所示:

  1. 获取路线网址需要调用Google Maps API
private String  getMapsApiDirectionsUrl(LatLng origin,LatLng dest) {
   // Origin of route
 String str_origin = "origin="+origin.latitude+","+origin.longitude;

 // Destination of route
 String str_dest = "destination="+dest.latitude+","+dest.longitude;        


 // Sensor enabled
 String sensor = "sensor=false";            

 // Building the parameters to the web service
 String parameters = str_origin+"&"+str_dest+"&"+sensor;

 // Output format
 String output = "json";

 // Building the url to the web service
 String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;


 return url;

}
Run Code Online (Sandbox Code Playgroud)
  1. 在后台进行URL调用

    private class ReadTask extends AsyncTask<String, Void , String> {
    
    @Override
    protected String doInBackground(String... url) {
        // TODO Auto-generated method stub
        String data = "";
        try {
            MapHttpConnection http = new MapHttpConnection();
            data = http.readUr(url[0]);
    
    
        } catch (Exception e) {
            // TODO: handle exception
            Log.d("Background Task", e.toString());
        }
        return data;
    }
    
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        new ParserTask().execute(result);
    }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  public class MapHttpConnection {
  public String readUr(String mapsApiDirectionsUrl) throws IOException{
      String data = "";
      InputStream istream = null;
      HttpURLConnection urlConnection = null;
      try {
          URL url = new URL(mapsApiDirectionsUrl);
          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 reading url", e.toString());
      } finally {
          istream.close();
          urlConnection.disconnect();
      }
      return data;

  }
}
Run Code Online (Sandbox Code Playgroud)
  1. 创建Parser类以将数据从JSON解析为指针列表

    public class PathJSONParser {
    
    public List<List<HashMap<String, String>>> parse(JSONObject jObject) {
        List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>();
        JSONArray jRoutes = null;
        JSONArray jLegs = null;
        JSONArray jSteps = null;
        try {
            jRoutes = jObject.getJSONArray("routes");
            for (int i=0 ; i < jRoutes.length() ; i ++) {
                jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
                List<HashMap<String, String>> path = new ArrayList<HashMap<String,String>>();
                for(int j = 0 ; j < jLegs.length() ; j++) {
                    jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");
                    for(int k = 0 ; k < jSteps.length() ; k ++) {
                        String polyline = "";
                        polyline = (String) ((JSONObject) ((JSONObject) jSteps.get(k)).get("polyline")).get("points");
                        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);
                }
    
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }
        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;
    }}
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用另一个线程 进行解析以扩展性能

private class ParserTask extends AsyncTask<String,Integer, List<List<HashMap<String , String >>>> {
  @Override
  protected List<List<HashMap<String, String>>> doInBackground(
          String... jsonData) {
      // TODO Auto-generated method stub
      JSONObject jObject;
      List<List<HashMap<String, String>>> routes = null;
      try {
          jObject = new JSONObject(jsonData[0]);
          PathJSONParser parser = new PathJSONParser();
          routes = parser.parse(jObject);


      } catch (Exception e) {
          e.printStackTrace();
      }
      return routes;
  }

  @Override
  protected void onPostExecute(List<List<HashMap<String, String>>> routes) {
      ArrayList<LatLng> points = null;
      PolylineOptions polyLineOptions = null;

      // traversing through routes
      for (int i = 0; i < routes.size(); i++) {
          points = new ArrayList<LatLng>();
          polyLineOptions = new PolylineOptions();
          List<HashMap<String, String>> path = routes.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);
          }

          polyLineOptions.addAll(points);
          polyLineOptions.width(4);
          polyLineOptions.color(Color.BLUE);
      }

      googleMap.addPolyline(polyLineOptions);

  }}
Run Code Online (Sandbox Code Playgroud)
  1. 当你想获得两点的路径时
 String url = getMapsApiDirectionsUrl(latlngOne, latlngTwo);                    
    ReadTask downloadTask = new ReadTask();       
    // Start downloading json data from Google Directions API
    downloadTask.execute(url);
Run Code Online (Sandbox Code Playgroud)

计算点之间的距离

float[] results = new float[1];
Location.distanceBetween(latLongA.latitude, latLongB.longitude,
                         latLongB.latitude, latLongB.longitude,
                         results); 
Run Code Online (Sandbox Code Playgroud)

结果将以米为单位