Geotools-PG空间库(Crud,属性查询,空间查询)

2024-01-11 02:04

本文主要是介绍Geotools-PG空间库(Crud,属性查询,空间查询),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

建立连接

经过测试,这套连接逻辑除了支持纯PG以外,也支持人大金仓,凡是套壳PG的都可以尝试一下。我这里的测试环境是Geosence创建的pg SDE,数据库选用的是人大金仓。

/*** 获取数据库连接资源** @param connectConfig* @return* {@link PostgisNGDataStoreFactory} PostgisNGDataStoreFactory还有跟多的定制化参数可以进去看看* @throws Exception*/public static DataStore ConnectDatabase(GISConnectConfig connectConfig) throws Exception {if (pgDatastore != null) {return pgDatastore;}//数据库连接参数配置Map<String, Object> params = new HashMap<String, Object>();// 数据库类型params.put(PostgisNGDataStoreFactory.DBTYPE.key, connectConfig.getType());params.put(PostgisNGDataStoreFactory.HOST.key, connectConfig.getHost());params.put(PostgisNGDataStoreFactory.PORT.key, connectConfig.getPort());// 数据库名params.put(PostgisNGDataStoreFactory.DATABASE.key, connectConfig.getDataBase());//用户名和密码params.put(PostgisNGDataStoreFactory.USER.key, connectConfig.getUser());params.put(PostgisNGDataStoreFactory.PASSWD.key, connectConfig.getPassword());// 模式名称params.put(PostgisNGDataStoreFactory.SCHEMA.key, "sde");// 最大连接params.put( PostgisNGDataStoreFactory.MAXCONN.key, 25);// 最小连接params.put(PostgisNGDataStoreFactory.MINCONN.key, 10);// 超时时间params.put( PostgisNGDataStoreFactory.MAXWAIT.key, 10);try {pgDatastore = DataStoreFinder.getDataStore(params);return pgDatastore;} catch (IOException e) {LOG.error("获取数据源信息出错");}return null;}

查询

  • 查询所有的表格
/*** 查询所有的表格* @return* @throws IOException*/public List<String> getAllTables() throws IOException {String[] typeNames = this.dataStore.getTypeNames();List<String> tables = Arrays.stream(typeNames).collect(Collectors.toList());return tables;}

属性查询&&空间查询通用

 /*** 查询要素* @param layerName* @param filter* @return* @throws IOException*/public  SimpleFeatureCollection queryFeatures(String layerName, Filter filter) throws IOException {SimpleFeatureCollection features = null;try {SimpleFeatureSource featureSource = dataStore.getFeatureSource(layerName);features = featureSource.getFeatures(filter);return features;} catch (Exception e) {e.printStackTrace();}return features;}
  • 属性筛选查询
    用数据库查:
    在这里插入图片描述
SELECT *FROM mzxm_lx WHERE xmbh = '3308812023104'  AND zzdybh = '3308812023104003' AND zzlx = '10'

在这里插入图片描述
用代码查:

 SimpleFeatureCollection simpleFeatureCollection = pgTemplate.queryFeatures("mzxm_lx", CQL.toFilter("xmbh = '3308812023104'  AND zzdybh = '3308812023104003' AND zzlx = '10'"));

在这里插入图片描述

  • 空间筛选
Geometry geometry = new WKTReader().read("Polygon ((119.13571152004580256 29.96675730309299368, 119.14239751148502933 29.62242874397260195, 119.49341206204465493 29.84975245290645063, 119.23265839591465465 30.0670471746814556, 119.13571152004580256 29.96675730309299368))");
// 直接写SQL
Filter filter = CQL.toFilter("INTERSECTS(shape," + geometry .toString() + ")");
// 或者使用FilterFactory 
Within within = ff.within(ff.property("shape"), ff.literal(geometry));
SimpleFeatureCollection simpleFeatureCollection = pgTemplate.queryFeatures("mzxm_lx", within);

如果不知道使用的什么关键字就比如相交INTERSECTS,可以点进对应的这个空间关系里去看这个Name,和这个保持一致。
在这里插入图片描述

总结:这里就在于怎么去写这个Filter,可以直接使用SQL语法。也可以自己去构造,需要借助这两个类

private static FilterFactory2 spatialFilterFc = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints());
private static FilterFactory propertyFilterFc = CommonFactoryFinder.getFilterFactory(null);

