Add WMS support and measurement functionality

- Implemented WMS layer handling for Slovenian aerial imagery and overlays for cadastral parcels and forest roads.
- Added distance measurement feature allowing users to measure distances on the map with long press interactions.
- Updated localization files for Croatian, Italian, and Slovenian languages to include new measurement and WMS-related strings.
- Enhanced the map layer model to support WMS-specific properties.
- Introduced a new tile provider for debugging WMS requests.
- Updated the drawing toolbar to include measurement mode and clear measurement functionality.
- Integrated SharedPreferences to persist overlay visibility states across app sessions.
- Added utility functions for handling the Slovenian coordinate reference system (EPSG:3794).
This commit is contained in:
Janez T
2025-10-27 21:49:58 +01:00
parent a03cc4a363
commit a4dc85d130
29 changed files with 3327 additions and 20 deletions

View File

@@ -57,6 +57,26 @@ class TileCacheService {
);
}
/// Get tile provider for WMS layers with caching support
/// WMS layers require special handling because they use WMSTileLayerOptions
FMTCTileProvider getTileProviderForWms(MapLayer layer) {
if (!_isInitialized) {
throw StateError(
'TileCacheService not initialized. Call initialize() first.',
);
}
if (!layer.isWms) {
throw ArgumentError('Layer must be a WMS layer');
}
// Return the same cached tile provider
// The WMS URL construction is handled by flutter_map's WMSTileLayerOptions
return _store.getTileProvider(
loadingStrategy: BrowseLoadingStrategy.cacheFirst,
cachedValidDuration: const Duration(days: 30),
);
}
Future<void> downloadRegion({
required MapLayer layer,
required LatLngBounds bounds,

View File

@@ -0,0 +1,73 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:http/http.dart' as http;
/// Custom tile provider that logs WMS URLs for debugging
class DebugWmsTileProvider extends TileProvider {
final http.Client httpClient;
DebugWmsTileProvider() : httpClient = http.Client();
@override
ImageProvider getImage(TileCoordinates coordinates, TileLayer options) {
return DebugNetworkTileProvider(
coordinates: coordinates,
options: options,
httpClient: httpClient,
);
}
@override
void dispose() {
httpClient.close();
super.dispose();
}
}
class DebugNetworkTileProvider extends ImageProvider<DebugNetworkTileProvider> {
final TileCoordinates coordinates;
final TileLayer options;
final http.Client httpClient;
const DebugNetworkTileProvider({
required this.coordinates,
required this.options,
required this.httpClient,
});
@override
ImageStreamCompleter loadImage(DebugNetworkTileProvider key, ImageDecoderCallback decode) {
// Get the WMS URL from the tile layer options
final wmsOptions = options.wmsOptions;
if (wmsOptions == null) {
throw Exception('WMSTileLayerOptions is required for DebugWmsTileProvider');
}
// Build the WMS URL
final url = wmsOptions.getUrl(coordinates, 256, false);
// Log the URL for debugging
debugPrint('🌐 WMS Request URL: $url');
// Use NetworkImage to load the tile
return NetworkImage(url, headers: {'User-Agent': 'MeshCore SAR'})
.loadImage(NetworkImage(url), decode);
}
@override
Future<DebugNetworkTileProvider> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<DebugNetworkTileProvider>(this);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is DebugNetworkTileProvider &&
other.coordinates == coordinates &&
other.options == options;
}
@override
int get hashCode => Object.hash(coordinates, options);
}