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!
You can trace a path or highlight an area on your map by drawing lines and shapes.
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.
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.
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/
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With