GeoPackage一个开放的地理空间信息的格式,基于标准的、平台独立的,可移植的、自描述、紧凑格式将地理空间信息。遵循OGC标准,数据库内核使用ormlite数据库。GeoPackage 数据库表可以转换成title进行地图绘制,有自已的表的边界范围等等。
github网址:https://github.com/ngageoint/geopackage-android
仓库地址:http://repo1.maven.org/maven2/mil/nga/geopackage/
这篇博客示例代码下载:http://download.csdn.net/download/qq_16064871/9937001
1、实现效果
2、简单的介绍
geopackage的数据库内核使用ormlite数据库
FeatureDao 带有Geometry的表,就是说这张表可以存储点,线,面,多边形等等的存储,当然还有其它属性。
AttributesDao 一般的数据库表。跟一般数据库字段基本是一样的。
数据库存储格式是gpkg。这种格式也是地图格式之一。不过一般存储的数据相当于数据库数据,不能直接加载与地图显示(osmdroid 加载gpkg格式的离线底图)。需要转换成title。或者自已拿出数据,进行屏幕上地图分辨率的转换,进行绘制也是可以的。在这里就先不做过多介绍。
下面主要介绍数据库的创建,增删查改。
3、数据库操作
创建数据库
mGeoManager = GeoPackageFactory.getManager(mContext); File file = new File(FilePathManage.GetInstance().getMapDirectoryPath(), GeopackageConstants.CREATE_ELEVATION_TILES_DB_FILE_NAME); //有数据库,直接打开 if (!file.exists()) { try { if (!mGeoManager.createAtPath(GeopackageConstants.CREATE_ELEVATION_TILES_DB_NAME, FilePathManage.GetInstance().getMapDirectory())) { Toast.makeText(mContext, "数据库创建失败", Toast.LENGTH_SHORT).show(); return; } } catch (Exception e) { e.printStackTrace(); Toast.makeText(mContext, "open storage permission", Toast.LENGTH_SHORT).show(); return; } }
创建FeatureDao 表,以及增删查改等示例代码
package com.custom.geopackage; import android.content.ContentValues; import java.util.ArrayList; import java.util.List; import java.util.Locale; import mil.nga.geopackage.BoundingBox; import mil.nga.geopackage.GeoPackage; import mil.nga.geopackage.attributes.AttributesCursor; import mil.nga.geopackage.db.GeoPackageDataType; import mil.nga.geopackage.features.columns.GeometryColumns; import mil.nga.geopackage.features.user.FeatureColumn; import mil.nga.geopackage.features.user.FeatureCursor; import mil.nga.geopackage.features.user.FeatureDao; import mil.nga.geopackage.features.user.FeatureRow; import mil.nga.geopackage.geom.GeoPackageGeometryData; import mil.nga.geopackage.projection.ProjectionConstants; import mil.nga.geopackage.schema.TableColumnKey; import mil.nga.wkb.geom.Geometry; import mil.nga.wkb.geom.GeometryType; import mil.nga.wkb.geom.Point; /** * 点的操作类 */ public class PointGeoOperation extends GeoOperationBase { private FeatureDao mPointTableDao; public PointGeoOperation(GeoPackage geoPackage) { super(geoPackage); } public void init() { if (mGeoPackage != null) mPointTableDao = mGeoPackage.getFeatureDao(GeopackageConstants.POINT_TABLE); } public FeatureDao getSurveyDao() { return mPointTableDao; } public boolean createTable() { //不存在表才创建表 if (mGeoPackage.isFeatureOrTileTable(GeopackageConstants.POINT_TABLE)){ return true; } try { //创建表 double minLat=-90+1; double maxLat=90-1; double minLon=-180+1;double maxLon= 180-1; BoundingBox boundingBox = new BoundingBox(minLon, maxLon, minLat, maxLat); GeometryColumns geometryColumns = new GeometryColumns(); //设置id geometryColumns.setId(new TableColumnKey(GeopackageConstants.POINT_TABLE, "geom")); //todo GeometryType 可以选择 点 线 面 多边形等等 geometryColumns.setGeometryType(GeometryType.POINT); geometryColumns.setZ((byte) 1); /** * 首先构建表的列,然后再构建表对象 */ int index = 0; List<FeatureColumn> columns = new ArrayList<FeatureColumn>(); columns.add(FeatureColumn.createPrimaryKeyColumn(index++, GeopackageConstants.FID)); columns.add(FeatureColumn.createGeometryColumn(index++, geometryColumns.getColumnName(), geometryColumns.getGeometryType(), false, null)); columns.add(FeatureColumn.createColumn(index++, GeopackageConstants.POINT_NAME, GeoPackageDataType.TEXT, true, "")); columns.add(FeatureColumn.createColumn(index++, GeopackageConstants.CODE, GeoPackageDataType.TEXT, true, "")); if (mGeoPackage != null) mGeoPackage.createFeatureTableWithMetadata(geometryColumns, boundingBox, ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM, columns); } catch (Exception e) { e.printStackTrace(); return false; } return true; } public boolean deleteTable() { if (mGeoPackage != null) mGeoPackage.deleteTable(GeopackageConstants.POINT_TABLE); return true; } public boolean insertData(Geometry geometry,ContentValues values) { try { GeoPackageGeometryData geomData = new GeoPackageGeometryData( mPointTableDao.getGeometryColumns().getSrsId()); geomData.setGeometry(geometry); FeatureRow row = mPointTableDao.newRow(); row.setGeometry(geomData); row.setValue(GeopackageConstants.POINT_NAME,values.getAsString(GeopackageConstants.POINT_NAME)); row.setValue(GeopackageConstants.CODE,values.getAsString(GeopackageConstants.CODE)); mPointTableDao.insert(row); } catch (Exception e) { e.printStackTrace(); } return true; } public boolean deleteData(int ID) { String queSQL = String.format(Locale.ENGLISH, GeopackageConstants.FID + "= %d",ID); return mPointTableDao.delete(queSQL,null) > 0; } private List<ContentValues> getAllSurveyPoint() { List<ContentValues> arrayslist = new ArrayList<ContentValues>(); if (mPointTableDao != null) { FeatureCursor cursor = mPointTableDao.queryForAll(); while (cursor.moveToNext()) { ContentValues contentValues = cursor.getRow().toContentValues(); arrayslist.add(0, contentValues); } } return arrayslist; } public List<FeatureRow> getAllPoint() { List<FeatureRow> arrayslist = new ArrayList<FeatureRow>(); if (mPointTableDao != null) { FeatureCursor cursor = mPointTableDao.queryForAll(); while (cursor.moveToNext()) { FeatureRow row = cursor.getRow(); Point point = (Point) row.getGeometry().getGeometry(); arrayslist.add(row); } } return arrayslist; } public void updateWithID(int ID,ContentValues values) { String queSQL = String.format(Locale.ENGLISH, GeopackageConstants.FID + "= %d",ID); if (mPointTableDao != null) mPointTableDao.update(values,queSQL,null); } public boolean updateGeomtry(FeatureRow row) { return mPointTableDao.update(row) > 0; } }
package com.custom.geopackage; import android.content.ContentValues; import java.util.ArrayList; import java.util.List; import java.util.Locale; import mil.nga.geopackage.GeoPackage; import mil.nga.geopackage.attributes.AttributesColumn; import mil.nga.geopackage.attributes.AttributesCursor; import mil.nga.geopackage.attributes.AttributesDao; import mil.nga.geopackage.attributes.AttributesRow; import mil.nga.geopackage.db.GeoPackageDataType; /** * 线操作类 */ public class LineGeoOperation extends GeoOperationBase{ //普通表 private AttributesDao commonDao; public LineGeoOperation(GeoPackage geoPackage) { super(geoPackage); } public void init() { commonDao = mGeoPackage.getAttributesDao(GeopackageConstants.LINE_TABLE); } public AttributesDao getSurveyDao() { return commonDao; } public boolean createTable() { //不存在表才创建表 if (mGeoPackage.isTable(GeopackageConstants.LINE_TABLE)){ return true; } int index = 1; List<AttributesColumn> additionalColumns = new ArrayList<>(); additionalColumns.add(AttributesColumn.createColumn(index++, GeopackageConstants.POINT_NAME, GeoPackageDataType.TEXT, false, "")); additionalColumns.add(AttributesColumn.createColumn(index++, GeopackageConstants.CODE, GeoPackageDataType.TEXT, false, "")); //根据需要在继续添加,等等 mGeoPackage.createAttributesTable(GeopackageConstants.LINE_TABLE, GeopackageConstants.FID, additionalColumns); return true; } public boolean deleteTable() { mGeoPackage.deleteTable(GeopackageConstants.POINT_TABLE); return true; } public boolean insertData(ContentValues values) { try { AttributesRow row = commonDao.newRow(); row.setValue(GeopackageConstants.POINT_NAME,values.getAsString(GeopackageConstants.POINT_NAME)); row.setValue(GeopackageConstants.CODE,values.getAsString(GeopackageConstants.CODE)); long fid = commonDao.insert(row); } catch (Exception e) { e.printStackTrace(); return false; } return true; } public boolean deleteData(int ID) { String queSQL = String.format(Locale.ENGLISH, GeopackageConstants.FID + "= %d",ID); return commonDao.delete(queSQL,null) > 0; } private List<ContentValues> getAllSurveyPoint() { AttributesCursor cursor = commonDao.queryForAll(); List<ContentValues> arrayslist = new ArrayList<ContentValues>(); while (cursor.moveToNext()) { ContentValues contentValues = cursor.getRow().toContentValues(); arrayslist.add(0, contentValues); } return arrayslist; } public List<AttributesRow> getAllPoint() { AttributesCursor cursor = commonDao.queryForAll(); List<AttributesRow> arrayslist = new ArrayList<AttributesRow>(); while (cursor.moveToNext()) { AttributesRow row = cursor.getRow(); arrayslist.add(row); } return arrayslist; } public void updateWithID(int ID,ContentValues values) { String queSQL = String.format(Locale.ENGLISH, GeopackageConstants.FID + "= %d",ID); commonDao.update(values,queSQL,null); } public boolean updateAttributesRow(AttributesRow row) { return commonDao.update(row) > 0; } }
这两个类的操作管理示例代码,就是一些初始化,打开数据库等
package com.custom.geopackage; import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.widget.Toast; import java.io.File; import mil.nga.geopackage.GeoPackage; import mil.nga.geopackage.GeoPackageManager; import mil.nga.geopackage.db.metadata.GeoPackageMetadata; import mil.nga.geopackage.db.metadata.GeoPackageMetadataDb; import mil.nga.geopackage.factory.GeoPackageFactory; public class CustomGeoPackageManager { private static GeoPackageManager mGeoManager; private Context mContext; private static CustomGeoPackageManager myGeoPackageManager = null; GeoPackage mGeoPackage; PointGeoOperation mPointGeoOperation = null; LineGeoOperation mLineGeoOperation = null; PolygonGeoOperation mPolygonGeoOperation = null; private CustomGeoPackageManager(Activity context) { this.mContext = context; mGeoManager = GeoPackageFactory.getManager(mContext); File file = new File(FilePathManage.GetInstance().getMapDirectoryPath(), GeopackageConstants.CREATE_ELEVATION_TILES_DB_FILE_NAME); //有数据库,直接打开 if (!file.exists()) { try { if (!mGeoManager.createAtPath(GeopackageConstants.CREATE_ELEVATION_TILES_DB_NAME, FilePathManage.GetInstance().getMapDirectory())) { Toast.makeText(mContext, "数据库创建失败", Toast.LENGTH_SHORT).show(); return; } } catch (Exception e) { e.printStackTrace(); Toast.makeText(mContext, "open storage permission", Toast.LENGTH_SHORT).show(); return; } } initGeopackageMetadata(); mGeoPackage = mGeoManager.open(GeopackageConstants.CREATE_ELEVATION_TILES_DB_NAME); if (mGeoPackage == null) return; getPointGeoOperation().createTable(); getPointGeoOperation().init(); getLineGeoOperation().createTable(); getLineGeoOperation().init(); } public static CustomGeoPackageManager getInstance(Activity context) { if (myGeoPackageManager == null && context != null) synchronized (CustomGeoPackageManager.class) { if (myGeoPackageManager == null) myGeoPackageManager = new CustomGeoPackageManager(context); } return myGeoPackageManager; } public GeoPackageManager getGeoPackageManager() { if (mGeoManager == null) { GeoPackageFactory.getManager(mContext); } return mGeoManager; } public PointGeoOperation getPointGeoOperation() { if (mPointGeoOperation == null) { mPointGeoOperation = new PointGeoOperation(mGeoPackage); } return mPointGeoOperation; } public LineGeoOperation getLineGeoOperation() { if (mLineGeoOperation == null) { mLineGeoOperation = new LineGeoOperation(mGeoPackage); } return mLineGeoOperation; } public PolygonGeoOperation getPolygonGeoOperation() { if (mPolygonGeoOperation == null) { mPolygonGeoOperation = new PolygonGeoOperation(mGeoPackage); } return mPolygonGeoOperation; } private void initGeopackageMetadata() { //TODO 卸载软件时候会把geopackage数据库内部存储的数据路径卸载掉,这里为了查找加上去 File file = new File(FilePathManage.GetInstance().getMapDirectoryPath()); File[] projectList = file.listFiles(); GeoPackageMetadataDb dbHelper = new GeoPackageMetadataDb(mContext); dbHelper.open(); SQLiteDatabase db = dbHelper.getWritableDatabase(); if (projectList == null ) return; for (File file1 : projectList) { String projectName = file1.getName(); Cursor query = db.query(GeoPackageMetadata.TABLE_NAME, null, "name=?", new String[]{projectName}, null, null, null); if (query.getCount() <= 0) { ContentValues values = new ContentValues(); values.put(GeoPackageMetadata.COLUMN_NAME, projectName); values.put(GeoPackageMetadata.COLUMN_EXTERNAL_PATH, FilePathManage.GetInstance().getMapDirectoryPath() + "/" + projectName + ".gpkg"); db.insert(GeoPackageMetadata.TABLE_NAME, null, values); } query.close(); } } }
看看activity怎么进行数据示例调用
@Override public void onClick(View v) { switch (v.getId()){ case R.id.button: //删除 String temp = mIDeditText.getText().toString().trim(); if(temp.isEmpty()) return; int id = Integer.parseInt(temp); if(id>0){ if(CustomGeoPackageManager.getInstance(this).getPointGeoOperation().deleteData(id)){ Toast.makeText(this,"delete succeed",Toast.LENGTH_SHORT).show(); }else Toast.makeText(this,"not exit id",Toast.LENGTH_SHORT).show(); } break; case R.id.button1: //增加 Geometry geometry = new Point(23,113); ContentValues values = new ContentValues(); values.put(GeopackageConstants.POINT_NAME,"point_name"); values.put(GeopackageConstants.CODE,"test_code"); if(CustomGeoPackageManager.getInstance(this).getPointGeoOperation().insertData(geometry,values)){ Toast.makeText(this,"add succeed",Toast.LENGTH_SHORT).show(); } break; case R.id.button2: //修改 //编辑点返回参数 if(CustomGeoPackageManager.getInstance(this).getPointGeoOperation().getAllPoint().size()>3){ FeatureRow row = CustomGeoPackageManager.getInstance(this).getPointGeoOperation().getAllPoint().get(2); GeoPackageGeometryData geomData = new GeoPackageGeometryData( CustomGeoPackageManager.getInstance(this).getPointGeoOperation().getSurveyDao().getGeometryColumns().getSrsId()); Point point = new Point(true,false,24, 114); point.setZ(new Double(114)); geomData.setGeometry(point); row.setGeometry(geomData); row.setValue(GeopackageConstants.POINT_NAME,"point_name2"); row.setValue(GeopackageConstants.CODE,"test_code"); if(CustomGeoPackageManager.getInstance(this).getPointGeoOperation().updateGeomtry(row)){ Toast.makeText(this,"update succeed",Toast.LENGTH_SHORT).show(); } } break; case R.id.button3: //查询 String strResult = "the table have " + String.valueOf(CustomGeoPackageManager.getInstance(this).getPointGeoOperation().getAllPoint().size()); Toast.makeText(this,strResult,Toast.LENGTH_SHORT).show(); break; ///////////////////////////////////////////////////////////////////////////// //普通表操作 case R.id.button5: //删除 String temp1 = mIDeditText1.getText().toString().trim(); if(temp1.isEmpty()) return; int id1 = Integer.parseInt(temp1); if(id1>0){ if(CustomGeoPackageManager.getInstance(this).getLineGeoOperation().deleteData(id1)){ Toast.makeText(this,"delete succeed",Toast.LENGTH_SHORT).show(); }else Toast.makeText(this,"not exit id",Toast.LENGTH_SHORT).show(); } break; case R.id.button4: //增加 ContentValues values1 = new ContentValues(); values1.put(GeopackageConstants.POINT_NAME,"line_name"); values1.put(GeopackageConstants.CODE,"test_code"); if(CustomGeoPackageManager.getInstance(this).getLineGeoOperation().insertData(values1)){ Toast.makeText(this,"add succeed",Toast.LENGTH_SHORT).show(); } break; case R.id.button6: //修改 if(CustomGeoPackageManager.getInstance(this).getLineGeoOperation().getAllPoint().size()>3){ AttributesRow row = CustomGeoPackageManager.getInstance(this).getLineGeoOperation().getAllPoint().get(2); row.setValue(GeopackageConstants.POINT_NAME,"point_name2"); row.setValue(GeopackageConstants.CODE,"test_code"); if(CustomGeoPackageManager.getInstance(this).getLineGeoOperation().updateAttributesRow(row)){ Toast.makeText(this,"update succeed",Toast.LENGTH_SHORT).show(); } } break; case R.id.button7: //查询 String strResult1 = "the table have " + String.valueOf(CustomGeoPackageManager.getInstance(this).getLineGeoOperation().getAllPoint().size()); Toast.makeText(this,strResult1,Toast.LENGTH_SHORT).show(); break; } }
数据库存储涉及到在机器上存储读写的权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
就先介绍到这里
作者:qq_16064871 发表于2017/8/18 8:59:12 原文链接
阅读:0 评论:0 查看评论