Could someone guide me to get the coordinates of an address in flutter?
I need to enter addresses in a text box and get the longitude and latitude of that address
You can copy paste run full code below
You can use package https://pub.dev/packages/geocoder
code snippet
import 'package:geocoder/geocoder.dart';
// From a query
final query = "1600 Amphiteatre Parkway, Mountain View";
var addresses = await Geocoder.local.findAddressesFromQuery(query);
var first = addresses.first;
print("${first.featureName} : ${first.coordinates}");
working demo, last line is coordinates
full code
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geocoder/geocoder.dart';
import 'package:geocoder/services/base.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class AppState extends InheritedWidget {
const AppState({
Key key,
this.mode,
Widget child,
}) : assert(mode != null),
assert(child != null),
super(key: key, child: child);
final Geocoding mode;
static AppState of(BuildContext context) {
return context.inheritFromWidgetOfExactType(AppState);
}
@override
bool updateShouldNotify(AppState old) => mode != old.mode;
}
class GeocodeView extends StatefulWidget {
GeocodeView();
@override
_GeocodeViewState createState() => new _GeocodeViewState();
}
class _GeocodeViewState extends State<GeocodeView> {
_GeocodeViewState();
final TextEditingController _controller = new TextEditingController();
List<Address> results = [];
bool isLoading = false;
Future search() async {
this.setState(() {
this.isLoading = true;
});
try {
var geocoding = AppState.of(context).mode;
var results = await geocoding.findAddressesFromQuery(_controller.text);
this.setState(() {
this.results = results;
});
} catch (e) {
print("Error occured: $e");
} finally {
this.setState(() {
this.isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return new Column(children: <Widget>[
new Card(
child: new Padding(
padding: const EdgeInsets.all(10.0),
child: new Row(
children: <Widget>[
new Expanded(
child: new TextField(
controller: _controller,
decoration: new InputDecoration(hintText: "Enter an address"),
),
),
new IconButton(
icon: new Icon(Icons.search), onPressed: () => search())
],
),
),
),
new Expanded(child: new AddressListView(this.isLoading, this.results)),
]);
}
}
class ReverseGeocodeView extends StatefulWidget {
ReverseGeocodeView();
@override
_ReverseGeocodeViewState createState() => new _ReverseGeocodeViewState();
}
class _ReverseGeocodeViewState extends State<ReverseGeocodeView> {
final TextEditingController _controllerLongitude =
new TextEditingController();
final TextEditingController _controllerLatitude = new TextEditingController();
_ReverseGeocodeViewState();
List<Address> results = [];
bool isLoading = false;
Future search() async {
this.setState(() {
this.isLoading = true;
});
try {
var geocoding = AppState.of(context).mode;
var longitude = double.parse(_controllerLongitude.text);
var latitude = double.parse(_controllerLatitude.text);
var results = await geocoding
.findAddressesFromCoordinates(new Coordinates(latitude, longitude));
this.setState(() {
this.results = results;
});
} catch (e) {
print("Error occured: $e");
} finally {
this.setState(() {
this.isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return new Column(children: <Widget>[
new Card(
child: new Padding(
padding: const EdgeInsets.all(10.0),
child: new Row(
children: <Widget>[
new Expanded(
child: new Column(
children: <Widget>[
new TextField(
controller: _controllerLatitude,
decoration: new InputDecoration(hintText: "Latitude"),
),
new TextField(
controller: _controllerLongitude,
decoration: new InputDecoration(hintText: "Longitude"),
),
],
),
),
new IconButton(
icon: new Icon(Icons.search), onPressed: () => search())
],
),
),
),
new Expanded(child: new AddressListView(this.isLoading, this.results)),
]);
}
}
class _MyAppState extends State<MyApp> {
Geocoding geocoding = Geocoder.local;
final Map<String, Geocoding> modes = {
"Local": Geocoder.local,
"Google (distant)": Geocoder.google("<API-KEY>"),
};
void _changeMode(Geocoding mode) {
this.setState(() {
geocoding = mode;
});
}
@override
Widget build(BuildContext context) {
return new AppState(
mode: this.geocoding,
child: new MaterialApp(
home: new DefaultTabController(
length: 2,
child: new Scaffold(
appBar: new AppBar(
title: new Text('Geocoder'),
actions: <Widget>[
new PopupMenuButton<Geocoding>(
// overflow menu
onSelected: _changeMode,
itemBuilder: (BuildContext context) {
return modes.keys.map((String mode) {
return new CheckedPopupMenuItem<Geocoding>(
checked: modes[mode] == this.geocoding,
value: modes[mode],
child: new Text(mode),
);
}).toList();
},
),
],
bottom: new TabBar(
tabs: [
new Tab(
text: "Query",
icon: new Icon(Icons.search),
),
new Tab(
text: "Coordinates",
icon: new Icon(Icons.pin_drop),
),
],
),
),
body: new TabBarView(children: <Widget>[
new GeocodeView(),
new ReverseGeocodeView(),
]),
),
),
),
);
}
}
class AddressTile extends StatelessWidget {
final Address address;
AddressTile(this.address);
final titleStyle =
const TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold);
@override
Widget build(BuildContext context) {
return new Padding(
padding: const EdgeInsets.all(10.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new ErrorLabel(
"feature name",
this.address.featureName,
fontSize: 15.0,
isBold: true,
),
new ErrorLabel("address lines", this.address.addressLine),
new ErrorLabel("country name", this.address.countryName),
new ErrorLabel("locality", this.address.locality),
new ErrorLabel("sub-locality", this.address.subLocality),
new ErrorLabel("admin-area", this.address.adminArea),
new ErrorLabel("sub-admin-area", this.address.subAdminArea),
new ErrorLabel("thoroughfare", this.address.thoroughfare),
new ErrorLabel("sub-thoroughfare", this.address.subThoroughfare),
new ErrorLabel("postal code", this.address.postalCode),
this.address.coordinates != null
? new ErrorLabel("", this.address.coordinates.toString())
: new ErrorLabel("coordinates", null),
]),
);
}
}
class AddressListView extends StatelessWidget {
final List<Address> addresses;
final bool isLoading;
AddressListView(this.isLoading, this.addresses);
@override
Widget build(BuildContext context) {
if (this.isLoading) {
return new Center(child: new CircularProgressIndicator());
}
return new ListView.builder(
itemCount: this.addresses.length,
itemBuilder: (c, i) => new AddressTile(this.addresses[i]),
);
}
}
class ErrorLabel extends StatelessWidget {
final String name, text;
final TextStyle descriptionStyle;
ErrorLabel(this.name, String text,
{double fontSize = 9.0, bool isBold = false})
: this.text = text ?? "Unknown $name",
this.descriptionStyle = new TextStyle(
fontSize: fontSize,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
color: text == null ? Colors.red : Colors.black);
@override
Widget build(BuildContext context) {
return new Text(this.text, style: descriptionStyle);
}
}
Here created an Input Text Widget and when user taps on it. This takes to google autocomplete screen, where user inputs the location.
TextFormField(
decoration: new InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(left: 15),
hintText: Strings.enter_your_house_number_street_etc,
hintStyle: TextStyle(
fontSize: 14,
color: AppColor.grey,
fontFamily: "Open Sans",
fontWeight: FontWeight.normal
)),
maxLines: 1,
controller: _address,
onTap: ()async{
// then get the Prediction selected
Prediction p = await PlacesAutocomplete.show(
context: context, apiKey: kGoogleApiKey,
onError: onError);
displayPrediction(p);
},
)
Here it is getting the lat and long of entered location.
Future<Null> displayPrediction(Prediction p) async {
if (p != null) {
PlacesDetailsResponse detail = await _places.getDetailsByPlaceId(p.placeId);
var placeId = p.placeId;
lat = detail.result.geometry.location.lat;
long = detail.result.geometry.location.lng;
var address =detail.result.formattedAddress;
print(lat);
print(long);
print(address);
setState(() {
_address.text = address;
});
}
}
import 'package:flutter_google_places/flutter_google_places.dart';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With