Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8892773
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T23:05:31+00:00 2026-06-14T23:05:31+00:00

I have an overlay for drawing a path on my MapView , but i

  • 0

I have an overlay for drawing a path on my MapView, but i noticed it gets unnecessarily redrawn about ten times per second.
Since in the draw method i draw every single segment of the path, this could easily be an efficiency issue.

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.

Now, one of the parameters of the draw method is the Canvas 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.
I can’t instantiate a new canvas, nor can i call setBitmap because the canvas in a HardwareCanvas and it throws an UnsupportedOperationException if that method is invoked.

So, to recap, i have a canvas and a bitmap, how can i copy the canvas’ content to the bitmap?

Edit
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

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 < 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);
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T23:05:32+00:00Added an answer on June 14, 2026 at 11:05 pm

    You can’t get the bitmap to where the Mapviewcanvas is drawing.

    The approach should be following:

    • First you create your own (empty and transparent) bitmap, with the same size as the MapView canvas
    • Then you create your won canvas for your bitmap (this canvas is the drawing tool that you are using to draw to your bitmap) and you draw the path using it.
    • Finally you draw your bitmap (with the path already drawn) to the MapView canvas.

    However the performance/efficiency issues you are refering are probably due to incorrect design of your existing solution. I can draw paths with 10.000 points without using bitmap (and there are a few good reasons to not use them) in about 3ms in a medium range device.

    There are a few hints on how to approach it, on my answer to this post: Overlay.draw() calls many times. Check also the answer from @shkschneider in the same post.

    –EDITED–

    Just by looking at the code, I can’t figure out why you are getting this warning … But are making it much more complex then it needs to be.

    Organize you code in the following way:

    draw

    The draw()methos only checks if there is a zoom change (if so ask the path to be rebuild) and if map has moved (if so offset path) and finally draws the path.

    @Override
    public void draw(Canvas canvas, MapView mapview, boolean shadow) {
        super.draw(canvas, mapview, shadow);
        if(shadow) return;
        if(mp.getPoints() == null || mp.getPoints().size() < 2) return;
    
        Projection projection = mapview.getProjection();
        int lonSpanNew = projection.fromPixels(0,mapview.getHeight()/2).getLongitudeE6() - 
                projection.fromPixels(mapview.getWidth(),mapview.getHeight()/2).getLongitudeE6();
        if(lonSpanNew != pathInitialLonSpan)
            pathBuild();
        else{ //check if path need to be offset
            projection.toPixels(mp.getPoints().get(0), p1);
            if(p1.x != pathInitialPoint.x || p1.y != pathInitialPoint.y){
                path.offset(p1.x - pathInitialPoint.x, p1.y - pathInitialPoint.y);
                pathInitialPoint.x = p1.x;
                pathInitialPoint.y = p1.y;
            }
    
        }
        canvas.drawPath(path, paint); 
    }
    

    pathBuild

    The path has to be built every time zoom changes. The zoom change detection is done using pathInitialLonSpan as getZoomLevel() is not shyncronous with map zoom animation.

    private void pathBuild(){
        path.rewind(); 
        if(mp.getPoints() == null || mp.getPoints().size() < 2) return;
    
        Projection projection = mapView.getProjection();
        pathInitialLonSpan = projection.fromPixels(0,mapView.getHeight()/2).getLongitudeE6() - 
                projection.fromPixels(mapView.getWidth(),mapView.getHeight()/2).getLongitudeE6();
    
        projection.toPixels(mp.getPoints().get(0), pathInitialPoint);
        path.moveTo(pathInitialPoint.x,pathInitialPoint.y); 
    
        for(int i=1; i<mp.getPoints().size(); i++){
            projection.toPixels(mp.getPoints().get(i), p1);
            int distance2 = (pPrev.x - p1.x) * (pPrev.x - p1.x) + (pPrev.y - p1.y) * (pPrev.y - p1.y); 
            if(distance2 > 9){
                path.lineTo(p1.x,p1.y);
                pPrev.set(p1.x, p1.y);
            }
        }
    

    Some objects (i.e. p1, pPrev, etc) are defined at class level to avoid creating new ones everytime the methos runs.

    Note: I’ve changed the variable names to fit the ones you are using. I hope I’ve not made any mistake, but you should be able to figure that out.

    Regards.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an application that uses the mapview-overlay-manager code to draw map markers on
I have a MapView in my app and am drawing a few circle overlays
I love the new Drawing library for Google Maps v3.7, but I have the
I have a MapView that works properly and is setup, the overlay items being
I have an overlay that I created with a width of 700px and height
I have an overlay that I want to hide on mousedown outside it. Here
I have a overlay delay on my html page, if the page couldnt load
I have two overlay options in my map: a MKCircleOverlay and a MKPolygonOverlay.The first
i have setup an overlay script to enable me to display an overlay popup
I have added an overlay to the map and changed colors of the overlay.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.