Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

draw over 4K polylines in android google maps

I'm developing right now an application for Android devices. The main functionality is to draw polylines on map to show what is the traffic in the city on each street. Unfortunately when I draw around 3K polylines - the number is reduced according to the screen size and zoom level - my map gets incredibly slow... I do not mention the time of drawing all of the lines.

Maybe you know more efficient way to mark streets or draw lines on a map?

I was also thinking about switching to OSM but I never used it and I don't know how efficient it is.

I debug app on Samsung Galaxy Note 10.1 and App uses Map API v2

My code to draw polylines:

Polyline line;
List<Float> coordinatesStart;
List<Float> coordinatesEnd;
LatLng start;
LatLng end;
List<List<Float>> coordinates;
int polylinesNumber = 0;
for(Features ftr : features){
    coordinates = ftr.geometry.coordinates;

    for(int i = 0; i<coordinates.size()-1; i++){

            coordinatesStart = coordinates.get(i);
            coordinatesEnd = coordinates.get(i+1);
            start = new LatLng(coordinatesStart.get(1), coordinatesStart.get(0));
            end = new LatLng(coordinatesEnd.get(1), coordinatesEnd.get(0));
            line = map.addPolyline(new PolylineOptions()
             .add(start, end)
             .width(3)
             .color(0x7F0000FF)); //semi-transparent blue
            polylinesNumber++;

    }
}

I would appreciate any help!

like image 723
Krzysztof Jackowski Avatar asked May 24 '13 14:05

Krzysztof Jackowski


People also ask

Can you draw on Google Maps Android?

You can trace a path or highlight an area on your map by drawing lines and shapes.


4 Answers

Great optimization here:

Your main error is that you use new PolyLineOptions instance for each and every line you draw to the maps. This is make the drawing terribly slow.

The solution would be:

Only use one instance of polyline options and use only the .add(LatLng) function inside the loops.

    //MAGIC #1 here
    //You make only ONE instance of polylineOptions.
    //Setting width and color, points for the segments added later inside the loops.
    PolylineOptions myPolylineOptionsInstance = new PolylineOptions()
            .width(3)
            .color(0x7F0000FF);

    for (Features ftr : features) {
        coordinates = ftr.geometry.coordinates;

        for (int i = 0; i < coordinates.size(); i++) {

            coordinatesStart = coordinates.get(i);
            start = new LatLng(coordinatesStart.get(1), coordinatesStart.get(0));

            //MAGIC #2 here
            //Adding the actual point to the polyline instance.
            myPolylineOptionsInstance.add(start);

            polylinesNumber++;
        }
    }

    //MAGIC #3 here
    //Drawing, simply only once.
    line = map.addPolyline(myPolylineOptionsInstance);

Attention:

If you would like to have different colors for different line segmnents/sections you would have to use multiple polyline options, because polyline option could have only 1 color. But the method would be the same: Use as few polylineOptions as you can.

like image 85
Adam Varhegyi Avatar answered Sep 20 '22 14:09

Adam Varhegyi


Do you check if the polyline that you draw is even visible to the user on the screen? If not, that would be my first idea. This question could be of help for that.

like image 37
fweigl Avatar answered Sep 19 '22 14:09

fweigl


This might be of help as well:

http://discgolfsoftware.wordpress.com/2012/12/06/hiding-and-showing-on-screen-markers-with-google-maps-android-api-v2/

like image 26
chfshifter Avatar answered Sep 23 '22 14:09

chfshifter


I want to chime in on this because I didn't find this answer complete. If you zoom out you're going to still have a ton of individual polylines on screen and the UI thread will grind to a halt. I solved this problem using a custom TileProvider and a spherical mercator projection of my LatLng points to screen pixels. The idea came from the map-utils-library, which has most of the needed tools to write a canvas to a tile (and a lot of other niceities, too).

I've written an example ComplexTileOverlays from a project I was working on. This includes ways to change alpha and line thickness in the CustomTileProvider.

I first load my custom database of polylines into memory using a splashscreen (for this example, it's an open database of bike facilities on the island of Montréal). from there, I draw each line projection on a canvas 256x256 pixel canvas representing one tile. Overall this technique is faster by leaps and bounds if you have a lot of graphical overlays to tie to the map.

like image 31
stewjacks Avatar answered Sep 19 '22 14:09

stewjacks