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

相关文章

浅谈mysql的sql_mode可能会限制你的查询

《浅谈mysql的sql_mode可能会限制你的查询》本文主要介绍了浅谈mysql的sql_mode可能会限制你的查询,这个问题主要说明的是,我们写的sql查询语句违背了聚合函数groupby的规则... 目录场景:问题描述原因分析:解决方案:第一种:修改后,只有当前生效,若是mysql服务重启,就会失效;

MySQL多列IN查询的实现

《MySQL多列IN查询的实现》多列IN查询是一种强大的筛选工具,它允许通过多字段组合快速过滤数据,本文主要介绍了MySQL多列IN查询的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析与优化1.

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

MySQL中实现多表查询的操作方法(配sql+实操图+案例巩固 通俗易懂版)

《MySQL中实现多表查询的操作方法(配sql+实操图+案例巩固通俗易懂版)》本文主要讲解了MySQL中的多表查询,包括子查询、笛卡尔积、自连接、多表查询的实现方法以及多列子查询等,通过实际例子和操... 目录复合查询1. 回顾查询基本操作group by 分组having1. 显示部门号为10的部门名,员

mysql关联查询速度慢的问题及解决

《mysql关联查询速度慢的问题及解决》:本文主要介绍mysql关联查询速度慢的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql关联查询速度慢1. 记录原因1.1 在一次线上的服务中1.2 最终发现2. 解决方案3. 具体操作总结mysql

HTML5 data-*自定义数据属性的示例代码

《HTML5data-*自定义数据属性的示例代码》HTML5的自定义数据属性(data-*)提供了一种标准化的方法在HTML元素上存储额外信息,可以通过JavaScript访问、修改和在CSS中使用... 目录引言基本概念使用自定义数据属性1. 在 html 中定义2. 通过 JavaScript 访问3.

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效