前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学HarmonyOS应用开发(55)- 使用对象关系映射数据库保存地图数据

自学HarmonyOS应用开发(55)- 使用对象关系映射数据库保存地图数据

作者头像
面向对象思考
发布2021-08-06 13:17:30
6680
发布2021-08-06 13:17:30
举报
文章被收录于专栏:C++核心准则原文翻译

前一篇文章实现了地图数据的正确表示,但是由于每次执行都需要至少一次从网上获取地图数据,不可避免地产生显示延迟。本文介绍利用对象数据库储存已经获取的地图数据,从而避免重复下载相同数据并大幅度提高初次显示速度的方法。

还是先看疗效:

配置“build.gradle”文件

修改对应HAP中的build.gradle文件,在ohos字段中增加compleOptions配置。

代码语言:javascript
复制
ohos {
    signingConfigs {
       ...
    }
    compileSdkVersion 5
    defaultConfig {
        compatibleSdkVersion 4
    }
    buildTypes {
        release {
            proguardOpt {
                proguardEnabled false
                rulesFiles 'proguard-rules.pro'
            }
        }
    }
    compileOptions{
        annotationEnabled true
    }
}

构建应用数据库

基本上不需要做什么,主要是在@Database宣言中声明两个数据表,这里我们只需要关注用来存储地图数据的TileDtata类。

代码语言:javascript
复制
代码语言:javascript
复制
@Database(entities = {TimeRecord.class, TileData.class}, version = 1)
public abstract class StopWatchDB extends OrmDatabase {
}

定义地图数据表类

首先在Entiry宣言中声明的表名和索引的构成。然后是字段的声明和每个字段的set和get方法。这些get和set方法都有固定的命名规则,不过不知道也没关系,编译出错时照着错误信息改就行了。

代码语言:javascript
复制
代码语言:javascript
复制
@Entity(tableName = "tile_data",
        indices = {@Index(value = {"type", "zoom", "tileX", "tileY"}, name = "tile_index", unique = true)})
public class TileData extends OrmObject {
    @PrimaryKey(autoGenerate = true)
    private Integer tileId;
    private Integer type;
    private Integer zoom;
    private Integer tileX;
    private Integer tileY;
    private Blob data;

    Integer getTileId(){
        return tileId;
    }

    void setTileId(Integer id){
        tileId = id;
    }

    Integer getType(){
        return type;
    }

    void setType(Integer t){
        type = t;
    }

    Integer getZoom(){
        return zoom;
    }

    void setZoom(int z){
        zoom = z;
    }

    Integer getTileX(){
        return tileX;
    }

    void setTileX(Integer x){
        tileX = x;
    }

    Integer getTileY(){
        return tileY;
    }

    void setTileY(Integer y){
        tileY = y;
    }

    Blob getData(){
        return data;
    }

    void setData(Blob _data){
        data = _data;
    }
}

本例中我们使用Blob类型保存地图数据,需要进行PixelMap和Blob之间的转换,为此我们准备了两个辅助方法:

代码语言:javascript
复制
void setPixelMap(PixelMap image){
    ImagePacker imagePacker = ImagePacker.create();
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
    packingOptions.quality = 100;
    imagePacker.initializePacking(os, packingOptions);
    imagePacker.addImage(image);
    imagePacker.finalizePacking();
    Blob blob = new Blob(os.toByteArray());
    setData(blob);
}

PixelMap getPixelMap(){
    InputStream is = getData().getBinaryStream();
    ImageSource source = ImageSource.create(is, new ImageSource.SourceOptions());
    ImageSource.DecodingOptions options = new ImageSource.DecodingOptions();
    options.desiredSize = new Size(512,512);
    return source.createPixelmap(options);
}

使用对象关系映射数据库

在应用启动时构建数据库:

代码语言:javascript
复制
DatabaseHelper helper = new DatabaseHelper(this);
OrmContext dbContext = helper.getOrmContext("StopWatch", "StopWatch.db", StopWatchDB.class);

使用数据库:

我们为地图数据设计了一个2级缓存类:一级是内存中的Map对象,二级是数据库:

代码语言:javascript
复制
代码语言:javascript
复制
public class TileDataStorage {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00207, "TileMapData");
    Map<Tile.MapSource, Integer> typeMap = new HashMap<Tile.MapSource, Integer>(){{
        put(Tile.MapSource.GAODE_ROAD, 0);
        put(Tile.MapSource.GAODE_SATELLITE,1);
        put(Tile.MapSource.GAODE_VECTOR, 2);
    }};

    Map<String, Tile> mapData = new HashMap<String, Tile>();
    OrmContext db;

    void setDbContext(OrmContext context){
        db = context;
    }

    void setData(Tile.MapSource source, int zoom, int tile_x, int tile_y, Tile tile){
        HiLog.info(LABEL, "TileMapData.setData Start x=%{public}d, y=%{public}d, z=%{public}d!",
                                tile_x, tile_y, zoom);
        int type = typeMap.get(source);
        mapData.put(getKey(type, zoom, tile_x, tile_y), tile);
        TileData td = new TileData();
        td.setType(type);
        td.setZoom(zoom);
        td.setTileX(tile_x);
        td.setTileY(tile_y);
        td.setPixelMap(tile.getPixelMap());
        HiLog.info(LABEL, "TileMapData.setData1!");
        boolean isSuccessed = db.insert(td);
        HiLog.info(LABEL, "TileMapData.setData2!");
        try {
            isSuccessed = db.flush();
        } catch (RdbConstraintException e) {
            HiLog.info(LABEL, "TileMapData.setData Exception!!!");
            db.update(td);
            db.flush();
            HiLog.info(LABEL, "TileMapData.insert->update!!!");
        }
        HiLog.info(LABEL, "TileMapData.setData End!");
    }

    Tile getData(Tile.MapSource source, int zoom, int tile_x, int tile_y){
        HiLog.info(LABEL, "TileMapData.getData!");
        int type = typeMap.get(source);
        Tile tile = mapData.get(getKey(type, zoom, tile_x, tile_y));
        if(tile != null) return tile;
        OrmPredicates query = db.where(TileData.class).equalTo("type", type).and().equalTo("zoom", zoom).and().equalTo("tileX", tile_x).and().equalTo("tileY", tile_y);
        List<TileData> tds = db.query(query);
        if (tds.size() > 0) {
            TileData td = (TileData) tds.get(0);
            tile = new Tile(td.getPixelMap());
            tile.setTileInfo(td.getTileX(), td.getTileY(), td.getZoom());
            mapData.put(getKey(type, zoom, tile_x, tile_y), tile);
            HiLog.info(LABEL, "TileMapData.getData success!");
            return tile;
        } else {
            HiLog.info(LABEL, "TileMapData.getData null!");
            return null;
        }
    }

    private String getKey(int type, int zoom, int tile_x, int tile_y){
        String key = String.format("%d.%d.%d.%d", type, zoom, tile_x, tile_y);
        return key;
    }
}

两次缓存的处理是通过setData和getData进行的。

代码语言:javascript
复制

参考代码

完整代码可以从以下链接下载:

https://github.com/xueweiguo/Harmony/tree/master/StopWatch

参考资料

开发-对象关系映射数据库概述 (harmonyos.com)

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-orm-overview-0000000000030070

开发-对象关系映射数据库开发指导 (harmonyos.com)

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-orm-guidelines-0000000000030063

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用对象关系映射数据库
  • 完整代码可以从以下链接下载:
  • 开发-对象关系映射数据库概述 (harmonyos.com)
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档