缩放时的叠加行为

时间:2012-10-24 14:58:01

标签: android google-maps android-mapview overlays

我遇到覆盖问题。我在地图上绘制了一个多边形叠加层,但是,当我放大或缩小时,边缘不再与我想要的位置对齐。我该如何解决这个问题?

这是我启动应用程序时的样子(它完全覆盖整个停车场): Correct

这是我缩小时的样子(边缘不再与停车场对齐。覆盖层看起来比停车场大一点): Zoomed out

此外,当我放大时,它不能很好地对齐。在这种情况下,叠加比停车场小一点。 (抱歉,stackoverflow不允许我发布更多2个链接)

有关如何解决此问题的任何建议?

以下是代码:

private Projection projection; 
private List<Overlay> mapOverlays;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MapView mapView = (MapView) findViewById(R.id.mapView); 
    mapView.setBuiltInZoomControls(true);

    MapController mc = mapView.getController();
    mc.setZoom(17); 
    mc.animateTo(new GeoPoint((int)(32.734248*1E6), (int)(-97.113448*1E6)));

    mapOverlays = mapView.getOverlays();        
    projection = mapView.getProjection();
    mapOverlays.add(new MyOverlay());        

    mapView.postInvalidate();
}

@Override
protected boolean isRouteDisplayed() {
    return false;
}

class MyOverlay extends Overlay{

    public MyOverlay(){

    }   

    public void draw(Canvas canvas, MapView mapv, boolean shadow){
        super.draw(canvas, mapv, shadow);

        Paint   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAlpha(100);

        GeoPoint gP1 = new GeoPoint(32733839,-97112976);
        GeoPoint gP2 = new GeoPoint(32733875, -97113448);
        GeoPoint gP3 = new GeoPoint(32734961,-97113455);
        GeoPoint gP4 = new GeoPoint(32734953, -97112962);

        Point p1 = new Point();
        Point p2 = new Point();
        Point p3 = new Point();
        Point p4 = new Point();
        Path path = new Path();

        projection.toPixels(gP1, p1);
        projection.toPixels(gP2, p2);
        projection.toPixels(gP3, p3);
        projection.toPixels(gP4, p4);

        path.moveTo(p1.x, p1.y);
        path.lineTo(p2.x,p2.y);
        path.lineTo(p3.x,p3.y);
        path.lineTo(p4.x,p4.y);

        canvas.drawPath(path, mPaint);
    }
}

}

1 个答案:

答案 0 :(得分:0)

每次缩放变化时,Projection也会发生变化。即使您在不改变变焦的情况下在地图中进行大幅移动,投影也可能会发生变化。

要更正您的代码,您需要添加以下行:

public void draw(Canvas canvas, MapView mapv, boolean shadow){ 
    super.draw(canvas, mapv, shadow); 

    Projection projection = mapv.getProjection();  //Add this line

    Paint   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setColor(Color.RED); 
    mPaint.setStyle(Paint.Style.FILL); 
    mPaint.setAlpha(100); 

    GeoPoint gP1 = new GeoPoint(32733839,-97112976); 
    GeoPoint gP2 = new GeoPoint(32733875, -97113448); 
    GeoPoint gP3 = new GeoPoint(32734961,-97113455); 
    GeoPoint gP4 = new GeoPoint(32734953, -97112962); 

    Point p1 = new Point(); 
    Point p2 = new Point(); 
    Point p3 = new Point(); 
    Point p4 = new Point(); 
    Path path = new Path(); 

    projection.toPixels(gP1, p1); 
    projection.toPixels(gP2, p2); 
    projection.toPixels(gP3, p3); 
    projection.toPixels(gP4, p4); 

    path.moveTo(p1.x, p1.y); 
    path.lineTo(p2.x,p2.y); 
    path.lineTo(p3.x,p3.y); 
    path.lineTo(p4.x,p4.y); 

    canvas.drawPath(path, mPaint); 
} 

您可以移除onCreate()中创建的投影。

- 编辑 -

改进 - 快速获胜

在移动地图或更改缩放级别时,

onDraw()被称为eveytime两次,因此尽可能使其变得非常重要。贝娄,你可以找到一些建议:

private List<Overlay> mapOverlays; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    MapView mapView = (MapView) findViewById(R.id.mapView);  
    mapView.setBuiltInZoomControls(true); 

    MapController mc = mapView.getController(); 
    mc.setZoom(17);  
    mc.animateTo(new GeoPoint((int)(32.734248*1E6), (int)(-97.113448*1E6))); 

    mapOverlays = mapView.getOverlays();         
    mapOverlays.add(new MyOverlay());         

    mapView.postInvalidate(); 
} 

@Override 
protected boolean isRouteDisplayed() { 
    return false; 
} 

class MyOverlay extends Overlay{ 

    //Moved objects that need only one instance to the initialization, to avoid creating a new copy of each every time draw() runs  
    private Paint   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private GeoPoint gP1 = new GeoPoint(32733839,-97112976); 
    private GeoPoint gP2 = new GeoPoint(32733875, -97113448); 
    private GeoPoint gP3 = new GeoPoint(32734961,-97113455); 
    private GeoPoint gP4 = new GeoPoint(32734953, -97112962); 

    private Point p1 = new Point(); 
    private Point p2 = new Point(); 
    private Point p3 = new Point(); 
    private Point p4 = new Point(); 
    private Path path = new Path(); 

    public MyOverlay(){
        //mPaint settings done on class creation, to avoid repeating them on draw() call 
        mPaint.setColor(Color.RED); 
        mPaint.setStyle(Paint.Style.FILL); 
        mPaint.setAlpha(100); 
    }    

    public void draw(Canvas canvas, MapView mapv, boolean shadow){ 
        super.draw(canvas, mapv, shadow); 

        //draw is always called twice, one with shadow equal to true and one to false.
        //This can be used to draw the same image with shadow
        //But you are not using shadows, so you can immediately return half of the calls, and reduce the draw() effort by half
        if(shadow) return;

        Projection projection = mapv.getProjection();

        projection.toPixels(gP1, p1); 
        projection.toPixels(gP2, p2); 
        projection.toPixels(gP3, p3); 
        projection.toPixels(gP4, p4); 

        path.rewind();
        path.moveTo(p1.x,p1.y); 
        path.lineTo(p2.x,p2.y); 
        path.lineTo(p3.x,p3.y); 
        path.lineTo(p4.x,p4.y); 

        canvas.drawPath(path, mPaint); 
    } 
} 

改进 - 更复杂的

我所描述的改进对你当前的叠加来说太过分了。只有你有很大的绘制途径才有意义。

移动地图时,如果没有对其进行控制,则使用上面的代码重新创建路径并在不同的位置重新绘制以与地图对齐。但是你创建的路径与前一个路径大小相同,形状相同,只是在不同的位置。

您可以使用以下方法获得相同的结果:

path.offset(dx, dy);

其中dx, dy是您需要移动路径以使其与地图保持对齐的像素数。当然,您需要跟踪上次偏移路径时地图的位置,这样您就可以将路径偏移到新的地图位置。

如果你有一个包含数千个点的路径,那么离开路径的速度将比重绘它快100倍。

您还需要跟踪缩放级别,因为您仍需要在缩放更改时重新创建路径。您无法使用getCurrentZoomLevel()来执行此操作,因为它与缩放动画不同步。您需要测试longitudeSpan()值更改,才能使用缩放更改动画创建同步路径。

我希望这会有所帮助。

问候。