如何将从移动GPS读取的LAT/LON信息存储到SQLITE数据库中?

发布于 2025-02-12 17:25:33 字数 112 浏览 1 评论 0原文

我构建了读取当前位置(每10-20米)的坐标的应用程序,当移动移动在街道上并显示当前的LAT/LON时,现在我想开发将这些LAT/LON保存到SQLITE数据库中的应用程序。任何帮助(指南)作为起点将不胜感激。

i build app that read coordinates of current location (every 10-20 meters) when move mobile in streets and displays current lat/lon, now i would like to develop app that save (storing) these lat/lon into a sqlite database. Any help (guide) as starting point would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一笑百媚生 2025-02-19 17:25:33

首先,您需要设计数据库架构。仅存储lat/lon可能会毫无用处。您说每10-20米,所以还有其他东西,也许是时候使LAT/LON有用。

因此,假设时间是与LAT/LON相结合的因素使其有用。然后,您需要存储LAT,LON和时间。

因此,这将是您的模式中的3列,因为ROWID(一个特殊的列)都包含在所有表中(一些较少使用的例外)。然后4列(ROWID唯一标识一行)。

因此您的模式可能是: -

  • 用于存储ROWID的列,但是如果使用标准的Android Basecolumns,则将使用等同于_id,存储的值将是一个唯一的整数(long),它将是主要键(它将是主要键(意味着独特的列)。
  • LON的LAT双列的列
  • 对于LON也
  • 足够了,可以将日期/时间存储在

下一阶段,即执行所有数据库处理内容。通过扩展SQLiteOpenhelper类,可以极大地简化这一点。

因此,您可以参加这样做的课程。该类必须实现两种越过的方法 ongreate onupgrade

  • 当创建数据库时,请调用onCreate,并且是创建表(s)或其他组件的地方(即设置架构)
    • 注意到这是数据库的寿命
  • 用于处理数据库版本时,并且超出了此答案的范围。它不会做任何事情。

您可能想最大程度地减少数据库的开放和关闭,因为这两者都可能是相对饥饿的资源。因此,建议采用单身方法,而无需关闭数据库。

您可能希望包括访问同类数据库(CRUD)的方法。

因此,将上述所有内容放在一起,例如 dbhelper as: -

class DBHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "the_database.db";
    public static final int DATABASE_VERSION = 1;

    public static final String TABLE_NAME_LATLON = "_latlon";
    public static final String COL_NAME_LATLON_ID = BaseColumns._ID;
    public static final String COL_NAME_LATLON_LAT = "_lat";
    public static final String COl_NAME_LATLON_LON = "_lon";
    public static final String COL_NAME_TIMESTAMP = "_timestamp";
    private static final String TABLE_LATLON_CRTSQL = "CREATE TABLE IF NOT EXISTS "
            + TABLE_NAME_LATLON + "("
            + COL_NAME_LATLON_ID + " INTEGER PRIMARY KEY"
            + "," + COL_NAME_LATLON_LAT + " REAL "
            + "," + COl_NAME_LATLON_LON + " REAL "
            + "," + COL_NAME_TIMESTAMP + " INTEGER "
            + ")";

    /* protect the constructor from being used elsewhere, thus forcing use of the singleton */
    private SQLiteDatabase db;
    private DBHelper(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
        db = this.getWritableDatabase();
    }

    /* Use a singleton approach */
    private volatile static DBHelper INSTANCE=null;

    public static DBHelper getInstance(Context context) {
        if (INSTANCE==null) {
            INSTANCE = new DBHelper(context);
        }
        return INSTANCE;
    }

    @Override /* REQUIRED - ****NOTE ONLY EVER RUNS ONCE FOR THE LIFETIME OF THE DATABASE**** */
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLE_LATLON_CRTSQL);
    }

    @Override /* REQUIRED (but doesn't have to do anything)*/
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    /* Full Insert method */
    public long insertLatLonRow(Long id,double lat, double lon,Long timestamp) {
        ContentValues cv = new ContentValues();
        if (id != null && id > -1) {
            cv.put(COL_NAME_LATLON_ID,id);
        }
        cv.put(COL_NAME_LATLON_LAT,lat);
        cv.put(COl_NAME_LATLON_LON,lon);
        if (timestamp == null) {
            timestamp = System.currentTimeMillis() / 1000;
        }
        cv.put(COL_NAME_TIMESTAMP,timestamp);
        return db.insert(TABLE_NAME_LATLON,null,cv);
    }
    /* Partial Insert method lat,lon and timestamp */
    public long insertLatLonRow(double lat, double lon, long timestamp) {
        return insertLatLonRow(null, lat,lon,timestamp);
    }
    /* Partial Insert method (calls full method) */
    public long insertLatLonRow(double lat, double lon) {
        return insertLatLonRow(null,lat,lon,null);
    }

    /* Extract data */
    public Cursor getLatLonsForAPeriod(long start_timestamp, long end_timestamp) {
        return db.query(
                TABLE_NAME_LATLON, /* The table that the rows will be SELECTed from */
                null /* ALL COLUMNS */,
                COL_NAME_TIMESTAMP + " BETWEEN ? AND ?", /* The WHERE clause (less the WHERE keyword) note that ?'s will be bound (replaced)*/
                new String[]{String.valueOf(start_timestamp),String.valueOf(end_timestamp)}, /* The values to be bound first replaces the first?, 2nd the 2nd .... */
                null, /* no GROUP BY clause*/
                null, /* no HAVING clause */
                COL_NAME_TIMESTAMP /* ORDER BY clause */
        );
    }
}

