当前位置: 首页 > news >正文

基于Java和GeoTools的根据矢量BBOx自动生成格网文件实践

目录

前言

一、基础数据介绍及生成方法简介

1、矢量数据处理

2、格网生成算法

二、代码实现

1、根据Shp计算Bounds

2、生成经纬网要素集合

3、写入 Shapefile

三、结果输出与验证

1、格网文件输出格式

2、GIS工具验证

四、总结


前言

        在当今数字化与信息化高速发展的时代,地理空间数据在众多领域发挥着至关重要的作用,如城市规划、资源管理、环境监测、灾害预警等。矢量文件作为地理空间数据的重要存储形式之一,以其精确表达地理实体的形状、位置和属性等特点,被广泛应用于各种地理信息系统(GIS)项目中。然而,在一些特定的应用场景下,我们需要将矢量数据转换为格网文件格式,以便于进行更高效的计算、分析和可视化处理。格网数据在空间分析中具有独特的优势,例如在进行空间插值、地形分析、空间建模等方面,格网数据能够提供更直观、更易于处理的数据结构。然而,手动进行矢量文件到格网文件的转换往往耗费大量时间和精力,且容易出现人为错误,难以满足大规模、高效处理地理空间数据的需求。因此,开发一种基于 Java 和 GeoTools 的自动生成格网文件的方法具有重要的现实意义。

        Java 作为一种广泛使用的编程语言,以其跨平台性、稳定性和丰富的类库支持,为地理空间数据处理提供了强大的编程基础。GeoTools 作为开源的 Java GIS 工具库,为地理空间数据的读取、处理、分析和转换提供了丰富的功能和便捷的 API。通过结合 Java 和 GeoTools,我们可以充分利用它们的优势,实现矢量文件到格网文件的自动化转换。

        本实践旨在探索利用 Java 和 GeoTools 的强大功能,构建一个高效、准确的矢量文件转格网文件的系统。从矢量文件的读取与解析开始,深入研究如何根据矢量数据的空间分布和属性特征,自动划分格网并生成相应的格网文件。在实践过程中,我们将面临诸多挑战,如矢量数据的复杂性、格网划分的精度控制、数据转换的效率提升等,需要通过不断尝试和优化算法来解决。本文将详细阐述基于 Java 和 GeoTools 进行矢量文件转格网文件实践的过程、方法和技术细节,包括环境搭建、矢量数据处理、格网生成算法设计以及结果验证等方面。希望本实践研究能够为地理空间数据处理领域提供一种新的方法和思路,提高矢量文件转格网文件的效率和质量,为相关领域的研究和应用提供有力的支持和参考。

一、基础数据介绍及生成方法简介

        本节将对设计的基础数据和格网生成算法进行简单介绍,让大家在最开始的时候对实现过程有一个基本的思路。

