Android Google地图:结合scrollBy和zoomBy实现同时平移和缩放

6
我想同时缩放和滚动一个GoogleMap对象。但是,如果我只使用两个moveCamera调用(一个接一个地),似乎只有第二个调用会生效。
另一种方法是传递一个CameraPosition,但不幸的是,CameraPosition构造函数没有接受处理滚动量的参数(与缩放级别无关),而只接受要移动到哪个纬度/经度的参数。
有没有一些巧妙的方式来组合/连接CameraUpdate对象,以便我可以发出一条同时执行平移和缩放的moveCamera命令?
我认为这样的事情是可能的,因为当你触摸地图时就可以做到。您可以放下两个手指,通过同时移动它们来实现缩放和平移。
2个回答

5
看起来您最好的选择是修改调用 GoogleMap.getCameraPosition() 时返回的 CameraPosition 对象。但是,您不能仅仅将 CameraPosition 对象的纬度和经度增加滚动的像素数量。您需要获取 CameraPosition 的 LatLng 坐标,使用 Projection 类将其转换为 Point 对象,修改 Point,然后再将其转换回 LatLng 对象。
例如:
GoogleMap map; // This is your GoogleMap object
int dx; // X distance scrolled
int dy; // Y distance scrolled
float dz; // Change in zoom level
float originalZoom;

CameraPosition position = map.getCameraPosition();
Project projection = map.getProjection();

LatLng mapTarget = position.target;
originalZoom = position.zoom;

Point mapPoint = projection.toScreenLocation(mapTarget);
mapPoint.x += dx;
mapPoint.y += dy;
mapTarget = projection.fromScreenLocation(mapPoint);

CameraPosition newPosition = new CameraPosition(position)
                                  .target(mapTarget)
                                  .zoom(originalZoom+dz)
                                  .build();

map.moveCamera(CameraUpdateFactory.newCameraPosition(newPosition));

哦,我喜欢这个。我会试一试并回复你的。谢谢你的想法! - aardvarkk
所以...这真的非常接近了。也许这是我们能做到的最好的了?但目前的问题是缩放始终以地图中心为焦点进行缩放。在我的应用程序中,有一个小光标可以在X、Y和Z轴上移动,您可以控制它。如果关闭缩放,则此解决方案在滚动时非常有效。但是当启用缩放时,当您尝试在地图边缘缩放时,效果不正确,因为它会朝向光标位置而不是中心进行缩放。再次说明,这可能是最好的选择,因此我可能会采用它! - aardvarkk
我认为我基本上需要带有焦点的“缩放”功能才能使这个工作方式符合我的要求...但是再次强调,我认为这可能是最接近的解决方案? - aardvarkk
因为我正在尝试同时缩放和滚动,所以我不能使用地图暴露的滚动和缩放功能,因为它们会相互“冲突”。交互方式不是基于触摸的--我正在使用外部控件来移动地图,所以触摸控件正常工作的事实对我不适用。 - aardvarkk
没错,但这样我也不能使用scrollBy,因为它们会互相“冲突”。似乎只有一个生效,而另一个不生效。 - aardvarkk
显示剩余5条评论

1
这里有一个方法 newLatLngZoom (LatLng latLng, float zoom),它将缩放到位于latLng的点。对于需要缩放到偏离中心点P的情况,需要使用一些数学计算才能实现。
为了反向思考问题,我们知道在缩放后地图中心点C的屏幕坐标,因此我们知道C的LatLng。需要将此LatLng传递给newLatLngZoom方法,以便将其居中到点P并使P与之前相同(根据我们定义的问题,缩放到P)。因此,需要找到缩放前C的屏幕坐标。
假设缩放前的缩放值是z1,缩放后是z1 + dz。Google地图API指出,在缩放级别N下,世界的宽度大约为256*2^N dp。因此,缩放前世界的宽度为256*2^z1,缩放后为256*2^(z1 + dz)
我们还知道,在缩放前后,P到C的距离与整个世界的比率不会改变。缩放后,C的坐标就是您地图视图的中心点,这是已知的。假设缩放前C的坐标为(Cx,Cy),那么我们可以得出以下方程:(Px-Cx)/ 256 * 2 ^ z1 =(Px-C'x)/ 256 * 2 ^(z1 + dz)(Py-Cy)/ 256 * 2 ^ z1 =(Py-C'y)/ 256 * 2 ^(z1 + dz)。我忽略了宽高比,因为在解方程时会被消除。
解出方程得到Cx和Cy的值,并将该值用作newLatLngZoom中的参数。如果您想添加平移并且知道需要平移的dx dy值,则只需计算缩放后地图中的dx' dy',并将其添加到C中即可。

只是好奇,这与创建具有latLng目标和zoom缩放的CameraPosition,然后使用CameraUpdateFactory创建指向此位置/缩放的CameraUpdate有何不同? CameraUpdateFactory.newLatLngZoom()只是创建新的CameraPosition,然后创建指向该位置的CameraUpdate的快捷方式,还是还有其他内容? - ertemplin
CameraUpdateFactory.newLatLngZoom()与创建CameraPosition然后执行CameraUpdate是相同的。 - Hcling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接