Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtain coordinates from an address flutter

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

like image 542
marelizal Avatar asked Dec 06 '22 08:12

marelizal


2 Answers

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

enter image description here

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);
  }
}
like image 54
chunhunghan Avatar answered Jan 06 '23 18:01

chunhunghan


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';

like image 31
Aayush Singh Avatar answered Jan 06 '23 16:01

Aayush Singh