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