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

标签 android google-maps

<分区>

我想在两点之间画一条路径并计算从 A 移动到 B 需要多少时间。我认为这对于 Google Maps API 来说是微不足道的任务。

我在 documentation 中找到的所有内容都是关于 PolyUtil 的小 fragment 没有关于如何使用它的内容。

我做了什么?

onMapReady 方法中的 MapsActivity 中,我正在尝试创建编码路径:

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);

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

最佳答案

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

  1. 获取调用 Google Maps API 所需的方向 URL
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;

}
  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);
    }
    
    }
    
  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;

  }
}
  1. 创建 Parser 类以将数据从 JSON 解析为 List of pointes

    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;
    }}
    
  2. 使用另一个Thread 进行解析以扩展性能

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);

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

计算点之间的距离

float[] results = new float[1];
Location.distanceBetween(latLongA.latitude, latLongB.longitude,
                         latLongB.latitude, latLongB.longitude,
                         results); 

结果以米为单位

关于Android 谷歌地图绘制两点之间的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40562312/

相关文章:

android - 如何使用 MediaRecorder 获取每个录音频率?

android - 在 Android 中显示包含不同类型信息的列表

java - LinkedIn 集成到 Android 应用程序中

javascript - Wordpress 高级自定义字段,Google map ,一次只打开一个信息窗口

android - android中的 map Activity

android - 应用程序在每次重启时都会导致 AOT(优化应用程序)

javascript - Google Maps Api - 不要在 Zoom 上更改 map 中心

java - 如何在android中晃动时调用谷歌地图?

android - 在更新位置之前从 Google map 中删除特定标记

android - 场景SDK : How to add a 3D renderable on things other than plane