如何使相机居中,使标记位于屏幕底部? (Google map api V2 Android)
当点击一个标记时,摄像机的默认行为是将其居中在屏幕上,但是因为我通常在信息窗口中有很长的文字描述,所以实际改变摄像机位置以便标记位于底部(使屏幕中心的信息窗口)。 我认为我应该可以通过覆盖onMarkerClick函数来做到这一点(如果此函数返回true,则默认行为被取消)
@Override public boolean onMarkerClick(final Marker marker) { // Google sample code comment : We return false to indicate that we have not // consumed the event and that we wish // for the default behavior to occur (which is for the camera to move // such that the // marker is centered and for the marker's info window to open, if it // has one). marker.showInfoWindow(); CameraUpdate center= CameraUpdateFactory.newLatLng(new LatLng(XXXX, XXXX)); mMap.moveCamera(center);//my question is how to get this center // return false; return true; }
编辑:
问题解决使用接受的答案的步骤,代码如下:
@Override public boolean onMarkerClick(final Marker marker) { //get the map container height LinearLayout mapContainer = (LinearLayout) findViewById(R.id.map_container); container_height = mapContainer.getHeight(); Projection projection = mMap.getProjection(); LatLng markerLatLng = new LatLng(marker.getPosition().latitude, marker.getPosition().longitude); Point markerScreenPosition = projection.toScreenLocation(markerLatLng); Point pointHalfScreenAbove = new Point(markerScreenPosition.x, markerScreenPosition.y - (container_height / 2)); LatLng aboveMarkerLatLng = projection .fromScreenLocation(pointHalfScreenAbove); marker.showInfoWindow(); CameraUpdate center = CameraUpdateFactory.newLatLng(aboveMarkerLatLng); mMap.moveCamera(center); return true; }
感谢您的帮助^ ^
我可能稍后编辑这个答案来提供一些代码,但我认为可以工作的是这样的:
- 获取点击标记的
LatLng
( LatLng M )。 - 使用
Projection.toScreenLocation(LatLng)
方法将LatLng M转换为Point
( Point M )。 这会给出设备显示屏上标记的位置(以像素为单位)。 - 计算点M上方一个点( 新点 )的位置,以地图高度的一半计算。
- 将新点转换回
LatLng
并将其放在地图上。
在这里寻找我如何获得地图高度的答案。
// googleMap is a GoogleMap object // view is a View object containing the inflated map // marker is a Marker object Projection projection = googleMap.getProjection(); LatLng markerPosition = marker.getPosition(); Point markerPoint = projection.toScreenLocation(markerPosition); Point targetPoint = new Point(markerPoint.x, markerPoint.y - view.getHeight() / 2); LatLng targetPosition = projection.fromScreenLocation(targetPoint); googleMap.animateCamera(CameraUpdateFactory.newLatLng(targetPosition), 1000, null);
是的,使用投影类。 进一步来说:
获取地图投影:
Projection projection = map.getProjection();
获取标记的位置:
LatLng markerLocation = marker.getPosition();
将位置传递给Projection.toScreenLocation()方法:
Point screenPosition = projection.toScreenLocation(markerLocation);
像这样,您可以将标记相对于中心或围绕屏幕移动
Point mappoint = googleMap.getProjection().toScreenLocation(new LatLng(latitude, longitude)); mappoint.set(mappoint.x, mappoint.y-30); googleMap.animateCamera(CameraUpdateFactory.newLatLng(googleMap.getProjection().fromScreenLocation(mappoint)));
我更喜欢拉里·麦肯齐的答案,它不依赖于屏幕投影(即mProjection.toScreenLocation()),我的猜测是当地图缩放级别低时,投影分辨率会变差,这使我有时无法获得准确位置。 所以,基于谷歌地图规范的计算必将解决问题。
以下是将标记从底部移动到屏幕大小的30%的示例代码。
zoom_lvl = mMap.getCameraPosition().zoom; double dpPerdegree = 256.0*Math.pow(2, zoom_lvl)/170.0; double screen_height = (double) mapContainer.getHeight(); double screen_height_30p = 30.0*screen_height/100.0; double degree_30p = screen_height_30p/dpPerdegree; LatLng centerlatlng = new LatLng( latlng.latitude + degree_30p, latlng.longitude ); mMap.animateCamera( CameraUpdateFactory.newLatLngZoom( centerlatlng, 15 ), 1000, null);
我有同样的问题,我尝试了以下完美的工作解决scheme
mMap.setOnMarkerClickListener(new OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { int yMatrix = 200, xMatrix =40; DisplayMetrics metrics1 = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics1); switch(metrics1.densityDpi) { case DisplayMetrics.DENSITY_LOW: yMatrix = 80; xMatrix = 20; break; case DisplayMetrics.DENSITY_MEDIUM: yMatrix = 100; xMatrix = 25; break; case DisplayMetrics.DENSITY_HIGH: yMatrix = 150; xMatrix = 30; break; case DisplayMetrics.DENSITY_XHIGH: yMatrix = 200; xMatrix = 40; break; case DisplayMetrics.DENSITY_XXHIGH: yMatrix = 200; xMatrix = 50; break; } Projection projection = mMap.getProjection(); LatLng latLng = marker.getPosition(); Point point = projection.toScreenLocation(latLng); Point point2 = new Point(point.x+xMatrix,point.y-yMatrix); LatLng point3 = projection.fromScreenLocation(point2); CameraUpdate zoom1 = CameraUpdateFactory.newLatLng(point3); mMap.animateCamera(zoom1); marker.showInfoWindow(); return true; } });
如果你不关心地图放大,只是想要标记在底部,我认为这是一个更简单的解决scheme
double center = mMap.getCameraPosition().target.latitude; double southMap = mMap.getProjection().getVisibleRegion().latLngBounds.southwest.latitude; double diff = (center - southMap); double newLat = marker.getPosition().latitude + diff; CameraUpdate centerCam = CameraUpdateFactory.newLatLng(new LatLng(newLat, marker.getPosition().longitude)); mMap.animateCamera(centerCam);
我做了一点研究,根据文件的地图是正方形,在零缩放级别的宽度和高度是256dp和+/- 85度N / S。 地图宽度随着缩放级别增加,宽度和高度= 256 * 2N dp。 其中N是缩放级别。 所以理论上你可以通过获得地图高度来确定新的位置,并将其除以总共170度以获得每度的dp。 然后在dp中将屏幕高度(或mapview高度)除以2,并将半视图大小转换为纬度。 然后设置你的新的相机点,南纬度多。 我可以添加代码,如果你需要它,但我现在在手机上。
我一直在尝试所有在这里提出的解决scheme,并结合实施。 考虑到地图投影,倾斜,缩放和信息窗口的高度。
它不会真的把标记放在“相机视图”的底部,但是我认为在大多数情况下它可以很好地适应信息窗口和标记中心。
@Override public boolean onMarkerClick(Marker marker) { mIsMarkerClick = true; mHandler.removeCallbacks(mUpdateTimeTask); mLoadTask.cancel(true); getActivity().setProgressBarIndeterminateVisibility(false); marker.showInfoWindow(); Projection projection = getMap().getProjection(); Point marketCenter = projection.toScreenLocation(marker.getPosition()); float tiltFactor = (90 - getMap().getCameraPosition().tilt) / 90; marketCenter.y -= mInfoWindowAdapter.getInfoWindowHeight() / 2 * tiltFactor; LatLng fixLatLng = projection.fromScreenLocation(marketCenter); mMap.animateCamera(CameraUpdateFactory.newLatLng(fixLatLng), null); return true; }
然后,您的自定义适配器将不得不保持一个信息窗口的实例充气视图,以便能够获取其高度。
public int getInfoWindowHeight(){ if (mLastInfoWindoView != null){ return mLastInfoWindoView.getMeasuredHeight(); } return 0; }
任何仍在寻找根据位置坐标来定位相机的人
CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(Lat, Lon)) .zoom(15) .bearing(0) .tilt(45) .build(); map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
积分
经过一些经验,我已经实施了对我来说很好的解决scheme。
DisplayMetrics metrics = new DisplayMetrics(); context.getWindowManager().getDefaultDisplay().getMetrics(metrics); Point targetPoint = new Point(metrics.widthPixels / 2, metrics.heightPixels - metrics.heightPixels / 9); LatLng targetLatlng = map.getProjection().fromScreenLocation(targetPoint); double fromCenterToTarget = SphericalUtil.computeDistanceBetween(map.getCameraPosition().target, targetLatlng); LatLng center = SphericalUtil.computeOffset(new LatLng(location.latitude, location.longitude), fromCenterToTarget/1.2, location.bearing); CameraUpdate camera = CameraUpdateFactory.newLatLng(center); map.animateCamera(camera, 1000, null);
这里。 首先,我们select标记应该移动的屏幕上的物理点。 然后,将其转换为LatLng。 下一步 – 计算从当前标记位置(在中心)到目标的距离。 最后,我们将地图的中心从标记直接移动到计算的距离。