添加要素

/*** * @param type * @param features 需要追加的要素* @throws IOException*/
public  void appendFeatures(SimpleFeatureType type, List<SimpleFeature> features) throws IOException {ListFeatureCollection featureCollection = new ListFeatureCollection(type, features);String typeName = type.getTypeName();FeatureStore featureStore = (FeatureStore) dataStore.getFeatureSource(typeName);try {featureStore.addFeatures(featureCollection);} catch (IOException e) {e.printStackTrace();}Transaction transaction = new DefaultTransaction("appendData");featureStore.setTransaction(transaction);transaction.commit();
}

测试代码:

Geometry geometry = new WKTReader().read("Polygon ((118.41044123299997182 29.89092741100000694, 118.42024576499994737 29.83296547499998042, 118.30907619399994246 29.75101510400003235, 118.19200671200002262 29.74673207400002184, 118.41044123299997182 29.89092741100000694))");SimpleFeature build = CustomFeatureBuilder.build(new HashMap<String, Object>() {{put("xmbh", "ceshiceshi");put("zxmmc", "测试一把");put("shape", geometry);}}, "mzxm_lx" , geometry);SimpleFeatureType simpleFeatureType = dataStore.getSchema("mzxm_lx");pgTemplate.appendFeatures(simpleFeatureType, Arrays.asList(build));

构建要素的代码如下:

/***  构建一个Feature* @param fieldsMap* @param typeName* @return*/public static SimpleFeature build(Map<String, Object> fieldsMap, String typeName) {SimpleFeatureTypeBuilder simpleFeatureTypeBuilder = new SimpleFeatureTypeBuilder();List<Object> values = new ArrayList<>();fieldsMap.forEach((key, val) -> {simpleFeatureTypeBuilder.add(key, val.getClass());values.add(val);});simpleFeatureTypeBuilder.setName(typeName);SimpleFeatureType simpleFeatureType = simpleFeatureTypeBuilder.buildFeatureType();SimpleFeatureBuilder builder = new SimpleFeatureBuilder(simpleFeatureType);builder.addAll(values);SimpleFeature feature = builder.buildFeature(null);return feature;}

在这里插入图片描述
图形也能正常展示:
在这里插入图片描述

/*** 通过FeatureWriter 追加要素* @param type* @param features* @throws IOException*/public  void appendFeatureByFeatureWriter(SimpleFeatureType type, List<SimpleFeature> features) throws IOException {String typeName = type.getTypeName();FeatureWriter<SimpleFeatureType, SimpleFeature> featureWriter = dataStore.getFeatureWriterAppend(typeName, new DefaultTransaction("appendData"));for (SimpleFeature feature : features) {SimpleFeature remoteNext = featureWriter.next();remoteNext.setAttributes(feature.getAttributes());remoteNext.setDefaultGeometry(feature.getDefaultGeometry());featureWriter.write();}featureWriter.close();}

使用FeatureWriter这个时候要注意啦,你插入的时候必须每个字段都设置值,追进源码里面发现它的SQL是写了所有字段的
源码路径:JDBCDataStore#insertNonPS

在这里插入图片描述
所以下面这种方式是不会成功的,要成功的话必须设置所有的字段对应上,我懒得弄了原理就是上面源码那样的:

// 错误示范
Geometry geometry = new WKTReader().read("Polygon ((118.41044123299997182 29.89092741100000694, 118.42024576499994737 29.83296547499998042, 118.30907619399994246 29.75101510400003235, 118.19200671200002262 29.74673207400002184, 118.41044123299997182 29.89092741100000694))");
SimpleFeature build = CustomFeatureBuilder.build(new HashMap<String, Object>() {{put("xmbh", "writer");put("zxmmc", "demo");put("zzdybh", "fdsa");put("shape", geometry);
}}, "mzxm_lx" );
SimpleFeatureType simpleFeatureType = dataStore.getSchema("mzxm_lx");
pgTemplate.appendFeatureByFeatureWriter(simpleFeatureType, Arrays.asList(build));

