モバイル(iOSおよびAndroid)の実際の移動距離を計算したい。 Google Map APIを使用すると、2つの座標間の最適なルート距離を見つけることができます。しかし、距離を計算したいのですが、実際のモバイル(車内)の経路がカバーされています。
私が知った1つのアルゴは、x秒後に座標を保存し、5または10秒後に言って、連続した座標間の距離を計算すると、合計が合計距離を与えます。
私はその解決策のより良いアプローチについて議論したい、より良い解決策はありますか?
編集:Nike実行アプリやUberのようなアプリはどのように機能しますか?
------------------[〜#〜] update [〜#〜]--- -------------------
あなたの質問には2つの大きなポイントがあります。
1)電話座標を取得します(この応答の最初の部分で処理されています)
2)実この2つの座標間の距離を計算する
私見、計算はWebサービスによって実行できます。2つの座標間の距離のみに基づく計算は、本当に間違った結果につながる可能性があります。
このようなWebサービスの例を次に示します https://graphhopper.com/#directions-api
デモアプリ: https://graphhopper.com/api/1/examples/
(このツールの多くと同様に)トラフィックフローに基づいているため、間違った結果をもたらす可能性があるため、座標の順序に注意する必要があります。
これは良い結果をもたらします
同じ座標の場合、極端に異なる結果になる可能性があります。
したがって、座標ABCD(年代順)については、以下を行う必要があります。
A-> B B-> C C-> D
Graphhopperはオフライン距離計算を実行できるようです
IOSおよびAndroidのライブラリは次のとおりです。
https://github.com/graphhopper/graphhopper-ios/
https://github.com/graphhopper/graphhopper/tree/master/Android
----------------------------------------- ----------
アプリの動作を定義する必要があります。前景か背景か?
他の応答で述べたように、X秒ごとにユーザーの位置を取得する必要があります。次に、距離を計算します。
iOSの場合:
アプリがバックグラウンドにある場合のiOSでのユーザーの位置の追跡について説明します。
次に、ポイントのおかげで変換する必要があります
CLLocationDistance distance = [aCLLocationA distanceFromLocation:aCLLocationB];
これも確認できます(Apple doc) https://developer.Apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.htmlから) :
ロケーションマネージャーのpausesLocationUpdatesAutomaticallyプロパティがYESに設定されていることを確認します。このプロパティがYESに設定されている場合、ユーザーが移動する可能性が低い場合など、そうすることが理にかなっている場合はいつでも、コアロケーションはロケーション更新を一時停止します(ロケーションハードウェアの電源を切ります)。 (コアロケーションも、ロケーション修正を取得できない場合、更新を一時停止します。)
ロケーションマネージャーのactivityTypeプロパティに適切な値を割り当てます。このプロパティの値は、ロケーションマネージャーがロケーションの更新を一時停止しても安全かどうかを判断するのに役立ちます。ターンバイターンの自動車ナビゲーションを提供するアプリの場合、プロパティをCLActivityTypeAutomotiveNavigationに設定すると、ロケーションマネージャーは、ユーザーが一定の時間にわたって大きな距離を移動しない場合にのみイベントを一時停止します。
CLActivityTypeAutomotiveNavigation道路上の位置を確実に取得します。
Androidの場合:
TrackerSettingsオブジェクトのおかげで、ユーザーの位置を簡単に取得できます。
TrackerSettings settings =
new TrackerSettings()
.setUseGPS(true)
.setUseNetwork(true)
.setUsePassive(true)
.setTimeBetweenUpdates(30 * 60 * 1000)
.setMetersBetweenUpdates(100);
OS両方
X秒ごとに取得される位置に基づいて、位置データを取得する間隔を短縮して精度を向上させる必要があります。
道路のコンテキストで距離を計算する場合は、ロケーションマネージャーをナビゲーションモードに設定します。このモードでは、道路上の座標が得られます。
最後に
距離計算の精度を向上させる場合は、Google APIを使用できます。 https://developers.google.com/maps/documentation/distance-matrix/intro
正しいmodeパラメーターを設定することにより:
オプションのパラメーター
mode(デフォルトは運転モード)—距離を計算するときに使用する輸送モードを指定します。有効な値とその他のリクエストの詳細は、このドキュメントの旅行モードのセクションで指定されています。
私はAndoriodで似たようなことに取り組んでいますが、プリンシパルはiOSでも同じです:
onLocationChanged
メソッドを使用)。実行に使用する場合/ウォーキングでは、速度が遅いことを考慮してください-2つの連続した測定値は比較的近い値になりますが、GPSの精度により、それらの間の距離は非常に長くなります。または、それらのいくつかを無視することによって(つまり、10回ごとの読み取りのみを考慮に入れる)。Location.distanceTo()
メソッドで実行できます。車の走行距離計でテストし、加速度計のしきい値を調整する必要があります。
次の戦略を組み合わせることで、より高い精度を実現できます。
他の回答で述べたように、GPSを使用してX秒ごとにモバイルの位置を保存します(たとえば10秒)ポイント間の連続時間を測定します。
また、ユーザーがクイックターンを行うときは、磁気センサー値を使用してそれを必ず読み取ってください。そのような場合は、「位置記憶間のタイミング」を1- 2秒(正確さのために必要になります)
最後のステップとして、地図データ(Googleマップなど)を使用して、適切に追跡されていることを確認します(道路上にある場合)。
そして、すべての値を合計して正確な距離を取得します。
追伸Android(またはiOS)での実装についてはよく分からないので、戦略についてのみ情報を提供しました。
お役に立てれば :)
4年前、Landsurvayorというアプリを作成しました。このアプリは、Googleマップに描かれた2つの地理的ポイントの実際の距離を計算します。私はそれがあなたに役立つかもしれないかどうかは知りませんが、2つの地理的なポイント間の実際の距離を計算するHaversineの式と呼ばれる式がありますあなたはそれを試してみて、それがあなたにとって役に立つかどうかを見るかもしれません。 Haversine数式のサンプルコードは次のとおりです。
public double CalculationByDistance(double initialLat, double initialLong,
double finalLat, double finalLong){
int R = 6371; // km
double dLat = toRadians(finalLat-initialLat);
double dLon = toRadians(finalLong-initialLong);
lat1 = toRadians(lat1);
lat2 = toRadians(lat2);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
public double toRadians(deg) {
return deg * (Math.PI/180)
}
Haversineフォーミュラの詳細: https://en.wikipedia.org/wiki/Haversine_formula
2つの緯度経度間の距離を計算する別の簡単なAndroid SDKビルトインアプローチ:
Location locationA = new Location("point A");
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
Location locationB = new Location("point B");
locationB.setLatitude(latB);
LocationB.setLongitude(lngB);
distance = locationA.distanceTo(locationB) ;
それがあなたの助けになることを願っています。
正確な(またはほぼ正確な)距離情報を探している場合は、たどる経路を追跡する必要があります。つまり、数秒ごとに座標を確認する必要があります(予想される移動速度に応じて)。各セグメントを計算し、現在の移動距離を保存するだけで古い座標を破棄することにより、スペースを節約できます。
GPS座標の使用に関する1つの問題は、それらが(明らかに)正確ではないことです。直線で移動している場合、GPS座標はジグザグの経路で移動していることを示している可能性があるため、実際の距離よりも大きな移動距離を返します。 GPSの精度が良好であっても、このエラーは重大な場合があります。より少ない座標を使用すると、より正確な計算が行われる場合と行われない場合があります。
必要なのは、必要な精度を十分に考慮して、プロットされたGPSパスを滑らかにする方法です(これもトレードオフです)。
私の最初の考えは、ポイントをグループに分割し、各グループに線分を当てはめることです(「線形回帰」を調べてください)。次に、連続する各ラインペアが重複する場所を見つけて、各ラインセグメントを定義します。次に、線分の長さを合計します。
セグメントをカーブフィットすることもできますが、数学的にははるかに強力であり、より良い結果が得られない可能性があります(使用するカーブ式は?)。私が知らないより良い数学的な方法があるかもしれません。
お役に立てれば。
GPSを使用して両方の場所の緯度経度を取得し、両方を取得した後、メソッドの下にパスします。距離はkm単位で返されます
public static double getDistanceFromLatLonInKm(double lat1, double lon1,
double lat2, double lon2) {
double R = 6371; // Radius of the earth in km
double dLat = deg2rad(lat2 - lat1); // deg2rad below
double dLon = deg2rad(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
* Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = R * c; // Distance in km
return d;
}
public static double deg2rad(double deg) {
return deg * (Math.PI / 180);
}
}
精度が重要な場合は、加速度計とジャイロスコープのデータを使用できます。シンプルな映画のタスクを解決するための非常にシンプルな公式を見つけることができるので、グローバル軸でaccを取得できます。積分を2回使用する必要があります(最初に速度を取得し、位置を取得する)。別の視点を示すためだけに。
Android :: Androidでの歩行中の距離の計算方法
これを行うにはさまざまな方法があります。
1.GPS:X秒(10秒など)ごとに2ポイント間のGPS距離を追加し続けます。 Check Android Location.distanceToまたはdistanceBetween。MyTracksアプリをチェックしてください。オープンソースです。GPSは屋内では利用できず、ユーザーが頻繁に方向を変えている場合はエラーが発生します。 )2.加速度計:加速度計を使用したステップ検出用のコード/ライブラリを探します。距離は加速度の二重積分から生じるため、ここでエラーが急速に増加する場合があります。3.ステップ検出器:Nexus 5に組み込まれています。これはハードウェアベースの計算であり、バッテリーの消費は少なくなりますが、現在のほとんどの携帯電話では利用できません。
2番目のオプションはあなたが提案したものと非常に似ているようで、iOSとAndroidはコードと機能を延期し、それを達成するための最良の方法は保存することですcurrentLocationおよびpreviousLocationwhileループで。sleep()そして、移動距離に応じてループ全体を合計します。より大きな問題は、このアプリは距離サマー化アプリですか?それは内部の小さな機能ですか?距離の計算をいつ停止するかをどのように決定しますか?
X秒ごとにポイントをログに記録し(2〜3か?)、記録するすべてのポイントに対して以下の距離式を使用します。
Distance = sqrt((x2−x1)^2+(y2−y1)^2)
それらをすべて合計すると、距離が得られます