feat: add vehicle customization, Arabic search normalization, and smooth movement interpolation

This commit is contained in:
Hamza-Ayed
2026-09-19 12:34:25 +03:00
parent 43ad2e0ad4
commit 55830beee8
16 changed files with 2295 additions and 393 deletions
@@ -4,6 +4,7 @@ import 'package:http/http.dart' as http;
import 'package:intaleq_maps/intaleq_maps.dart';
import '../../core/constants/api_constants.dart';
import '../../core/utils/polyline_decoder.dart';
import '../../core/utils/arabic_search_normalizer.dart';
import '../../core/services/location_service.dart';
import '../models/route_model.dart';
import '../models/place_model.dart';
@@ -149,6 +150,7 @@ class MapSaasRepository {
String country = 'jordan',
}) async {
final center = userLocation ?? const LatLng(ApiConstants.defaultLat, ApiConstants.defaultLng);
final normalizedQuery = ArabicSearchNormalizer.normalize(query);
List<PlaceModel> places = [];
// 1. Try MapSaaS Primary Geocoding Search Endpoint (Within 50 km)
@@ -221,7 +223,7 @@ class MapSaasRepository {
} catch (_) {}
}
// 3. Strict 50 km radius enforcement and proximity sorting
// 3. Strict 50 km radius enforcement
final filteredPlaces = places.where((p) {
final distM = LocationService.instance.calculateDistance(
center,
@@ -230,8 +232,14 @@ class MapSaasRepository {
return distM <= ApiConstants.maxSearchRadiusMeters;
}).toList();
// Sort by proximity ascending (closest first)
// 4. Smart Ranking: exact text match priority + proximity ascending
filteredPlaces.sort((a, b) {
final matchA = ArabicSearchNormalizer.matches(a.name, normalizedQuery);
final matchB = ArabicSearchNormalizer.matches(b.name, normalizedQuery);
if (matchA && !matchB) return -1;
if (!matchA && matchB) return 1;
final distA = LocationService.instance.calculateDistance(
center,
LatLng(a.latitude, a.longitude),