feat: Add Mapy.cz Outdoor (OSM + LIDAR) base map layer

- New MapLayerType.mapyOutdoor with Referer header support
  (tile server rejects requests without mapy.com Referer)
- Headered layers get a dedicated NetworkTileProvider sharing
  the offline tile cache
- Offline region downloads pass layer headers through
  TileDownloadService

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Janez T
2026-06-12 17:28:56 +02:00
parent ba27843166
commit 365bd76cbc
5 changed files with 55 additions and 9 deletions

View File

@@ -12,6 +12,8 @@ enum MapLayerType {
// Kept for stored preference compatibility after MBTiles removal.
vectorMbtiles,
wmsBase,
// Appended last: stored layer preference is the enum index.
mapyOutdoor,
}
class MapLayer {
@@ -21,6 +23,9 @@ class MapLayer {
final String attribution;
final double maxZoom;
/// Extra HTTP headers required by the tile server (e.g. Referer).
final Map<String, String>? headers;
// WMS specific properties
final bool isWms;
final String? wmsBaseUrl;
@@ -36,6 +41,7 @@ class MapLayer {
required this.urlTemplate,
required this.attribution,
required this.maxZoom,
this.headers,
this.isWms = false,
this.wmsBaseUrl,
this.wmsLayers,
@@ -64,6 +70,9 @@ class MapLayer {
case MapLayerType.vectorMbtiles:
// Legacy value kept only for preference migration compatibility.
return name;
case MapLayerType.mapyOutdoor:
// Brand name, not translated.
return name;
case MapLayerType.wmsBase:
// For WMS layers, use the name (will be localized separately)
return name;
@@ -86,6 +95,17 @@ class MapLayer {
maxZoom: 17.49, // OpenTopoMap maximum (just below level 18)
);
/// Mapy.cz outdoor map: OSM data with LIDAR-based shaded relief.
/// The tile server rejects requests without a mapy.com Referer.
static const mapyOutdoor = MapLayer(
type: MapLayerType.mapyOutdoor,
name: 'Mapy.cz Outdoor (OSM + LIDAR)',
urlTemplate: 'https://mapserver.mapy.cz/turist-en/retina/{z}-{x}-{y}',
attribution: '© Seznam.cz, a.s., © OpenStreetMap contributors',
maxZoom: 19,
headers: {'Referer': 'https://mapy.com/'},
);
static const esriWorldImagery = MapLayer(
type: MapLayerType.esriWorldImagery,
name: 'ESRI Satellite',
@@ -160,6 +180,7 @@ class MapLayer {
static const List<MapLayer> allLayers = [
openStreetMap,
openTopoMap,
mapyOutdoor,
esriWorldImagery,
googleHybrid,
googleRoadmap,