如何从谷歌地图 api android 中删除多余的折线

Posted

技术标签:

【中文标题】如何从谷歌地图 api android 中删除多余的折线【英文标题】:How to remove the extra polyline from google maps api android 【发布时间】:2018-03-06 21:22:56 【问题描述】:

我添加了一个航路点,并通过该航路点绘制了从起点到目的地的折线。但是从起点到终点画了一条额外的直线。我怎样才能删除它?

下面的代码显示了 ParserTask 和 getDirections URL。

private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> 

        // Parsing the data in non-ui thread
        @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);

                Log.d("routes", routes.toString());
                Log.d("jObject", jObject.toString());

             catch (Exception e) 
                e.printStackTrace();
            
            return routes;
        

        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> result) 
            ArrayList<LatLng> points = new ArrayList<LatLng>();;
            PolylineOptions lineOptions = new PolylineOptions();;
            lineOptions.width(2);
            lineOptions.color(Color.RED);
            MarkerOptions markerOptions = new MarkerOptions();
            // Traversing through all the routes
            for(int i=0;i<result.size();i++)
                // Fetching i-th route
                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);
                lineOptions.geodesic(true);

            

// Drawing polyline in the Google Map for the i-th route
            mMap.addPolyline(lineOptions);
        
    

    private String getDirectionsUrl(LatLng origin_start, LatLng dest, LatLng waypoint_xx) 


        String origin = "origin=" + origin_start.latitude + "," + origin_start.longitude;
        //String waypointss = "waypoints=optimize:true|" + waypoint_xx.latitude + "," + waypoint_xx.longitude ;
        String destination = "destination=" + dest.latitude + "," + dest.longitude;


        // Waypoints
        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 sensor = "sensor=false";
        String alternative = "alternatives=false";
        String params = origin +  "&"  + destination + "&" + alternative + "&" + sensor + "&" + waypoints  ;
        String output = "json";
        String url = "https://maps.googleapis.com/maps/api/directions/"
                + output + "?" + params;
        return url;
    

此代码是方向 JSON 解析器

public class DirectionsJSONParser 

    /** Receives a JSONObject and returns a list of lists containing latitude and longitude */
    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");

            /** Traversing all routes */
            for(int i=0;i<jRoutes.length();i++)
                jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
                List path = new ArrayList<HashMap<String, String>>();

                /** Traversing all legs */
                for(int j=0;j<jLegs.length();j++)
                    jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");

                    /** Traversing all steps */
                    for(int k=0;k<jSteps.length();k++)
                        String polyline = "";
                        polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
                        List list = decodePoly(polyline);

                        /** Traversing all points */
                        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 (JSONException e) 
            e.printStackTrace();
        catch (Exception e)
        

        return routes;
    

    /**
     * Method to decode polyline points
     * Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
     * */
    private List decodePoly(String encoded) 

        List poly = new ArrayList();
        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 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());
            
            Log.d("parserTask data", data.toString());
            return data;
        

        @Override
        protected void onPostExecute(String result) 
            super.onPostExecute(result);

            ParserTask parserTask = new ParserTask();

            Log.d("parserTask result", result.toString());
            parserTask.execute(result);



        
    

最后是 onMapReady 方法

public void onMapReady(GoogleMap googleMap) 
        mMap = googleMap;

        UiSettings uiSettings = googleMap.getUiSettings();
        //uiSettings.setCompassEnabled(false);
        uiSettings.setZoomControlsEnabled(true);

        //-------------
