#2点間の距離を計測したい
###はじめに
この記事ではFlutterで緯度経度を利用して自分と対象地の距離を計測したい時に、自分で作った関数の失敗と公式関数の有用性を語っています。
###Flutter公式提供の関数
Future<void> getLocation() async {
// 現在の位置を返す
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.best);
print("緯度: " + position.latitude.toString());
print("経度: " + position.longitude.toString());
// 距離をメートルで返す
double distanceInMeters = Geolocator.distanceBetween(35.68, 139.76, -23.61, -46.40);
}
LocationAccuracy.bestの.bestを.hightや.lowにすることで計測精度を変えることができます。
###ヒュベニの公式を利用して実装した関数
double CalculateDisntance(double lat1, double lon1, double lat2, double lon2){
// 緯度経度をラジアンに変換
double radLat1 = lat1*(pi/180);
double radLon1 = lon1*(pi/180);
double radLat2 = lat2*(pi/180);
double radLon2 = lon2*(pi/180);
// 緯度差
double radratDiff = (radLat1 - radLat2);
// 経度差
double radlonDiff = (radLon1 - radLon2);
// 平均緯度
double radLatAverage = (radLat1 + radLat2);
// 赤道半径
double horizontal = 6377397.155;
// 離心率の2乗
double e2 = 0.00667436061028297;
double sinLat = radLatAverage.sign;
double w2 = 1.0 - e2 *(sinLat * sinLat);
// 子午曲半径M
double M = horizontal*(1-e2) / (sqrt(w2*w2*w2));
// 卯酉線曲率半径
double N = horizontal / (sqrt(w2));
double t1 = M * radratDiff;
double t2 = N * cos(radLatAverage) * radlonDiff;
double dist = sqrt((t1*t1)+(t2*t2));
return dist;
}
##計測結果
Flutter公式提供のGeolocator関数と私の作ったCalculateDisntance関数では計測値に大きな違いが出ました。
公式提供では誤差は5m以下だったのに対し私の距離計測関数は倍以上の誤差が生じてしまった。
緯度経度から自分と対象との距離を求めたい時は素直に公式関数を利用することを勧める。
##終わりに
今回私が距離を計測するために利用した関数はヒュベニの公式というもので、下記のサイトでは比較的誤差が小さくなっている。しかし、私が作成したものは大きな誤差がある。おそらくどこか見落としなどがあるのだろう。式が違う所などあればご教示願いたい。
また、公式関数は非常に正確だが、aync/awaitを利用する非同期処理なので、注意して利用して欲しい。
###参考リンク
ヒュベニの公式:https://komoriss.com/calculate-distance-between-two-points-from-latitude-and-longitude/
Flutter Package:https://pub.dev/packages/geolocator