Android谷歌地图在两点之间绘制一条路径 [英] Android Google Maps draw a path between two points
问题描述
我想绘制两点之间的路径,并计算从A移动到B需要多长时间。我认为这对于Google Maps API来说是微不足道的任务。
我发现的所有内容都是 PolyUtil api / utility /rel =nofollow noreferrer>文档,不知道如何使用它。
我做了什么?
里面 MapsActivity
在 onMapReady中
方法我试图创建一个编码路径:
列表< LatLng> latLngList = new ArrayList<>();
latLngList.add(new LatLng(56.952503,24.083719));
latLngList.add(new LatLng(55.877526,26.533898));
字符串encodedPath = PolyUtil.encode(latLngList);
但下一步是什么?如何在地图上绘制此路径?如何计算这两点之间的车/步行距离?
路径是点的序列。其中一个解决方案是向谷歌地图API发出HTTP请求,指定您的两个位置作为参数,并取回描述在两点之间建立路径所需的点的JSON。需要执行的代码如下所示:
- 获取调用Google Maps API的方向URL ol>
-
在后台执行URL调用
private class ReadTask extends AsyncTask< String,Void ,String> {
@Override
protected String doInBackground(String ... url){
// TODO自动生成的方法存根
String data =;
尝试{
MapHttpConnection http = new MapHttpConnection();
data = http.readUr(url [0]);
$ b $ catch(Exception e){
// TODO:处理异常
Log.d(Background Task,e.toString());
}
返回数据;
}
@Override
protected void onPostExecute(String result){
super.onPostExecute(result);
new ParserTask()。execute(result);
}
}
-
创建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;
尝试{
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>>(); $ j $ b $ for(int j = 0; jjSteps =((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);
列表< 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);
$ b catch(Exception e){
e.printStackTrace();
}
返回路线;
}
私人列表< LatLng> decodePoly(字符串编码){
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 + = 5;
} while(b> = 0x20);
int dlat =((result& 1)!= 0?〜(result>> 1):( result>> 1));
lat + = dlat;
shift = 0;
结果= 0;
do {
b = encoded.charAt(index ++) - 63;
result | =(b& 0x1f)<<转移;
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);
}
返回poly;
}}
-
使用另一个线程扩展性能
- 当您想获得两点的路径时
- Get direction URL require to call Google Maps API
Do the URL call in background
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); } }
Create Parser class to parse the data from JSON to 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; }}
Do the parse using another Thread to expand performance
- When you want to get the path of two point
private String getMapsApiDirectionsUrl(LatLng origin,LatLng dest){
//路由的起源
String str_origin =origin =+ origin.latitude +,+ origin.longitude;
//路线
的目的地String str_dest =destination =+ dest.latitude +,+ dest.longitude;
//启用传感器
String sensor =sensor = false;
//将参数构建到Web服务
字符串参数= str_origin +&+ str_dest +&+ sensor;
//输出格式
字符串输出=json;
//将网址构建到网络服务
String url =https://maps.googleapis.com/maps/api/directions/\"+output+\"?\"+parameters;
return url;
$ / code $ / pre
$ /
public class MapHttpConnection {
public String readUr(String mapsApiDirectionsUrl)throws IOException {
String data =;
InputStream istream = null;
HttpURLConnection urlConnection = null;
尝试{
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 =; ((line = br.readLine())!= null){
sb.append(line);
while
}
data = sb.toString();
br.close();
$ b catch(Exception e){
Log.d(读取url时的异常,e.toString());
} finally {
istream.close();
urlConnection.disconnect();
}
返回数据;
$ b $ / code $ / pre
$ /
private class ParserTask扩展AsyncTask< String,Integer,List< List< HashMap< String,String>>>> {
@Override
protected List< List< HashMap< String,String>>> doInBackground(
String ... jsonData){
// TODO自动生成的方法存根
JSONObject jObject;
List< List< HashMap< String,String>>> routes = null;
尝试{
jObject = new JSONObject(jsonData [0]);
PathJSONParser parser = new PathJSONParser();
routes = parser.parse(jObject);
} catch(Exception e){
e.printStackTrace();
}
返回路线;
$ b @Override
protected void onPostExecute(List< List< HashMap< String,String>>> routes){
ArrayList< LatLng> points = null;
PolylineOptions polyLineOptions = null;
//遍历路由
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();
//开始从Google Directions API下载json数据
downloadTask.execute(url);
计算积分之间的距离
float [] results = new float [1];
Location.distanceBetween(latLongA.latitude,latLongB.longitude,
latLongB.latitude,latLongB.longitude,
results);
结果将以米为单位
I would like to draw a path between two points and calculate how much time it will take to move from A to B. I have thought that it is trivial task for Google Maps API.
Everything that I found is small snippet about
PolyUtil
in documentation and nothing about how to use it.What I did ?
Inside
MapsActivity
inonMapReady
method I'm trying to create an encoded path: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);
But what is the next ? How to draw this path on map ? How to calculate car/walking distance between this points ?
解决方案Path is sequence of point . One of the solution is to make HTTP request to Google maps API specifying your two locations as parameters and get back JSON describing the points required to make the path between the two points. Require code to do that are listed below :
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; }
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; } }
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);
To calculate distance between points
float[] results = new float[1]; Location.distanceBetween(latLongA.latitude, latLongB.longitude, latLongB.latitude, latLongB.longitude, results);
the results will be in meters
这篇关于Android谷歌地图在两点之间绘制一条路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!