更新

  • 更新属性
/*** 更新属性* @param type* @param fieldsMap* @param filter* @throws IOException*/public  void updateFeatures(SimpleFeatureType type, Map<String, Object> fieldsMap, Filter filter) throws IOException {String typeName = type.getTypeName();List<Name> names =new ArrayList<>();FeatureStore featureStore = (FeatureStore) dataStore.getFeatureSource(typeName);Set<String> keys = fieldsMap.keySet();for (String field : keys) {Name name = new NameImpl(field);names.add(name);}featureStore.modifyFeatures(names.toArray(new NameImpl[names.size()]), fieldsMap.values().toArray(), filter);}

测试代码:

HashMap<String, Object> fieldsMap = new HashMap<String, Object>() {{put("xmbh", "testupdate");put("zxmmc", "update");put("zzdybh", "3308812023104003");
}};
SimpleFeatureType simpleFeatureType = dataStore.getSchema("mzxm_lx");
pgTemplate.updateFeatures(simpleFeatureType, fieldsMap, CQL.toFilter(" xmbh = 'ceshiceshi'"));

在这里插入图片描述
如果你需要更新几何,只需要设置几何字段即可:

HashMap<String, Object> fieldsMap = new HashMap<String, Object>() {{put("xmbh", "ces");put("zxmmc", "update");put("zzdybh", "3308812023104003");put("shape", geometry);}};

我们还可以这样写

/*** 覆盖更新* @param type* @param fieldsMap* @param filter* @throws IOException*/
public  void updateFeatureFeatureReader(SimpleFeatureType type, Map<String, Object> fieldsMap, Filter filter) throws IOException {String typeName = type.getTypeName();FeatureStore featureStore = (FeatureStore) dataStore.getFeatureSource(typeName);SimpleFeature simpleFeature = CustomFeatureBuilder.build(fieldsMap, typeName);// 设置一个 FeatureReaderFeatureReader<SimpleFeatureType, SimpleFeature> featureReader = new CollectionFeatureReader(simpleFeature);featureStore.setFeatures(featureReader);featureReader.close();
}

这里还需要注意一点,featureReaders 是覆盖更新的逻辑,所以使用的时候要谨慎一点
在这里插入图片描述

下面有这么多实现类,具体怎么组合使用就看你的想象力了:
在这里插入图片描述

删除要素

/*** 删除数据** @param layerName 图层名称* @param filter 过滤器*/
public  boolean deleteData(String layerName, Filter filter) {try {SimpleFeatureSource featureSource = dataStore.getFeatureSource(layerName);FeatureStore featureStore = (FeatureStore) featureSource;featureStore.removeFeatures(filter);Transaction transaction = new DefaultTransaction("delete");featureStore.setTransaction(transaction);transaction.commit();} catch (Exception e) {e.printStackTrace();return false;}return true;
}

完整DEMO

Demo 代码难免写的比较草率,不要喷我奥,哈哈哈哈哈

public class PgTemplate {
private final DataStore dataStore;public PgTemplate(DataStore dataStore) {this.dataStore = dataStore;
}/*** @param type* @param features 需要追加的要素* @throws IOException*/
public void appendFeatures(SimpleFeatureType type, List<SimpleFeature> features) throws IOException {ListFeatureCollection featureCollection = new ListFeatureCollection(type, features);String typeName = type.getTypeName();FeatureStore featureStore = (FeatureStore) dataStore.getFeatureSource(typeName);try {featureStore.addFeatures(featureCollection);} catch (IOException e) {e.printStackTrace();}Transaction transaction = new DefaultTransaction("appendData");featureStore.setTransaction(transaction);transaction.commit();
}/*** 更新属性** @param type* @param fieldsMap* @param filter* @throws IOException*/
public void updateFeatures(SimpleFeatureType type, Map<String, Object> fieldsMap, Filter filter) throws IOException {String typeName = type.getTypeName();List<Name> names = new ArrayList<>();FeatureStore featureStore = (FeatureStore) dataStore.getFeatureSource(typeName);Set<String> keys = fieldsMap.keySet();for (String field : keys) {Name name = new NameImpl(field);names.add(name);}featureStore.modifyFeatures(names.toArray(new NameImpl[names.size()]), fieldsMap.values().toArray(), filter);
}/*** 覆盖更新** @param type* @param fieldsMap* @param filter* @throws IOException*/
public void updateFeatureFeatureReader(SimpleFeatureType type, Map<String, Object> fieldsMap, Filter filter) throws IOException {String typeName = type.getTypeName();FeatureStore featureStore = (FeatureStore) dataStore.getFeatureSource(typeName);SimpleFeature simpleFeature = CustomFeatureBuilder.build(fieldsMap, typeName);FeatureReader<SimpleFeatureType, SimpleFeature> featureReader = new CollectionFeatureReader(simpleFeature);featureStore.setFeatures(featureReader);featureReader.close();
}/*** 通过FeatureWriter 追加要素** @param type* @param features* @throws IOException*/
public void appendFeatureByFeatureWriter(SimpleFeatureType type, List<SimpleFeature> features) throws IOException {String typeName = type.getTypeName();FeatureWriter<SimpleFeatureType, SimpleFeature> featureWriter = dataStore.getFeatureWriterAppend(typeName, new DefaultTransaction("appendData"));for (SimpleFeature feature : features) {SimpleFeature remoteNext = featureWriter.next();remoteNext.setAttributes(feature.getAttributes());remoteNext.setDefaultGeometry(feature.getDefaultGeometry());featureWriter.write();}featureWriter.close();
}/*** 删除数据** @param* @param* @param*/
public boolean deleteData(String layerName, Filter filter) {try {SimpleFeatureSource featureSource = dataStore.getFeatureSource(layerName);FeatureStore featureStore = (FeatureStore) featureSource;featureStore.removeFeatures(filter);Transaction transaction = new DefaultTransaction("delete");featureStore.setTransaction(transaction);transaction.commit();} catch (Exception e) {e.printStackTrace();return false;}return true;
}/*** 查询要素** @param layerName* @param filter* @return* @throws IOException*/
public SimpleFeatureCollection queryFeatures(String layerName, Filter filter) throws IOException {SimpleFeatureCollection features = null;try {SimpleFeatureSource featureSource = dataStore.getFeatureSource(layerName);features = featureSource.getFeatures(filter);return features;} catch (Exception e) {e.printStackTrace();}return features;
}/*** 查询要素** @param layerName* @param filter* @return* @throws IOException*/
public SimpleFeatureCollection queryFeaturesByFeatureReader(String layerName, Filter filter) throws IOException {FeatureReader<SimpleFeatureType, SimpleFeature> featureReader = dataStore.getFeatureReader(new Query(layerName, filter), new DefaultTransaction("query"));SimpleFeatureType featureType = featureReader.getFeatureType();List<SimpleFeature> features = new ArrayList<>();while (featureReader.hasNext()) {SimpleFeature next = featureReader.next();features.add(next);}return new ListFeatureCollection(featureType, features);
}/*** 查询所有的表格** @return* @throws IOException*/
public List<String> getAllTables() throws IOException {String[] typeNames = this.dataStore.getTypeNames();List<String> tables = Arrays.stream(typeNames).collect(Collectors.toList());return tables;
}

这篇关于Geotools-PG空间库(Crud,属性查询,空间查询)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/592784

相关文章

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Ubuntu如何分配​​未使用的空间

《Ubuntu如何分配​​未使用的空间》Ubuntu磁盘空间不足,实际未分配空间8.2G因LVM卷组名称格式差异(双破折号误写)导致无法扩展,确认正确卷组名后,使用lvextend和resize2fs... 目录1:原因2:操作3:报错5:解决问题:确认卷组名称​6:再次操作7:验证扩展是否成功8:问题已解

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as