Files
fitness/mobile/lib/utils/polyline_utility.dart
T
2026-10-04 00:19:45 +03:00

85 lines
2.1 KiB
Dart

import '../models/gps_coordinate.dart';
/// أداة ترميز وفك ترميز Polyline
/// تستخدم خوارزمية Google Encoded Polyline لضغط المسارات بنسبة ~95%
class PolylineUtility {
/// Encode a list of GPS coordinates to a polyline string
static String encode(List<GpsCoordinate> coordinates) {
if (coordinates.isEmpty) return '';
final buffer = StringBuffer();
int prevLat = 0;
int prevLng = 0;
for (final point in coordinates) {
int lat = (point.latitude * 1e5).round();
int lng = (point.longitude * 1e5).round();
_encodeValue(lat - prevLat, buffer);
_encodeValue(lng - prevLng, buffer);
prevLat = lat;
prevLng = lng;
}
return buffer.toString();
}
/// Decode a polyline string back to coordinates
static List<GpsCoordinate> decode(String encoded) {
if (encoded.isEmpty) return [];
final coordinates = <GpsCoordinate>[];
int index = 0;
int lat = 0;
int lng = 0;
while (index < encoded.length) {
lat += _decodeValue(encoded, index);
index = _lastIndex;
if (index >= encoded.length) break;
lng += _decodeValue(encoded, index);
index = _lastIndex;
coordinates.add(GpsCoordinate(
latitude: lat / 1e5,
longitude: lng / 1e5,
timestamp: DateTime.now(), // Polylines don't store timestamps
));
}
return coordinates;
}
// Internal tracking for decode position
static int _lastIndex = 0;
static void _encodeValue(int value, StringBuffer buffer) {
int v = value < 0 ? ~(value << 1) : (value << 1);
while (v >= 0x20) {
buffer.writeCharCode((0x20 | (v & 0x1f)) + 63);
v >>= 5;
}
buffer.writeCharCode(v + 63);
}
static int _decodeValue(String encoded, int startIndex) {
int result = 0;
int shift = 0;
int index = startIndex;
while (index < encoded.length) {
int byte = encoded.codeUnitAt(index) - 63;
index++;
result |= (byte & 0x1f) << shift;
shift += 5;
if (byte < 0x20) break;
}
_lastIndex = index;
return (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
}
}