dynamic Polyline colors with google maps android a

2019-03-01 15:09发布

问题:

I'm making an app that uses google maps to show when you deviate from a path previously taken. I can show where the deviations occur with a different color, but I have to initialize a new PolyOptions(), resulting in "choppy" polylines instead of smooth polylines like I have with my base route. If I don't initialize a new PolyOptions() then when I start to deviate, it turns a large portion of the path red, even though I'm only trying to apply the color to that one particular polyline. When I come back to the path, after deviating, I lose the deviated coloring and it all goes back to black. Can anybody explain to me what's going on and how I can combine the proper coloring from the new PolyOptions() method with the smoothness that you get with using one PolyLineOptions()

  1. new PolyLineOptions() method:

for (HaulEvent event : cycle) { LatLng locToAdd = new LatLng(event.Latitude, event.Longitude);

                    if (event.cycle_num < 2) {

                        m_aPL.add(mMap.addPolyline(m_PolyLines.geodesic(true)
                                .color(Color.BLACK)
                                .add(locToAdd)
                                .clickable(true)));
                        m_aPolyLineList = (ArrayList<LatLng>) m_PolyLines.getPoints();
                    } else { //after we've got a base cycle drawn
                        if (PolyUtil.isLocationOnPath(locToAdd, m_aBaseRoute, true, tolerance)) {
                            m_aPL.add(mMap.addPolyline(new PolylineOptions().geodesic(true)
                                    .color(Color.BLACK)
                                    .add(new LatLng(prevLocation.getLatitude(), prevLocation.getLongitude()), locToAdd)
                                    .clickable(true)));

                            //m_aPolyLineList = (ArrayList<LatLng>) m_PolyLines.getPoints();

                        } else {
                            m_aPL.add(mMap.addPolyline(new PolylineOptions().geodesic(true)
                                    .color(Color.RED)
                                    .add(new LatLng(prevLocation.getLatitude(),prevLocation.getLongitude()),locToAdd)
                                    .clickable(true)));
                            //m_aPolyLineList = (ArrayList<LatLng>) m_PolyLines.getPoints();
                        }
                    }
                    prevLocation.setLatitude(locToAdd.latitude);
                    prevLocation.setLongitude(locToAdd.longitude);

                }
            }

With this code I get the desired coloring behavior, but it's not smooth. I know the solution to this is one polylineoptions, but as you will see, that doesn't give me the desired basic behavior with the different colors. Here's a zoomed in screenshot. It's hard to see the jaggedness because I was just walking, but normally it would be for a moving vehicle so the gaps will be easier to see like here:

  1. one PolyLineOptions() method:

    for (HaulEvent event : cycle) { LatLng locToAdd = new LatLng(event.Latitude, event.Longitude);

                        if (event.cycle_num < 2) {
    
                            m_aPL.add(mMap.addPolyline(m_PolyLines.geodesic(true)
                                    .color(Color.BLACK)
                                    .add(locToAdd)
                                    .clickable(true)));
                            m_aPolyLineList = (ArrayList<LatLng>) m_PolyLines.getPoints();
                        } else { //after we've got a base cycle drawn
                            if (PolyUtil.isLocationOnPath(locToAdd, m_aBaseRoute, true, tolerance)) {
                                m_aPL.add(mMap.addPolyline(m_PolyLines.geodesic(true)
                                        .color(Color.BLACK)
                                        .add(new LatLng(prevLocation.getLatitude(), prevLocation.getLongitude()), locToAdd)
                                        .clickable(true)));
    
                                m_aPolyLineList = (ArrayList<LatLng>) m_PolyLines.getPoints();
    
                            } else {
                                m_aPL.add(mMap.addPolyline(m_PolyLines.geodesic(true)
                                        .color(Color.RED)
                                        .add(new LatLng(prevLocation.getLatitude(),prevLocation.getLongitude()),locToAdd)
                                        .clickable(true)));
                                m_aPolyLineList = (ArrayList<LatLng>) m_PolyLines.getPoints();
                            }
                        }
                        prevLocation.setLatitude(locToAdd.latitude);
                        prevLocation.setLongitude(locToAdd.longitude);
    
                    }
    

m_PolyLines is my PolyLineOptions. With this way, when I haven't deviated from my base route I get:

And then when I start to deviate from my base route I get a bunch of red polylines. Each time I deviated, the red would go all the way back to that specific point, where nothing special seemed to happen.

