About the MBTiles format

MBTiles is a container format for tiled data. The format is based on the SQLite database engine: each MBTiles file is an SQLite database with at least two tables:

  • A metadata table with information about the file format version, the extent of the data, etc.

  • A table with BLOBs of data for each individual tile

The tiles are always structured in a Web Mercator quadtree tile pyramid. The tiles themselves can contain either images in the JPEG, PNG or WebP format, or vector data encoded in the Google Protocol Buffer format.

LuciadCPillar provides support for the MBTiles format through MbTilesModelDecoderMbTilesModelDecoderMbTilesModelDecoder. This decoder supports both image and vector tiles. See Decoding and visualizing image tiles and Decoding and visualizing vector tiles for more information.

Decoding and visualizing image tiles

Program: Visualizing MBTiles image data
luciad::expected<std::shared_ptr<Model>, ErrorInfo> modelExpected = MbTilesModelDecoder::decode(source);

if (modelExpected.has_value()) {
  auto rasterModel = std::dynamic_pointer_cast<IRasterModel>(*modelExpected);
  if (rasterModel != nullptr) {
    auto rasterLayer = RasterLayer::newBuilder()
        .model(rasterModel)
        .build();
  }

} else {
  ErrorInfo errorInfo = modelExpected.error();
  std::cout << "Failed to decode source '" << source << "' : " << errorInfo.getMessage();
}
try
{
    var model = MbTilesModelDecoder.Decode(source);
    if (model is IRasterModel rasterModel)
    {
        RasterLayer featureTileLayer = RasterLayer.NewBuilder().Model(rasterModel).Build();
    }
}
catch (IOException exception)
{
    Console.Error.WriteLine("Failed to decode source '" + source + "': " + exception.Message);
}
try {
    val model = MbTilesModelDecoder.decode(source)
    if (model is IRasterModel) {
        val rasterLayer = RasterLayer.newBuilder()
            .model(model)
            .build()
    }
} catch (exception: IOException) {
    Log.w("MBTiles", "Failed to decode source '" + source + "': " + exception.message)
}

Decoding and visualizing vector tiles

The MbTilesFeatureLayerMbTilesFeatureLayerMbTilesFeatureLayer uses default styling to visualize the vector data. You can specify your own styling by using the Mapbox style format. For more information about defining Mapbox styles, see the Mapbox style specification.

The MbTilesFeatureLayer::BuilderMbTilesFeatureLayer::BuilderMbTilesFeatureLayer::Builder allows you to specify the path or URL to the style file. For a list of unsupported Mapbox styling options, see the documentation of MbTilesFeatureLayer::Builder::styleMbTilesFeatureLayer::Builder::styleMbTilesFeatureLayer::Builder::style.

Program: Visualizing MBTiles vector data
luciad::expected<std::shared_ptr<Model>, ErrorInfo> modelExpected = MbTilesModelDecoder::decode(source);

if (modelExpected.has_value()) {
  auto featureTileModel = std::dynamic_pointer_cast<IFeatureTileModel>(*modelExpected);
  if (featureTileModel != nullptr) {
    auto featureTileLayer = MbTilesFeatureLayer::newBuilder()
        .model(featureTileModel)
        .style(stylePath)
        .build();
  }

} else {
  ErrorInfo errorInfo = modelExpected.error();
  std::cout << "Failed to decode source '" << source << "' : " << errorInfo.getMessage();
}
try
{
    var model = MbTilesModelDecoder.Decode(source);
    if (model is IFeatureTileModel featureTileModel)
    {
        MbTilesFeatureLayer featureTileLayer = MbTilesFeatureLayer.NewBuilder()
            .Model(featureTileModel)
            .Style(stylePath)
            .Build();
    }
}
catch (IOException exception)
{
    Console.Error.WriteLine("Failed to decode source '" + source + "': " + exception.Message);
}
try {
    val model = MbTilesModelDecoder.decode(source)
    if (model is IFeatureTileModel) {
        val featureTileLayer = MbTilesFeatureLayer.newBuilder()
            .model(model)
            .style(stylePath)
            .build()
    }
} catch (exception: IOException) {
    Log.w("MBTiles", "Failed to decode source '" + source + "': " + exception.message)
}