• GeoMesa Java API-写入与查询数据


    写入数据

    GeoMesa作为空间大数据处理框架,本身是不存储数据的。数据存储依赖于底层的分布式数据库,如HBase,Accumulo等。GeoMesa为了同时支持多种数据库,提供了一个抽象的接口,屏蔽不同数据库操作方法的差异,使用户用一种统一的方式存储和查询数据。来看下面这GeoMesa存储架构图:

    在这里插入图片描述

    ,无论采用何种方式写入数据,我们都不需要直接操作数据库,而只需按照GeoTools或GeoMesa的接口,规范好要存储的数据,提交给GeoMesa处理即可。GeoMesa会自动为我们完成创建元数据、创建索引、存储数据等一系列过程。

    GeoTools提供了许多用于表示地理空间数据的接口,可以用他们来定义需要存储的数据:

    DataStore

    DataStore是数据的核心访问模型,存储了数据集的名称、数据结构与类型、数据访问源等信息,类似一种数据元信息的存储集合,用于定义和描述数据的基本信息。

    SimpleFeatureType

    SimpleFeatureType即简单要素类型,用于定义数据类型,类似SQL语句中create table时定义表字段时所指定的信息。常用一种特殊格式的字符串表示,如:

    tpList:String,startTime:Date:default=true,startPoint:Point:srid=4326:default=true
    

    创建SimpleFeatureType时,需要使用GeoMesa提供的org.locationtech.geomesa.utils.interop.SimpleFeatureTypes类,而不是直接使用Geotools的DataUtilities创建,目的是为了支持更多的数据类型。

    sft = SimpleFeatureTypes.createType(getTypeName(), attributes.toString());
    

    SimpleFeatureType在DataStore中被称为Schema,使用dataStore.createSchema(sft)函数在DataStore中创建Schema。

    SimpleFeature

    SimpleFeature即简单要素,用于定义具体的数据。可以使用Geotools提供的SimpleFeatureBuilder类创建,只需要按照先前定义的SimpleFeatureType,依次传入相应类型的数据,最后设置Feature的ID即可,如:

    SimpleFeatureBuilder builder = new SimpleFeatureBuilder(getSimpleFeatureType());
    builder.set("tpList", ptListString);
    builder.set("startTime", new Date(Long.valueOf(startTime)*1000));
    builder.set("startPoint", "POINT (" + startPointY + " " + startPointX + ")");
    SimpleFeature feature = builder.buildFeature(id);
    

    其中,空间数据可以用WKT(well-known-text)格式的字符串来表示。

    写入

    创建好SimpleFeature后,就可以开始向数据库中写入数据了。
    使用Geotools提供的FeatureWriter执行写入操作,具体代码如下:

    FeatureWriter<SimpleFeatureType, SimpleFeature> writer = datastore.getFeatureWriterAppend(sft.getTypeName(), Transaction.AUTO_COMMIT)
    for (SimpleFeature feature : features) {
        SimpleFeature toWrite = writer.next();
        // copy attributes
        toWrite.setAttributes(feature.getAttributes());
        // if you want to set the feature ID, you have to cast to an implementation class
        // and add the USE_PROVIDED_FID hint to the user data
         ((FeatureIdImpl) toWrite.getIdentifier()).setID(feature.getID());
         toWrite.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.TRUE);
    
        // make sure to copy the user data, if there is any
        toWrite.getUserData().putAll(feature.getUserData());
    
        // write the feature
        writer.write();
    }
    

    查询数据

    GeoMesa同样使用了GeoTools工具,作为查询操作的接口,查询时的过程图如下:
    在这里插入图片描述

    使用GeoTools进行查询的基本流程如下:

    • ① 获取要查询的要素名称,即写入时SimpleFeatureType的Name
    • ② 对想要查询的字段,编写相应的查询条件,并创建Filter类型的对象
    • ③ 创建Query对象,将上一步中所有查询条件加入其中
    • ④ 执行查询,获得查询结果

    其中,查询条件可以使用GeoTools提供的CQL(GeoTools’ Contextual Query Language)或ECQL语句编写,并直接转换为Filter对象,例如:

    Filter result = CQL.toFilter("ATTR1 < 10 AND ATTR2 < 2 OR ATTR3 > 10" );
    Filter result = CQL.toFilter( "ATTR1 AFTER 2006-11-30T01:30:00Z/2006-12-31T01:30:00Z" );
    Filter result = CQL.toFilter( "CONTAINS(ATTR1, POINT(1 2))" );
    Filter result = CQL.toFilter( "BBOX(ATTR1, 10,20,30,40)" );
    Filter result = CQL.toFilter( "DWITHIN(ATTR1, POINT(1 2), 10, kilometers)" );
    

    执行查询时,使用FeatureReader完成查询操作,代码如下:

    List<SimpleFeature> queryFeatureList = new ArrayList<>();
    FeatureReader<SimpleFeatureType, SimpleFeature> reader = datastore.getFeatureReader(query, Transaction.AUTO_COMMIT) 
    int n = 0;
    while(reader.hasNext()){
        SimpleFeature feature=reader.next();
        queryFeatureList.add(feature);
        n++;
    }
    System.out.println();
    System.out.println("Returned"+n+"totalfeatures");
    

    几个常用查询条件

    设置最大返回条目:

    Query query = new Query(typeName, ECQL.toFilter(queryCQL));
    query.setMaxFeatures(Integer.parseInt(maxView));
    

    设置排序:

    Query query = new Query(typeName, ECQL.toFilter(queryCQL));
    FilterFactoryImpl ff = new FilterFactoryImpl();
    query.setSortBy(new SortBy[]{new SortByImpl(ff.property("startTime"), SortOrder.ASCENDING)});
    

    统计查询-查总数

    Query query = new Query(typeName);
    query.getHints().put(QueryHints.STATS_STRING(), "Count()");
    

    聚合查询-GroupBy,查每个分组的总数

    Query query = new Query(typeName);
    query.getHints().put(QueryHints.STATS_STRING(), "GroupBy("carID",Count())");
    

    统计查询-查最大最小值

    Query query = new Query(typeName);
    query.getHints().put(QueryHints.STATS_STRING(), "MinMax("startTime")");
    

    作者:涛O_O 链接:https://www.jianshu.com/p/cfbe6e7c89b2

  • 相关阅读:
    HA分布式集群二hive配置
    win下写任务提交给集群
    win10下将spark的程序提交给远程集群中运行
    Scala快学笔记(三)
    Scala快学笔记(二)
    Scala快学笔记(一)
    统计学习方法 三 kNN
    统计学习方法 二 感知机
    fluent python(一)
    Codewar (1)
  • 原文地址:https://www.cnblogs.com/aixing/p/13327390.html
Copyright © 2020-2023  润新知