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 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 decode(String encoded) { if (encoded.isEmpty) return []; final coordinates = []; 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); } }