getSpeedLimit method
Fetches speed limit for given location (lat, lon) with intelligent rate-limiting.
Layer 1: In-flight lock (prevents duplicate simultaneous requests)
Layer 2: Time cooldown check (minInterval)
Layer 3: Distance threshold check (minDistanceMeters)
Layer 4: Segment ID (ogc_fid) caching
Implementation
Future<SpeedLimitResult?> getSpeedLimit(LatLng location) async {
final now = DateTime.now();
// Layer 1: In-flight lock
if (_isFetching) {
return _cachedResult;
}
// Layer 2: Time cooldown check
if (_lastFetchTime != null && now.difference(_lastFetchTime!) < minInterval) {
return _cachedResult;
}
// Layer 3: Distance threshold check
if (_lastFetchLocation != null) {
final distMoved = NavigationMathUtils.haversineDistance(
_lastFetchLocation!,
location,
);
if (distMoved < minDistanceMeters && _cachedResult != null) {
return _cachedResult;
}
}
_isFetching = true;
try {
final baseUrl = PowerMapSDK.baseUrl;
final headers = await PowerMapSDK.getServiceHeaders();
final uri = Uri.parse('$baseUrl/api/v2/map/speed-limit').replace(
queryParameters: {
'lat': location.latitude.toString(),
'lon': location.longitude.toString(),
},
);
final response = await _client.get(uri, headers: headers).timeout(
const Duration(seconds: 5),
);
if (response.statusCode == 200) {
final Map<String, dynamic> jsonMap = json.decode(response.body);
final result = SpeedLimitResult.fromJson(jsonMap);
// Layer 4: Segment ID (ogc_fid) check
_lastFetchTime = now;
_lastFetchLocation = location;
_lastOgcFid = result.ogcFid ?? _lastOgcFid;
_cachedResult = result;
return result;
} else {
if (kDebugMode) {
print('SpeedLimitService API response error: ${response.statusCode}');
}
}
} catch (e) {
if (kDebugMode) {
print('SpeedLimitService error fetching speed limit: $e');
}
} finally {
_isFetching = false;
}
return _cachedResult;
}