CARTO移动SDK制作透明地图背景的方法
How to make transparent map background with CARTO mobile SDK
我想在地图下方显示不同的视图(例如一些动画),并且需要为此使地图部分透明。我如何使用 CARTO Mobile SDK 执行此操作?
好的,感谢您的提问,这实际上不是最微不足道的任务。
详情取决于您要使地图的哪些部分透明。假设您希望海域透明。本质上,您有四个不同的级别需要透明:
- 底图的水层
- 底图的土地颜色(技术地图背景颜色)
- GLView 的背景颜色
- MapView 的背景位图
我的示例片段在 Swift 中,但应该可以轻松转换为其他语言。
在 Carto 的 Mobile SDK 中,土地实际上是覆盖整个地图的纯色背景,水作为蓝色(或深色)多边形放置在它上面。所以如果你想让水层透明,你也需要让地图背景透明,但是这也会创建透明的土地。为避免这种情况,您需要 'color' 着陆一些多边形;普通矢量瓦片没有土地覆盖,但我们在 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)
现在您已经为土地区域着色,您可以添加另一个具有真实底图的图层。为此,我们需要一个自定义底图样式 - 具有透明 water/sea - 并将其与您的应用程序捆绑在一起。 Carto 的航海者风格可用 here。
解压缩,并在以下文件中进行以下更改:
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 的背景设置为透明,并将 mapview 背景位图设置为 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 呈现时看到以下内容:
我想在地图下方显示不同的视图(例如一些动画),并且需要为此使地图部分透明。我如何使用 CARTO Mobile SDK 执行此操作?
好的,感谢您的提问,这实际上不是最微不足道的任务。
详情取决于您要使地图的哪些部分透明。假设您希望海域透明。本质上,您有四个不同的级别需要透明:
- 底图的水层
- 底图的土地颜色(技术地图背景颜色)
- GLView 的背景颜色
- MapView 的背景位图
我的示例片段在 Swift 中,但应该可以轻松转换为其他语言。
在 Carto 的 Mobile SDK 中,土地实际上是覆盖整个地图的纯色背景,水作为蓝色(或深色)多边形放置在它上面。所以如果你想让水层透明,你也需要让地图背景透明,但是这也会创建透明的土地。为避免这种情况,您需要 'color' 着陆一些多边形;普通矢量瓦片没有土地覆盖,但我们在 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)
现在您已经为土地区域着色,您可以添加另一个具有真实底图的图层。为此,我们需要一个自定义底图样式 - 具有透明 water/sea - 并将其与您的应用程序捆绑在一起。 Carto 的航海者风格可用 here。
解压缩,并在以下文件中进行以下更改:
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 的背景设置为透明,并将 mapview 背景位图设置为 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 呈现时看到以下内容: