org.runnerup.export.format.FacebookCourse.java Source code

Java tutorial

Introduction

Here is the source code for org.runnerup.export.format.FacebookCourse.java

Source

/*
 * Copyright (C) 2014 jonas.oreland@gmail.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.runnerup.export.format;

import android.annotation.TargetApi;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.os.Build;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.runnerup.common.util.Constants.DB;
import org.runnerup.util.Formatter;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * @author jonas.oreland@gmail.com
 */

@TargetApi(Build.VERSION_CODES.FROYO)
public class FacebookCourse {

    long mID = 0;
    SQLiteDatabase mDB = null;
    Formatter formatter = null;
    final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ", Locale.getDefault());

    public FacebookCourse(Context ctx, SQLiteDatabase db) {
        mDB = db;
        formatter = new Formatter(ctx);
    }

    String formatTime(long time) {
        return dateFormat.format(new Date(time));
    }

    JSONObject pace(double distance, double duration) throws JSONException {
        if (distance != 0)
            return pace(duration / distance);
        return null;
    }

    JSONObject pace(double val) throws JSONException {
        if (formatter.getUnitMeters() == Formatter.km_meters) {
            return new JSONObject().put("value", val).put("units", "s/m");
        } else {
            return new JSONObject().put("value", val).put("units", " s/ft");
        }
    }

    public JSONObject export(long activityId, boolean showTrail, JSONObject runObj)
            throws IOException, JSONException {

        final String[] aColumns = { DB.ACTIVITY.NAME, DB.ACTIVITY.COMMENT, DB.ACTIVITY.START_TIME,
                DB.ACTIVITY.DISTANCE, DB.ACTIVITY.TIME, DB.ACTIVITY.SPORT };
        Cursor cursor = mDB.query(DB.ACTIVITY.TABLE, aColumns, "_id = " + activityId, null, null, null, null);
        cursor.moveToFirst();

        if (runObj != null) {
            runObj.put("sport", cursor.getInt(5));
            runObj.put("startTime", cursor.getLong(2));
            runObj.put("endTime", cursor.getLong(2) + cursor.getLong(4));
            if (!cursor.isNull(1))
                runObj.put("comment", cursor.getString(1));
        }

        JSONObject obj = new JSONObject();
        double distance = cursor.getDouble(3);
        long duration = cursor.getLong(4);
        cursor.close();

        double unitMeters = formatter.getUnitMeters();
        if (distance < unitMeters) {
            obj.put("distance", new JSONObject().put("value", distance).put("units", "m"));
        } else {
            final int decimals = 1;
            double base = distance / unitMeters;
            double val = Formatter.round(base, decimals);
            obj.put("distance", new JSONObject().put("value", val).put("units", formatter.getUnitString()));
        }

        obj.put("duration", new JSONObject().put("value", duration).put("units", "s"));
        if (distance != 0) {
            obj.put("pace", pace(distance, duration));
        }

        if (showTrail) {
            JSONArray trail = trail(activityId);
            if (trail != null)
                obj.put("metrics", trail);
        }

        return obj;
    }

    private JSONArray trail(long activityId) throws JSONException {
        final String cols[] = { DB.LOCATION.TYPE, DB.LOCATION.LATITUDE, DB.LOCATION.LONGITUDE, DB.LOCATION.TIME,
                DB.LOCATION.SPEED };
        Cursor c = mDB.query(DB.LOCATION.TABLE, cols, DB.LOCATION.ACTIVITY + " = " + activityId, null, null, null,
                null);
        if (c.moveToFirst()) {
            Location prev = null, last = null;
            double sumDist = 0;
            long sumTime = 0;
            double accTime = 0;
            final double period = 30;
            JSONArray arr = new JSONArray();
            do {
                switch (c.getInt(0)) {
                case DB.LOCATION.TYPE_START:
                case DB.LOCATION.TYPE_RESUME:
                    last = new Location("Dill");
                    last.setLatitude(c.getDouble(1));
                    last.setLongitude(c.getDouble(2));
                    last.setTime(c.getLong(3));
                    accTime = period * 1000; // always emit first point
                                             // start/resume
                    break;
                case DB.LOCATION.TYPE_END:
                    accTime = period * 1000; // always emit last point
                case DB.LOCATION.TYPE_GPS:
                case DB.LOCATION.TYPE_PAUSE:
                    Location l = new Location("Sill");
                    l.setLatitude(c.getDouble(1));
                    l.setLongitude(c.getDouble(2));
                    l.setTime(c.getLong(3));
                    if (!c.isNull(4))
                        l.setSpeed(c.getFloat(4));
                    if (last != null) {
                        sumDist += l.distanceTo(last);
                        sumTime += l.getTime() - last.getTime();
                        accTime += l.getTime() - last.getTime();
                    }
                    prev = last;
                    last = l;
                }
                if (Math.round(accTime / 1000) >= period) {
                    arr.put(point(prev, last, sumTime, sumDist));
                    accTime -= period * 1000;
                }
            } while (c.moveToNext());
            c.close();
            return arr;
        }
        c.close();
        return null;
    }

    private JSONObject point(Location prev, Location last, long sumTime, double sumDist) throws JSONException {
        JSONObject obj = new JSONObject();
        obj.put("location",
                new JSONObject().put("latitude", last.getLatitude()).put("longitude", last.getLongitude()));
        obj.put("distance", new JSONObject().put("value", sumDist / 1000.0).put("units", "km"));
        obj.put("timestamp", formatTime(last.getTime()));
        if (last.hasSpeed() && last.getSpeed() > 0) {
            obj.put("pace", pace(1.0f / last.getSpeed()));
        }
        return obj;
    }
}