Hello, guys today we are going to learn how to draw a route path between two locations on Google Maps. If you don't know how to load GoogleMap read my Integrate Google maps in Flutter To achieve this we need to add the below dependencies to pubspec.yaml file GoogleMaps: Google Webservices: Follow These steps Step 1: Create AppState Class & Put ChangeProvider in Main File appstate.dart class AppState extends ChangeNotifier{ main.dart void main() { @override primarySwatch: Colors.blue, Step 2: Design the UI with Text Fields and Maps landingpage.dart class LandingPage extends StatefulWidget{ } class LandingPageState extends State child: Material( ); getInoutDecoration(hint,icon) } To Handle state changes we need to create AppState instance here Step 3: Write Logic to Fetch the Address and get Ploy Lines between Locations import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; //To Handle Text fileds data //To Get the Marker Psotions GoogleMapController get mapController => _mapController; Locationpath _locationPath = Locationpath(); // Handle the CameraMove Position // Fetch the User Current location // To Request Route path to Goolge Webservice // Add marker to markers set and update Map on Marker do { /*adding to previous value as done in encoding */ print(lList.toString()); return lList; locationpath.dart import 'package:google_maps_flutter/google_maps_flutter.dart'; Run App, The Current location will be shown in Source Text Field, then enter Destination address in Destination Text Field and hit keyboard go button, it will fetch the Route path and display the Route between two markers. Show Multiple Markers on Google Maps in Flutter
Load the Google Maps on to the screen
Provider:
To manage the State
GeoLocator:
To Fetch the Address from the Position
To Fetch the Route
}
runApp(
MultiProvider(providers: [
ChangeNotifierProvider.value(value: AppState())
],
child: MyApp(),)
);
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
),
home: LandingPage(),
);
}
}
@override
State createState() =>LandingPageState();
{
@override
Widget build(BuildContext context) {
final appState=Provider.of(context);
return SafeArea(
child: appState.initialPosition==null?Container(
child: Center(
child: CircularProgressIndicator(),
),
):Stack(
children: [
GoogleMap(
initialCameraPosition: CameraPosition(target: appState.initialPosition,zoom: 11),
onMapCreated: appState.onCreated,
onCameraMove: appState.onCameraMove,
markers: appState.markers,
polylines: appState.polyLines,
),
Positioned(
top: 50.0,
right: 15.0,
left: 15.0,
child: Container(
height: 50.0,
width: double.infinity,
decoration: getBoxShadow(),
child: TextField(
controller: appState.sourceController,
textInputAction: TextInputAction.next,
cursorColor: Colors.black,
decoration:getInoutDecoration("pick up Location?",Icon(
Icons.location_on,
color: Colors.green,
),),
),
),
),
),
Positioned(
top: 105.0,
right: 15.0,
left: 15.0,
child: Material(
child: Container(
height: 50.0,
width: double.infinity,
decoration:getBoxShadow(),
child: TextField(
controller: appState.destController,
cursorColor: Colors.black,
textInputAction: TextInputAction.go,
onSubmitted: (value) {
},
decoration: getInoutDecoration("destination?",Icon(
Icons.local_taxi,
color: Colors.black,
)),
),
),
),
),
(appState.isLoading)?Center(child: CircularProgressIndicator(),):Container(width: 0,height: 0,),
],
)
}
{
return InputDecoration(
icon: Container(
margin: EdgeInsets.only(left: 20, top: 5),
width: 10,
height: 10,
child:icon ,
),
hintText: hint,
border: InputBorder.none,
contentPadding: EdgeInsets.only(left: 15.0, top: 16.0),
);
}
getBoxShadow()
{
return BoxDecoration(
borderRadius: BorderRadius.circular(3.0),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(1.0, 5.0),
blurRadius: 10,
spreadRadius: 3)
]);
}
final appState=Provider.of(context);
This will handle the Entire app changes and update the state based on values.
I have updated the AppState class like below
import 'package:maps_uber_clone_app/module/pathrequest.dart';
class AppState extends ChangeNotifier{
static LatLng _initialPosition;
static LatLng _lastPosition;
GoogleMapController _mapController;
Set_markers={};
Set _polyLines={};
bool _isLoading=false;
TextEditingController sourceController=TextEditingController();
TextEditingController destController=TextEditingController();
LatLng get initialPosition => _initialPosition;
LatLng get lastposition => _lastPosition;
//To check the Route Fetching stage
bool get isLoading => _isLoading;
//TO Load Markers on to Map
Set get markers => _markers;
//To Load route on Map
Set get polyLines => _polyLines;
AppState()
{
_getUserLocation();
}
// ON CREATE, Will set the MapController after loading the Map
void onCreated(GoogleMapController controller) {
_mapController = controller;
notifyListeners();
}
void onCameraMove(CameraPosition position) {
_lastPosition = position.target;
notifyListeners();
}
void _getUserLocation() async {
Position position = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
List placemark = await Geolocator()
.placemarkFromCoordinates(position.latitude, position.longitude);
_initialPosition = LatLng(position.latitude, position.longitude);
sourceController.text = placemark[0].name;
_markers.add(Marker(markerId: MarkerId(position.toString()),icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueOrange),position: LatLng(position.latitude, position.longitude)));
notifyListeners();
}
void sendRequest(String intendedLocation) async {
_isLoading=true;
List placemark =
await Geolocator().placemarkFromAddress(intendedLocation);
double latitude = placemark[0].position.latitude;
double longitude = placemark[0].position.longitude;
LatLng destination = LatLng(latitude, longitude);
_addMarker(destination, intendedLocation);
String route = await _locationPath.getRouteCoordinates(
_initialPosition, destination);
createRoute(route);
notifyListeners();
}
void _addMarker(LatLng location, String address) {
_markers.add(Marker(
markerId: MarkerId(_lastPosition.toString()),
position: location,
infoWindow: InfoWindow(title: address, snippet: "Destination"),
icon: BitmapDescriptor.defaultMarker));
notifyListeners();
}
// ! TO CREATE ROUTE
void createRoute(String encondedPoly) {
_polyLines.add(Polyline(
polylineId: PolylineId(_lastPosition.toString()),
width: 4,
points: _convertToLatLng(_decodePoly(encondedPoly)),
color: Colors.deepPurple));
_isLoading=false;
notifyListeners();
}
List _convertToLatLng(List points) {
List result = [];
for (int i = 0; i < points.length; i++) {
if (i % 2 != 0) {
result.add(LatLng(points[i - 1], points[i]));
}
}
return result;
}
// DECODE POLY
List _decodePoly(String poly) {
var list = poly.codeUnits;
var lList = new List();
int index = 0;
int len = poly.length;
int c = 0;
var shift = 0;
int result = 0;
do {
c = list[index] - 63;
result |= (c & 0x1F) << (shift * 5);
index++;
shift++;
} while (c >= 32);
if (result & 1 == 1) {
result = ~result;
}
var result1 = (result >> 1) * 0.00001;
lList.add(result1);
} while (index < len);
for (var i = 2; i < lList.length; i++) lList[i] += lList[i - 2];
}
}
import 'package:http/http.dart' as http;
import 'dart:convert';
const apiKey = "PUT_YOUR_KEY";
class Locationpath {
Future getRouteCoordinates(LatLng l1, LatLng l2)async{
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=${l1.latitude},${l1.longitude}&destination=${l2.latitude}, ${l2.longitude}&key=$apiKey";
http.Response response = await http.get(url);
Map values = jsonDecode(response.body);
return values["routes"][0]["overview_polyline"]["points"];
}
}
Article Contributed By :
|
|
|
|
12463 Views |