add latitude and longitude
This commit is contained in:
parent
b22458021b
commit
44a0691e31
@ -85,11 +85,14 @@ class DisplayPictureScreenState extends State<DisplayPictureScreen>
|
||||
}
|
||||
|
||||
Future<void> searchEvents(String json, String imagePath) async {
|
||||
print(json);
|
||||
print(json.replaceAll("'''json", '').replaceAll("'''", ""));
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
||||
Map<String, dynamic> jsonData = jsonDecode(json);
|
||||
Map<String, dynamic> jsonData =
|
||||
jsonDecode(json.replaceAll("```json", '').replaceAll("```", ""));
|
||||
print("json : ${jsonData}");
|
||||
var name = jsonData["name"];
|
||||
print("name : ${name}");
|
||||
var place = jsonData["place"];
|
||||
var accessToken = prefs.getString("access_token") ?? "";
|
||||
|
||||
@ -132,7 +135,7 @@ class DisplayPictureScreenState extends State<DisplayPictureScreen>
|
||||
gemini
|
||||
.textAndImage(
|
||||
text:
|
||||
"Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, description, tags (tableau sans espace), organizers (tableau), start_date et end_date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère",
|
||||
"Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON (sans le caratère json au début de la chaine de caractère) avec les valeurs suivantes : name, place, description, tags (tableau sans espace), organizers (tableau), start_date et end_date sous le format en YYYY-MM-DD HH:mm:ssZ",
|
||||
images: [file.readAsBytesSync()],
|
||||
modelName: "models/gemini-1.5-pro-latest")
|
||||
.then((value) => searchEvents(
|
||||
|
@ -13,6 +13,8 @@ import 'dart:math';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import '../variable/globals.dart' as globals;
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import "Camera.dart";
|
||||
import 'package:camera/camera.dart';
|
||||
|
||||
void main() {
|
||||
initializeDateFormatting("fr_FR", null).then((_) => runApp(const MyApp()));
|
||||
@ -356,6 +358,11 @@ class _MyHomePageState extends State<ListItemMenu> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> popCamera() async {
|
||||
await availableCameras().then((value) => Navigator.push(context,
|
||||
MaterialPageRoute(builder: (_) => Camera(camera: value.first))));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -397,6 +404,12 @@ class _MyHomePageState extends State<ListItemMenu> {
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: popCamera,
|
||||
backgroundColor: Colors.blue,
|
||||
tooltip: 'Recherche',
|
||||
child: const Icon(Icons.photo_camera, color: Colors.white),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -433,7 +446,8 @@ class _MyHomePageState extends State<ListItemMenu> {
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => Divider(),
|
||||
);
|
||||
separatorBuilder: (context, index) {
|
||||
return Divider();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -44,20 +44,21 @@ class UpdateeventImage extends StatefulWidget {
|
||||
class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
with ShowErrorDialog, ShowEventDialog {
|
||||
TextEditingController inputName = TextEditingController();
|
||||
TextEditingController inputAddress = TextEditingController();
|
||||
TextEditingController inputZipCode = TextEditingController();
|
||||
|
||||
TextEditingController inputCity = TextEditingController();
|
||||
TextEditingController inputCountry = TextEditingController();
|
||||
|
||||
TextEditingController inputDate = TextEditingController();
|
||||
TextEditingController inputDesc = TextEditingController();
|
||||
|
||||
TextEditingController inputGeo = TextEditingController();
|
||||
|
||||
TextEditingController startDatepicker = TextEditingController();
|
||||
TextEditingController startTimepicker = TextEditingController();
|
||||
TextEditingController endDatepicker = TextEditingController();
|
||||
TextEditingController endTimepicker = TextEditingController();
|
||||
final _stringTagController = StringTagController();
|
||||
|
||||
List<Map<String, dynamic>> suggestions = [];
|
||||
String geographicalZone = "";
|
||||
|
||||
List<String> initialTags = [];
|
||||
|
||||
final _stringOrgaController = StringTagController();
|
||||
@ -128,10 +129,7 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
Future<void> _updateEvent(BuildContext context) async {
|
||||
var url = Uri.parse("${globals.api}/token");
|
||||
var name = inputName.text;
|
||||
var place = inputAddress.text;
|
||||
var city = inputCity.text;
|
||||
var country = inputCountry.text;
|
||||
var zipCode = inputZipCode.text;
|
||||
var place = inputGeo.text;
|
||||
var description = inputDesc.text;
|
||||
List<String> tags = List<String>.from(_stringTagController.getTags as List);
|
||||
List<String> organizers =
|
||||
@ -150,6 +148,19 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
if (accessToken.isNotEmpty) {
|
||||
try {
|
||||
await dotenv.load();
|
||||
final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? '';
|
||||
final url =
|
||||
'https://api.mapbox.com/geocoding/v5/mapbox.places/${place}.json?access_token=${mapboxAccessToken}&proximity=ip';
|
||||
final response = await http.get(Uri.parse(url));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
|
||||
if (data['features'].isNotEmpty) {
|
||||
final coordinates = data['features'][0]['geometry']['coordinates'];
|
||||
final longitude = coordinates[0]; // Longitude
|
||||
final latitude = coordinates[1]; // Latitude
|
||||
|
||||
final params = {
|
||||
'expiration': '15552000',
|
||||
'key': dotenv.env["IMGBB_API_KEY"],
|
||||
@ -180,7 +191,8 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
var responsePut = await http.put(urlPut,
|
||||
headers: {
|
||||
HttpHeaders.cookieHeader: 'access_token=${accessToken}',
|
||||
HttpHeaders.acceptHeader: 'application/json, text/plain, */*',
|
||||
HttpHeaders.acceptHeader:
|
||||
'application/json, text/plain, */*',
|
||||
HttpHeaders.contentTypeHeader: 'application/json'
|
||||
},
|
||||
body: jsonEncode({
|
||||
@ -188,12 +200,9 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
'place': place,
|
||||
'start_date': startDate,
|
||||
'end_date': endDate,
|
||||
'zip_code': zipCode,
|
||||
'country': country,
|
||||
'city': city,
|
||||
'organizers': organizers,
|
||||
'latitude': '0.0',
|
||||
'longitude': '0.0',
|
||||
'latitude': latitude,
|
||||
'longitude': longitude,
|
||||
'description': description,
|
||||
"imgUrl": imgUrl,
|
||||
"tags": tags
|
||||
@ -246,6 +255,12 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
} else {
|
||||
print("imgbb error : ${status}");
|
||||
}
|
||||
} else {
|
||||
showErrorDialog(context, "Aucune donnée geographique");
|
||||
}
|
||||
} else {
|
||||
showErrorDialog(context, "Mapbox non accessible");
|
||||
}
|
||||
} catch (e) {
|
||||
showErrorDialog(context, "${e}");
|
||||
}
|
||||
@ -255,11 +270,9 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
}
|
||||
|
||||
void start() async {
|
||||
print("events : ${widget.events}");
|
||||
inputName.text = convertNulltoEmptyString(widget.events["name"]);
|
||||
inputCity.text = convertNulltoEmptyString(widget.events["city"]);
|
||||
inputAddress.text = convertNulltoEmptyString(widget.events["address"]);
|
||||
inputZipCode.text = convertNulltoEmptyString(widget.events["zip_code"]);
|
||||
inputCountry.text = convertNulltoEmptyString(widget.events["country"]);
|
||||
inputGeo.text = convertNulltoEmptyString(widget.events["place"]);
|
||||
inputDesc.text = convertNulltoEmptyString(widget.events["description"]);
|
||||
|
||||
DateTime pickedStartDate =
|
||||
@ -286,6 +299,93 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
return value!.isEmpty ? 'Champ requis' : null;
|
||||
}
|
||||
|
||||
Future<void> searchSuggestions(String input) async {
|
||||
await dotenv.load(fileName: ".env"); // Load .env file
|
||||
|
||||
final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? '';
|
||||
final url =
|
||||
'https://api.mapbox.com/geocoding/v5/mapbox.places/${input}.json?access_token=${mapboxAccessToken}&proximity=ip';
|
||||
final response = await http.get(Uri.parse(url));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
setState(() {
|
||||
suggestions = (data['features'] as List)
|
||||
.map((feature) => {
|
||||
'place_name': feature['place_name'],
|
||||
'geometry': feature[
|
||||
'geometry'], // Include geometry for latitude/longitude
|
||||
})
|
||||
.toList();
|
||||
});
|
||||
} else {
|
||||
throw Exception('Failed to load suggestions');
|
||||
}
|
||||
}
|
||||
|
||||
Padding _buildGeographicalZoneSearchField() {
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 15.0, right: 15.0, top: 15, bottom: 0),
|
||||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
controller: inputGeo,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Lieu',
|
||||
border: OutlineInputBorder(),
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
inputGeo.clear(); // Clear the text field
|
||||
geographicalZone = ''; // Reset the geographical zone state
|
||||
suggestions.clear(); // Optionally clear suggestions
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
geographicalZone = value;
|
||||
searchSuggestions(value);
|
||||
});
|
||||
},
|
||||
),
|
||||
if (suggestions.isNotEmpty)
|
||||
Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.blue),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: suggestions.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text(suggestions[index]['place_name']),
|
||||
onTap: () async {
|
||||
final latitude =
|
||||
suggestions[index]['geometry']['coordinates'][1];
|
||||
final longitude =
|
||||
suggestions[index]['geometry']['coordinates'][0];
|
||||
|
||||
setState(() {
|
||||
geographicalZone = suggestions[index]['place_name'];
|
||||
inputGeo.text = geographicalZone;
|
||||
suggestions.clear();
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -323,58 +423,7 @@ class _UpdateeventImageState extends State<UpdateeventImage>
|
||||
hintText: 'Modifier le nom de l\'évènement'),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15.0, right: 15.0, top: 15, bottom: 0),
|
||||
//padding: EdgeInsets.symmetric(horizontal: 15),
|
||||
child: TextFormField(
|
||||
controller: inputAddress,
|
||||
validator: (value) => _validateField(value),
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Adresse',
|
||||
hintText: 'Entrer une adresse'),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15.0, right: 15.0, top: 15, bottom: 0),
|
||||
//padding: EdgeInsets.symmetric(horizontal: 15),
|
||||
child: TextFormField(
|
||||
controller: inputZipCode,
|
||||
validator: (value) => _validateField(value),
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Code postal',
|
||||
hintText: 'Entrer un code postal'),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15.0, right: 15.0, top: 15, bottom: 0),
|
||||
//padding: EdgeInsets.symmetric(horizontal: 15),
|
||||
child: TextFormField(
|
||||
controller: inputCity,
|
||||
validator: (value) => _validateField(value),
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Ville',
|
||||
hintText: 'Entrer une ville'),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15.0, right: 15.0, top: 15, bottom: 0),
|
||||
//padding: EdgeInsets.symmetric(horizontal: 15),
|
||||
child: TextFormField(
|
||||
controller: inputCountry,
|
||||
validator: (value) => _validateField(value),
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Pays',
|
||||
hintText: 'Entrer un pays'),
|
||||
),
|
||||
),
|
||||
_buildGeographicalZoneSearchField(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15.0, right: 15.0, top: 15, bottom: 0),
|
||||
|
Loading…
x
Reference in New Issue
Block a user