私はAndroidでgpsトラッキングに取り組んでおり、ユーザーの位置を追跡し、トラックを記録する機能を提供しています。パスを描画できるようになりました。ユーザーがレコードの追跡を開始して別の場所に移動すると仮定して、トラックの距離と時間を計算したいと思います。場所今私はグーグルマップで(ユーザーの場所の更新で)開始位置から終了位置までの合計距離とタイムトラベルを計算したいと思います。2つの位置の距離を計算する関数がありますが、ルートがポリラインであり、柔軟な緯度/経度の位置であるため、ルートに適合しません。そのためにグーグルが提供するAPIまたは機能やサービスです。どんな助けや提案もありがたいです。
3 に答える
ウェイポイントというクラスを作成します
class WayPoint
{
DateTime depart; //some date time container
DateTime arrive; //some date time container
Coordinate position; //some gps coordinate
}
次に、これらのクラスのリストを作成します。これにより、ルートが変更された場合に役立つ任意の位置に要素を挿入できます。
List<WayPoint> journey = new ArrayList<WayPoint>();
//just add your waypoints
journey.add(startWayPoint);
journey.add(wayPoint_1);
journey.add(wayPoint_2);
//...
journey.add(wayPoint_n_minus_2);
journey.add(wayPoint_n_minus_1);
journey.add(endWayPoint);
次に、配列に変換して合計を計算します。
WayPoint[] wayPoints = journey.toArray();
double total_distance = 0.0f; //distance in metres
double total_travel_time = 0.0f; // time in hours
//start at index 1 because there are n-1 segments
if(wayPoints.length>1)
foreach(int i=1; i<wayPoints.length;i++)
{
total_distance += calcDistanceBetween(
wayPoints[i-1].position,
wayPoints[i].position);
total_time += calcTimeInHoursBetween(
wayPoints[i-1].depart,
wayPoints[i].arrive);
}
log.d("Total Distance",String.valueOf(total_distance));
log.d("Total Travel Time",String.valueOf(total_travel_time));
ちなみに実装しました。Overlayクラスを拡張してマップ上にパス/ルートを描画する内部クラスを作成しました。
private class TrackOverlay extends Overlay {
private List<GeoPoint> polyline;
private Paint mPaint;
private Point p1;
public TrackOverlay() {
polyline = new ArrayList<GeoPoint>();
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
mPaint.setARGB(150, 62, 184, 240);
p1 = new Point();
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
if (drawTrack && polyline.size() > 0) {
mPaint.setARGB(120, 212, 51, 51);
drawTrackPath(canvas);
}
if (showTrack && polyline.size() > 0) {
mPaint.setARGB(150, 62, 184, 240);
drawTrackPath(canvas);
}
}
private void drawTrackPath(Canvas canvas) {
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
for (GeoPoint gp : polyline) {
mapView.getProjection().toPixels(gp, p1);
x2 = p1.x;
y2 = p1.y;
if (x1 != 0 && y1 != 0) {
canvas.drawLine(x1, y1, x2, y2, mPaint);
}
x1 = x2;
y1 = y2;
}
}
void addTrackPoint(GeoPoint geoPoint) {
polyline.add(geoPoint);
}
List<GeoPoint> getPolylineTrack() {
return polyline;
}
}
このクラスの新しいオブジェクトを作成し、このようにマップオーバーレイに追加します
trackOverlay = new TrackOverlay();
mapView.getOverlays().add(trackOverlay);
これで、ユーザーがボタンをクリックしてトラックを記録し、その合計距離と時間を見つけたときにパスを描画しました。gpsが新しい場所を取得したときにlocationChange()メソッドから呼び出すupdateメソッドを作成し、その場所が渡されます。マップアクティビティを作成し、TrackOverlayクラスのポリラインオブジェクトに保存します。
public static void updateMap() {
if (ServiceLocation.curLocation != null) {
curTime = ServiceLocation.curLocation.getTime();
curLat = ServiceLocation.curLocation.getLatitude();
curLng = ServiceLocation.curLocation.getLongitude();
if (mapView != null) {
point = new GeoPoint((int) (curLat * 1e6), (int) (curLng * 1e6));
mc.animateTo(point);
if (drawTrack && trackOverlay != null) {
trackOverlay.addTrackPoint(point);
if(prevTime>0)
totalSec += (curTime-prevTime);
double x1 = 0, x2 = 0, y1 = 0, y2 = 0, temp_dist=0,temp_speed=0;
if(trackOverlay.polyline.size()>1){
x1 = trackOverlay.polyline.get(trackOverlay.polyline.size()-2).getLatitudeE6()/1e6;
y1 = trackOverlay.polyline.get(trackOverlay.polyline.size()-2).getLongitudeE6()/1e6;
x2 = trackOverlay.polyline.get(trackOverlay.polyline.size()-1).getLatitudeE6()/1e6;
y2 = trackOverlay.polyline.get(trackOverlay.polyline.size()-1).getLongitudeE6()/1e6;
dist += (Geo_Class.distFrom(x1, y1, x2, y2) / METER_KILOMETER);
double totalMeter = dist * METER_KILOMETER;
double total_sec = (totalSec/1000) * KILOMETER_HOUR;
speed = totalMeter/total_sec;
txt_msg.setText("Distance " + round(dist,5,BigDecimal.ROUND_HALF_UP) + " km");
speed_msg.setText("Speed " + round(speed,3,BigDecimal.ROUND_HALF_UP) + " kmph \n time " +(totalSec/1000) + " sec");
}
}else{
totalSec = 0;
}
mapView.invalidate();
prevTime = curTime;
}
}
}
このメソッドが呼び出されてマップが新しいポイントで更新されるたびに、Geo_Class.distFrom(x1, y1, x2, y2)
2つのポイント間の距離を計算するmy createメソッドを使用しました。新しいポイントをcurrポイントに設定すると、currポイントがprevに割り当てられます。点。合計時間を計算する時間についても同じ方法です。また、これを使用してその速度を見つけます
speed = total distance/total time
タイムライン内に緯度/経度データのセットがある場合は、そのタイムライン内の各セット間の距離の合計によって合計距離を計算できます。
距離の計算に使用している数式はわかりませんが、こちらをご覧ください。
桃に似たものの表面の距離を計算しているので、これは非常に賢明なトピックです。
アイデアを説明するには:
- 01:00 pm = 50 21 50N、004 09 25W
- 05:00 pm = 45 21 50N、008 09 25W
- 10:00 pm = 42 21 04N、009 02 27W
合計時間:9時間
総距離:(a-> b + b-> c)= 630km + 342.4km = 972.4km