Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

geopackage-android 开源的地理空间信息数据库存储

$
0
0

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


创建AttributesDao 表,增删查改的示例代码

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 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>