diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/config.dart | 129 | ||||
-rw-r--r-- | lib/homepage.dart | 191 | ||||
-rw-r--r-- | lib/kuksa/class-provider.dart | 39 | ||||
-rw-r--r-- | lib/kuksa/class.dart | 52 | ||||
-rw-r--r-- | lib/kuksa/config.dart | 47 | ||||
-rw-r--r-- | lib/kuksa/intial-connection.dart | 43 | ||||
-rw-r--r-- | lib/kuksa/onBoarding.dart | 64 | ||||
-rw-r--r-- | lib/kuksa/paths.dart | 11 | ||||
-rw-r--r-- | lib/kuksa/vehicle-methods.dart | 148 | ||||
-rw-r--r-- | lib/main.dart | 29 | ||||
-rw-r--r-- | lib/map/Show-route.dart | 152 | ||||
-rw-r--r-- | lib/map/bottom-card.dart | 55 | ||||
-rw-r--r-- | lib/map/map-response.dart | 65 | ||||
-rw-r--r-- | lib/map/turnNavigation.dart | 231 | ||||
-rw-r--r-- | lib/mapbox.dart | 293 | ||||
-rw-r--r-- | lib/provider.dart | 95 | ||||
-rw-r--r-- | lib/search.dart | 69 |
17 files changed, 1713 insertions, 0 deletions
diff --git a/lib/config.dart b/lib/config.dart new file mode 100644 index 0000000..cda553b --- /dev/null +++ b/lib/config.dart @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter_navigation/kuksa/intial-connection.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:yaml/yaml.dart'; + + +class GetConfig extends ConsumerStatefulWidget { + const GetConfig({Key? key, required this.client}) : super(key: key); + final HttpClient client; + + @override + ConsumerState<GetConfig> createState() => _GetConfigState(); +} + +class _GetConfigState extends ConsumerState<GetConfig> { + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + final configStateProvider = ref.read(ConfigStateprovider.notifier); + + String configFilePath = '/etc/xdg/AGL/nav_config.yaml'; + String mapboxFilePath = '/etc/default/mapboxkey'; + + String keyContent = ""; + + final mapboxKeyFile = File(mapboxFilePath); + + final configFile = File(configFilePath); + configFile.readAsString().then((content) { + final dynamic yamlMap = loadYaml(content); + configStateProvider.update( + hostname: yamlMap['hostname'], + port: yamlMap['port'], + kuksaAuthToken: yamlMap['kuskaAuthToken'], + ); + }); + mapboxKeyFile.readAsString().then((content) { + keyContent = content.split(':')[1].trim(); + if (keyContent.isNotEmpty && keyContent != 'YOU_NEED_TO_SET_IT_IN_LOCAL_CONF') { + configStateProvider.update(mapboxAccessToken: keyContent); + } else { + print("WARNING: Mapbox API Key not found !"); + } + }); + }); + } + + @override + Widget build(BuildContext context) { + final config = ref.watch(ConfigStateprovider); + if (config.hostname == "" || + config.port == 0 || + config.kuksaAuthToken == "" || + config.mapboxAccessToken == "") { + return Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [ + Text("ERROR", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), + Text( + "Something Wrong with config file! Check config.yaml file and restart"), + ], + )), + ); + } + return InitialScreen(client: widget.client); + } +} + +class Config { + Config({ + required this.hostname, + required this.port, + required this.kuksaAuthToken, + required this.mapboxAccessToken, + + }); + final String hostname; + final int port; + final String kuksaAuthToken; + final String mapboxAccessToken; + + Config copywith({ + String? hostname, + int? port, + String? kuksaAuthToken, + String? mapboxAccessToken, + }) => + Config( + hostname: hostname ?? this.hostname, + port: port ?? this.port, + kuksaAuthToken: kuksaAuthToken ?? this.kuksaAuthToken, + mapboxAccessToken: mapboxAccessToken ?? this.mapboxAccessToken, + ); +} + +final ConfigStateprovider = +StateNotifierProvider<ConfigStateNotifier, Config>( + (ref) => ConfigStateNotifier()); + +class ConfigStateNotifier extends StateNotifier<Config> { + ConfigStateNotifier() : super(_initialValue); + static final Config _initialValue = Config( + hostname: "", + port: 0, + kuksaAuthToken: "", + mapboxAccessToken: "", + ); + void update({ + String? hostname, + int? port, + String? kuksaAuthToken, + String? mapboxAccessToken, + }) { + state = state.copywith( + hostname: hostname, + port: port, + kuksaAuthToken: kuksaAuthToken, + mapboxAccessToken: mapboxAccessToken, + ); + } +} diff --git a/lib/homepage.dart b/lib/homepage.dart new file mode 100644 index 0000000..4933741 --- /dev/null +++ b/lib/homepage.dart @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: Apache-2.0 + + +import 'package:flutter/material.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:flutter_navigation/config.dart'; +import 'package:flutter_navigation/kuksa/class-provider.dart'; +import 'package:flutter_navigation/kuksa/class.dart'; +import 'package:flutter_navigation/map/map-response.dart'; +import 'package:flutter_navigation/provider.dart'; +import 'package:flutter_navigation/search.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:latlong2/latlong.dart'; + + +import 'map/Show-route.dart'; + +class MyHomePage extends ConsumerStatefulWidget { + const MyHomePage({Key? key, required this.title}) : super(key: key); + + + final String title; + + @override + ConsumerState<MyHomePage> createState() => _MyHomePageState(); +} + +class _MyHomePageState extends ConsumerState<MyHomePage> { + + + late MapController mapController; + TextEditingController _destinationController = TextEditingController(); + + + + @override + void initState() { + // TODO: implement initState + super.initState(); + mapController = MapController(); + } + + String ConvertToTime(num duration){ + int hour = (duration/3600).toInt(); + int min = (duration%3600).toInt() ; + min = (min/60).toInt(); + String mini = min.toString(); + String Hour = hour.toString(); + String time = "$Hour hr $mini min"; + + return time; + } + + @override + Widget build(BuildContext context) { + + VehicleSignal vehicleSignal = ref.watch(vehicleSignalProvider); + LatLng center = LatLng(vehicleSignal.currentLatitude, vehicleSignal.currentLongitude); + + _destinationController.text = ref.watch(DestinationAdressProvider); + final config = ref.read(ConfigStateprovider); + + + + return Scaffold( + + body: Stack( + children: [ + + FlutterMap( + mapController: mapController, + options: MapOptions( + center: center, + minZoom: 12, + zoom: 12, + + maxZoom: 25.0, + keepAlive: true, + ), + layers: [ + + TileLayerOptions( + urlTemplate: "https://api.mapbox.com/styles/v1/hritik3961/cl7hxzrrf002t15o2j2yh14lm/tiles/256/{z}/{x}/{y}@2x?access_token=${config.mapboxAccessToken}", + additionalOptions: { + "access_token": config.mapboxAccessToken, + + }, + ), + MarkerLayerOptions( + rotate: true, + markers: [ + Marker( + point: center, + width: 70, + height: 70, + builder: (context) => + const Icon( + + Icons.location_pin, + size: 40, + color: Colors.red, + ) + + ), + ], + ), + + ], + ), + Container( + padding: EdgeInsets.all(8), + + alignment: Alignment.topLeft, + child: TextFormField( + + controller: _destinationController, + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder(), + icon: Icon(Icons.location_pin,color: Colors.black,), + hintText: "Choose your destination", + + + ), + + onTap: (){ + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SearchPage(iscurrent: false), + ), + ); + }, + ), + ), + ], + ), + floatingActionButton: FloatingActionButton.extended( + onPressed: () async{ + + + LatLng current = LatLng(vehicleSignal.currentLatitude, vehicleSignal.currentLongitude); + LatLng destination = LatLng(vehicleSignal.destinationLatitude,vehicleSignal.destinationLongitude); + + if(destination != LatLng(0,0)){ + + Map RouteResponse = await getDirectionsAPIResponse(current,destination,ref); + + if(RouteResponse.isNotEmpty){ + List RouteCoordinates = RouteResponse['geometry']['coordinates']; + List<LatLng> polyline =[]; + + for(int i =0; i<RouteCoordinates.length ;i++){ + polyline.add(LatLng((RouteCoordinates[i][1]).toDouble(),(RouteCoordinates[i][0]).toDouble())); + + } + ref.read(polylineprovider.notifier).update(polyline); + Map response = await getAdress(current,ref); + String curradress = response['features'][0]['place_name']; + num duration = RouteResponse['duration']; + String time = ConvertToTime(duration); + + + double distanc = ((RouteResponse['distance']).toDouble()); + int distance = (distanc/1000).toInt(); + + + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => + NavigationHome( polyLine: polyline, CurrAddress: curradress,Duration: time,Distance: distance,))); + + } + + + + } + + + }, + label: const Text('Show Route'), + backgroundColor: Colors.purple, + icon: const Icon(Icons.drive_eta_rounded), + ), + + + ); + } +} diff --git a/lib/kuksa/class-provider.dart b/lib/kuksa/class-provider.dart new file mode 100644 index 0000000..1169f6c --- /dev/null +++ b/lib/kuksa/class-provider.dart @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'class.dart'; + +final vehicleSignalProvider = +StateNotifierProvider<VehicleSignalNotifier, VehicleSignal>( + (ref) => VehicleSignalNotifier(), +); + +class VehicleSignalNotifier extends StateNotifier<VehicleSignal> { + VehicleSignalNotifier() : super(_initialValue); + static final VehicleSignal _initialValue = VehicleSignal( + + currentLatitude: 31.706964, + currentLongitude: 76.933138, + + destinationLatitude: 0, + destinationLongitude: 0, + ); + void update({ + + double? currentLatitude, + double? currentLongitude, + + double? destinationLatitude, + double? destinationLongitude, + }) { + state = state.copyWith( + + currentLatitude: currentLatitude, + currentLongitude: currentLongitude, + + destinationLatitude: destinationLatitude, + destinationLongitude: destinationLongitude, + ); + } +}
\ No newline at end of file diff --git a/lib/kuksa/class.dart b/lib/kuksa/class.dart new file mode 100644 index 0000000..2d64ac9 --- /dev/null +++ b/lib/kuksa/class.dart @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 + +class VehicleSignal { + VehicleSignal({ + + required this.currentLatitude, + required this.currentLongitude, + + required this.destinationLatitude, + required this.destinationLongitude, + }); + + + final double currentLongitude; + final double currentLatitude; + final double destinationLongitude; + final double destinationLatitude; + + + VehicleSignal copyWith({ + + double? currentLongitude, + double? currentLatitude, + + double? destinationLongitude, + double? destinationLatitude, + }) { + return VehicleSignal( + + currentLatitude: currentLatitude ?? this.currentLatitude, + currentLongitude: currentLongitude ?? this.currentLongitude, + + destinationLatitude: destinationLatitude ?? this.destinationLatitude, + destinationLongitude: destinationLongitude ?? this.destinationLongitude, + ); + } +} + +class info{ + info({required this.Duration, required this.Distance, required this.instruction}); + + final num Duration; + final num Distance; + final String instruction; + + info copywith({num? Duration , num? Distance, String? instruction}){ + return info(Duration: Duration ?? this.Duration, + Distance: Distance ?? this.Distance, + instruction: instruction ?? this.instruction); + + } +}
\ No newline at end of file diff --git a/lib/kuksa/config.dart b/lib/kuksa/config.dart new file mode 100644 index 0000000..5fb6965 --- /dev/null +++ b/lib/kuksa/config.dart @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:io'; + +import 'package:flutter_navigation/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; + + +// class VehicleSignalConfig { +// static String authTokenPath = "cert/all_read_write.json.token"; +// static String hostname = "localhost"; +// static int port = 8090; +// static String uri = "ws://${hostname}:${port}"; +// static String s_uri = "wss://${hostname}:${port}"; +// static String authToken = +// "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJtb2RpZnlUcmVlIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.p2cnFGH16QoQ14l6ljPVKggFXZKmD-vrw8G6Vs6DvAokjsUG8FHh-F53cMsE-GDjyZH_1_CrlDCnbGlqjsFbgAylqA7IAJWp9_N6dL5p8DHZTwlZ4IV8L1CtCALs7XVqvcQKHCCzB63Y8PgVDCAqpQSRb79JPVD4pZwkBKpOknfEY5y9wfbswZiRKdgz7o61_oFnd-yywpse-23HD6v0htThVF1SuGL1PuvGJ8p334nt9bpkZO3gaTh1xVD_uJMwHzbuBCF33_f-I5QMZO6bVooXqGfe1zvl3nDrPEjq1aPulvtP8RgREYEqE6b2hB8jouTiC_WpE3qrdMw9sfWGFbm04qC-2Zjoa1yYSXoxmYd0SnliSYHAad9aXoEmFENezQV-of7sc-NX1-2nAXRAEhaqh0IRuJwB4_sG7SvQmnanwkz-sBYxKqkoFpOsZ6hblgPDOPYY2NAsZlYkjvAL2mpiInrsmY_GzGsfwPeAx31iozImX75rao8rm-XucAmCIkRlpBz6MYKCjQgyRz3UtZCJ2DYF4lKqTjphEAgclbYZ7KiCuTn9HualwtEmVzHHFneHMKl7KnRQk-9wjgiyQ5nlsVpCCblg6JKr9of4utuPO3cBvbjhB4_ueQ40cpWVOICcOLS7_w0i3pCq1ZKDEMrYDJfz87r2sU9kw1zeFQk"; +// } + +final sockConnectprovider = FutureProvider.family<WebSocket, HttpClient>( + (ref, client) => connect(client,ref)); + + + +// load certificates and set context and returns http client +Future<HttpClient> initializeClient() async { + + + SecurityContext ctx = SecurityContext.defaultContext; + + HttpClient client = HttpClient(context: ctx) + ..findProxy = null + ..badCertificateCallback = (cert, host, port) { + return true; + }; + return client; +} + + + +Future<WebSocket> connect(HttpClient client, ref) async { + final config = ref.read(ConfigStateprovider); + WebSocket socket = await WebSocket.connect( + "wss://${config.hostname}:${config.port}", + customClient: client); + return socket; +} diff --git a/lib/kuksa/intial-connection.dart b/lib/kuksa/intial-connection.dart new file mode 100644 index 0000000..53879d9 --- /dev/null +++ b/lib/kuksa/intial-connection.dart @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'config.dart'; +import 'onBoarding.dart'; + + +class InitialScreen extends ConsumerWidget { + InitialScreen({Key? key, required this.client}) : super(key: key); + final HttpClient client; + late WebSocket socket; + + @override + Widget build(BuildContext context, ref) { + + final sockConnect = ref.watch(sockConnectprovider(client)); + + + return sockConnect.when( + data: (socket) { + + this.socket = socket; + this.socket.pingInterval = const Duration(seconds: 2); + return OnBoardingPage(client: client, socket: this.socket); + }, + error: (e, stk) { + print(e); + ref.refresh(sockConnectprovider(client)); + return const Scaffold( + backgroundColor: Colors.black, + body: Center(child: Text('error',style: TextStyle(color: Colors.white),)), + ); + }, + loading: () => const Scaffold( + backgroundColor: Colors.black, + body: Center(child: Text('loading',style: TextStyle(color: Colors.white))), + ), + ); + } +}
\ No newline at end of file diff --git a/lib/kuksa/onBoarding.dart b/lib/kuksa/onBoarding.dart new file mode 100644 index 0000000..84c85bd --- /dev/null +++ b/lib/kuksa/onBoarding.dart @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_navigation/homepage.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_navigation/kuksa/vehicle-methods.dart'; + +import 'config.dart'; + + +class OnBoardingPage extends ConsumerStatefulWidget { + const OnBoardingPage({Key? key, required this.client, required this.socket}) + : super(key: key); + final WebSocket socket; + final HttpClient client; + + @override + ConsumerState<OnBoardingPage> createState() => _OnBoardingPageState(); +} + +class _OnBoardingPageState extends ConsumerState<OnBoardingPage> { + late Timer _timer; + + + @override + void initState() { + + super.initState(); + VISS.init(widget.socket,ref); + _timer = Timer.periodic(const Duration(seconds: 2), (timer) { + // print(widget.socket.readyState); + if (widget.socket.readyState == 3) { + ref.refresh(sockConnectprovider(widget.client)); + } + }); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + widget.socket.listen( + (data) { + VISS.parseData(ref, data); + // print(data); + }, + onError: (e, stk) { + print(e.toString()); + ref.refresh(sockConnectprovider(widget.client)); + }, + ); + }); + } + + @override + void dispose() { + super.dispose(); + _timer.cancel(); + widget.socket.close(786887, "Connection lost with server!"); + } + + @override + Widget build(BuildContext context) { + return MyHomePage(title: 'navigation',); + } +}
\ No newline at end of file diff --git a/lib/kuksa/paths.dart b/lib/kuksa/paths.dart new file mode 100644 index 0000000..df22644 --- /dev/null +++ b/lib/kuksa/paths.dart @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: Apache-2.0 + +class VSPath { + + static const String vehicleCurrentLatitude = "Vehicle.CurrentLocation.Latitude"; + static const String vehicleCurrentLongitude = "Vehicle.CurrentLocation.Longitude"; + static const String vehicleDestinationLatitude = "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Latitude"; + static const String vehicleDestinationLongitude = "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Longitude"; + + +}
\ No newline at end of file diff --git a/lib/kuksa/vehicle-methods.dart b/lib/kuksa/vehicle-methods.dart new file mode 100644 index 0000000..dbbdc3b --- /dev/null +++ b/lib/kuksa/vehicle-methods.dart @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:convert'; +import 'dart:io'; + + +import 'package:flutter_navigation/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_navigation/kuksa/paths.dart'; + +import 'class-provider.dart'; + +class VISS { + static const requestId = "test-id"; + static void init(WebSocket socket, WidgetRef ref) { + authorize(socket,ref); + subscribe(socket,ref, VSPath.vehicleCurrentLatitude); + subscribe(socket,ref, VSPath.vehicleCurrentLongitude); + subscribe(socket,ref, VSPath.vehicleDestinationLatitude); + subscribe(socket,ref, VSPath.vehicleDestinationLongitude); + + } + + static void update(WebSocket socket,WidgetRef ref) { + get(socket,ref, VSPath.vehicleCurrentLatitude); + get(socket,ref, VSPath.vehicleCurrentLongitude); + get(socket, ref,VSPath.vehicleDestinationLatitude); + get(socket,ref, VSPath.vehicleDestinationLongitude); + + + + } + + static void authorize(WebSocket socket,WidgetRef ref) { + final config = ref.read(ConfigStateprovider); + Map<String, dynamic> map = { + "action": "authorize", + "tokens": config.kuksaAuthToken, + "requestId": requestId + }; + socket.add(jsonEncode(map)); + } + + static void get(WebSocket socket, WidgetRef ref,String path) { + final config = ref.read(ConfigStateprovider); + + Map<String, dynamic> map = { + "action": "get", + "tokens": config.kuksaAuthToken, + "path": path, + "requestId": requestId + }; + socket.add(jsonEncode(map)); + } + + static void set(WebSocket socket, WidgetRef ref,String path, String value) { + final config = ref.read(ConfigStateprovider); + + Map<String, dynamic> map = { + "action": "set", + "tokens": config.kuksaAuthToken, + "path": path, + "requestId": requestId, + "value": value + }; + socket.add(jsonEncode(map)); + } + + static void subscribe(WebSocket socket,WidgetRef ref, String path) { + final config = ref.read(ConfigStateprovider); + + Map<String, dynamic> map = { + "action": "subscribe", + "tokens": config.kuksaAuthToken, + "path": path, + "requestId": requestId + }; + socket.add(jsonEncode(map)); + } + + static String? numToGear(int? number) { + switch (number) { + case -1: + return 'R'; + case 0: + return 'N'; + case 126: + return 'P'; + case 127: + return 'D'; + default: + return null; + } + } + + static void parseData(WidgetRef ref, String data) { + final vehicleSignal = ref.read(vehicleSignalProvider.notifier); + Map<String, dynamic> dataMap = jsonDecode(data); + if (dataMap["action"] == "subscription" || dataMap["action"] == "get") { + if (dataMap.containsKey("data")) { + if ((dataMap["data"] as Map<String, dynamic>).containsKey("dp") && + (dataMap["data"] as Map<String, dynamic>).containsKey("path")) { + String path = dataMap["data"]["path"]; + Map<String, dynamic> dp = dataMap["data"]["dp"]; + if (dp.containsKey("value")) { + if (dp["value"] != "---") { + switch (path) { + + + case VSPath.vehicleCurrentLatitude: + vehicleSignal.update( + currentLatitude: double.parse(dp["value"])); + break; + case VSPath.vehicleCurrentLongitude: + vehicleSignal.update( + currentLongitude: double.parse(dp["value"])); + break; + case VSPath.vehicleDestinationLatitude: + vehicleSignal.update( + destinationLatitude: double.parse(dp["value"])); + break; + case VSPath.vehicleDestinationLongitude: + vehicleSignal.update( + destinationLongitude: double.parse(dp["value"])); + break; + + default: + print("$path Not Available yet!"); + } + } else { + print("ERROR:Value not available yet! Set Value of $path"); + } + } else { + print("ERROR:'value': Key not found!"); + } + } else if ((!dataMap["data"] as Map<String, dynamic>) + .containsKey("path")) { + print("ERROR:'path':key not found !"); + } else if ((dataMap["data"] as Map<String, dynamic>) + .containsKey("dp")) { + print("ERROR:'dp':key not found !"); + } + } else { + print("ERROR:'data':key not found!"); + } + } + } +}
\ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..8300961 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_navigation/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + + +import 'kuksa/config.dart'; + + + +Future<void> main() async { + WidgetsFlutterBinding.ensureInitialized(); + HttpClient client = await initializeClient(); + + + runApp( + ProviderScope( + child: MaterialApp( + home: GetConfig(client: client), + ), + ), + ); +} + + + diff --git a/lib/map/Show-route.dart b/lib/map/Show-route.dart new file mode 100644 index 0000000..6bb9987 --- /dev/null +++ b/lib/map/Show-route.dart @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: Apache-2.0 + + +import 'package:flutter/material.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:flutter_navigation/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:flutter_navigation/kuksa/class-provider.dart'; +import 'package:flutter_navigation/kuksa/class.dart'; +import 'package:flutter_navigation/map/bottom-card.dart'; +import 'package:flutter_navigation/map/turnNavigation.dart'; + +class NavigationHome extends ConsumerWidget { + final List<LatLng> polyLine; + String CurrAddress; + String Duration; + num Distance; + + NavigationHome({ + Key? key, + required this.polyLine, + required this.CurrAddress, + required this.Duration, + required this.Distance, + + }) : super(key: key); + + + + double tempangle = 0; + @override + Widget build(BuildContext context, WidgetRef ref) { + + final config = ref.read(ConfigStateprovider); + + + + MapController mapController = MapController(); + VehicleSignal vehicleSignal = ref.watch(vehicleSignalProvider); + LatLng currPos = LatLng(vehicleSignal.currentLatitude, vehicleSignal.currentLongitude); + LatLng destiPos = LatLng(vehicleSignal.destinationLatitude, vehicleSignal.destinationLongitude); + + return Scaffold( + + + body: Stack( + children: [ + FlutterMap( + mapController: mapController, + options: MapOptions( + + center: currPos, + minZoom: 1, + zoom: 8, + + maxZoom: 22.0, + keepAlive: true, + ), + layers: [ + + TileLayerOptions( + urlTemplate: "https://api.mapbox.com/styles/v1/hritik3961/cl7j225qm001w14o4xeiqtv36/tiles/256/{z}/{x}/{y}@2x?access_token=${config.mapboxAccessToken}", + additionalOptions: { + "access_token": config.mapboxAccessToken, + }, + ), + if (polyLine.isNotEmpty) + PolylineLayerOptions( + polylineCulling: false, + polylines: [ + + Polyline( + color : Colors.blue, + strokeWidth: 6, + + points: polyLine, + ), + + ], + ), + MarkerLayerOptions( + rotate: true, + markers: [ + Marker( + point: currPos, + width: 70, + height: 70, + builder: (context) => + const Icon( + + Icons.location_pin, + size: 50, + color: Colors.red, + ) + + ), + ], + ), + MarkerLayerOptions( + rotate: true, + markers: [ + Marker( + point: destiPos, + width: 70, + height: 70, + builder: (context) => + const Icon( + + Icons.location_pin, + size: 50, + color: Colors.green, + ) + + ), + ], + ), + + ], + ), + Container( + alignment: Alignment.topLeft, + child :IconButton( + icon: Icon(Icons.arrow_back, color: Colors.white,), + onPressed: (){ + Navigator.pop(context); + }, + ) + ), + bottomDetailCard(context,ref,Distance.toString(),Duration.toString(),CurrAddress), + ], + ), + + floatingActionButton: FloatingActionButton.extended( + backgroundColor: Colors.black, + onPressed: () async{ + + + + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => + TurnNavigation())); + + }, + label: const Text('lets go'), + icon: const Icon(Icons.drive_eta_rounded), + ), + ); + } +}
\ No newline at end of file diff --git a/lib/map/bottom-card.dart b/lib/map/bottom-card.dart new file mode 100644 index 0000000..0dc2c34 --- /dev/null +++ b/lib/map/bottom-card.dart @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'package:flutter/material.dart'; + +import 'package:flutter_navigation/kuksa/class-provider.dart'; +import 'package:flutter_navigation/kuksa/class.dart'; +import 'package:flutter_navigation/provider.dart'; + +Widget bottomDetailCard( + BuildContext context, ref,String distance, String dropOffTime,String CurrAdd) { + VehicleSignal vehicleSignal = ref.watch(vehicleSignalProvider); + String destiadd = ref.read(DestinationAdressProvider); + + return Container( + alignment: Alignment.bottomLeft, + + child: SizedBox( + + width: MediaQuery.of(context).size.width, + child: Card( + + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.all(15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text('$CurrAdd ➡ $destiadd', + style: Theme.of(context) + .textTheme + .titleMedium + ?.copyWith(color: Colors.indigo)), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: ListTile( + tileColor: Colors.grey[200], + leading: const Image( + image: AssetImage('assets/car2.png'), + height: 50, + width: 50), + title: const Text('Happy Journey', + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + subtitle: Text('$distance km $dropOffTime',style: TextStyle(color: Colors.black),), + + ), + ), + + ]), + ), + ), + ), + ); +}
\ No newline at end of file diff --git a/lib/map/map-response.dart b/lib/map/map-response.dart new file mode 100644 index 0000000..cfc50c2 --- /dev/null +++ b/lib/map/map-response.dart @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:flutter_navigation/config.dart'; + +import 'package:http/http.dart' as http; +import 'package:latlong2/latlong.dart'; + + + +String baseUrl = 'https://api.mapbox.com/directions/v5/mapbox'; +String navType = 'driving'; + +Dio _dio = Dio(); + +Future getdrivingRouteUsingMapbox(LatLng source, LatLng destination,ref) async { + final config = ref.read(ConfigStateprovider); + + String url = + '$baseUrl/$navType/${source.longitude},${source.latitude};${destination.longitude},${destination.latitude}?alternatives=true&continue_straight=true&geometries=geojson&language=en&overview=full&steps=true&access_token=${config.mapboxAccessToken}'; + try { + _dio.options.contentType = Headers.jsonContentType; + final responseData = await _dio.get(url); + return responseData.data; + } catch (e) { + print(e); + } +} + +Future<Map> getDirectionsAPIResponse(LatLng currentLatLng,LatLng destiLatLng,ref) async { + + final response = await getdrivingRouteUsingMapbox(currentLatLng, destiLatLng,ref); + + if(response != null){ + Map geometry = response['routes'][0]['geometry']; + num duration = response['routes'][0]['duration']; + num distance = response['routes'][0]['distance']; + Map legs = response['routes'][0]['legs'][0]; + + Map modifiedResponse = { + "geometry": geometry, + "duration": duration, + "distance": distance, + "legs" : legs, + }; + return modifiedResponse; + + } + else{ + Map map = {}; + return map; + } + +} + +Future<Map> getAdress(LatLng pos,ref) async{ + final config = ref.read(ConfigStateprovider); + + var url = 'https://api.mapbox.com/geocoding/v5/mapbox.places/${pos.longitude},${pos.latitude}.json?&access_token=${config.mapboxAccessToken}'; + http.Response response = await http.get(Uri.parse(url)); + Map data = json.decode(response.body); + return data; +}
\ No newline at end of file diff --git a/lib/map/turnNavigation.dart b/lib/map/turnNavigation.dart new file mode 100644 index 0000000..6370e44 --- /dev/null +++ b/lib/map/turnNavigation.dart @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:flutter_navigation/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:flutter_navigation/kuksa/class-provider.dart'; +import 'package:flutter_navigation/kuksa/class.dart'; +import 'package:flutter_navigation/provider.dart'; + +import 'map-response.dart'; + +class TurnNavigation extends ConsumerStatefulWidget { + TurnNavigation({Key? key,}) : super(key: key); + + @override + ConsumerState<TurnNavigation> createState() => _TurnNavigationState(); +} + +class _TurnNavigationState extends ConsumerState<TurnNavigation> { + + late Timer timer; + late MapController mapController; + List<LatLng> polyLine = []; + + String ConvertToTime(num duration){ + int hour = (duration/3600).toInt(); + int min = (duration%3600).toInt() ; + min = (min/60).toInt(); + String mini = min.toString(); + String Hour = hour.toString(); + String time = "$Hour hr $mini min"; + + return time; + } + + + + + @override + void initState() { + // TODO: implement initState + super.initState(); + mapController = MapController(); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + + timer = Timer.periodic(Duration(seconds: 7), (timer) async{ + VehicleSignal vehicleSignal = ref.read(vehicleSignalProvider); + + LatLng current = LatLng(vehicleSignal.currentLatitude, vehicleSignal.currentLongitude); + mapController.move(current, 18); + LatLng destination = LatLng(vehicleSignal.destinationLatitude,vehicleSignal.destinationLongitude); + + Map RouteResponse = await getDirectionsAPIResponse(current,destination,ref); + + + if(RouteResponse.isNotEmpty){ + + List RouteCoordinates = RouteResponse['geometry']['coordinates']; + + Map steps = RouteResponse['legs']['steps'][0]; + + ref.read(Infoprovider.notifier).update(Duration: RouteResponse['duration'], + Distance: RouteResponse['distance'], instruction: steps['maneuver']['instruction']); + List<LatLng> currpolyline =[]; + for(int i =0; i<RouteCoordinates.length ;i++){ + currpolyline.add(LatLng((RouteCoordinates[i][1]).toDouble(),(RouteCoordinates[i][0]).toDouble())); + + } + ref.read(polylineprovider.notifier).update(currpolyline); + double rotationDegree = 0; + int n = currpolyline.length; + if (currpolyline.isNotEmpty && n > 1) { + rotationDegree = calcAngle( + currpolyline[0], currpolyline[1]); + + rotationDegree = (rotationDegree.isNaN) ? 0 : rotationDegree; + } + + mapController.rotate(-1 * rotationDegree); + + + } + + + }); + + }); + } + + void dispose(){ + + super.dispose(); + timer.cancel(); + + } + + double tempangle = 0; + double calcAngle(LatLng a, LatLng b) { + List<double> newA = convertCoord(a); + List<double> newB = convertCoord(b); + double slope = (newB[1] - newA[1]) / (newB[0] - newA[0]); + + return ((atan(slope) * 180) / pi); + } + + List<double> convertCoord(LatLng coord) { + double oldLat = coord.latitude; + double oldLong = coord.longitude; + double newLong = (oldLong * 20037508.34 / 180); + double newlat = + (log(tan((90 + oldLat) * pi / 360)) / (pi / 180)) * (20037508.34 / 180); + return [newlat, newLong]; + } + @override + Widget build(BuildContext context) { + + + + + VehicleSignal vehicleSignal = ref.watch(vehicleSignalProvider); + LatLng currPos = LatLng(vehicleSignal.currentLatitude, vehicleSignal.currentLongitude); + polyLine = ref.watch(polylineprovider); + info routeinfo = ref.watch(Infoprovider); + final config = ref.read(ConfigStateprovider); + + + return Scaffold( + body: Stack( + children: [ + FlutterMap( + mapController: mapController, + options: MapOptions( + + center: currPos, + minZoom: 1, + zoom: 12, + + maxZoom: 30.0, + keepAlive: true, + ), + layers: [ + + TileLayerOptions( + urlTemplate: "https://api.mapbox.com/styles/v1/hritik3961/cl7hxzrrf002t15o2j2yh14lm/tiles/256/{z}/{x}/{y}@2x?access_token=${config.mapboxAccessToken}", + additionalOptions: { + "access_token": config.mapboxAccessToken, + }, + ), + if (polyLine.isNotEmpty) + PolylineLayerOptions( + polylineCulling: false, + polylines: [ + + Polyline( + strokeWidth: 3, + points: polyLine, + color: Colors.purple, + ), + + ], + ), + MarkerLayerOptions( + rotate: true, + markers: [ + Marker( + point: currPos, + width: 70, + height: 70, + builder: (context) => + const Icon( + Icons.circle, + size: 40, + color: Colors.green, + + ) + + + ), + ], + ), + + ], + ), + Container( + alignment: Alignment.bottomCenter, + + child: Card( + + color: Colors.black54, + elevation: 5, + child: ListTile( + leading: Icon(Icons.drive_eta_rounded,color: Colors.greenAccent,), + title: Text(routeinfo.instruction,style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ),), + subtitle: Text('Remaining Distance : ${(routeinfo.Distance/1000).toInt().toString()} KM',style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ),), + trailing: Text('Remaining Time : ${ConvertToTime(routeinfo.Duration)}',style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ),), + + ), + + ), + ), + Container( + alignment: Alignment.topLeft, + child :IconButton( + icon: Icon(Icons.arrow_back), + onPressed: (){ + Navigator.pop(context); + }, + ) + ), + ], + ), + ); + + } +} + + diff --git a/lib/mapbox.dart b/lib/mapbox.dart new file mode 100644 index 0000000..f7bf91e --- /dev/null +++ b/lib/mapbox.dart @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:mapbox_search/mapbox_search.dart'; + +class MapBoxPlaceSearchWidget extends StatefulWidget { + MapBoxPlaceSearchWidget({ + required this.apiKey, + required this.onSelected, + // this.onSearch, + this.fontSize, + this.searchHint = 'Search', + required this.context, + this.height, + this.popOnSelect = false, + this.location, + this.country, + }); + + /// True if there is different search screen and you want to pop screen on select + final bool popOnSelect; + + ///To get the height of the page + final BuildContext context; + + /// Height of whole search widget + final double? height; + + /// API Key of the MapBox. + final String apiKey; + + /// The callback that is called when one Place is selected by the user. + final void Function(MapBoxPlace place) onSelected; + + /// The callback that is called when the user taps on the search icon. + // final void Function(MapBoxPlaces place) onSearch; + + /// The point around which you wish to retrieve place information. + final Location? location; + + ///Limits the search to the given country + /// + /// Check the full list of [supported countries](https://docs.mapbox.com/api/search/) for the MapBox API + final String? country; + + ///Search Hint Localization + final String? searchHint; + + ///Font Size + final String? fontSize; + + @override + _MapBoxPlaceSearchWidgetState createState() => + _MapBoxPlaceSearchWidgetState(); +} + +class _MapBoxPlaceSearchWidgetState extends State<MapBoxPlaceSearchWidget> + with SingleTickerProviderStateMixin { + TextEditingController _textEditingController = TextEditingController(); + late AnimationController _animationController; + + + late Animation _containerHeight; + + + late Animation _listOpacity; + + List<MapBoxPlace> _placePredictions = []; + + + + late Timer _debounceTimer; + + + + + @override + void initState() { + _animationController = + AnimationController(vsync: this, duration: Duration(milliseconds: 500)); + + _containerHeight = Tween<double>( + begin: 73, + end: widget.height ?? + MediaQuery.of(widget.context).size.height - 60 ?? + 300) + .animate( + CurvedAnimation( + curve: Interval(0.0, 0.5, curve: Curves.easeInOut), + parent: _animationController, + ), + ); + _listOpacity = Tween<double>( + begin: 0, + end: 1, + ).animate( + CurvedAnimation( + curve: Interval(0.5, 1.0, curve: Curves.easeInOut), + parent: _animationController, + ), + ); + super.initState(); + } + + @override + void dispose() { + _debounceTimer.cancel(); + _animationController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => Container( + padding: EdgeInsets.symmetric(horizontal: 5), + width: MediaQuery.of(context).size.width, + child: _searchContainer( + child: _searchInput(context), + ), + ); + + // Widgets + Widget _searchContainer({Widget? child}) { + return AnimatedBuilder( + animation: _animationController, + builder: (context, _) { + return Container( + height: _containerHeight.value, + decoration: _containerDecoration(), + padding: EdgeInsets.only(left: 0, right: 0, top: 15), + alignment: Alignment.center, + child: Column( + children: <Widget>[ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: child, + ), + SizedBox(height: 10), + Expanded( + child: Opacity( + opacity: _listOpacity.value, + child: ListView( + // addSemanticIndexes: true, + // itemExtent: 10, + children: <Widget>[ + for (var places in _placePredictions) + _placeOption(places), + ], + ), + ), + ), + ], + ), + ); + }); + } + + Widget _searchInput(BuildContext context) { + return Center( + child: Row( + children: <Widget>[ + Expanded( + child: TextField( + decoration: _inputStyle(), + controller: _textEditingController, + style: TextStyle( + fontSize: MediaQuery.of(context).size.width * 0.04, + ), + onChanged: (value) async { + // _debounceTimer?.cancel(); + _debounceTimer = Timer( + Duration(milliseconds: 750), + () async { + await _autocompletePlace(value); + if (mounted) { + setState(() {}); + } + }, + ); + }, + ), + ), + Container(width: 15), + GestureDetector( + child: Icon(Icons.search, color: Colors.blue), + onTap: () {}, + ) + ], + ), + ); + } + + Widget _placeOption(MapBoxPlace prediction) { + String? place = prediction.text; + String? fullName = prediction.placeName; + + return MaterialButton( + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 3), + onPressed: () => _selectPlace(prediction), + child: ListTile( + title: Text( + place?.length != 0 ? place!.length < 45 + ? "$place" + : "${place?.replaceRange(45, place.length, "")} ..." : "", + style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.04), + maxLines: 1, + ), + subtitle: Text( + fullName!, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.03), + maxLines: 1, + ), + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 0, + ), + ), + ); + } + + // Styling + InputDecoration _inputStyle() { + return InputDecoration( + hintText: widget.searchHint, + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric(horizontal: 0.0, vertical: 0.0), + ); + } + + BoxDecoration _containerDecoration() { + return BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(6.0)), + boxShadow: [ + BoxShadow(color: Colors.black, blurRadius: 0, spreadRadius: 0) + ], + ); + } + + // Methods + Future _autocompletePlace(String input) async { + /// Will be called when the input changes. Making callbacks to the Places + /// Api and giving the user Place options + /// + if (input.length > 0) { + var placesSearch = PlacesSearch( + apiKey: widget.apiKey, + country: widget.country, + ); + + final predictions = await placesSearch.getPlaces( + input, + location: widget.location, + ); + + await _animationController.animateTo(0.5); + + + + setState(() => _placePredictions = predictions!); + + await _animationController.forward(); + } else { + + await _animationController.animateTo(0.5); + setState(() => _placePredictions = []); + await _animationController.reverse(); + } + } + + void _selectPlace(MapBoxPlace prediction) async { + /// Will be called when a user selects one of the Place options. + // Sets TextField value to be the location selected + _textEditingController.value = TextEditingValue( + text: prediction.placeName.toString(), + selection: TextSelection.collapsed(offset: prediction.placeName!.length), + ); + + // Makes animation + await _animationController.animateTo(0.5); + setState(() { + _placePredictions = []; + + }); + _animationController.reverse(); + + // Calls the `onSelected` callback + widget.onSelected(prediction); + if (widget.popOnSelect) Navigator.pop(context); + } +}
\ No newline at end of file diff --git a/lib/provider.dart b/lib/provider.dart new file mode 100644 index 0000000..228672f --- /dev/null +++ b/lib/provider.dart @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:latlong2/latlong.dart'; + +import 'kuksa/class.dart'; + + +final currlnglatProvider = StateNotifierProvider<currentLngLat,LatLng>( + (ref)=> currentLngLat(), +); + +class currentLngLat extends StateNotifier<LatLng>{ + currentLngLat() : super( + LatLng(31.706964,76.933138), + ); + Future<void> update(value) async{ + + state = value; + } + +} + +final destinationlnglatProvider = StateNotifierProvider<distiLngLat,LatLng>( + (ref)=> distiLngLat(), +); + +class distiLngLat extends StateNotifier<LatLng>{ + distiLngLat() : super( + LatLng(0,0), + ); + Future<void> update(value) async{ + state = value; + } + +} + +final CurrentAdressProvider = StateNotifierProvider<currentAdress,String>( + (ref)=> currentAdress(), +); + +class currentAdress extends StateNotifier<String>{ + currentAdress() : super( + '' + ); + Future<void> update(value)async{ + state = value; + } +} + +final DestinationAdressProvider = StateNotifierProvider<destiAdress,String>( + (ref)=> destiAdress(), +); + +class destiAdress extends StateNotifier<String>{ + destiAdress() : super( + '' + ); + Future<void> update(value)async{ + state = value; + } +} + +final polylineprovider = StateNotifierProvider<PolyLine,List<LatLng>>((ref) => PolyLine()); + +class PolyLine extends StateNotifier<List<LatLng>> { + + PolyLine() : super([]); + void update(List<LatLng> list) { + state = list; + } +} + +final Infoprovider = StateNotifierProvider<Info,info>((ref) => Info()); + +class Info extends StateNotifier<info> { + + Info() : super(initial); + static final info initial = info(Duration: 0, Distance: 0, instruction: ''); + + void update({ + num? Duration, + num? Distance, + String? instruction, + + }){ + state = state.copywith( + Duration: Duration, + Distance: Distance, + instruction: instruction, + ); + + + } +}
\ No newline at end of file diff --git a/lib/search.dart b/lib/search.dart new file mode 100644 index 0000000..9e02450 --- /dev/null +++ b/lib/search.dart @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_navigation/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'package:http/http.dart' as http; +import 'package:latlong2/latlong.dart'; +import 'package:flutter_navigation/kuksa/class-provider.dart'; +import 'package:flutter_navigation/provider.dart'; + +import 'mapbox.dart'; + +class SearchPage extends ConsumerWidget { + bool iscurrent; + + SearchPage({Key? key, required this.iscurrent}) : super(key: key); + final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); + + + @override + Widget build(BuildContext context,ref) { + final config = ref.read(ConfigStateprovider); + + return Scaffold( + key: _scaffoldKey, + floatingActionButton: FloatingActionButton( + child: Icon(Icons.done), + onPressed: () { + Navigator.pop(context); + }, + ), + body: SafeArea( + bottom: false, + child: MapBoxPlaceSearchWidget( + height: 600, + popOnSelect: false, + apiKey: config.mapboxAccessToken, + searchHint: 'Search around your place', + onSelected: (place) async{ + var url = 'https://api.mapbox.com/geocoding/v5/mapbox.places/${place.placeName}.json?proximity=ip&types=place%2Cpostcode%2Caddress&access_token=${config.mapboxAccessToken}'; + http.Response response = await http.get(Uri.parse(url)); + Map data = json.decode(response.body); + double longi = data['features'][0]['center'][0]; + double lati = data['features'][0]['center'][1]; + if(iscurrent){ + LatLng value = LatLng(lati,longi); + ref.read(vehicleSignalProvider.notifier).update(currentLatitude: lati,currentLongitude: longi); + ref.read(CurrentAdressProvider.notifier).update(place.placeName); + + } + else{ + ref.read(vehicleSignalProvider.notifier).update(destinationLatitude: lati,destinationLongitude: longi); + + ref.read(DestinationAdressProvider.notifier).update(place.placeName); + + } + + + + }, + context: context, + ), + ), + ); + } +}
\ No newline at end of file |