Android 缩放时的覆盖行为

Android 缩放时的覆盖行为,android,google-maps,android-mapview,overlays,Android,Google Maps,Android Mapview,Overlays,我的覆盖层有问题。我已经在地图上绘制了一个多边形覆盖,但是,当我放大或缩小时,边不再与我希望它们对齐的位置对齐。我怎样才能解决这个问题 下面是我启动应用程序时的样子(它完美地覆盖了整个停车场): 以下是缩小时的效果(边缘不再与停车场对齐。覆盖层看起来比停车场大一点): 而且,当我放大时,它没有很好地对齐。在这种情况下,覆盖层比停车场小一点。(抱歉,stackoverflow不允许我发布超过2个链接) 有没有关于如何解决这个问题的建议 代码如下: private Projection proj

我的覆盖层有问题。我已经在地图上绘制了一个多边形覆盖,但是,当我放大或缩小时,边不再与我希望它们对齐的位置对齐。我怎样才能解决这个问题

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

以下是缩小时的效果(边缘不再与停车场对齐。覆盖层看起来比停车场大一点):

而且,当我放大时,它没有很好地对齐。在这种情况下,覆盖层比停车场小一点。(抱歉,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);
    }
}
私人投影;
私有列表覆盖图;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MapView MapView=(MapView)findViewById(R.id.MapView);
mapView.SetBuilTinZoomControl(真);
MapController mc=mapView.getController();
mc.setZoom(17);
司仪animateTo(新地质点((int)(32.734248*1E6),(int)(-97.113448*1E6));
mapOverlays=mapView.getOverlays();
projection=mapView.getProjection();
添加(新的MyOverlay());
mapView.postInvalidate();
}
@凌驾
受保护的布尔值isRouteDisplayed(){
返回false;
}
类MyOverlay扩展覆盖{
公共MyOverlay(){
}   
公共空白绘制(画布、MapView mapv、布尔阴影){
super.draw(画布、贴图、阴影);
Paint mPaint=新油漆(Paint.ANTI_别名_标志);
mPaint.setColor(Color.RED);
mPaint.setStyle(油漆、样式、填充);
mPaint.setAlpha(100);
地质点gP1=新的地质点(32733839,-97112976);
地质点gP2=新的地质点(32733875,-97113448);
地质点gP3=新的地质点(32734961,-97113455);
地质点gP4=新的地质点(32734953,-97112962);
点p1=新点();
点p2=新点();
点p3=新点();
点p4=新点();
路径路径=新路径();
顶像素(gP1,p1);
顶像素投影(gP2,p2);
顶像素投影(gP3,p3);
顶像素投影(gP4,p4);
路径移动到(p1.x,p1.y);
lineTo路径(p2.x,p2.y);
线路图(p3.x,p3.y);
lineTo(p4.x,p4.y);
canvas.drawPath(路径,mPaint);
}
}

}

每次缩放更改时,
投影也会更改。即使在不更改缩放的情况下在地图中进行大移动,投影也可能会更改

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

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); 
    } 
} 
其中
dx,dy
是移动路径以使其与地图对齐所需的像素数。当然,您需要跟踪上次偏移路径时地图的位置,以便将路径偏移到新地图位置

如果有一条包含数千个点的路径,则偏移该路径的速度将比重新绘制该路径快大约100倍

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

我希望这会有所帮助


问候。

你应该发布一些代码,因为你可能会遇到精度问题。你确定你转换了你的点吗?是的,它们是微度。所有看起来都是正确的(对不起,我错过了微度)。。。我要验证的最后一项是,在更高的缩放级别显式调用view.invalidate/postInvalidate(非ui线程)是否有帮助…我不太确定非ui线程的含义。我添加了mapv.invalidate();在draw方法中的canvas.drawPath之后。这就是你的意思吗?这并不能解决问题,所以我添加了Projection=mapv.getProjection();。mapView用于onCreate()中的mapView。亲爱的@kvother,当有人花时间帮助我并指出我代码中的错误时,我会说“谢谢你的帮助,我已经纠正了你指出的错误”,然后,如果我的代码仍然不能像我预期的那样工作,我会说“尽管如此,我的代码仍然有其他错误,因为现在有以下行为。。。你能帮我找到它们吗?”。在花更多的时间查看你的代码之前,我会等待对发现一个粗略错误的正确理解,我相信你会发现,如果你不表示感谢,没有多少人会花时间帮助你。对不起,我不是故意这样说的(我指责睡眠不足)。我想说的是,我已经做了你建议的更改,但它没有起作用。它没有改变任何东西,应用程序的运行方式也一样。我真的非常感谢你和其他人在这个网站上提供的帮助,我真的不想听起来忘恩负义。因此,请接受我的道歉,并在你访问时再看一眼有机会吗?谢谢。不客气:-)。我注意到您没有关闭路径,但这不应该是问题所在。我会仔细看看,然后再回来找您。您可以做一些事情来提高代码的性能和内存利用率(如果您愿意,我可以与您分享),但没有什么可以被认为是错误的。我已经测试了你的代码,并将其与使用Internet Explorer的google maps的行为进行了比较。如果你打开此链接(这是你的停车场)并更改缩放,你会看到标记将
path.offset(dx, dy);