我想在两点之间画一条路径并计算从 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。需要执行此操作的代码如下所列:
- 获取调用 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;
}
在后台调用 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;
}
}
创建 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;
}}
使用另一个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);
}}
- 当你想得到两点的路径时
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);
结果以米为单位