如何在Android的Google地图上绘制两个以上的路线?

时间:2018-08-04 05:36:18

标签: android google-maps

我想在带有路线的Google地图上显示多个点。这些点应该是动态的,由用户输入。

输出如下图所示:

enter image description here

我想在我的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));
}

1 个答案:

答案 0 :(得分:1)

onPostExecute的{​​{1}}中,存在一个容易纠正的错误。在外部循环中,在result.size()上,重新创建ParserTask变量,这意味着由于您的lineOptions调用不在循环内,因此仅将最后一次迭代添加到映射中。

因此您可以通过两种方式解决此问题,但结果是相同的:

  • (a)将所有点添加到一个数组,然后添加到一个lineOptions或
  • (b)将路径循环的一次迭代中的点添加到一个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);
}