我想在带有路线的Google地图上显示多个点。这些点应该是动态的,由用户输入。
输出如下图所示:
我想在我的Android应用中显示多个位置之间的行车路线。
关于Stack Overflow本身有几个答案,并且所有答案都使用相同的方法。使用Google Directions API获取从起点到目的地的路线,并在返回的点之间绘制一条折线。
我使用了下面的代码,但是它仅显示了两点之间的路线。但是,我想显示多个点之间的路线。
谢谢。
private GoogleMap mMap;
ArrayList<LatLng> markerPoints;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
markerPoints = new ArrayList<LatLng>();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Button btnDraw = (Button) findViewById(R.id.btn_draw);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng point) {
if (markerPoints.size() >= 10) {
return;
}
markerPoints.add(point);
MarkerOptions options = new MarkerOptions();
options.position(point);
if (markerPoints.size() == 1) {
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
} else if (markerPoints.size() == 2) {
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
} else {
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
}
mMap.addMarker(options);
}
});
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng point) {
mMap.clear();
markerPoints.clear();
}
});
btnDraw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (markerPoints.size() >= 2) {
LatLng origin = markerPoints.get(0);
LatLng dest = markerPoints.get(1);
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(url);
}
}
});
}
private String getDirectionsUrl(LatLng origin, LatLng dest) {
String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
String sensor = "sensor=false";
String waypoints = "";
for (int i = 2; i < markerPoints.size(); i++) {
LatLng point = (LatLng) markerPoints.get(i);
if (i == 2)
waypoints = "waypoints=";
waypoints += point.latitude + "," + point.longitude + "|";
}
String parameters = str_origin + "&" + str_dest + "&" + sensor + "&" + waypoints;
String output = "json";
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
return url;
}
@SuppressLint("LongLogTag")
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
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 downloading url", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
private class DownloadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... url) {
String data = "";
try {
data = downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
parserTask.execute(result);
}
}
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
routes = parser.parse(jObject);
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
List<HashMap<String, String>> path = result.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);
}
lineOptions.addAll(points);
lineOptions.width(12);
lineOptions.color(Color.RED);
}
// Drawing polyline in the Google Map for the i-th route
mMap.addPolyline(lineOptions);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng AT = new LatLng(20.039413, 74.479977);
mMap.addMarker(new MarkerOptions().position(AT).title("Marker in Yeola"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(AT));
}
答案 0 :(得分:1)
在onPostExecute
的{{1}}中,存在一个容易纠正的错误。在外部循环中,在result.size()上,重新创建ParserTask
变量,这意味着由于您的lineOptions
调用不在循环内,因此仅将最后一次迭代添加到映射中。
因此您可以通过两种方式解决此问题,但结果是相同的:
addPolyline
。 (这似乎是您的意图。)由于地图不在乎聚合路径的组成方式,并且由于方向指示结果将针对每个路段正确终止,因此我更愿意使用(a)作为解决方案,但我同时列出了两者。
要使用选项(a)进行修复:
addPolyline
要使用选项(b)进行修复:
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = new ArrayList<>();
PolylineOptions lineOptions = new PolylineOptions();
for (int i = 0; i < result.size(); i++) {
List<HashMap<String, String>> path = result.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);
}
}
lineOptions.addAll(points);
lineOptions.width(12);
lineOptions.color(Color.RED);
// Drawing polyline in the Google Map for the entire route
mMap.addPolyline(lineOptions);
}