我想在两点之间绘制一条路径并计算从A移动到B需要多长时间。我认为对Google Maps API来说这是一项微不足道的任务。
我发现的所有内容都是关于documentation中MapsActivity
的小片段,而不是如何使用它。
我做了什么?
在onMapReady
方法中的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);
内{我}尝试创建编码路径:
function addObservableStates()
{
var request = db.transaction(['ObservableStates'],"readwrite").objectStore('ObservableStates').add(observableState);
request.onerror = function(event)
{
console.log("Unable to add observableState to table ObservableStates");
}
request.onsuccess = function(event)
{
console.log("Observable State Added");
}
}
但下一步是什么?如何在地图上绘制此路径?如何计算这点之间的车/步行距离?
答案 0 :(得分:14)
路径是点的序列。其中一个解决方案是向Google maps API发出HTTP请求,将两个位置指定为参数,然后返回JSON,描述在两点之间建立路径所需的点。要求执行此操作的代码如下所示:
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; }
在后台进行网址调用
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 解析为指针列表
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;
}}
使用其他主题进行解析以扩展性能
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);
结果将以米为单位