回答1:

you have to provide a Polylineoptions to addPolyline() to googlemaps object. and to change color of the PolylineOptions you can use color() . or to dynamically change the color of the polyline in googlemaps you can save the line object in a polyline and then use setColor() to change the color of the polyline at any point of code as long as the polyline object is not null.

to change color of any polyline drawn on google maps or to be drawn you have one method for each of them.

first case (polylineoptions)

the polylineoptions is the object that you pass to addpolyline() to draw into the googlemaps. so to change color in this case you have to change it before assigning. using the color() method. but the problem is that once you have changed the color and assigned you can not change it again. to change it again you have to clear the google map and redraw the polyline .

second case (polyline)

when you assign a polylineoptions to a googlemaps via the addpolyline() then you can save this object into an polyline. then you can change color of this polyline at any point of time after drawing it on the googlemaps . and this will be easy if you want to change color dynamically after drawing the polyline. the method you will use is setColor().

i hope this solves your query.

thank you



回答2:

There is no direct solution to your problem as you can only control a couple of drawing parameters for the polylines, but I propose a workaround that mixes both of your methods.

That is, addíng points to the existing polyline until it has to change the color, and then start a new polyline. This way you will only see a leap when the color changes.

here is the example code (not tested):

int currentColor = Color.BLACK;

for (HaulEvent event : cycle) { LatLng locToAdd = new LatLng(event.Latitude, event.Longitude);
    if (event.cycle_num < 2) {
        m_aPL.add(mMap.addPolyline(m_PolyLines.geodesic(true)
                .color(Color.BLACK)
                .add(locToAdd)
                .clickable(true)));
        m_aPolyLineList = (ArrayList<LatLng>) m_PolyLines.getPoints();

        currentColor = Color.BLACK;
    } else { //after we've got a base cycle drawn
        if (PolyUtil.isLocationOnPath(locToAdd, m_aBaseRoute, true, tolerance)) {
            if (currentColor == Color.BLACK) {
                m_aPL.add(mMap.addPolyline(m_PolyLines.geodesic(true)
                    .color(Color.BLACK)
                    .add(new LatLng(prevLocation.getLatitude(), prevLocation.getLongitude()), locToAdd)
                    .clickable(true)));
            } else {
                m_aPL.add(mMap.addPolyline(new PolylineOptions().geodesic(true)
                    .color(Color.BLACK)
                    .add(new LatLng(prevLocation.getLatitude(), prevLocation.getLongitude()), locToAdd)
                    .clickable(true)));
            }

            currentColor = Color.BLACK;
        } else {
            if (currentColor == Color.RED) {
                m_aPL.add(mMap.addPolyline(m_PolyLines.geodesic(true)
                    .color(Color.RED)
                    .add(new LatLng(prevLocation.getLatitude(),prevLocation.getLongitude()),locToAdd)
                    .clickable(true)));
            } else {
                m_aPL.add(mMap.addPolyline(new PolylineOptions().geodesic(true)
                    .color(Color.RED)
                    .add(new LatLng(prevLocation.getLatitude(),prevLocation.getLongitude()),locToAdd)
                    .clickable(true)));
            }

            currentColor = Color.RED;
        }
    }
    prevLocation.setLatitude(locToAdd.latitude);
    prevLocation.setLongitude(locToAdd.longitude);
}

Update

Improvement using https://github.com/antoniocarlon/richmaps (I am the owner of the project):

RichLayer richLayer = new RichLayer.Builder(mMap).zIndex(0).build();
RichPolylineOptions polylineOpts = new RichPolylineOptions(null)
    .zIndex(0)
    .strokeWidth(5)
    .strokeColor(Color.BLACK)
    .linearGradient(true);
RichPolyline polyline = polylineOpts.build();
richLayer.addShape(polyline);

// ...

for (HaulEvent event : cycle) { 
    LatLng locToAdd = new LatLng(event.Latitude, event.Longitude);

    if (event.cycle_num < 2) {
        polyline.add(new RichPoint(locToAdd));
    } else { //after we've got a base cycle drawn
        if (PolyUtil.isLocationOnPath(locToAdd, m_aBaseRoute, true, tolerance)) {
            polyline.add(new RichPoint(locToAdd));
        } else {
            polyline.add(new RichPoint(locToAdd).color(Color.RED));
        }
    }
}