211 lines
6.8 KiB
Dart
211 lines
6.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:geocoding/geocoding.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:cofounderella/models/location.dart';
|
|
|
|
class LocationSelector extends StatefulWidget {
|
|
final Function(MyLocation) onLocationChanged; // Callback function
|
|
|
|
const LocationSelector({super.key, required this.onLocationChanged});
|
|
|
|
@override
|
|
LocationSelectorState createState() => LocationSelectorState();
|
|
}
|
|
|
|
class LocationSelectorState extends State<LocationSelector> {
|
|
final TextEditingController _locationController = TextEditingController();
|
|
String _street = '';
|
|
String _country = '';
|
|
String? _administrativeArea; // DE: Bundesland
|
|
String _city = '';
|
|
String? _subLocality; // DE: Stadtteil
|
|
String? _postalCode;
|
|
double? _latitude;
|
|
double? _longitude;
|
|
String? errorText;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
TextField(
|
|
// onSubmitted: (loc) => {_searchLocation2(loc)},
|
|
controller: _locationController,
|
|
decoration: InputDecoration(
|
|
labelText: 'Enter location',
|
|
suffixIcon: IconButton(
|
|
icon: const Icon(Icons.search),
|
|
onPressed: _searchLocation,
|
|
),
|
|
),
|
|
),
|
|
Text(
|
|
errorText != null ? '$errorText' : '',
|
|
style: const TextStyle(color: Colors.red),
|
|
),
|
|
const SizedBox(height: 20),
|
|
ElevatedButton(
|
|
onPressed: _getCurrentLocation,
|
|
child: const Text('Use Current Position'),
|
|
),
|
|
const SizedBox(height: 20),
|
|
Text('Country: $_country'),
|
|
Text('City: $_city'),
|
|
Text('Postal Code: $_postalCode'),
|
|
Text('Street: $_street'),
|
|
Text('Administrative Area: $_administrativeArea'),
|
|
Text('Latitude: $_latitude'),
|
|
Text('Longitude: $_longitude'),
|
|
],
|
|
);
|
|
}
|
|
|
|
void _searchLocation() async {
|
|
String locationQuery = _locationController.text;
|
|
|
|
if (locationQuery.trim().isEmpty) {
|
|
setState(() {
|
|
errorText = 'Specify an address for the search';
|
|
_street = '';
|
|
_country = '';
|
|
_city = '';
|
|
_subLocality = null;
|
|
_postalCode = null;
|
|
_administrativeArea = null;
|
|
_latitude = null;
|
|
_longitude = null;
|
|
});
|
|
return;
|
|
}
|
|
|
|
try {
|
|
List<Location> locations = await locationFromAddress(locationQuery);
|
|
if (locations.isNotEmpty) {
|
|
// Take first match
|
|
Location firstLocation = locations.first;
|
|
|
|
// Extract country and city information
|
|
List<Placemark> placeMarks = await placemarkFromCoordinates(
|
|
firstLocation.latitude, firstLocation.longitude);
|
|
if (placeMarks.isNotEmpty) {
|
|
Placemark placeMark = placeMarks.first;
|
|
setState(() {
|
|
_latitude = firstLocation.latitude;
|
|
_longitude = firstLocation.longitude;
|
|
_street = '${placeMark.street}';
|
|
_country = placeMark.country!;
|
|
_city = placeMark.locality!;
|
|
_subLocality = placeMark.subLocality;
|
|
_postalCode = placeMark.postalCode;
|
|
_administrativeArea = placeMark.administrativeArea;
|
|
errorText = null;
|
|
});
|
|
// location is found, trigger callback
|
|
widget.onLocationChanged(MyLocation(
|
|
street: _street,
|
|
country: _country,
|
|
administrativeArea: _administrativeArea,
|
|
locality: _city,
|
|
subLocality: _subLocality,
|
|
postalCode: _postalCode,
|
|
latitude: _latitude,
|
|
longitude: _longitude,
|
|
));
|
|
} else {
|
|
setState(() {
|
|
// should placeMarks be empty return latitude and longitude anyway
|
|
_latitude = firstLocation.latitude;
|
|
_longitude = firstLocation.longitude;
|
|
errorText = null;
|
|
});
|
|
}
|
|
} else {
|
|
setState(() {
|
|
errorText = 'Location $locationQuery not found';
|
|
_street = '';
|
|
_country = '';
|
|
_city = '';
|
|
_subLocality = null;
|
|
_postalCode = null;
|
|
_administrativeArea = null;
|
|
_latitude = null;
|
|
_longitude = null;
|
|
});
|
|
}
|
|
} catch (e) {
|
|
setState(() {
|
|
errorText = 'Error searching location $locationQuery: $e';
|
|
_street = '';
|
|
_country = '';
|
|
_city = '';
|
|
_subLocality = null;
|
|
_postalCode = null;
|
|
_administrativeArea = null;
|
|
_latitude = null;
|
|
_longitude = null;
|
|
});
|
|
}
|
|
}
|
|
|
|
/// Determine users position using geolocator package
|
|
void _getCurrentLocation() async {
|
|
bool serviceEnabled;
|
|
LocationPermission permission;
|
|
|
|
try {
|
|
// Test if location services are enabled.
|
|
serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
|
if (!serviceEnabled) {
|
|
// Location services are not enabled don't continue
|
|
// accessing the position and request users of the
|
|
// App to enable the location services.
|
|
return Future.error('Location services are disabled.');
|
|
}
|
|
|
|
permission = await Geolocator.checkPermission();
|
|
if (permission == LocationPermission.denied) {
|
|
permission = await Geolocator.requestPermission();
|
|
if (permission == LocationPermission.denied) {
|
|
// Permissions are denied, next time you could try
|
|
// requesting permissions again (this is also where
|
|
// Android's shouldShowRequestPermissionRationale
|
|
// returned true. According to Android guidelines
|
|
// your App should show an explanatory UI now.
|
|
return Future.error('Location permissions are denied');
|
|
}
|
|
}
|
|
|
|
if (permission == LocationPermission.deniedForever) {
|
|
// Permissions are denied forever, handle appropriately.
|
|
return Future.error(
|
|
'Location permissions are permanently denied, we cannot request permissions.');
|
|
}
|
|
} catch (e) {
|
|
print('Error getting location permission: $e');
|
|
}
|
|
|
|
try {
|
|
// When we reach here, permissions are granted and we can
|
|
// continue accessing the position of the device.
|
|
Position position = await Geolocator.getCurrentPosition(
|
|
desiredAccuracy: LocationAccuracy.high);
|
|
|
|
List<Placemark> placeMarks =
|
|
await placemarkFromCoordinates(position.latitude, position.longitude);
|
|
if (placeMarks.isNotEmpty) {
|
|
Placemark placeMark = placeMarks.first;
|
|
setState(() {
|
|
_street = placeMark.street!;
|
|
_country = placeMark.country!;
|
|
_city = placeMark.locality!;
|
|
_latitude = position.latitude;
|
|
_longitude = position.longitude;
|
|
});
|
|
}
|
|
} catch (e) {
|
|
print('Error getting current location: $e');
|
|
}
|
|
}
|
|
}
|