1、矢量数据处理

        这里我们需要对湖南省及其相邻地市的范围数据进行后端的格网生成。首先需要准备的是一份面状的基础数据。大家可以在Qgis中打开这份数据,如下图所示:

        为了能更清晰的展示各地市的基本信息,我们使用分类样式对当前的矢量数据进行分类标绘,这是可以清晰的看到各地市的空间分布情况。 

    2、格网生成算法

            本文中说明的根据矢量文件自动生成格网的算法流程表示如下:

            流程步骤说明如下:

            1、使用GeoTools读取矢量数据 。

            2、提取矢量数据的边界框(BBOX)。

            3、创建要素集合

            4、生成经纬线格网(根据BBOX计算格网大小与分辨率)

            5、写入到Shp矢量文件中

            6、文件写入

            以上就是格网生成的具体实现步骤。熟悉了生成的算法步骤之后,下面就一起来一步一步的进行实现上面的经纬网生成实现。

    二、代码实现

            本节将按照前面的流程步骤说明,进一步的完成经纬格网的数据自动生成。本段的内容包含具体的实例代码,可以作为重点参考部分。

    1、根据Shp计算Bounds

            读取矢量数据并提取BBOX的关键代码如下:

    // 1. 读取源SHP文件
    File sourceFile = new File("F:/vector_data/2021年7月中国乡镇行政区划shp-(乡镇信息有点旧)/2021湖南省乡镇行政区划/湖南省/湖南省/湖南省_市界.shp");
    ShapefileDataStore dataStore = new ShapefileDataStore(sourceFile.toURI().toURL());
    ReferencedEnvelope bounds = dataStore.getFeatureSource().getBounds();        
    double minLon = bounds.getMinX();
    double maxLon = bounds.getMaxX();
    double minLat = bounds.getMinY();
    double maxLat = bounds.getMaxY();
    System.out.println(minLon);
    System.out.println(maxLon);
    System.out.println(minLat);
    System.out.println(maxLat);

    2、生成经纬网要素集合

            在获取了矢量数据的BBOX后,我们就可以根据BBOX的最大最小值来生成对应的经纬线。因此这里就成了文章的核心,如何根据bbox来生成经纬线数据。由于最后我们需要生成一个完整标准的shp文件,因此我们首先就需要创建一个要素信息,创建要素类型的代码如下:

    /** 创建要素类型 */
    private static SimpleFeatureType createFeatureType() throws SchemaException {SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();builder.setName("Graticule");builder.setCRS(WGS84);builder.add("geometry", LineString.class); // 几何字段builder.add("type", String.class);         // 类型(经线/纬线)builder.add("degree", Double.class);       // 度数return builder.buildFeatureType();
    }

             上面的代码就好像是在关系型数据库中,我们已经创建了一个表结构。里面包含了三个字段,第一个字段是空间属性数据,使用geometry来进行存储,除此之外还有两个属性字段,即类型(纬线还是经线),最后是一个标准的度数数据,这里采用的是默认的WGS84的地理坐标。有了表结构之后,接下来就是往表中写入数据。根据bbox来自动生成格网的关键代码如下:

    /** 创建线要素 */
    private static SimpleFeature createFeature(SimpleFeatureType type, LineString line, String typeStr, double degree) {SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);featureBuilder.set("geometry", line);featureBuilder.set("type", typeStr);featureBuilder.set("degree", degree);return featureBuilder.buildFeature(null);
    }
    /** 创建线段 */
    private static LineString createLine(double x1, double y1, double x2, double y2) {org.locationtech.jts.geom.Coordinate[] coordinates = {new org.locationtech.jts.geom.Coordinate(x1, y1),new org.locationtech.jts.geom.Coordinate(x2, y2)};return JTSFactoryFinder.getGeometryFactory().createLineString(coordinates);
    }

            接下来是生成格网的核心算法,这里采用循环的方式,自动按照矢量的边界范围进行生成。示例代码如下:

    /**
    * 生成经纬网要素集合
    * @param minLon 最小经度
    * @param maxLon 最大经度
    * @param minLat 最小纬度
    * @param maxLat 最大纬度
    * @param interval 间隔(度)
    */
    private static SimpleFeatureCollection generateGraticule(double minLon, double maxLon, double minLat, double maxLat, double interval) throws SchemaException {// 创建要素类型SimpleFeatureType TYPE = createFeatureType();// 存储所有要素的集合List<SimpleFeature> features = new ArrayList<>();// 生成经线(固定经度,纬度从 minLat 到 maxLat)for (double lon = minLon; lon <= maxLon; lon += interval) {LineString line = createLine(lon, minLat, lon, maxLat);features.add(createFeature(TYPE, line, "LON", lon));}// 生成纬线(固定纬度,经度从 minLon 到 maxLon)for (double lat = minLat; lat <= maxLat; lat += interval) {LineString line = createLine(minLon, lat, maxLon, lat);features.add(createFeature(TYPE, line, "LAT", lat));}return new ListFeatureCollection(TYPE, features);
    }

    3、写入 Shapefile

            这里我们将shp文件准备完成之后,接下来就是最重要的一步,即往shp文件中写入要素信息,这样就实现了生成的格网shapefile的落盘处理。写出shapefile的实现比较简单,示例代码如下:

    private static void writeToShapefile(SimpleFeatureCollection features, File file) throws IOException {// 方法 1:直接使用 ShapefileDataStoreFactoryShapefileDataStore dataStore = new ShapefileDataStore(file.toURI().toURL());dataStore.createSchema(features.getSchema());// 写入数据try (FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriterAppend(null)) {SimpleFeatureIterator iterator = features.features();while (iterator.hasNext()) {SimpleFeature feature = iterator.next();SimpleFeature newFeature = writer.next();newFeature.setAttributes(feature.getAttributes());writer.write();}iterator.close();}dataStore.dispose();
    }

            在需要调用的逻辑如下,需要定义一个本地保存的矢量文件。

    // 3、写入 Shapefile
    // 定义输出路径
    File shapefile = new File("D:/shp_test/graticule250508.shp");
    writeToShapefile(features, shapefile);
    System.out.println("完成!!!");

    三、结果输出与验证

            本节将对经过前面的步骤生成的格网成果进行输出和验证。

    1、格网文件输出格式

            经过前面的步骤在目标磁盘可以看到已经成功的生成我们需要的shp文件,打开磁盘目录如下图所示:

            表名需要的文件已经成功的生成到我们的目标磁盘中。 

    2、GIS工具验证

            将生成shp文件使用QGIS这样的GIS软件中进行查看,可以看到以下的效果:

            为了验证当前生成的经纬网线数据是否是符合目标的文件bbox范围的,我们再叠加原始的数据图层来校验一下。

            可以看到生成的格网数据是完全按照我们的预期来生成,需求得到了满足。 

    四、总结

            以上就是本文的主要内容,本实践旨在探索利用 Java 和 GeoTools 的强大功能,构建一个高效、准确的矢量文件转格网文件的系统。从矢量文件的读取与解析开始,深入研究如何根据矢量数据的空间分布和属性特征,自动划分格网并生成相应的格网文件。在实践过程中,我们将面临诸多挑战,如矢量数据的复杂性、格网划分的精度控制、数据转换的效率提升等,需要通过不断尝试和优化算法来解决。本文将详细阐述基于 Java 和 GeoTools 进行矢量文件转格网文件实践的过程、方法和技术细节,包括环境搭建、矢量数据处理、格网生成算法设计以及结果验证等方面。希望本实践研究能够为地理空间数据处理领域提供一种新的方法和思路,提高矢量文件转格网文件的效率和质量,为相关领域的研究和应用提供有力的支持和参考。当然在生成的结果中可以看到,还是存在一些不足,即我们生成的格网的末端不是很平滑,因此在未来我们可以优化以下末端的处理。同时对于经纬线的标注可以将值进行格式化一下,这样看起来会更加符合人类的习惯。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。

            实例代码已上传到资源库下载点击:使用Geotools自动提取Shp文件bbox生成格网示例。

    http://www.xdnf.cn/news/352675.html

    相关文章:

  • 基于C++的多线程网络爬虫设计与实现(CURL + 线程池)
  • Java游戏服务器开发流水账(3)游戏数据的缓存简介
  • 第04章—技术突击篇:如何根据求职意向进行快速提升与复盘
  • 数据库索引
  • 使用Java处理多客户端服务器:从传统线程到虚拟线程
  • [250509] x-cmd 发布 v0.5.11 beta:x ping 优化、AI 模型新增支持和语言变量调整
  • kotlin 数据类
  • Electron知识框架
  • 基于SSM + JSP 的个人通讯录管理系统
  • 使用 ANSYS AEDT(单向耦合)进行高功率同轴射频滤波器的热分析
  • 前端取经路——性能优化:唐僧的九道心经
  • 橡胶制品行业质检管理的痛点 质检LIMS如何重构橡胶制品质检价值链
  • STM32外设-串口UART
  • 项目高压生存指南:科学重构身体与认知系统的抗压算法
  • 计算机二级WPS Office第三套电子表格
  • 排序算法-插入排序
  • Linux快速入门
  • 排序算法-归并排序
  • 在线caj转换word
  • 安全核查基线-2.nfslock服务
  • 密码学--AES
  • 解密火星文:LeetCode 269 题详解与 Swift 实现
  • Uskin阵列式三轴力触觉传感器:驱动机器人智能的触觉数据专家
  • 达梦、PostgreSQL数据库讲json解析成临时表(json_table函数的使用)
  • HunyuanCustom, 腾讯混元开源的多模态定制视频生成框架
  • PostgreSQL 的 pg_advisory_lock 函数
  • 输入顶点坐标输出立方体长宽高的神经网络
  • Microsoft Azure DevOps针对Angular项目创建build版本的yaml
  • 【MySQL】存储引擎 - ARCHIVE、BLACKHOLE、MERGE详解
  • 电机密集型工厂环境下的无线通信技术选型与优化策略