Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid MapView overlay, caching bitmap on draw
    primarykey
    data
    text
    <p>I have an overlay for drawing a path on my <code>MapView</code>, but i noticed it gets unnecessarily redrawn about ten times per second. Since in the <code>draw</code> method i draw every single segment of the path, this could easily be an efficiency issue.</p> <p>For this reason i decided to cache the contents of the overlay and actually redraw it just when necessary, that is when the path changes, or the center of the map has moved, or the zoom level has changed.</p> <p>Now, one of the parameters of the <code>draw</code> method is the <code>Canvas</code> to draw on. I know how to draw the cached bitmap on it, the problem is i don't know how to cache the content of the canvas on a bitmap.<br> I can't instantiate a new canvas, nor can i call <code>setBitmap</code> because the canvas in a <code>HardwareCanvas</code> and it throws an <code>UnsupportedOperationException</code> if that method is invoked.</p> <p>So, to recap, i have a canvas and a bitmap, how can i copy the canvas' content to the bitmap?</p> <p><strong>Edit</strong><br> this is my draw method for clarity, i don't invoke it manually but still it gets called repeatedly even when the map is not moving at all</p> <pre><code>public void draw(Canvas canvas, MapView map, boolean shadow) { if (shadow) { // this overlay doesn't need to draw shadows return; } if (paths.isEmpty()) { // nothing to draw return; } center = map.getMapCenter(); zoomLevel = map.getZoomLevel(); map.getDrawingRect(bounds); projection = map.getProjection(); maxLevel = map.getMaxZoomLevel(); for (MapPath mp : paths) { // adjust path width to current zoom adjustedWidth = mp.getWidth() * zoomLevel / maxLevel; if (adjustedWidth &lt; MIN_WIDTH_TO_DRAW) { // path is too thin, avoid drawing it continue; } paint.setStrokeWidth(adjustedWidth); paint.setColor(mp.getColor()); state = PathState.FIRST_POINT; path.reset(); for (PathPoint pp : mp.getPoints()) { if (!pp.shoudAppearAtZoomLevel(zoomLevel)) { // do not draw this point at this zoom level continue; } // project a geopoint to a pixel projection.toPixels(pp.getGeoPoint(), point); inside = isInsideBounds(point, map); switch (state) { case FIRST_POINT: // move to starting point firstX = point.x; firstY = point.y; path.moveTo(firstX, firstY); break; case WAS_INSIDE: // segment is completely or partially on map path.lineTo(point.x, point.y); break; case WAS_OUTSIDE: if (inside) { // segment is partially on map path.lineTo(point.x, point.y); } else { // segment is completely off map path.moveTo(point.x, point.y); } break; } // update state state = inside ? PathState.WAS_INSIDE : PathState.WAS_OUTSIDE; } // workaround to avoid canvas becoming too big when path is mostly off screen path.moveTo(firstX, firstY); // draw this path to canvas canvas.drawPath(path, paint); } super.draw(canvas, map, shadow); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload