Flutter - Get geocode address from coordinates - flutter

I've implemented a reliable way of getting user lat,long coordinates in an app I'm creating, but can't seem to turn these coordinates into a placemark.
I'd also like to figure out what I need to use to print this data.
This is what I'm trying to get this data with:
List<Placemark> place = [];
void _getPlace() async {
List<Placemark> newPlace = await _geolocator.placemarkFromCoordinates(_position.latitude, _position.longitude);
print(newPlace);
setState(() {
place = newPlace;
});
}
Thanks
Edit:
After CopsOnRoad's response, I'm getting this error:
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception:
NoSuchMethodError: The method 'placemarkFromCoordinates' was called on null.
Receiver: null
Tried calling: placemarkFromCoordinates(51.4998, -0.129)
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
#1 _NearbyPageState._getPlace
package:tr/pages/nearby.dart:128
<asynchronous suspension>
#2 _NearbyPageState._controlCard.<anonymous closure>
package:tr/pages/nearby.dart:629
#3 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:182
#4 TapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:365
#5 TapGestureRecognizer.acceptGesture
package:flutter/…/gestures/tap.dart:312
#6 GestureArenaManager.sweep
package:flutter/…/gestures/arena.dart:156
#7 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent
package:flutter/…/gestures/binding.dart:222
#8 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (p<…>

Update:
Use geocoding
import 'package:geocoding/geocoding.dart';
List<Placemark> placemarks = await placemarkFromCoordinates(52.2165157, 6.9437819);
Old solution:
You are already there, extra stuff that you need is:
String _address = ""; // create this variable
void _getPlace() async {
List<Placemark> newPlace = await _geolocator.placemarkFromCoordinates(_position.latitude, _position.longitude);
// this is all you need
Placemark placeMark = newPlace[0];
String name = placeMark.name;
String subLocality = placeMark.subLocality;
String locality = placeMark.locality;
String administrativeArea = placeMark.administrativeArea;
String postalCode = placeMark.postalCode;
String country = placeMark.country;
String address = "${name}, ${subLocality}, ${locality}, ${administrativeArea} ${postalCode}, ${country}";
print(address);
setState(() {
_address = address; // update _address
});
}

Placemark has been removed from geolocator starting from version 6.0.0 and moved to geocoding.
Starting from version 6.0.0 the geocoding features (placemarkFromAddress and placemarkFromCoordinates) are no longer part of the geolocator plugin. We have moved these features to their own plugin: geocoding. This new plugin is an improved version of the old methods.
To translate latitude and longitude into an address with geocoding use
List<Placemark> placemarks = await placemarkFromCoordinates(52.2165157, 6.9437819);

Use pub.dev flutter_geocoding
https://pub.dev/packages/flutter_geocoding
OR
I have used swift 'GMSGeocoder' and java 'android.location.Geocoder' and applied it to flutter.I think it is more efficient than the library Geocode in pub.dev.
My example code
Geocode library java and swift add by yourself
java
#Override
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "samples.flutter.dev/latlng")
.setMethodCallHandler(
(call, result) -> {
double lat = call.argument("lat");
double lng = call.argument("lng");
result.success("return value lat and lng");
}
);
}
swift
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/latlng",
binaryMessenger: controller.binaryMessenger)
batteryChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: #escaping FlutterResult) -> Void in
// Note: this method is invoked on the UI thread.
guard call.method == "latlng" else {
result(FlutterMethodNotImplemented)
return
}
self?.latlng(call,result: result)
})
GMSServices.provideAPIKey("")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func latlng(_ call: FlutterMethodCall,result:FlutterResult) {
if let args = call.arguments as? Dictionary<String, Any>,
let lat = args["lat"] as? Double ,let lng = args["lng"] as? Double {
result("return latlng result" )
} else {
result(FlutterError.init(code: "bad args", message: nil, details: nil))
}
}
flutter
Future<void> _getBatteryLevel(double a, double b) async {
String latlng;
try {
final String result = await const MethodChannel('samples.flutter.dev/latlng').invokeMethod(
'latlng', <String, dynamic>{"lat": a, "lng": b});
latlng = result;
} on PlatformException catch (e) {
latlng = "Failed to get latlng level: '${e.message}'.";
}
}

