Flutter-geolocator: Calculate distance between two locations

Created on 29 Jun 2018  路  9Comments  路  Source: Baseflow/flutter-geolocator

Nice extra feature to have would be the option to calculate the distance between two points.

enhancement

Most helpful comment

import 'dart:math' show cos, sqrt, asin;

void main() {
double calculateDistance(lat1, lon1, lat2, lon2){
var p = 0.017453292519943295;
var c = cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * asin(sqrt(a));
}

double totalDistance = calculateDistance(26.196435, 78.197535,26.197195, 78.196408);

print(totalDistance);
}

All 9 comments

I needed this feature too, and really didn't want to do the complex calculations on my own, so I dug and found the dart package great_circle_distance which made it fairly easy to calculate the distance. Not saying it couldn't be integrated here, but at least it's a solution...

@Skquark do you have a code sample of that?

Sure, it was fairly simple.. The package is from github.com/yeradis/great_circle_distance.dart which gives 3 different formulas to do the math, but I'm not sure which method is most accurate. Here's my main function to measure, I'm using the GeoPoint class from Cloud FireStore since that's where I save it, but easily adapted to geolocator's Position...

import 'package:great_circle_distance/great_circle_distance.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geolocator/models/position.dart' as geoposition;

double getDistanceBetween(GeoPoint point1, GeoPoint point2, {int method = 1}) {
  var gcd = new GreatCircleDistance.fromDegrees(latitude1: point1.latitude, longitude1: point1.longitude, latitude2: point2.latitude, longitude2: point2.longitude);
  print('Distance from location 1 to 2 using the Haversine formula is: ${gcd.haversineDistance()}');
  print('Distance from location 1 to 2 using the Spherical Law of Cosines is: ${gcd.sphericalLawOfCosinesDistance()}');
  print('Distance from location 1 to 2 using the Vicenty`s formula is: ${gcd.vincentyDistance()}');
  if (method == 1)
    return gcd.haversineDistance();
  else if (method == 2)
    return gcd.sphericalLawOfCosinesDistance();
  else
    return gcd.vincentyDistance();
}

Future<GeoPoint> getCurrentGeoPoint() async {
  Geolocator _geolocator = new Geolocator();
  geoposition.Position position;
  GeoPoint geoPoint;
  try {
      position = await _geolocator.getPosition(LocationAccuracy.high);
      geoPoint = new GeoPoint(position.latitude, position.longitude);
  } on PlatformException {
      print("Couldn't get position");
      geoPoint = new GeoPoint(0.0, 0.0);
  }
  return geoPoint;
}

Easy enough to use. I have to to be honest though, I still haven't figured out what distance unit is being returned, if it's in km, m, mile, feet, dunno, wasn't spelled out in the docs or wiki page that I found. Haven't gotten around to calibrating yet. Let me know if you figure that out, I even dug into their source code a bit looking for a label, but good enough for now. . .

I also discovered FirebaseHelpers after I implemented with Great Circle Distance, and for the way I'm using it, I could have used that instead to filter the results by distance from the database query, might do that later.. Thought I'd mention that option in case anyone else could use that solution.

@martijn00, on Android you could simply use the distanceBetween or distanceTo methods on the Location class (see here).

On iOS you can use the distance method from the CLLocation class (see here).

Both are fairly straight forward and should be easy to implement.

import 'dart:math' show cos, sqrt, asin;

void main() {
double calculateDistance(lat1, lon1, lat2, lon2){
var p = 0.017453292519943295;
var c = cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * asin(sqrt(a));
}

double totalDistance = calculateDistance(26.196435, 78.197535,26.197195, 78.196408);

print(totalDistance);
}

Thank You for ticket, I also need help some other.
In my firebase coordinates of many object - about 200. I want show to user 3 nearest objects from these. How I need to do it correct?
Thank You

import 'dart:math' show cos, sqrt, asin;

void main() {
double calculateDistance(lat1, lon1, lat2, lon2){
var p = 0.017453292519943295;
var c = cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * asin(sqrt(a));
}

double totalDistance = calculateDistance(26.196435, 78.197535,26.197195, 78.196408);

print(totalDistance);
}

Is output KM right? how to get meter?

there is a librarie do that geo_locator its simple

I've used the vector_math for converting degree to radians and also the geolocator for getting the current user latitude and longitude if in case searching from the current location.

```
import 'dart:math' show sin, cos, sqrt, atan2;
import 'package:vector_math/vector_math.dart';
import 'package:geolocator/geolocator.dart';

Position _currentPosition;
double earthRadius = 6371000;

//Using pLat and pLng as dummy location
double pLat = 22.8965265; double pLng = 76.2545445;

//Use Geolocator to find the current location(latitude & longitude)
getUserLocation() async {
_currentPosition = await GeoLocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
}

//Calculating the distance between two points
getDistance(){
var dLat = radians(pLat - _currentPosition.latitude);
var dLng = radians(pLng - _currentPosition.longitude);
var a = sin(dLat/2) * sin(dLat/2) + cos(radians(_currentPosition.latitude))
* cos(radians(pLat)) * sin(dLng/2) * sin(dLng/2);
var c = 2 * atan2(sqrt(a), sqrt(1-a));
var d = earthRadius * c;
print(d); //d is the distance in meters
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

samo92 picture samo92  路  6Comments

long1eu picture long1eu  路  4Comments

prasant10050 picture prasant10050  路  6Comments

seakmengc picture seakmengc  路  3Comments

dark-chocolate picture dark-chocolate  路  3Comments