0

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

这是我启动应用程序时的样子(它完美地覆盖了整个停车场): 正确

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

此外,当我放大时,它不能很好地对齐。在这种情况下,叠加层比停车场要小一些。(抱歉,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);
    }
}

}

4

1 回答 1

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()每次移动地图或更改缩放级别时都会调用两次,因此尽可能地做到这一点很重要。您可以在下面找到一些建议:

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()值更改,以便能够使用缩放更改动画创建同步路径。

我希望这将有所帮助。

问候。

于 2012-10-24T18:16:53.963 回答