first, you have include lib -geolocator: ^3.0.1 in pubspec.yaml
///Get current location
Geolocator _geolocator = Geolocator();
String latitude = "";
String longitude = "";
String address = "";
Try this solution -
///Call this function
_fetchLocation() async {
Position position = await _geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);///Here you have choose level of distance
latitude = position.latitude.toString() ?? '';
longitude = position.longitude.toString() ?? '';
var placemarks = await _geolocator.placemarkFromCoordinates(position.latitude, position.longitude);
address ='${placemarks.first.name.isNotEmpty ? placemarks.first.name + ', ' : ''}${placemarks.first.thoroughfare.isNotEmpty ? placemarks.first.thoroughfare + ', ' : ''}${placemarks.first.subLocality.isNotEmpty ? placemarks.first.subLocality+ ', ' : ''}${placemarks.first.locality.isNotEmpty ? placemarks.first.locality+ ', ' : ''}${placemarks.first.subAdministrativeArea.isNotEmpty ? placemarks.first.subAdministrativeArea + ', ' : ''}${placemarks.first.postalCode.isNotEmpty ? placemarks.first.postalCode + ', ' : ''}${placemarks.first.administrativeArea.isNotEmpty ? placemarks.first.administrativeArea : ''}';
print("latitude"+latitude);
print("longitude"+longitude);
print("adreess"+address);
}

try {
await Geolocator()
.placemarkFromCoordinates(value[0], value[1])
.then((result) {
Placemark placeMark = result[0];
String name = placeMark.name;
String subLocality = placeMark.subLocality;
String locality = placeMark.locality;
String administrativeArea = placeMark.administrativeArea;
String postalCode = placeMark.postalCode;
String country = placeMark.country;
String address =
"${name}, ${subLocality}, ${locality}, ${administrativeArea} ${postalCode}, ${country}";
print(address);
});
} on PlatformException catch (e) {
print(e);
}

With Geolocator Plugin new version (from version 6.0.0). Geocoding features (placemarkFromAddress and placemarkFromCoordinates) are no longer part of the geolocator plugin. This method have moved these features to their own plugin: geocoding

Future getLatAndlong() async{
cl = await Geolocator.getCurrentPosition().then((value)=>value);
lat = cl.latitude;
long = cl.longitude;
_kGooglePlex = CameraPosition(
target: LatLng(lat,long),
zoom:14
);
List<Placemark> placemarks = await placemarkFromCoordinates(
lat, long);
print("country"+placemarks[0].country!);
print("area"+placemarks[0].administrativeArea!);
print("locality"+placemarks[0].locality!);
print("sublocality"+placemarks[0].subLocality!);
print("postlocality"+placemarks[0].postalCode!);
print("street"+placemarks[0].street!);
setState(() {
countrycurrent = placemarks[0].country!;
localcurrent = placemarks[0].administrativeArea!;
madinacurrent = placemarks[0].subLocality!;
curren=countrycurrent+","+localcurrent+","+madinacurrent;
});
mymarker.add(
Marker(
infoWindow: InfoWindow(
title: placemarks[0].country! + "," +
placemarks[0].administrativeArea! +
"," + placemarks[0].locality!
),
draggable: true,
icon:
BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueOrange),
markerId: MarkerId("4"),
position: LatLng(lat, long)),
);}

Related

Flutter map get address

This is all my code. I want it to be able to search for places from lat , lng , and if lat,lng is not there, it will search for places from names. But now it's like when searching for a place from the name. In the part where the name is converted to lat,lng it's correct but my marker appears in the middle of the sea
LatLng centerMap = LatLng(13.730452094709594, 100.64180575311175);
#override
void initState() {
findLocation();
super.initState();
}
void findLocation() async {
var lat = double.tryParse(searchitems[0].address![widget.index].latitude.toString());
var lng = double.tryParse(searchitems[0].address![widget.index].longitude.toString());
if (lat != null && lng != null) {
centerMap = LatLng(lat, lng);
} else {
var name = searchitems[0].name;
var addr = '${searchitems[0].address![widget.index].addr1!}, ${searchitems[0].address![widget.index].thanon!}, ${searchitems[0].address![widget.index].tambon!}, ${searchitems[0].address![widget.index].province!}';
var addresses = await Geocoder.local.findAddressesFromQuery(addr);
var first = addresses.first;
centerMap = LatLng(first.coordinates.latitude!, first.coordinates.longitude!);
print("Location not found, searching for name: $name and address: $addr");
}
print("map:$centerMap");
}
GoogleMap(
initialCameraPosition: CameraPosition(
target: centerMap,
zoom: 16.0,
),
You can add a controller in Google maps, then when you call the API and get new lat long, you can animate camera to that position like this:
Future<void> _goToNewPosition() async {
final GoogleMapController controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(_kLake));
}
There's also an example on the official package, you can check it out by this link

Get request of google maps api from postman is working properly but in the app it is showing null(NoSuchMethodError)

