How to draw lots of markers on a map

2019-05-23 14:44发布

问题:

I'm trying to draw on a map using markers. The problem I'm having is when I try to add lots of them, then I can't get it to run. To illustrate my problem, let's say I want to draw a square made of 900 smaller squares (30x30). By the way, I do need those squares, not just one big square I'm trying to add the markers to an itemizedoverlay, then drawing it.

the code is below. Any suggestion how I could do that? Thank you very much!!

public class MainActivity extends MapActivity {
MapView mapView;
MapController mc;
GeoPoint p;
static Context context;

int k=1;    
List<Overlay> mapOverlays;
MyItemizedOverlay itemizedoverlay;  
int[] xx,yy;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);        
    context = getApplicationContext();        
    mapView = (MapView) findViewById(R.id.mapView);
    mapView.setBuiltInZoomControls(true);        

    mc = mapView.getController();
    String coordinates[] = {"36.186382", "-112.221909"};
    double lat = Double.parseDouble(coordinates[0]);
    double lng = Double.parseDouble(coordinates[1]);
    p = new GeoPoint(
                    (int) (lat * 1E6),
                    (int) (lng * 1E6));
    mc.animateTo(p);
    mc.setZoom(10);

    mapOverlays = mapView.getOverlays();
    Drawable squareM = this.getResources().getDrawable(R.drawable.square);
    itemizedoverlay = new MyItemizedOverlay(squareM);

    int n=0;
    xx = new int[30];
    yy = new int[30];
    while(n<30){
        xx[n]=n;
        yy[n]=n;
        n++;
    }

}

protected void drawNewMarker(GeoPoint p){
    OverlayItem overlayitem = new OverlayItem(p, "", "");
    itemizedoverlay.addOverlay(overlayitem);
    mapOverlays.add(itemizedoverlay);
    mapView.postInvalidate(); 
}

protected void drawNewMarkerD(){
    Point pointP = new Point(0,0);
    mapView.getProjection().toPixels(p, pointP);
    int xoff = 20*k;
    int yoff = 20*k;
    GeoPoint pp = mapView.getProjection().fromPixels(pointP.x + xoff, pointP.y + yoff);

    OverlayItem overlayitem = new OverlayItem(pp, "", "");
    Drawable iconM = this.getResources().getDrawable(R.drawable.icon);
    iconM.setBounds(0,0, 50, 50);
    overlayitem.setMarker(iconM);
    itemizedoverlay.addOverlay(overlayitem);
    mapOverlays.add(itemizedoverlay);
    k++;
    //mapView.postInvalidate(); 
}

@Override
protected boolean isRouteDisplayed() {

    return false;
}


protected void drawGrid(int xoff, int yoff){
    GeoPoint p = newGeoPointFromOffset(xoff, yoff);
    OverlayItem overlayitem = new OverlayItem(p, "", "");
    Drawable marker = this.getResources().getDrawable(R.drawable.grid);
    marker.setBounds(0,0, 15, 15);
    overlayitem.setMarker(marker);
    itemizedoverlay.addOverlay(overlayitem);
    mapOverlays.add(itemizedoverlay);
}

protected GeoPoint newGeoPointFromOffset(int xoff, int yoff){   
    Point screenPointP = new Point(0,0);      
    mapView.getProjection().toPixels(p, screenPointP);  
    int x = 15*xoff;
    int y = 15*yoff;    
    return mapView.getProjection().fromPixels(screenPointP.x + x, screenPointP.y + y);              
}

public boolean onKeyDown(int keyCode, KeyEvent event){
    MapController mc = mapView.getController();
    switch(keyCode){
    case KeyEvent.KEYCODE_3:
        mc.zoomIn();
        break;
    case KeyEvent.KEYCODE_1:
        mc.zoomOut();
        break;
    case KeyEvent.KEYCODE_0:
        drawNewMarker(p);
        break;
    case KeyEvent.KEYCODE_9:    
        for(int r=0;r<30;r++){
            for(int s=0;s<30;s++){
                 drawGrid(r,s);
            }
        }  
        mapView.postInvalidate();           
        break;
    }       
    return super.onKeyDown(keyCode, event);
}       

}

public class MyItemizedOverlay extends ItemizedOverlay{
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private Context mContext;

public MyItemizedOverlay(Drawable defaultMarker) {
    super(boundCenterBottom(defaultMarker));
}

public MyItemizedOverlay(Drawable defaultMarker, Context context) {
      super(defaultMarker);
      mContext = context;
}

public void draw(android.graphics.Canvas canvas, MapView mapView,boolean shadow) {
        super.draw(canvas, mapView, false);
}

public void addOverlay(OverlayItem overlay) {
    mOverlays.add(overlay);
    populate();
}

@Override
protected OverlayItem createItem(int i) {
    return mOverlays.get(i);
}

}

回答1:

There is a limit to the number of overlay items that MapView can handle. There is no official word on what this limit is, but after some while, you will see sluggish behaviour during zoom/pan.

Some solutions are :

  • LazyLoading of MapView
  • Load only as many markers that are visible, do this based on the zoom level and span.
  • 10 overlays with 99 points are faster than 1 overlay with 900 points.