Как сосредоточиться на местоположении на картах Google, учитывая, что взгляд на него сверху?
Фон
Предположим, что у меня есть вид Google maps, а другой вид поверх него, который покрывает его часть, скрывая некоторое содержимое карты.
Проблема
Мне нужно сделать "камеру" на карте, сфокусироваться и иметь маркер на координате, но пусть все это будет в середине видимой части карты.
Что-то вроде этого:
![введите описание изображения здесь]()
Исходный код фокусировался на центре всего экрана, делая маркер почти невидимым (поскольку его вид снизу).
Вещь, я не могу найти правильный способ установить правильное значение для координаты Y самой карты (что означает широта).
Что я пробовал
Я попробовал, учитывая высоту представления снизу, и координату, на которую я положил маркер, для вычисления дельта (но, конечно, не изменить сам маркер):
final float neededZoom = 6.5f;
int bottomViewHeight = bottomView.getHeight();
LatLng posToFocusOn = ...;
final Point point = mMap.getProjection().toScreenLocation(posToFocusOn);
final float curZoom = mMap.getCameraPosition().zoom;
point.y += bottomViewHeight * curZoom / neededZoom;
posToFocusOn = mMap.getProjection().fromScreenLocation(point);
final CameraUpdate cameraPosition = CameraUpdateFactory.newCameraPosition(new Builder().target(posToFocusOn).zoom(neededZoom).build());
К сожалению, это фокусируется выше маркера.
Вопрос
Что случилось с тем, что я написал? Что я могу сделать, чтобы исправить это?
Ответы
Ответ 1
ok, я нашел обходное решение, которое, я думаю, работает на всех устройствах (тестировалось по 3, каждое с различным разрешением и размером экрана):
Я измерил, сколько пикселей (а затем преобразовано в DP) изменение одной степени имеет на самом марке.
Из этого я измерил высоту каждого вида и вычислил дельту, необходимую для перемещения камеры.
В моем случае это так (предположим, что масштаб составляет 6,5 фут):
//measured as 223 pixels on Nexus 5, which has xxhdpi, so divide by 3
final float oneDegreeInPixels = convertDpToPixels( 223.0f / 3.0f);
final float mapViewCenter = mapViewHeight / 2.0f;
final float bottomViewHeight = ...;
final float posToFocusInPixelsFromTop = (mapViewHeight - bottomViewHeight) / 2.0f ;// can optionally add the height of the view on the top area
final float deltaLatDegreesToMove = (mapViewCenter - posToFocusInPixelsFromTop) / oneDegreeInPixels;
LatLng posToFocusOn = new LatLng(latitude - deltaLatDegreesToMove, longitude);
final CameraUpdate cameraPosition = CameraUpdateFactory.newCameraPosition(new Builder().target(posToFocusOn).zoom(neededZoom).build());
И это сработало.
Интересно, можно ли его настроить для поддержки любого значения масштабирования.
Ответ 2
Ваш код почти прав, но он идет выше маркера, потому что вы принимаете во внимание bottomViewHeight
при вычислении point.y
вместо bottomViewHeight/2
(Когда размер вашего представления составляет 200 пикселей, вам нужно всего лишь вытеснить карту 100px для его повторного использования):
point.y += (bottomViewHeight / 2) * curZoom / neededZoom;
Update:
Это более общий подход. taht учитывает границы карт и вычисляет новые границы карт в соответствии с высотой вашего bottomView
. Это независимое масштабирование.
public void recenter() {
LatLngBounds mapBounds = mMap.getProjection().getVisibleRegion().latLngBounds;
Point nothEastPoint = mMap.getProjection().toScreenLocation(mapBounds.northeast);
Point souhWestPoint = mMap.getProjection().toScreenLocation(mapBounds.southwest);
Point newNorthEast = new Point(nothEastPoint.x, nothEastPoint.y + bottomView.getHeight() / 2);
Point newSouhWestPoint = new Point(souhWestPoint.x, souhWestPoint.y + bottomView.getHeight() / 2);
LatLngBounds newBounds = LatLngBounds.builder()
.include(mMap.getProjection().fromScreenLocation(newNorthEast))
.include(mMap.getProjection().fromScreenLocation(newSouhWestPoint))
.build();
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(newBounds, 0));
}
Обратите внимание, что каждый раз, когда вы вызываете recenter()
, карта будет перемещаться.