Why is the GET request to the Google Maps API working properly in Postman but showing a null error (NoSuchMethodError) when implemented in the app?
Environment
I've configured a local REST API:
static const String BASE_URL = "http://localhost:8000";
static const String GEOCODE_URI = "api/v1/config/geocode-api";
Code I'm Using
Here are the excerpts of the code I'm attempting this with.
The main implementation is in location_controller.dart:
<!-- location_controller.dart -->
import 'package:ecommerceapp/models/address_model.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get_connect/http/src/response/response.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:ecommerceapp/data/repositary/location_repo.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class LocationController extends GetxController implements GetxService {
LocationRepo locationRepo;
LocationController({
required this.locationRepo,
});
bool _loading = false;
late Position _position;
late Position _pickPosition;
Placemark _placemark = Placemark();
Placemark _pickPlacemark = Placemark();
List<AddressModel> _addressList = [];
late List<AddressModel> _allAddressList = [];
List<String> _addressTypelist = ["home", "office", "others"];
int _addressTypeIndex = 0;
late Map<String, dynamic> _getAddress;
late GoogleMapController _mapController;
List<AddressModel> get addressList => _addressList;
bool get loading => _loading;
Position get position => _position;
Position get pickPosition => _pickPosition;
Map get getAddress => _getAddress;
bool _updateAddressData = true;
bool _changeAddress = true;
void setMapController(GoogleMapController mapController) {
_mapController = mapController;
}
void updatePosition(CameraPosition position, bool fromAddress) async {
print("Update Position");
if (_updateAddressData) {
_loading = true;
update();
try {
if (fromAddress) {
_position = Position(
latitude: position.target.latitude,
longitude: position.target.longitude,
timestamp: DateTime.now(),
heading: 1,
accuracy: 1,
altitude: 1,
speedAccuracy: 1,
speed: 1,
);
} else {
_pickPosition = Position(
latitude: position.target.latitude,
longitude: position.target.longitude,
timestamp: DateTime.now(),
heading: 1,
accuracy: 1,
altitude: 1,
speedAccuracy: 1,
speed: 1,
);
}
if (_changeAddress) {
String _address = await getAddressfromGeocode(LatLng(position.target.latitude, position.target.longitude));
}
} catch (e) {
print(e);
}
}
}
Future<String> getAddressfromGeocode(LatLng latLng) async {
String _address = "Unknown Location Found";
print("Address : $_address");
Response response = await locationRepo.getAddressfromGeocode(latLng);
print("Status Code : ${response.statusCode}");
print(response.body);
if (response.body["status"] == "OK") {
_address = response.body["result"][0]['formatted_address'].toString();
print("Printing Address : $_address");
} else {
print("Error getting the google api");
}
return _address;
}
}
which calls the location_repo.dart:
import 'package:ecommerceapp/utils/app_constants.dart';
import 'package:get/get_connect/http/src/response/response.dart';
import 'package:google_maps_flutter_platform_interface/src/types/location.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:ecommerceapp/data/api/api_client.dart';
class LocationRepo {
final ApiClient apiClient;
final SharedPreferences sharedPreferences;
LocationRepo({
required this.apiClient,
required this.sharedPreferences,
});
Future<Response> getAddressfromGeocode(LatLng latLng) async {
return await apiClient.getData('${AppConstants.GEOCODE_URI}'
'?lat=${latLng.latitude}&lng=${latLng.longitude}');
}
}
In the getAddressfromGeocode method, when I tried to print the latitude and longitude, the print statements were also working fine:
Future<Response> getData(String uri, {Map<String, String>? headers}) async {
try {
Response response = await get(
uri,
headers: headers == null ? _mainHeaders : headers,
);
return response;
} catch (e) {
return Response(statusCode: 1, statusText: e.toString());
}
}
But, my code fails and response.body is null:
flutter: NoSuchMethodError: The method '\[\]' was called on null.
Receiver: null
Tried calling: \[\]("status")
I have no idea what I'm doing and still haven't asked ChatGTP, so I did not find any working solutions. Please help.

Flutter - <asynchronous suspension> with geocoder package

I need to get the city name from Longitude and Latitude.
I do not found a single package to do that, so I use location package to get Long and Lat and used geocoder to get the city name.
But I keep have this error and have no result :
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: PlatformException(failed, Failed, null, null)
and this one after it on the console: < asynchronous suspension >
Here is my code :
class _ProfileScreenState extends State<ExploreScreen> {
dynamic currentLocation;
double userLongitude;
double userLatitude;
Coordinates coordinates;
var addresses;
var first;
#override
initState() {
super.initState();
_getCurrentLongAndLat();
_getCurrentPosition(userLatitude, userLatitude);
}
Future _getCurrentLongAndLat() async {
currentLocation = LocationData;
var error;
var location = new Location();
try {
currentLocation = await location.getLocation();
userLatitude = currentLocation.latitude;
userLongitude = currentLocation.longitude;
print('$userLatitude $userLatitude');
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
}
currentLocation = null;
}
}
Future _getCurrentPosition(double long, double lat) async {
coordinates = new Coordinates(userLatitude, userLongitude);
addresses = await Geocoder.local.findAddressesFromCoordinates(coordinates);
print(addresses.first);
}
}
I realized flutter packages geolocator and location conflict with each other sometimes.
Try using geolocator to get your current position:
Future _getCurrentPosition() async {
Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high).then((Position position) {
setState(() {
_currentPosition = position;
userLongitude = position.longitude;
userLatitude = position.latitude;
});
});
}
It is a Future, so you can use await to really wait for results and after that call the getAddress function with the userLat and userLng.