//        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        //Initialize Google Play Services
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) 
                //Location Permission already granted
                buildGoogleApiClient();
                mMap.setMyLocationEnabled(true);
             else 
                //Request Location Permission
                checkLocationPermission();
            
        
        else 
            buildGoogleApiClient();
            mMap.setMyLocationEnabled(true);
        
        //-------------

        DatabaseReference myRef = FirebaseDatabase.getInstance().getReference().child("location");
        myRef.addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) 

                NotificationCompat.Builder builder =
                        new NotificationCompat.Builder(MapsActivity.this)
                                .setSmallIcon(R.drawable.applogo)
                                .setContentTitle("Trip Request")
                                .setContentText("Click to accept trip!");
                manager = (NotificationManager) MapsActivity.this.getSystemService( MapsActivity.this.NOTIFICATION_SERVICE );
                manager.notify(0, builder.build());

              //  sendNotification();

                startLatFB = (Double) dataSnapshot.child("startLat").getValue();
                startLonFB = (Double) dataSnapshot.child("startLon").getValue();
                endLatFB = (Double) dataSnapshot.child("endLat").getValue();
                endLonFB = (Double) dataSnapshot.child("endLon").getValue();

                Log.d("startLat", startLatFB.toString());
                Log.d("startLon", startLonFB.toString());
                Log.d("endLat", endLatFB.toString());
                Log.d("endLon", endLonFB.toString());

                if (markerPoints.size() > 1) 
                    markerPoints.clear();
                    mMap.clear();
                

                double startLat = startLatFB;  //SLIIT
                double startLon = startLonFB;

                double wayPointLat = 6.9040322;  //FAB - Malabe
                double wayPointLon = 79.948803;

                double wayPointLatTwo = 6.053519;  //FAB - Malabe
                double wayPointLonTwo = 80.220977;

                double endLat = endLatFB; //MAS
                double endLon = endLonFB;


                LatLng start_latLng = new LatLng(startLat, startLon);
                LatLng waypoint_latLng = new LatLng(wayPointLat, wayPointLon);
                LatLng end_latLng = new LatLng(endLat, endLon);

//                LatLng start_latLng = new LatLng(startLatFB, startLonFB);
//                LatLng waypoint_latLng = new LatLng(wayPointLat, wayPointLon);
//                LatLng end_latLng = new LatLng(endLatFB, endLonFB);
                mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(start_latLng, 11));
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(start_latLng,11f));

//                start_latLng = startLatFB;



                // Adding new item to the ArrayList
                markerPoints.add(start_latLng);
                markerPoints.add(end_latLng);
                markerPoints.add(waypoint_latLng);

                // Creating MarkerOptions
                MarkerOptions options = new MarkerOptions();
                MarkerOptions optionsTwo = new MarkerOptions();
                MarkerOptions optionsThree = new MarkerOptions();

                BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.startlocation);
                BitmapDescriptor icon2 = BitmapDescriptorFactory.fromResource(R.drawable.endlocation);

                // Setting the position of the marker
                options.position(start_latLng);
                optionsTwo.position(end_latLng);
                optionsThree.position(waypoint_latLng);



                if (markerPoints.size() == 1) 
                    options.icon(icon);
                 else if (markerPoints.size() == 2) 
                    options.icon(icon2);
                

                // Add new marker to the Google Map Android API V2
                mMap.addMarker(options);
                mMap.addMarker(optionsTwo);
                mMap.addMarker(optionsThree);



                // Checks, whether start and end locations are captured
                if (markerPoints.size() >= 3) 
                    LatLng origin = (LatLng) markerPoints.get(0);
                    LatLng dest = (LatLng) markerPoints.get(1);
                    LatLng waypointss = (LatLng) markerPoints.get(2);

                    Log.d("origin url", origin.toString());
                    Log.d("dest url", origin.toString());
                    Log.d("waypoint url", origin.toString());
                    // Getting URL to the Google Directions API
                    String url = getDirectionsUrl(origin, dest, waypointss);

                    DownloadTask downloadTask = new DownloadTask();

                    // Start downloading json data from Google Directions API
                    downloadTask.execute(url);

                    Log.d("DownloadTask url", url);
                


            

            @Override
            public void onCancelled(DatabaseError databaseError) 

            
        );



    

【问题讨论】:

【参考方案1】:

尝试在每次遍历时初始化新的 Arraylist of Points。

这是一个示例:

@Override
    protected void onPostExecute(List<List<HashMap<String, String>>> result) 
        ArrayList<LatLng> points = null;
        PolylineOptions lineOptions = null;

        // Traversing through all the routes
        for(int i=0;i<result.size();i++)
            points = new ArrayList<LatLng>();   //initialize here
            lineOptions = new PolylineOptions();

            // Fetching i-th route
            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);
    

具体实现请转至This Link

【讨论】:

以上是关于如何从谷歌地图 api android 中删除多余的折线的主要内容,如果未能解决你的问题,请参考以下文章

如何从谷歌地图中删除额外信息

JSON,如何从谷歌地图 API 获取所有国家

如何从谷歌地图位置标记(iOS)中删除箭头?

在本机反应中从谷歌地图中删除标记

如何从谷歌地图 API 获取楼层号或套房与纬度

如何从谷歌地图中删除特定的多个标记而不是单个或所有标记