Skip to content

Commit

Permalink
support raster tiles from PmTilesVectorTileProvider
Browse files Browse the repository at this point in the history
Vector tiles can have raster layers. This change
adds support for TileProviderType.raster to
PmTilesVectorTileProvider.

Optional support for ignoring missing tiles was
removed, since there is no good way to return an
empty raster tile. Instead, library support for
missing tiles via ProviderException is leveraged.

Updated tests.
  • Loading branch information
greensopinion committed Feb 19, 2024
1 parent 2cad8bc commit 11d458a
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 39 deletions.
5 changes: 1 addition & 4 deletions example/lib/vector_map_tiles_pmtiles/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ class VectorMapTilesPmTilesPage extends StatelessWidget {
logger: kDebugMode ? const vtr.Logger.console() : null,
);

final _futureTileProvider = PmTilesVectorTileProvider.fromSource(
tileSource,
silenceTileNotFound: true,
);
final _futureTileProvider = PmTilesVectorTileProvider.fromSource(tileSource);

VectorMapTilesPmTilesPage({super.key});

Expand Down
38 changes: 13 additions & 25 deletions vector_map_tiles_pmtiles/lib/src/vector_tile_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,26 @@ import 'package:flutter/foundation.dart';
import 'package:pmtiles/pmtiles.dart';
import 'package:vector_map_tiles/vector_map_tiles.dart';

/// Use this [TileProvider] to provide raster tiles from a PMTiles archive.
/// Use this [VectorTileProvider] to provide vector or raster tiles from a
/// PMTiles archive.
///
/// Note that this tile provider only supports vector tiles (mvt / pbf).
class PmTilesVectorTileProvider extends VectorTileProvider {
final PmTilesArchive archive;
@override
final TileProviderType type;

/// Create a tile provider directly with a [PmTilesArchive] from the
/// pmtiles package.
PmTilesVectorTileProvider.fromArchive(
this.archive, {
this.silenceTileNotFound = !kDebugMode,
});

/// Set to true if [TileNotFoundException]s should not be visible in the
/// console.
///
/// By default this is disabled in debug mode and enabled else.
final bool silenceTileNotFound;
PmTilesVectorTileProvider.fromArchive(this.archive,
{this.type = TileProviderType.vector});

/// Create a tile provider by specifying the source of the PMTiles file.
///
/// [source] can either be a URL or path on your file system.
static Future<PmTilesVectorTileProvider> fromSource(
String source, {
bool silenceTileNotFound = !kDebugMode,
}) async {
static Future<PmTilesVectorTileProvider> fromSource(String source,
{TileProviderType type = TileProviderType.vector}) async {
final archive = await PmTilesArchive.from(source);
return PmTilesVectorTileProvider.fromArchive(
archive,
silenceTileNotFound: silenceTileNotFound,
);
return PmTilesVectorTileProvider.fromArchive(archive, type: type);
}

/// The maximum zoom level that the tile provider supports.
Expand All @@ -51,11 +40,10 @@ class PmTilesVectorTileProvider extends VectorTileProvider {
final data = await archive.tile(tileId);
return Uint8List.fromList(data.bytes());
} on TileNotFoundException {
if (silenceTileNotFound) {
return Uint8List(0);
} else {
rethrow;
}
throw ProviderException(
message: 'Not found: $tile',
retryable: Retryable.none,
statusCode: 404);
}
}
}
2 changes: 1 addition & 1 deletion vector_map_tiles_pmtiles/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies:
flutter:
sdk: flutter
pmtiles: ^1.2.0
vector_map_tiles: ^7.0.1
vector_map_tiles: ^7.3.0
vector_tile_renderer: ^5.2.0

dev_dependencies:
Expand Down
23 changes: 14 additions & 9 deletions vector_map_tiles_pmtiles/test/pmtiles_tile_provider_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ Future<void> main() async {
final mockPmTiles = MockPmTilesArchive();
final provider = PmTilesVectorTileProvider.fromArchive(mockPmTiles);
expect(provider.archive, equals(mockPmTiles));
expect(provider.type, TileProviderType.vector);
});
test('Create tile provider from source', () async {
const source =
'https://raw.githubusercontent.com/protomaps/PMTiles/main/spec/v3/protomaps(vector)ODbL_firenze.pmtiles';
final provider = await PmTilesVectorTileProvider.fromSource(source);
expect(provider.type, TileProviderType.vector);
expect(
provider.archive.centerPosition.latitude,
closeTo(43.779779, 0.001),
Expand All @@ -25,7 +27,6 @@ Future<void> main() async {
provider.archive.centerPosition.longitude,
closeTo(11.2414827, 0.001),
);
expect(provider.silenceTileNotFound, isFalse);
expect(provider.maximumZoom, equals(14));
expect(provider.minimumZoom, equals(0));
expect(
Expand All @@ -34,23 +35,27 @@ Future<void> main() async {
);
await expectLater(
provider.provide(TileIdentity(10, 1, 1)),
throwsA(isA<TileNotFoundException>()),
throwsA(isA<ProviderException>()),
);
});
test('Create silenced tile provider', () async {
test('Ignores tiles that are not found', () async {
const source =
'https://raw.githubusercontent.com/protomaps/PMTiles/main/spec/v3/protomaps(vector)ODbL_firenze.pmtiles';
final provider = await PmTilesVectorTileProvider.fromSource(
source,
silenceTileNotFound: true,
);
final provider = await PmTilesVectorTileProvider.fromSource(source);
expect(
await provider.provide(TileIdentity(0, 0, 0)),
isA<Uint8List>(),
);
await expectLater(
await provider.provide(TileIdentity(10, 1, 1)),
equals(Uint8List(0)),
provider.provide(TileIdentity(10, 1, 1)),
throwsA(isA<ProviderException>()),
);
});

test('Accepts a type', () async {
final mockPmTiles = MockPmTilesArchive();
final provider = PmTilesVectorTileProvider.fromArchive(mockPmTiles,
type: TileProviderType.raster);
expect(provider.type, TileProviderType.raster);
});
}

0 comments on commit 11d458a

Please sign in to comment.