GPS off message, and continous location update flutter

i made an app which uses the geolocator package to check for GPS and get the location of the user, and i use the provider package to handle the state. The problem is, when the GPS is switched off, a red screen appears that says the latitude was null, i would like to implement a screen to tell the user to switch on the GPS, and update the location accordingly.
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong/latlong.dart';
class MapState with ChangeNotifier {
bool locationServiceActive = true;
MapController _mapController;
MapController get mapController => _mapController;
static var _initialPosition;
var _lastPosition = _initialPosition;
LatLng get initialPosition => _initialPosition;
LatLng get lastPosition => _lastPosition;
MapState(){
checkGPS();
_getUserLocation();
}
checkGPS() async{
bool conn = await Geolocator().isLocationServiceEnabled();
if(conn == false){
locationServiceActive = false;
} else {
locationServiceActive = true;
}
notifyListeners();
}
void _getUserLocation() async{
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
print("/////////////////////////////////////////////////////////////////////////////////position");
print(position);
_initialPosition = LatLng(position.latitude, position.longitude);
notifyListeners();
}
}
update:-
i changed my _getUserLocation function to a stream, which works much better if the user switched on or off the gps (and it uses the last known location if the gps is off)... but it doesn't print the statement in the terminal if the position is null which is weird, only when there is lat and lng!!!
here is the modification i made...
void _getUserLocation() async{
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
var geolocator = Geolocator();
var locationOptions = LocationOptions(accuracy: LocationAccuracy.high, distanceFilter: 10);
StreamSubscription<Position> positionStream = geolocator.getPositionStream(locationOptions).listen(
(Position position) {
print("/////////////////////////////////////////////////////////////////////////// position");
print(position == null ? 'Unknown' : position.latitude.toString() + ', ' + position.longitude.toString());
});
_initialPosition = LatLng(position.latitude, position.longitude);
notifyListeners();
}
If you want to notify the user about the GPS, you can use something like this
#override
void initState() {
super.initState();
initPlatformState();
location.onLocationChanged.listen((result) {
currentLocation = result;
// your code
});
});
}
void initPlatformState() async {
LocationData currentLocation;
try {
currentLocation = await location.getLocation();
error = "";
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED')
error = 'Permission Denied';
else if (e.code == 'PERMISSION_DENIED_NEVER_ASK')
error =
'Permission denied - please ask the user to enable it from the app settings';
currentLocation = null;
}
setState(() {
currentLocation = currentLocation;
});
}
Here, you are listening to the location stream if enabled. In case it is not then it throws an error. The package being used here is location

How to get latitude and longitude in flutter

I can figure out how to get the user's latitude and longitude together, but need to get them individually to utilise the Geolocator().distanceBetween function from the Geolocator package. My code below keeps getting the error:
Unhandled Exception: NoSuchMethodError: The getter 'latitude' was called on null.
Receiver: null
Tried calling: latitude
Future<Position> getLocation() async {
var currentLocation;
try {
currentLocation = await geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
} catch (e) {
currentLocation = null;
}
return currentLocation;
}
void calculateDistance() async {
getLocation().then((position) {
userLocation = position;
});
final double myPositionLat = userLocation.latitude;
final double myPositionLong = userLocation.longitude;
final double TPLat = 51.5148731;
final double TPLong = -0.1923663;
final distanceInMetres = await Geolocator().distanceBetween(myPositionLat, myPositionLong, TPLat, TPLong)/1000;
print(distanceInMetres);
}
Try this :
void calculateDistance() async {
getLocation().then((position) {
userLocation = position;
final double myPositionLat = userLocation.latitude;
final double myPositionLong = userLocation.longitude;
final double TPLat = 51.5148731;
final double TPLong = -0.1923663;
final distanceInMetres = await Geolocator().distanceBetween(myPositionLat, myPositionLong, TPLat, TPLong)/1000;
print(distanceInMetres);
});
}
or another way of doing this is :
void calculateDistance() async {
userLocation = await getLocation();
final double myPositionLat = userLocation.latitude;
final double myPositionLong = userLocation.longitude;
final double TPLat = 51.5148731;
final double TPLong = -0.1923663;
final distanceInMetres = await Geolocator().distanceBetween(myPositionLat, myPositionLong, TPLat, TPLong)/1000;
print(distanceInMetres);
}