tiles not working but new map data provider exists in theory

This commit is contained in:
stopflock
2025-08-09 13:50:10 -05:00
parent 01e8ebfdbb
commit 3dca7d5751
9 changed files with 232 additions and 16 deletions
@@ -0,0 +1,58 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:latlong2/latlong.dart';
import 'package:flutter_map/flutter_map.dart';
import '../../models/camera_profile.dart';
import '../../models/osm_camera_node.dart';
import '../../app_state.dart';
/// Fetches cameras from the Overpass OSM API for the given bounds and profiles.
Future<List<OsmCameraNode>> camerasFromOverpass({
required LatLngBounds bounds,
required List<CameraProfile> profiles,
UploadMode uploadMode = UploadMode.production,
}) async {
if (profiles.isEmpty) return [];
final nodeClauses = profiles.map((profile) {
final tagFilters = profile.tags.entries
.map((e) => '["${e.key}"="${e.value}"]')
.join('\n ');
return '''node\n $tagFilters\n (${bounds.southWest.latitude},${bounds.southWest.longitude},\n ${bounds.northEast.latitude},${bounds.northEast.longitude});''';
}).join('\n ');
const String prodEndpoint = 'https://overpass-api.de/api/interpreter';
final query = '''
[out:json][timeout:25];
(
$nodeClauses
);
out body 250;
''';
try {
print('[camerasFromOverpass] Querying Overpass...');
print('[camerasFromOverpass] Query:\n$query');
final resp = await http.post(Uri.parse(prodEndpoint), body: {'data': query.trim()});
print('[camerasFromOverpass] Status: ${resp.statusCode}, Length: ${resp.body.length}');
if (resp.statusCode != 200) {
print('[camerasFromOverpass] Overpass failed: ${resp.body}');
return [];
}
final data = jsonDecode(resp.body) as Map<String, dynamic>;
final elements = data['elements'] as List<dynamic>;
print('[camerasFromOverpass] Retrieved elements: ${elements.length}');
return elements.whereType<Map<String, dynamic>>().map((e) {
return OsmCameraNode(
id: e['id'],
coord: LatLng(e['lat'], e['lon']),
tags: Map<String, String>.from(e['tags'] ?? {}),
);
}).toList();
} catch (e) {
print('[camerasFromOverpass] Overpass exception: $e');
return [];
}
}
@@ -0,0 +1,40 @@
import 'dart:math';
import 'dart:io';
import 'package:http/http.dart' as http;
/// Fetches a tile from OSM, with in-memory retries/backoff.
/// Returns tile image bytes, or throws on persistent failure.
Future<List<int>> fetchOSMTile({
required int z,
required int x,
required int y,
}) async {
final url = 'https://tile.openstreetmap.org/$z/$x/$y.png';
const int maxAttempts = 3;
int attempt = 0;
final random = Random();
final delays = [
0,
3000 + random.nextInt(1000) - 500,
10000 + random.nextInt(4000) - 2000
];
while (true) {
try {
attempt++;
final resp = await http.get(Uri.parse(url));
if (resp.statusCode == 200) {
return resp.bodyBytes;
} else {
throw HttpException('Failed to fetch tile $z/$x/$y: status ${resp.statusCode}');
}
} catch (e) {
if (attempt >= maxAttempts) {
print("[fetchOSMTile] Failed for $z/$x/$y after $attempt attempts: $e");
rethrow;
}
final delay = delays[attempt - 1].clamp(0, 60000);
print("[fetchOSMTile] Attempt $attempt for $z/$x/$y failed: $e. Retrying in ${delay}ms.");
await Future.delayed(Duration(milliseconds: delay));
}
}
}