track distance and time based on my track details

2019-02-07 15:18发布

问题:

I am working on gps tracking in android to track the user location and provide the feature to record the track.I am able to draw path now i want to calculate the track distance and time with that like suppose user start tracking record and move to another location now i want to calculate total distance and time travel for from start to end position (with user location update) in google map. I have function which calculate the distance for 2 position but that not fit for my route, because route are in polyline and it's flexible lat/lng position. is their any api or any function or services provide by google for that. any help or suggestion are appreciate.

回答1:

I would create a class called waypoint

class WayPoint
{
   DateTime depart; //some date time container
   DateTime arrive; //some date time container
   Coordinate position; //some gps coordinate
}

Then create a list of these classes which allows inserting of elements at any position which is helpful if your route changes:

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);

Then convert to array and calculate the totals:

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));


回答2:

I have implement by my way, I have create inner class which extends the Overlay class to draw the path/route on map

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;
    }
}

create new object of this class and add into the map overlay like this way

trackOverlay = new TrackOverlay();
mapView.getOverlays().add(trackOverlay);

now I have draw the path when the user click on button to record the track and find the total distance and time for that I have create update method which will call from the locationChange() method when gps get new location that location will be pass to the map activity and store into the polyline object of the TrackOverlay class.

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;
        }
    }
}

ok every time this method was call and update the map with new point and in this I have use the Geo_Class.distFrom(x1, y1, x2, y2) my create method which was calculate the distance between two point and when getting new point set to the curr point and curr point will assign to the prev point. same way for time to calculate the total time. and also find the speed for that using this

speed = total distance/total time


回答3:

If you do have a set of lat/lon data within a timeline, you can calculate total distance by the sum of the distance between each set in that timeline.

I don’t know which formula you are using to calculate distance, but it is nice to take a look here.

It is a quite sensible topic since you are calculating distance on the surface of something that resemble a.. how can I say that.. a peach.

To illustrate the idea:

  • 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

Total time: 9hrs

Total distance: (a->b + b->c) = 630km + 342.4km = 972.4km