Цвет фона карты Google для типа карты GoogleMap.MAP_TYPE_NONE - PullRequest
1 голос
/ 28 мая 2020

Я использовал наземное наложение моего плана этажа, добавленного в Google Map. Загружается отлично. Код показан ниже.

override fun onMapReady(map: GoogleMap) {
    mMap = map;

    mMap.setOnGroundOverlayClickListener(this);
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(DEFAULT_LAT_LNG, 1F));
    mMap.setMapType(GoogleMap.MAP_TYPE_NONE);


    mGroundOverlay = mMap.addGroundOverlay(GroundOverlayOptions()
            .image(BitmapDescriptorFactory.fromBitmap(bitmap)).anchor(0F, 1F)
            .position(DEFAULT_LAT_LNG, floorPlanWidth.toFloat(), 
    floorPlanHeight.toFloat()));

    mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(mGroundOverlay.getBounds(), 0))
}

Это приведет к созданию пользовательского интерфейса, как указано ниже.

enter image description here

У меня есть 2 вопроса:

  1. Как изменить цвет фона на цвет по моему выбору?
  2. Как программно увеличивать и уменьшать масштаб? Скажем, я хочу увеличить масштаб на 5F, как только карта загрузится.

1 Ответ

1 голос
/ 03 июня 2020

Для стр. 1 проще всего использовать дополнительный GroundOverlay, который представляет собой solid цветное растровое изображение, заполненное цветом фона вашего наложения на землю. Точно для вашего примера изображение может быть примерно таким (overlay_background.png):

Background overlay

Это изображение вы должны использовать в качестве «фона» GroundOverlay размещено под вашими "этажами" GroundOverlay с.

Чтобы гарантировать, что «фон» GroundOverlay покрывает всю видимую область, вы должны немного масштабировать это изображение поверх наложения «этажей». Вы можете сделать это с помощью .positionFromBounds() метода GroundOverlayOptions. Для получения "фоновых" границ наложения radius, удаленных от center, вы можете использовать такой метод:

public LatLngBounds createBounds(LatLng center, float radius) {
    LatLngBounds bounds = null;
    if (center != null) {
        bounds = new LatLngBounds.Builder()
                .include(SphericalUtil.computeOffset(center, radius * Math.sqrt(2), 45))
                .include(SphericalUtil.computeOffset(center, radius * Math.sqrt(2), 225))
                .build();
    }
    return bounds;
}

где SphericalUtil является частью Maps SDK для Android Utility Library . Как добавить его для проекта, описанного здесь .

Также с помощью метода setLatLngBoundsForCameraTarget() вы можете установить границы обзора камеры немного меньше, чем область наложения «фона», чтобы избежать ситуации когда пользователь прокручивает карту за пределы "фонового" наложения. Вам также необходимо установить минимальный и максимальный уровень масштабирования (через setMinZoomPreference() и setMaxZoomPreference()).

Общая идея описана на рисунке ниже:

Idea description

Для размещения «фона» GroundOverlay под вашими «полами» GroundOverlay s вы можете использовать .setZIndex() метод GroundOverlayOptions или GroundOverlay и установите Z-Index для «фона» GroundOverlay меньше, чем Z-Index «этажей» GroundOverlay например, Z-Index = 1 для «фона» и Z-Index = 2 для перекрытие пола (значение Z-индекса по умолчанию 0).

Таким образом, с исходным кодом, подобным этому:

@Override
public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;

    // calculate borders for "background" overlay
    LatLngBounds borders = createBounds(OVERLAY_CENTER, 1000);

    // constrain the camera target to slightly less bounds.
    LatLngBounds cameraBorders = createBounds(OVERLAY_CENTER, 500);
    mGoogleMap.setLatLngBoundsForCameraTarget(borders);
    mGoogleMap.setMinZoomPreference(18.0f);
    mGoogleMap.setMaxZoomPreference(21.0f);

    GroundOverlayOptions overlayBackground = new GroundOverlayOptions()
            .image(BitmapDescriptorFactory.fromResource(R.drawable.overlay_background))
            .transparency(0.0f)
            .bearing(0)
            .zIndex(1) // NB! set Z-Index for "background" overlay
            .positionFromBounds(borders);

    mGoogleMap.addGroundOverlay(overlayBackground);

    mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NONE);

    GroundOverlayOptions overlayOptions = new GroundOverlayOptions()
            .image(BitmapDescriptorFactory.fromResource(R.drawable.overlay))
            .transparency(0.0f)
            .bearing(0)
            .zIndex(2)  // NB! set Z-Index for "floor" overlay
            .position(OVERLAY_CENTER, 200f);

    GroundOverlay overlay = mGoogleMap.addGroundOverlay(overlayOptions);

    mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(OVERLAY_CENTER, 18.0f));
}

, вы можете получить такой результат:

Overlay background result

Для вопроса п.2. ИМХО, самый простой способ - "эмулировать" внутренние карты с помощью набора перекрытий этажей. В этом случае вы можете отобразить необходимый этаж, добавив на карту соответствующее наложение пола, и показать / скрыть его, используя метод setTransparency(): используйте use setTransparency(1) для всех этажей, которые вы хотите скрыть, и setTransparency(0) для одного этажа, для которого нужно показать. Например, для отображения наложения для этажа № 3:

GroundOverlay floor1Overlay = mGoogleMap.addGroundOverlay(floor1OverlayOptions);
GroundOverlay floor2Overlay = mGoogleMap.addGroundOverlay(floor2OverlayOptions);
GroundOverlay floor3Overlay = mGoogleMap.addGroundOverlay(floor2OverlayOptions);
...
floor1Overlay.setTransparency(1);
floor2Overlay.setTransparency(1);
floor3Overlay.setTransparency(0);

Или вы можете удалить ненужное наложение этажей с карты с помощью метода remove() на GroundOverlay (не на GroundOverlayOptions!) И воссоздайте его снова при необходимости. Для этого нужно сохранить объект перекрытия, когда он был добавлен на карту:

GroundOverlay floor1Overlay = mGoogleMap.addGroundOverlay(floor1OverlayOptions);
...
floor1Overlay.remove();
...