Как сделать прозрачный фон карты с помощью CARTO mobile SDK

Я хочу показать другой вид под картой (например, анимацию), и мне нужно сделать карту частично прозрачной для этого. Как я могу сделать это с CARTO Mobile SDK?

1 ответ

Решение

Хорошо, спасибо за вопрос, на самом деле это была не самая тривиальная задача.

Детали зависят от того, какие части карты вы хотите сделать прозрачными. Предположим, вы хотите, чтобы морские районы были прозрачными. По сути, у вас есть четыре разных уровня, которые должны быть прозрачными:

  1. Водный слой базовой карты
  2. Цвет земли базовой карты (технически цвет фона карты)
  3. Цвет фона GLView
  4. Фоновое растровое изображение MapView

Мои примеры фрагментов в Swift, но должны быть легко конвертируемыми в другие языки.

В Mobile SDK от Carto земля на самом деле имеет сплошной фоновый цвет, покрывающий всю карту, вода помещается поверх нее в виде синих (или темных) цветных полигонов. Поэтому, если вы хотите сделать слой воды прозрачным, вам также нужно сделать фон карты прозрачным, но это также создает прозрачную землю. Чтобы избежать этого, вам нужно "раскрасить" сушу несколькими полигонами; обычные векторные плитки не имеют покрытия земли, но мы создали специальный набор плиток в учетной записи mapbox, который вы можете использовать как VectorTileLayer:

    // Purple land for visibility. You probably want to keep it white
    let css = "#land-polygons { polygon-fill: #826DBA; polygon-opacity: 1.0;}"
    // Load the land layer (polygons) from a tileset in MapBox
    let url = "https://a.tiles.mapbox.com/v4/jaakl.landpolygons-mz12/{z}/{x}/{y}.vector.pbf?access_token=YOUR_MAPBOX_TOKEN"

    let baseSource = NTHTTPTileDataSource(minZoom: 0, maxZoom: 12, baseURL: url)

    let baseDecoder = NTMBVectorTileDecoder(cartoCSSStyleSet: NTCartoCSSStyleSet(cartoCSS: css))
    let baseLayer = NTVectorTileLayer(dataSource: baseSource, decoder: baseDecoder)

    contentView!.mapView?.getLayers().add(baseLayer)

Теперь, когда у вас есть цветной участок земли, вы бы добавили еще один слой с реальной базовой картой. Для этого нам нужен настроенный стиль базовой карты - с прозрачной водой / морем - и в комплекте с вашим приложением. Стиль Carto's Voyager доступен здесь.

Разархивируйте его и внесите следующие изменения в следующие файлы:

hydro.mss:

@water: transparent;// desaturate(#A0DBE6,26%);
@water_shadow: transparent; // rgb(210,234,237);

style.mss:

Map {
  background-color: transparent;

Сожмите файлы (убедитесь, что в zip нет папки, иначе SDK не найдет никаких файлов) и добавьте новый стиль к вашему assets папка (если Android) или где угодно (если iOS).

Теперь вы можете загрузить свой стиль из файла ресурсов следующим образом:

    let baseDecoder = NTMBVectorTileDecoder(cartoCSSStyleSet: NTCartoCSSStyleSet(cartoCSS: css))
    let baseLayer = NTVectorTileLayer(dataSource: baseSource, decoder: baseDecoder)
    contentView!.mapView?.getLayers().add(baseLayer)

    let data = NTAssetUtils.loadAsset("cartostyles-custom.zip")
    let package = NTZippedAssetPackage(zip: data)
    let styleSet = NTCompiledStyleSet(assetPackage: package)

    let source = NTCartoOnlineTileDataSource(source: "carto.streets")
    let decoder = NTMBVectorTileDecoder(compiledStyleSet: styleSet)

    let layer = NTVectorTileLayer(dataSource: source, decoder: decoder)
    contentView!.mapView!.getLayers().add(layer)

Затем установите прозрачный фон вашего GlView, и установите фоновое растровое изображение карты в null, и вы готовы к работе:

    // Set clear background for our GLView
    mapView?.backgroundColor = UIColor.clear

    // Ensure that there's no background bitmap
    mapView?.getOptions().setBackgroundBitmap(nil)

Когда вы разрабатываете Android, вам также нужно добавить следующие две строки для прозрачного фона NTMapView для правильной визуализации, иначе он останется черным:

mapView.setZOrderOnTop(true);
mapView.getHolder().setFormat(PixelFormat.RGBA_8888);

Здесь я установил фон родительских просмотров на красный. Теперь я вижу следующее при отображении MapView:

Другие вопросы по тегам