dbhelper不会独自一人做任何事情,所以这里是利用它的示例。这将插入一些数据(2行),然后提取数据并将其写入日志: -

public class MainActivity extends AppCompatActivity {

    DBHelper mDBHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHelper = DBHelper.getInstance(this);

        /* Add some test data */
        mDBHelper.insertLatLonRow(10.1,100.5678);
        mDBHelper.insertLatLonRow(null,11.1,11.6789,(System.currentTimeMillis() / 1000) - (60 * 60)); /* 1 hour before */

        /* Extract the data */
        Cursor csr = mDBHelper.getLatLonsForAPeriod((System.currentTimeMillis() / 1000) - (10 * 60 * 60),System.currentTimeMillis() / 1000 + (60 * 60));
        int id_offset = csr.getColumnIndex(DBHelper.COL_NAME_LATLON_ID);
        int lat_offset = csr.getColumnIndex(DBHelper.COL_NAME_LATLON_LAT);
        int lon_offset = csr.getColumnIndex(DBHelper.COl_NAME_LATLON_LON);
        int ts_offset = csr.getColumnIndex(DBHelper.COL_NAME_TIMESTAMP);
        while (csr.moveToNext()) {
            Log.d(
                    "LATLONINFO",
                    "ID is " + csr.getString(id_offset)
                            + " LAT is " + csr.getDouble(lat_offset)
                            + " LON is " + csr.getDouble(lon_offset)
                            + " TimeStamp is " + csr.getLong(ts_offset)

            );
        }
    }
}

结果: -

当运行2行插入2行时,第二行有一个时间1小时。 。然后提取数据(对于10小时前到将来1小时之间的行(所有均为fir均为此标准的行))。但是,由于它们是根据时间戳(按升序(默认)(默认值)进行排序的,第二行将首先显示。

因此,日志包括(如预期): -

D/LATLONINFO: ID is 2 LAT is 11.1 LON is 11.6789 TimeStamp is 1656841299
D/LATLONINFO: ID is 1 LAT is 10.1 LON is 100.5678 TimeStamp is 1656844899

First you would need to design the database schema. Storing just lat/lon would probably be pretty useless. You say every 10-20 meters, so there is something else, perhaps the time that makes the lat/lon useful.

So assuming that time is the factor that in conjuntion with the lat/lon makes it useful. Then per row you would want to store the lat, lon and time.

So that would be 3 columns in your schema, as the rowid (a special column) is included in all tables (with some less frequently used exceptions). Then 4 columns (the rowid uniquely identifies a row).

So your schema could be :-

  • a column for storing the rowid, but just in case the standard android BaseColumns will be used which equates to _ID, the value stored will be a unique integer (long) and it will be the PRIMARY KEY (which implies a unique column).
  • a column for the lat double should suffice
  • likewise for lon
  • the date/time can be stored as a long

Th next stage is to do all the database handling stuff. This is greatly simplified by extending the SQLiteOpenHelper class.

So you can have a class that does this. That class MUST implement two overiding methods onCreate and onUpgrade.

  • onCreate is invoked when the database is created and is where you create the table(s) and perhaps other components (i.e. setting up the schema)
    • Noting that this is once for the lifetime of the database
  • onUpgrade is for handling when the database version is changed and is beyond the scope of this answer. It will just do nothing.

You probably want to minimise the opening and closing of the database as both can be relatively resource hungry. So a singleton approach without any closing of the database is recommended.

You may wish to include the methods that access the database (the CRUD) in the class.

So putting all the above together you could have, for example the class DBHelper as :-

class DBHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "the_database.db";
    public static final int DATABASE_VERSION = 1;

    public static final String TABLE_NAME_LATLON = "_latlon";
    public static final String COL_NAME_LATLON_ID = BaseColumns._ID;
    public static final String COL_NAME_LATLON_LAT = "_lat";
    public static final String COl_NAME_LATLON_LON = "_lon";
    public static final String COL_NAME_TIMESTAMP = "_timestamp";
    private static final String TABLE_LATLON_CRTSQL = "CREATE TABLE IF NOT EXISTS "
            + TABLE_NAME_LATLON + "("
            + COL_NAME_LATLON_ID + " INTEGER PRIMARY KEY"
            + "," + COL_NAME_LATLON_LAT + " REAL "
            + "," + COl_NAME_LATLON_LON + " REAL "
            + "," + COL_NAME_TIMESTAMP + " INTEGER "
            + ")";

    /* protect the constructor from being used elsewhere, thus forcing use of the singleton */
    private SQLiteDatabase db;
    private DBHelper(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
        db = this.getWritableDatabase();
    }

    /* Use a singleton approach */
    private volatile static DBHelper INSTANCE=null;

    public static DBHelper getInstance(Context context) {
        if (INSTANCE==null) {
            INSTANCE = new DBHelper(context);
        }
        return INSTANCE;
    }

    @Override /* REQUIRED - ****NOTE ONLY EVER RUNS ONCE FOR THE LIFETIME OF THE DATABASE**** */
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLE_LATLON_CRTSQL);
    }

    @Override /* REQUIRED (but doesn't have to do anything)*/
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    /* Full Insert method */
    public long insertLatLonRow(Long id,double lat, double lon,Long timestamp) {
        ContentValues cv = new ContentValues();
        if (id != null && id > -1) {
            cv.put(COL_NAME_LATLON_ID,id);
        }
        cv.put(COL_NAME_LATLON_LAT,lat);
        cv.put(COl_NAME_LATLON_LON,lon);
        if (timestamp == null) {
            timestamp = System.currentTimeMillis() / 1000;
        }
        cv.put(COL_NAME_TIMESTAMP,timestamp);
        return db.insert(TABLE_NAME_LATLON,null,cv);
    }
    /* Partial Insert method lat,lon and timestamp */
    public long insertLatLonRow(double lat, double lon, long timestamp) {
        return insertLatLonRow(null, lat,lon,timestamp);
    }
    /* Partial Insert method (calls full method) */
    public long insertLatLonRow(double lat, double lon) {
        return insertLatLonRow(null,lat,lon,null);
    }

    /* Extract data */
    public Cursor getLatLonsForAPeriod(long start_timestamp, long end_timestamp) {
        return db.query(
                TABLE_NAME_LATLON, /* The table that the rows will be SELECTed from */
                null /* ALL COLUMNS */,
                COL_NAME_TIMESTAMP + " BETWEEN ? AND ?", /* The WHERE clause (less the WHERE keyword) note that ?'s will be bound (replaced)*/
                new String[]{String.valueOf(start_timestamp),String.valueOf(end_timestamp)}, /* The values to be bound first replaces the first?, 2nd the 2nd .... */
                null, /* no GROUP BY clause*/
                null, /* no HAVING clause */
                COL_NAME_TIMESTAMP /* ORDER BY clause */
        );
    }
}

The DBHelper will do nothing on it's own so here's an example of utilising it. This will insert some data (2 rows) and then extract the data and write it to the log:-

public class MainActivity extends AppCompatActivity {

    DBHelper mDBHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHelper = DBHelper.getInstance(this);

        /* Add some test data */
        mDBHelper.insertLatLonRow(10.1,100.5678);
        mDBHelper.insertLatLonRow(null,11.1,11.6789,(System.currentTimeMillis() / 1000) - (60 * 60)); /* 1 hour before */

        /* Extract the data */
        Cursor csr = mDBHelper.getLatLonsForAPeriod((System.currentTimeMillis() / 1000) - (10 * 60 * 60),System.currentTimeMillis() / 1000 + (60 * 60));
        int id_offset = csr.getColumnIndex(DBHelper.COL_NAME_LATLON_ID);
        int lat_offset = csr.getColumnIndex(DBHelper.COL_NAME_LATLON_LAT);
        int lon_offset = csr.getColumnIndex(DBHelper.COl_NAME_LATLON_LON);
        int ts_offset = csr.getColumnIndex(DBHelper.COL_NAME_TIMESTAMP);
        while (csr.moveToNext()) {
            Log.d(
                    "LATLONINFO",
                    "ID is " + csr.getString(id_offset)
                            + " LAT is " + csr.getDouble(lat_offset)
                            + " LON is " + csr.getDouble(lon_offset)
                            + " TimeStamp is " + csr.getLong(ts_offset)

            );
        }
    }
}

Result :-

When run 2 rows will be inserted the 2nd row have a time 1 hour before the first. Then the data is extracted (for rows between 10 hours ago and 1 hour in the future (all rows as both fir this criteria)). However, as they are ORDERED according to the timestamp (in ascending order (the default)) the 2nd row is shown first.

The log thus includes (as expected):-

D/LATLONINFO: ID is 2 LAT is 11.1 LON is 11.6789 TimeStamp is 1656841299
D/LATLONINFO: ID is 1 LAT is 10.1 LON is 100.5678 TimeStamp is 1656844899
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文