1

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:

enter image description 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: enter image description here

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. enter image description here

Community
  • 1
  • 1
M. Smith
  • 379
  • 1
  • 20

2 Answers2

0

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

Sagar Nayak
  • 2,138
  • 2
  • 19
  • 52
0

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));
        }
    }
}
antonio
  • 18,044
  • 4
  • 45
  • 61
  • your method seems to work similar to mine with the red polylines, but when I get back on path and switch back to the black color, it redraws a polyline connecting the new black polyline to the previous black polyline before the red polyline, because it's a continuation of m_PolyLines and the methods connect any polylines using the same polyline options *long sigh* I'm going to try maybe waiting til I get a full cycle in to post-process everything, that way I can hopefully smooth it out. it wont be nearly real-time like it is now but it will lag one cycle behind, which is acceptable – M. Smith Mar 04 '16 at 16:40
  • I haven't tested the method, but my intention is to create a new polyline each time the color changes, so when you get back on track, a new black polyline will be created and not connected to the previous black polyline – antonio Mar 04 '16 at 16:44
  • Oh, sorry! I see my mistake now. As you say, I'm adding points to he existing m_PolyLines. Let me try to clear my mind with it. Where are you initializing m_PolyLines and what do you use it for (besides adding points to it to show on the map)? – antonio Mar 04 '16 at 16:47
  • It's initialized at the beginning of the class and it's also used to set all of the polylines visible or invisible at other points in the app (via an overlay). – M. Smith Mar 04 '16 at 18:06
  • With a little more creative googling I've discovered that this concept of "polyline gradients" is not possible on android. Google did make this possible on iOS a couple years ago (typical). There is a pretty complicated github project out there that strives to do this so I'll check it out later: [link](http://stackoverflow.com/questions/14258830/colourful-polylines-in-android-maps-api-v2/30178108#30178108) – M. Smith Mar 04 '16 at 19:28
  • ^ in case you didn't get a notification – M. Smith Mar 04 '16 at 19:29
  • You are right, sadly the drawing options for polylines and polygons are very basic. The link you are referring looks promising, but I would draw polylines on a GroundOverlay instead of a TileOverlay. Thanks for sharing your findings! – antonio Mar 05 '16 at 11:00
  • As this kind of advanced rendering options for polylines and polygons is relevant to my interests (I am working on a personal project that will make heavy use of it), I have created a GitHub project to improve default drawing. You can take a look at it at: https://github.com/antoniocarlon/richmaps – antonio Mar 07 '16 at 18:20