Как центрировать камеру так, чтобы маркер находился в нижней части экрана? (Google map api V2 Android)

При щелчке по маркеру поведение камеры по умолчанию заключается в том, чтобы центрировать ее на экране, но поскольку у меня обычно есть длинное текстовое описание в информационном окне, удобнее фактически изменить положение камеры, чтобы маркер находился на дне (создание информационного windows в центре экрана). Я думаю, что я мог бы это сделать, переопределив функцию 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; } в @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; } 

Спасибо за помощь ^ ^

Я могу отредактировать этот ответ позже, чтобы предоставить некоторый код, но я думаю, что это может сработать:

  1. Получите LatLng ( LatLng M ) щелкнутого маркера.
  2. Преобразование LatLng M в Point ( точка M ) с использованием метода Projection.toScreenLocation(LatLng) . Это дает расположение маркера на дисплее устройства (в пикселях).
  3. Вычислите местоположение точки ( Новая точка ), которая находится выше точки M, на половину высоты карты.
  4. Преобразуйте новую точку обратно в LatLng и 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); 

Да, используйте class Projection. Более конкретно:

Получить outlook карты:

  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 ()). Думаю, разрешение проекции будет ухудшаться, если уровень масштабирования карты низкий, это заставило меня иногда не получить точный должность. Таким образом, расчет на основе спецификации google map определенно решит проблему.

Ниже приведен пример кода перемещения маркера до 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); 

У меня была такая же проблема, я пробовал следующее прекрасно работающее решение

 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; } }); 

Если вам не нравится масштабирование карты и просто нужно, чтобы маркер находился внизу, см. Ниже, я думаю, что это более простое решение

 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 gradleусов N / S. Ширина карты увеличивается с уровнем масштабирования, поэтому ширина и высота = 256 * 2N дп. Где N – уровень масштабирования. Поэтому теоретически вы можете определить новое местоположение, получив высоту карты и разделив ее на 170 gradleусов, чтобы получить dp на gradleус. Затем получите высоту экрана (или высоту карты) в dp, разделив ее на две части и преобразуйте размер полувидного изображения в gradleусы широты. Затем установите новую точку камеры, которая находится на многих широтах на юг. Я могу добавить код, если он вам нужен, но я нахожусь на телефоне в данный момент.

Я пробовал все предлагаемые здесь решения и пришел с их совместной реализацией. Учитывая, проекция карты, наклона, увеличения и высоты информационного windows.

Он действительно не помещает маркер в нижней части «камеры», но я думаю, что в большинстве случаев он хорошо освещает информационное окно и центр маркеров.

 @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; } 

И тогда ваш пользовательский адаптер должен будет поддерживать экземпляр информационного windows с инфляционным окном, чтобы иметь возможность получать его высоту.

 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)); 

кредиты

После некоторого опыта я реализовал решение, которое подходит для меня.

 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); 

Вот. Сначала мы выбираем физическую точку на экране, где маркер должен быть перемещен. Затем преобразуйте его в LatLng. Следующий шаг – рассчитать расстояние от текущей позиции маркера (в центре) до цели. Наконец, мы перемещаем центр карты прямо от маркера к расчетному расстоянию.

  • Активность запуска Android от службы
  • Использование DiskLruCache в android 4.0 не предусматривает метод openCache
  • SecurityException: caller uid XXXX отличается от идентификатора аутентификатора
  • java.lang.NoClassDefFoundError: com.google.firebase.FirebaseOptions
  • Как периодически проверять подключение к Интернету в целом приложении?
  • Преимущества использования Bundle вместо прямого намерения putExtra () в Android
  • Фрагмент в ViewPager с использованием FragmentPagerAdapter пуст во второй раз
  • SupportMapFragment.getmap () возвращает null
  • Режим киоска в Android
  • Заменить селекторные изображения программно
  • Как сделать телефонный звонок, используя намерение в Android?
  • Давайте будем гением компьютера.