25-10-5/1
This commit is contained in:
@@ -6,6 +6,7 @@ import 'dart:math' as math;
|
||||
import 'dart:ui';
|
||||
import 'dart:convert';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:Intaleq/constant/univeries_polygon.dart';
|
||||
@@ -22,7 +23,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_polyline_algorithm/google_polyline_algorithm.dart';
|
||||
// import 'package:google_polyline_algorithm/google_polyline_algorithm.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:location/location.dart';
|
||||
import 'package:Intaleq/constant/colors.dart';
|
||||
@@ -52,6 +53,7 @@ import '../functions/launch.dart';
|
||||
import '../functions/package_info.dart';
|
||||
import '../functions/secure_storage.dart';
|
||||
import '../payment/payment_controller.dart';
|
||||
import 'decode_polyline_isolate.dart';
|
||||
import 'deep_link_controller.dart';
|
||||
import 'device_tier.dart';
|
||||
import 'vip_waitting_page.dart';
|
||||
@@ -1035,7 +1037,7 @@ class MapPassengerController extends GetxController {
|
||||
if (isBeginRideFromDriverRunning) return; // Prevent duplicate streams
|
||||
isBeginRideFromDriverRunning = true;
|
||||
|
||||
Timer.periodic(const Duration(seconds: 1), (timer) async {
|
||||
Timer.periodic(const Duration(seconds: 2), (timer) async {
|
||||
try {
|
||||
var res = await CRUD().get(
|
||||
link: AppLink.getRideStatusBegin, payload: {'ride_id': rideId});
|
||||
@@ -1138,13 +1140,14 @@ class MapPassengerController extends GetxController {
|
||||
|
||||
Map<String, dynamic> tripData =
|
||||
box.read(BoxName.tripData) as Map<String, dynamic>;
|
||||
final points = decodePolyline(
|
||||
tripData["routes"][0]["overview_polyline"]["points"]);
|
||||
String pointsString =
|
||||
(tripData["routes"][0]["overview_polyline"]["points"]);
|
||||
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
double lat = points[i][0].toDouble();
|
||||
double lng = points[i][1].toDouble();
|
||||
polylineCoordinates.add(LatLng(lat, lng));
|
||||
List<LatLng> decodedPoints =
|
||||
await compute(decodePolylineIsolate, pointsString);
|
||||
// decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
|
||||
for (int i = 0; i < decodedPoints.length; i++) {
|
||||
polylineCoordinates.add(decodedPoints[i]);
|
||||
}
|
||||
var polyline = Polyline(
|
||||
polylineId: const PolylineId('begin trip'),
|
||||
@@ -1819,6 +1822,7 @@ class MapPassengerController extends GetxController {
|
||||
await getCarsLocationByPassengerAndReloadMarker(
|
||||
box.read(BoxName.carType), reloadDuration);
|
||||
// await getNearestDriverByPassengerLocation();
|
||||
currentTimeSearchingCaptainWindow = 0;
|
||||
driversStatusForSearchWindow = 'We are search for nearst driver'.tr;
|
||||
if (isDriversDataValid()) {
|
||||
driversFound = true;
|
||||
@@ -2142,8 +2146,9 @@ class MapPassengerController extends GetxController {
|
||||
} else if (rideStatusDelayed == 'Apply' ||
|
||||
rideStatusDelayed == 'Applied') {
|
||||
isApplied = true;
|
||||
rideAppliedFromDriver(isApplied);
|
||||
timer.cancel();
|
||||
rideAppliedFromDriver(isApplied);
|
||||
// timer.cancel();
|
||||
// Close stream after applying
|
||||
} else if (attemptCounter >= maxAttempts ||
|
||||
rideStatusDelayed == 'waiting') {
|
||||
@@ -2186,7 +2191,7 @@ class MapPassengerController extends GetxController {
|
||||
rideAppliedFromDriver(bool isApplied) async {
|
||||
await getUpdatedRideForDriverApply(rideId);
|
||||
NotificationController().showNotification(
|
||||
'Accepted Ride'.tr,
|
||||
'Accepted Ride',
|
||||
'$driverName ${'accepted your order at price'.tr} ${totalPassenger.toStringAsFixed(1)} ${'with type'.tr} ${box.read(BoxName.carType)}',
|
||||
'ding');
|
||||
if (box.read(BoxName.carType) == 'Speed' ||
|
||||
@@ -2306,7 +2311,7 @@ class MapPassengerController extends GetxController {
|
||||
// driversToken.remove(driverToken);
|
||||
// for (var i = 1; i < driversToken.length; i++) {
|
||||
firebaseMessagesController.sendNotificationToDriverMAP(
|
||||
'Order Accepted'.tr,
|
||||
'Order Accepted',
|
||||
'$driverName${'Accepted your order'.tr}',
|
||||
driverToken.toString(),
|
||||
[],
|
||||
@@ -3514,57 +3519,71 @@ class MapPassengerController extends GetxController {
|
||||
|
||||
/// تحويل نصف قطر بالكيلومتر إلى دلتا درجات عرض
|
||||
|
||||
double _haversineKm(double lat1, double lon1, double lat2, double lon2) {
|
||||
const R = 6371.0; // km
|
||||
final dLat = (lat2 - lat1) * math.pi / 180.0;
|
||||
final dLon = (lon2 - lon1) * math.pi / 180.0;
|
||||
final a = math.sin(dLat / 2) * math.sin(dLat / 2) +
|
||||
math.cos(lat1 * math.pi / 180.0) *
|
||||
math.cos(lat2 * math.pi / 180.0) *
|
||||
math.sin(dLon / 2) *
|
||||
math.sin(dLon / 2);
|
||||
final c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
|
||||
return R * c;
|
||||
}
|
||||
// double _haversineKm(double lat1, double lon1, double lat2, double lon2) {
|
||||
// const R = 6371.0; // km
|
||||
// final dLat = (lat2 - lat1) * math.pi / 180.0;
|
||||
// final dLon = (lon2 - lon1) * math.pi / 180.0;
|
||||
// final a = math.sin(dLat / 2) * math.sin(dLat / 2) +
|
||||
// math.cos(lat1 * math.pi / 180.0) *
|
||||
// math.cos(lat2 * math.pi / 180.0) *
|
||||
// math.sin(dLon / 2) *
|
||||
// math.sin(dLon / 2);
|
||||
// final c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
|
||||
// return R * c;
|
||||
// }
|
||||
|
||||
/// تحويل نصف قطر بالكيلومتر إلى دلتا درجات عرض
|
||||
double _kmToLatDelta(double km) => km / 111.0;
|
||||
// double _kmToLatDelta(double km) => km / 111.0;
|
||||
|
||||
/// تحويل نصف قطر بالكيلومتر إلى دلتا درجات طول (تعتمد على خط العرض)
|
||||
double _kmToLngDelta(double km, double atLat) =>
|
||||
km / (111.320 * math.cos(atLat * math.pi / 180.0)).abs().clamp(1e-6, 1e9);
|
||||
// /// تحويل نصف قطر بالكيلومتر إلى دلتا درجات طول (تعتمد على خط العرض)
|
||||
// double _kmToLngDelta(double km, double atLat) =>
|
||||
// km / (111.320 * math.cos(atLat * math.pi / 180.0)).abs().clamp(1e-6, 1e9);
|
||||
|
||||
/// حساب درجة التطابق النصي (كل كلمة تبدأ بها الاسم = 2 نقاط، يحتويها = 1 نقطة)
|
||||
double _relevanceScore(String name, String query) {
|
||||
final n = name.toLowerCase();
|
||||
final parts =
|
||||
query.toLowerCase().split(RegExp(r'\s+')).where((p) => p.length >= 2);
|
||||
double s = 0.0;
|
||||
for (final p in parts) {
|
||||
if (n.startsWith(p)) {
|
||||
s += 2.0;
|
||||
} else if (n.contains(p)) {
|
||||
s += 1.0;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
// double _relevanceScore(String name, String query) {
|
||||
// final n = name.toLowerCase();
|
||||
// final parts =
|
||||
// query.toLowerCase().split(RegExp(r'\s+')).where((p) => p.length >= 2);
|
||||
// double s = 0.0;
|
||||
// for (final p in parts) {
|
||||
// if (n.startsWith(p)) {
|
||||
// s += 2.0;
|
||||
// } else if (n.contains(p)) {
|
||||
// s += 1.0;
|
||||
// }
|
||||
// }
|
||||
// return s;
|
||||
// }
|
||||
// الدالة الرئيسية لجلب الأماكن من السيرفر وترتيبها
|
||||
// انسخ هذه الدوال والصقها داخل كلاس الكنترولر الخاص بك
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// --== الدالة الرئيسية للبحث ==--
|
||||
// -----------------------------------------------------------------
|
||||
/// الدالة الرئيسية لجلب الأماكن من السيرفر وترتيبها
|
||||
// انسخ هذه الدوال والصقها داخل كلاس الكنترولر الخاص بك
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// --== الدالة الرئيسية للبحث ==--
|
||||
// -----------------------------------------------------------------
|
||||
/// الدالة الرئيسية لجلب الأماكن من السيرفر وترتيبها
|
||||
Future<void> getPlaces() async {
|
||||
// افترض وجود `placeDestinationController` و `passengerLocation` و `CRUD()` معرفة في الكنترولر
|
||||
final q = placeDestinationController.text.trim();
|
||||
if (q.isEmpty) {
|
||||
if (q.isEmpty || q.length < 3) {
|
||||
// يفضل عدم البحث قبل 3 أحرف
|
||||
placesDestination = [];
|
||||
update();
|
||||
update(); // افترض أنك تستخدم GetX أو أي State Management آخر
|
||||
return;
|
||||
}
|
||||
|
||||
final lat = passengerLocation.latitude;
|
||||
final lng = passengerLocation.longitude;
|
||||
|
||||
// نصف قطر البحث بالكيلومتر (عدّل حسب رغبتك)
|
||||
// نصف قطر البحث بالكيلومتر
|
||||
const radiusKm = 200.0;
|
||||
|
||||
// حساب الباوند الصحيح (درجات، وليس 2.2 درجة ثابتة)
|
||||
// حساب النطاق الجغرافي (Bounding Box) لإرساله للسيرفر
|
||||
final latDelta = _kmToLatDelta(radiusKm);
|
||||
final lngDelta = _kmToLngDelta(radiusKm, lat);
|
||||
|
||||
@@ -3574,6 +3593,7 @@ class MapPassengerController extends GetxController {
|
||||
final lngMax = lng + lngDelta;
|
||||
|
||||
try {
|
||||
// استدعاء الـ API (تأكد من أن AppLink.getPlacesSyria يشير للسكريبت الجديد)
|
||||
final response = await CRUD().post(
|
||||
link: AppLink.getPlacesSyria,
|
||||
payload: {
|
||||
@@ -3585,59 +3605,106 @@ class MapPassengerController extends GetxController {
|
||||
},
|
||||
);
|
||||
|
||||
// يدعم شكلي استجابة: إما {"...","message":[...]} أو قائمة مباشرة [...]
|
||||
// --- [تم الإصلاح هنا] ---
|
||||
// معالجة الاستجابة من السيرفر بشكل يوافق {"status":"success", "message":[...]}
|
||||
List list;
|
||||
if (response is Map && response['message'] is List) {
|
||||
list = List.from(response['message'] as List);
|
||||
if (response is Map) {
|
||||
if (response['status'] == 'success' && response['message'] is List) {
|
||||
list = List.from(response['message'] as List);
|
||||
} else if (response['status'] == 'failure') {
|
||||
print('Server Error: ${response['message']}');
|
||||
return;
|
||||
} else {
|
||||
print('Unexpected Map shape from server');
|
||||
return;
|
||||
}
|
||||
} else if (response is List) {
|
||||
// للتعامل مع الحالات التي قد يرجع فيها السيرفر قائمة مباشرة
|
||||
list = List.from(response);
|
||||
} else {
|
||||
print('Unexpected response shape');
|
||||
print('Unexpected response shape from server');
|
||||
return;
|
||||
}
|
||||
|
||||
// جهّز الحقول المحتملة للأسماء
|
||||
// --- هنا يبدأ عمل فلاتر: الترتيب النهائي الدقيق ---
|
||||
|
||||
// دالة مساعدة لاختيار أفضل اسم متاح
|
||||
String _bestName(Map p) {
|
||||
return (p['name'] ?? p['name_ar'] ?? p['name_en'] ?? '').toString();
|
||||
return (p['name_ar'] ?? p['name'] ?? p['name_en'] ?? '').toString();
|
||||
}
|
||||
|
||||
// احسب المسافة ودرجة التطابق والنقاط
|
||||
// حساب المسافة والصلة والنقاط النهائية لكل نتيجة
|
||||
for (final p in list) {
|
||||
final plat = double.tryParse(p['latitude']?.toString() ?? '') ?? 0.0;
|
||||
final plng = double.tryParse(p['longitude']?.toString() ?? '') ?? 0.0;
|
||||
final plat = double.tryParse(p['latitude']?.toString() ?? '0.0') ?? 0.0;
|
||||
final plng =
|
||||
double.tryParse(p['longitude']?.toString() ?? '0.0') ?? 0.0;
|
||||
|
||||
final d = _haversineKm(lat, lng, plat, plng);
|
||||
final rel = _relevanceScore(_bestName(p), q);
|
||||
final distance = _haversineKm(lat, lng, plat, plng);
|
||||
final relevance = _relevanceScore(_bestName(p), q);
|
||||
|
||||
// معادلة ترتيب ذكية: مسافة أقل + تطابق أعلى = نقاط أعلى
|
||||
// تضيف +1 لضمان عدم وصول الوزن للصفر عند عدم وجود تطابق
|
||||
final score = (1.0 / (1.0 + d)) * (1.0 + rel);
|
||||
// معادلة الترتيب: (الأولوية للمسافة الأقرب) * (ثم الصلة الأعلى)
|
||||
final score = (1.0 / (1.0 + distance)) * (1.0 + relevance);
|
||||
|
||||
p['distanceKm'] = d;
|
||||
p['relevance'] = rel;
|
||||
p['distanceKm'] = distance;
|
||||
p['relevance'] = relevance;
|
||||
p['score'] = score;
|
||||
}
|
||||
|
||||
// رتّب حسب score تنازليًا، ثم المسافة تصاعديًا كحسم
|
||||
// ترتيب القائمة النهائية حسب النقاط (الأعلى أولاً)
|
||||
list.sort((a, b) {
|
||||
final sa = (a['score'] ?? 0.0) as double;
|
||||
final sb = (b['score'] ?? 0.0) as double;
|
||||
final cmp = sb.compareTo(sa);
|
||||
if (cmp != 0) return cmp;
|
||||
final da = (a['distanceKm'] ?? 1e9) as double;
|
||||
final db = (b['distanceKm'] ?? 1e9) as double;
|
||||
return da.compareTo(db);
|
||||
return sb.compareTo(sa);
|
||||
});
|
||||
|
||||
// خذ أول 10–15 للعرض (اختياري)، أو اعرض الكل
|
||||
placesDestination = list.take(15).toList();
|
||||
Log.print('placesDestination: $placesDestination');
|
||||
placesDestination = list;
|
||||
print('Updated places: $placesDestination');
|
||||
update();
|
||||
} catch (e) {
|
||||
print('Exception in getPlaces: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// --== دوال مساعدة ==--
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
/// تحسب المسافة بين نقطتين بالكيلومتر (معادلة هافرساين)
|
||||
double _haversineKm(double lat1, double lon1, double lat2, double lon2) {
|
||||
const R = 6371.0; // نصف قطر الأرض بالكيلومتر
|
||||
final dLat = (lat2 - lat1) * (pi / 180.0);
|
||||
final dLon = (lon2 - lon1) * (pi / 180.0);
|
||||
final rLat1 = lat1 * (pi / 180.0);
|
||||
final rLat2 = lat2 * (pi / 180.0);
|
||||
|
||||
final a = sin(dLat / 2) * sin(dLat / 2) +
|
||||
cos(rLat1) * cos(rLat2) * sin(dLon / 2) * sin(dLon / 2);
|
||||
final c = 2 * atan2(sqrt(a), sqrt(1 - a));
|
||||
return R * c;
|
||||
}
|
||||
|
||||
/// تحسب درجة تطابق بسيطة بين اسم المكان وكلمة البحث
|
||||
double _relevanceScore(String placeName, String query) {
|
||||
if (placeName.isEmpty || query.isEmpty) return 0.0;
|
||||
final pLower = placeName.toLowerCase();
|
||||
final qLower = query.toLowerCase();
|
||||
if (pLower.startsWith(qLower)) return 1.0; // تطابق كامل في البداية
|
||||
if (pLower.contains(qLower)) return 0.5; // تحتوي على الكلمة
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// تحويل كيلومتر إلى فرق درجات لخط العرض
|
||||
double _kmToLatDelta(double km) {
|
||||
const kmInDegree = 111.32;
|
||||
return km / kmInDegree;
|
||||
}
|
||||
|
||||
/// تحويل كيلومتر إلى فرق درجات لخط الطول (يعتمد على خط العرض الحالي)
|
||||
double _kmToLngDelta(double km, double latitude) {
|
||||
const kmInDegree = 111.32;
|
||||
return km / (kmInDegree * cos(latitude * (pi / 180.0)));
|
||||
}
|
||||
|
||||
// var languageCode;
|
||||
|
||||
// // تحديد اللغة حسب الإدخال
|
||||
@@ -3786,27 +3853,102 @@ class MapPassengerController extends GetxController {
|
||||
// update();
|
||||
// }
|
||||
|
||||
Future getPlacesStart() async {
|
||||
var languageCode = wayPoint0Controller.text;
|
||||
|
||||
// Regular expression to check for English alphabet characters
|
||||
final englishRegex = RegExp(r'[a-zA-Z]');
|
||||
|
||||
// Check if text contains English characters
|
||||
if (englishRegex.hasMatch(languageCode)) {
|
||||
languageCode = 'en';
|
||||
} else {
|
||||
languageCode = 'ar';
|
||||
Future<void> getPlacesStart() async {
|
||||
// افترض وجود `placeDestinationController` و `passengerLocation` و `CRUD()` معرفة في الكنترولر
|
||||
final q = placeStartController.text.trim();
|
||||
if (q.isEmpty || q.length < 3) {
|
||||
// يفضل عدم البحث قبل 3 أحرف
|
||||
placesStart = [];
|
||||
update(); // افترض أنك تستخدم GetX أو أي State Management آخر
|
||||
return;
|
||||
}
|
||||
|
||||
var url =
|
||||
// '${AppLink.googleMapsLink}place/nearbysearch/json?location=${mylocation.longitude}&radius=25000&language=ar&keyword=&key=${placeController.text}${AK.mapAPIKEY}';
|
||||
'${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeStartController.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=250000&language=$languageCode&key=${AK.mapAPIKEY.toString()}';
|
||||
final lat = passengerLocation.latitude;
|
||||
final lng = passengerLocation.longitude;
|
||||
|
||||
var response = await CRUD().getGoogleApi(link: url, payload: {});
|
||||
// نصف قطر البحث بالكيلومتر
|
||||
const radiusKm = 200.0;
|
||||
|
||||
placesStart = response['results'];
|
||||
update();
|
||||
// حساب النطاق الجغرافي (Bounding Box) لإرساله للسيرفر
|
||||
final latDelta = _kmToLatDelta(radiusKm);
|
||||
final lngDelta = _kmToLngDelta(radiusKm, lat);
|
||||
|
||||
final latMin = lat - latDelta;
|
||||
final latMax = lat + latDelta;
|
||||
final lngMin = lng - lngDelta;
|
||||
final lngMax = lng + lngDelta;
|
||||
|
||||
try {
|
||||
// استدعاء الـ API (تأكد من أن AppLink.getPlacesSyria يشير للسكريبت الجديد)
|
||||
final response = await CRUD().post(
|
||||
link: AppLink.getPlacesSyria,
|
||||
payload: {
|
||||
'query': q,
|
||||
'lat_min': latMin.toString(),
|
||||
'lat_max': latMax.toString(),
|
||||
'lng_min': lngMin.toString(),
|
||||
'lng_max': lngMax.toString(),
|
||||
},
|
||||
);
|
||||
|
||||
// --- [تم الإصلاح هنا] ---
|
||||
// معالجة الاستجابة من السيرفر بشكل يوافق {"status":"success", "message":[...]}
|
||||
List list;
|
||||
if (response is Map) {
|
||||
if (response['status'] == 'success' && response['message'] is List) {
|
||||
list = List.from(response['message'] as List);
|
||||
} else if (response['status'] == 'failure') {
|
||||
print('Server Error: ${response['message']}');
|
||||
return;
|
||||
} else {
|
||||
print('Unexpected Map shape from server');
|
||||
return;
|
||||
}
|
||||
} else if (response is List) {
|
||||
// للتعامل مع الحالات التي قد يرجع فيها السيرفر قائمة مباشرة
|
||||
list = List.from(response);
|
||||
} else {
|
||||
print('Unexpected response shape from server');
|
||||
return;
|
||||
}
|
||||
|
||||
// --- هنا يبدأ عمل فلاتر: الترتيب النهائي الدقيق ---
|
||||
|
||||
// دالة مساعدة لاختيار أفضل اسم متاح
|
||||
String _bestName(Map p) {
|
||||
return (p['name_ar'] ?? p['name'] ?? p['name_en'] ?? '').toString();
|
||||
}
|
||||
|
||||
// حساب المسافة والصلة والنقاط النهائية لكل نتيجة
|
||||
for (final p in list) {
|
||||
final plat = double.tryParse(p['latitude']?.toString() ?? '0.0') ?? 0.0;
|
||||
final plng =
|
||||
double.tryParse(p['longitude']?.toString() ?? '0.0') ?? 0.0;
|
||||
|
||||
final distance = _haversineKm(lat, lng, plat, plng);
|
||||
final relevance = _relevanceScore(_bestName(p), q);
|
||||
|
||||
// معادلة الترتيب: (الأولوية للمسافة الأقرب) * (ثم الصلة الأعلى)
|
||||
final score = (1.0 / (1.0 + distance)) * (1.0 + relevance);
|
||||
|
||||
p['distanceKm'] = distance;
|
||||
p['relevance'] = relevance;
|
||||
p['score'] = score;
|
||||
}
|
||||
|
||||
// ترتيب القائمة النهائية حسب النقاط (الأعلى أولاً)
|
||||
list.sort((a, b) {
|
||||
final sa = (a['score'] ?? 0.0) as double;
|
||||
final sb = (b['score'] ?? 0.0) as double;
|
||||
return sb.compareTo(sa);
|
||||
});
|
||||
|
||||
placesStart = list;
|
||||
print('Updated places: $placesDestination');
|
||||
update();
|
||||
} catch (e) {
|
||||
print('Exception in getPlaces: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future getPlacesListsWayPoint(int index) async {
|
||||
@@ -4557,12 +4699,15 @@ class MapPassengerController extends GetxController {
|
||||
data[0]["start_location"]['lat'], data[0]["start_location"]['lng']);
|
||||
|
||||
durationToRide = data[0]['duration']['value'];
|
||||
final points =
|
||||
decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
double lat = points[i][0].toDouble();
|
||||
double lng = points[i][1].toDouble();
|
||||
polylineCoordinates.add(LatLng(lat, lng));
|
||||
final String pointsString =
|
||||
response['routes'][0]["overview_polyline"]["points"];
|
||||
List<LatLng> decodedPoints =
|
||||
await compute(decodePolylineIsolate, pointsString);
|
||||
// decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
|
||||
for (int i = 0; i < decodedPoints.length; i++) {
|
||||
// double lat = decodedPoints[i][0].toDouble();
|
||||
// double lng = decodedPoints[i][1].toDouble();
|
||||
polylineCoordinates.add(decodedPoints[i]);
|
||||
}
|
||||
// Define the northeast and southwest coordinates
|
||||
|
||||
@@ -4609,18 +4754,18 @@ class MapPassengerController extends GetxController {
|
||||
position: LatLng(
|
||||
data[0]["end_location"]['lat'], data[0]["end_location"]['lng']),
|
||||
icon: endIcon,
|
||||
// infoWindow: InfoWindow(
|
||||
// title: endNameAddress,
|
||||
// snippet:
|
||||
// '$distance ${'KM'.tr} ⌛ ${hours > 0 ? '${'Your Ride Duration is '.tr}$hours ${'H and'.tr} $minutes ${'m'.tr}' : '${'Your Ride Duration is '.tr} $minutes ${'m'.tr}'}'),
|
||||
infoWindow: InfoWindow(
|
||||
title: endNameAddress,
|
||||
snippet:
|
||||
'$distance ${'KM'.tr} ⌛ ${hours > 0 ? '${'Your Ride Duration is '.tr}$hours ${'H and'.tr} $minutes ${'m'.tr}' : '${'Your Ride Duration is '.tr} $minutes ${'m'.tr}'}'),
|
||||
),
|
||||
);
|
||||
// // Show info windows automatically
|
||||
// Future.delayed(const Duration(milliseconds: 500), () {
|
||||
// mapController?.showMarkerInfoWindow(const MarkerId('start'));
|
||||
// });
|
||||
// Future.delayed(const Duration(milliseconds: 500), () {
|
||||
// mapController?.showMarkerInfoWindow(const MarkerId('end'));
|
||||
// mapController?.showMarkerInfoWindow(const MarkerId('start'));
|
||||
// });
|
||||
// Future.delayed(const Duration(milliseconds: 500), () {
|
||||
// mapController?.showMarkerInfoWindow(const MarkerId('end'));
|
||||
// });
|
||||
// update();
|
||||
|
||||
@@ -4632,11 +4777,23 @@ class MapPassengerController extends GetxController {
|
||||
false; // الأفضل أن يكون الافتراضي هو الجودة العالية
|
||||
|
||||
// نمرر عدد النقاط المناسب هنا
|
||||
animatePolylineLayered(
|
||||
polylineCoordinates,
|
||||
maxPoints:
|
||||
lowEndMode ? 30 : 150, // 30 نقطة لوضع الأداء، 150 للوضع العادي
|
||||
);
|
||||
if (Platform.isIOS) {
|
||||
animatePolylineLayered(
|
||||
polylineCoordinates,
|
||||
maxPoints:
|
||||
lowEndMode ? 30 : 150, // 30 نقطة لوضع الأداء، 150 للوضع العادي
|
||||
);
|
||||
} else {
|
||||
polyLines.add(Polyline(
|
||||
polylineId: const PolylineId('route'),
|
||||
points: polylineCoordinates,
|
||||
width: 6,
|
||||
color: AppColor.primaryColor,
|
||||
endCap: Cap.roundCap,
|
||||
startCap: Cap.roundCap,
|
||||
jointType: JointType.round,
|
||||
));
|
||||
}
|
||||
|
||||
rideConfirm = false;
|
||||
isMarkersShown = true;
|
||||
@@ -4672,7 +4829,7 @@ class MapPassengerController extends GetxController {
|
||||
|
||||
// 2) رسم متدرّج بطبقات متراكبة (بدون حذف)، برونزي ↔ أخضر، مع zIndex وعرض مختلف
|
||||
Future<void> animatePolylineLayered(List<LatLng> coordinates,
|
||||
{int layersCount = 1, int stepDelayMs = 10, int maxPoints = 150}) async {
|
||||
{int layersCount = 8, int stepDelayMs = 10, int maxPoints = 160}) async {
|
||||
// امسح أي طبقات قديمة فقط الخاصة بالطريق
|
||||
polyLines.removeWhere((p) => p.polylineId.value.startsWith('route_layer_'));
|
||||
update();
|
||||
@@ -4682,8 +4839,8 @@ class MapPassengerController extends GetxController {
|
||||
if (coords.length < 2) return;
|
||||
|
||||
// ألوان مع شفافية خفيفة للتمييز
|
||||
Color bronze([int alpha = 220]) => const Color(0xFFCD7F32).withAlpha(alpha);
|
||||
Color green([int alpha = 220]) => Colors.green.withAlpha(alpha);
|
||||
Color bronze([int alpha = 220]) => AppColor.gold;
|
||||
Color green([int alpha = 220]) => AppColor.primaryColor;
|
||||
|
||||
Color _layerColor(int layer) => (layer % 2 == 0) ? bronze() : green();
|
||||
|
||||
@@ -4818,14 +4975,16 @@ class MapPassengerController extends GetxController {
|
||||
distance = distanceOfDestination + (data[0]['distance']['value']) / 1000;
|
||||
|
||||
update();
|
||||
final points =
|
||||
decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
if (points[i][0].toString() != '') {
|
||||
double lat = points[i][0].toDouble();
|
||||
double lng = points[i][1].toDouble();
|
||||
polylineCoordinatesPointsAll[index].add(LatLng(lat, lng));
|
||||
}
|
||||
// final points =
|
||||
// decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
|
||||
final String pointsString =
|
||||
response['routes'][0]["overview_polyline"]["points"];
|
||||
|
||||
List<LatLng> decodedPoints =
|
||||
await compute(decodePolylineIsolate, pointsString);
|
||||
// decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
|
||||
for (int i = 0; i < decodedPoints.length; i++) {
|
||||
polylineCoordinates.add(decodedPoints[i]);
|
||||
}
|
||||
// Define the northeast and southwest coordinates
|
||||
|
||||
|
||||
Reference in New Issue
Block a user