feat: city selection now uses haversine radius filtering (10km)
Enrich kerala_pincodes.json with lat/lng for all 463 entries via
pgeocode offline DB (453 exact matches + 10 district centroids).
Update SearchScreen _LocationItem to carry lat/lng fields, load them
from JSON on init, and pass them through every selection path
(_selectWithPincode, _selectAndClose, search result onTap).
Result: selecting Chavakkad (or any Kerala city) now pops
{label, pincode, lat:10.59322, lng:76.0297} → home_screen saves coords
to prefs → getEventsByLocation sends lat/lng to Django → haversine
filtering returns events within 10km radius, expanding to 25/50/100km
if fewer than 6 events found.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -9,13 +9,15 @@ import '../core/utils/error_utils.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:geocoding/geocoding.dart';
|
||||
|
||||
/// Data model for a location suggestion (city + optional pincode).
|
||||
/// Data model for a location suggestion (city + optional pincode + optional coords).
|
||||
class _LocationItem {
|
||||
final String city;
|
||||
final String? district;
|
||||
final String? pincode;
|
||||
final double? lat;
|
||||
final double? lng;
|
||||
|
||||
const _LocationItem({required this.city, this.district, this.pincode});
|
||||
const _LocationItem({required this.city, this.district, this.pincode, this.lat, this.lng});
|
||||
|
||||
String get displayTitle => district != null && district!.isNotEmpty ? '$city, $district' : city;
|
||||
String get displaySubtitle => pincode ?? '';
|
||||
@@ -71,6 +73,8 @@ class _SearchScreenState extends State<SearchScreen> {
|
||||
city: e['city'] as String,
|
||||
district: e['district'] as String?,
|
||||
pincode: e['pincode'] as String?,
|
||||
lat: (e['lat'] as num?)?.toDouble(),
|
||||
lng: (e['lng'] as num?)?.toDouble(),
|
||||
)).toList();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
@@ -106,24 +110,28 @@ class _SearchScreenState extends State<SearchScreen> {
|
||||
});
|
||||
}
|
||||
|
||||
/// Pop with a structured result so home_screen can update both the display
|
||||
/// label AND the pincode / GPS coordinates used for API filtering.
|
||||
void _selectWithPincode(String label, {String? pincode}) {
|
||||
Navigator.of(context).pop(<String, dynamic>{
|
||||
/// Pop with a structured result so home_screen can update the display label,
|
||||
/// pincode, and GPS coordinates used for haversine filtering.
|
||||
void _selectWithPincode(String label, {String? pincode, double? lat, double? lng}) {
|
||||
final result = <String, dynamic>{
|
||||
'label': label,
|
||||
'pincode': pincode ?? 'all',
|
||||
});
|
||||
};
|
||||
if (lat != null && lng != null) {
|
||||
result['lat'] = lat;
|
||||
result['lng'] = lng;
|
||||
}
|
||||
Navigator.of(context).pop(result);
|
||||
}
|
||||
|
||||
void _selectAndClose(String location) {
|
||||
// Legacy path for plain strings — wrap in structured map.
|
||||
// Tries to look up a pincode from the database for the given city name.
|
||||
// Looks up pincode + coordinates from the database for the given city name.
|
||||
final match = _locationDb.cast<_LocationItem?>().firstWhere(
|
||||
(loc) => loc!.city.toLowerCase() == location.toLowerCase() ||
|
||||
loc.displayTitle.toLowerCase() == location.toLowerCase(),
|
||||
orElse: () => null,
|
||||
);
|
||||
_selectWithPincode(location, pincode: match?.pincode);
|
||||
_selectWithPincode(location, pincode: match?.pincode, lat: match?.lat, lng: match?.lng);
|
||||
}
|
||||
|
||||
Future<void> _useCurrentLocation() async {
|
||||
@@ -344,7 +352,7 @@ class _SearchScreenState extends State<SearchScreen> {
|
||||
subtitle: loc.pincode != null && loc.pincode!.isNotEmpty
|
||||
? Text(loc.pincode!, style: TextStyle(color: Colors.grey[500], fontSize: 13))
|
||||
: null,
|
||||
onTap: () => _selectWithPincode(loc.displayTitle, pincode: loc.pincode),
|
||||
onTap: () => _selectWithPincode(loc.displayTitle, pincode: loc.pincode, lat: loc.lat, lng: loc.lng),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user