GIS 数据质检:验证 Geometry 有效性

前言

在GIS开发中,数据的几何有效性直接影响分析结果的准确性。无效的几何(如自相交、空洞或坐标错误)可能导致空间计算失败或输出偏差。无论是Shapefile、GeoJSON还是数据库中的空间数据,几何质检都是数据处理中不可忽视的关键步骤。

本篇教程在之前文章的基础上讲解如何将使用GeoTools检验Shapefile数据几何图形的有效性。

开发环境

本文使用如下开发环境,以供参考。

时间:2025年

GeoTools:34-SNAPSHOT

IDE:IDEA2025.1.2

JDK:17

1. 安装依赖

pom.xml文件中添加gt-shapefilegt-swing两个依赖。其中gt-shapefile用于shp数据的转换处理,gt-swing属于图形用户界面工具库,用于地理空间数据的可视化、交互操作和地图应用的快速开发。

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-shapefile</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-swing</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>${geotools.version}</version>
    </dependency>
</dependencies>
<repositories>
  <repository>
    <id>osgeo</id>
    <name>OSGeo Release Repository</name>
    <url>https://repo.osgeo.org/repository/release/</url>
    <snapshots><enabled>false</enabled></snapshots>
    <releases><enabled>true</enabled></releases>
  </repository>
  <repository>
    <id>osgeo-snapshot</id>
    <name>OSGeo Snapshot Repository</name>
    <url>https://repo.osgeo.org/repository/snapshot/</url>
    <snapshots><enabled>true</enabled></snapshots>
    <releases><enabled>false</enabled></releases>
  </repository>
</repositories>

2. 创建工具类

在开发工具中创建验证GeometryValidateGeometry

main方法中调用显示地图方法。

arduino 复制代码
public class ValidateGeometry {

    // 定义Shp源数据
    private File sourceFile;
    // 定义要素源
    private SimpleFeatureSource featureSource;
    // 定义地图组件
    private MapContent map;

    public static void main(String[] args) throws Exception {
        ValidateGeometry validateGeometry = new ValidateGeometry();
        // 打开地图显示Shp文件
        validateGeometry.displayShapefile();
    }

定义Shp显示方法,将其添加到地图窗口。通过在JMapFrame的工具栏上添加一个按钮来用于检要素几何对象是否有效(例如多边形边界是否闭合)。

ini 复制代码
// 显示Shp数据
private void displayShapefile() throws Exception{
    sourceFile = JFileDataStoreChooser.showOpenFile("shp",null);
    if(sourceFile==null){
        System.out.println("Shp 文件未知错误,请重新选择!");
        return;
    }
    // 数据仓库
    FileDataStore dataStore = FileDataStoreFinder.getDataStore(sourceFile);

    // 获取要素数据源
    featureSource = dataStore.getFeatureSource();

    // 创建地图
    map = new MapContent();
    Style style = SLD.createSimpleStyle(featureSource.getSchema());
    Layer layer = new FeatureLayer(featureSource,style);

    // 添加图层
    map.layers().add(layer);

    // 创建工具条
    JMapFrame  mapFrame = new JMapFrame(map);
    mapFrame.enableToolBar(true);
    mapFrame.enableStatusBar(true);

    JToolBar toolBar = mapFrame.getToolBar();
    toolBar.addSeparator();
    toolBar.add(new JButton(new ValidateGeometryAction()));

    // 设置地图窗口大小
    mapFrame.setSize(800,600);
    mapFrame.setVisible(true);
}

在上面的代码中使用JMapFrame创建了一个工具条,使用JButton创建了一个按钮,并将其添加到工具栏中。这个按钮的会触发一个动作ValidateGeometryAction,检验几何对象的有效性。

3. 验证 Geometry

通过定义一个内部嵌套类ValidateGeometryAction完成几何对象有效性的检验,大部分工作由父类中的辅助方法完成。

java 复制代码
// 定义内部嵌套类
class ValidateGeometryAction extends SafeAction {
     ValidateGeometryAction() {
         super("ValidateGeometryAction");
         putValue(Action.SHORT_DESCRIPTION, "check each geometry");
     }
     public void action(ActionEvent e) throws Throwable{
         // 记录无效 Geometry 数量
         int numInvalid  = validateFeatureGeometry(null);
         String msg;
         if(numInvalid==0){
             msg = "All feature geometries are valid";
         }else {
             msg = "Invalid feature geometries: " + numInvalid;
         }
         JOptionPane.showMessageDialog(null,msg,"Geometry Results",JOptionPane.INFORMATION_MESSAGE);
     }
}

当点击该检验按钮时,对Shp数据的几何对象进行验证,使用JOptionPane弹出框显示输出信息。

定义上文中的validateFeatureGeometry方法,用于统计错误几何图形的数量。此方法检查与shapefile中的每个要素关联的几何对象是否存在常见问题(例如没有闭合边界的多边形)。

java 复制代码
private int validateFeatureGeometry(ProgressListener progress) throws Exception{
    final SimpleFeatureCollection featureCollection = featureSource.getFeatures();

    // 创建一个 FeatureVisitor 来检查每个 fature
    class ValidationVisitor implements FeatureVisitor {
        public int numInvalidGeometries = 0;

        public void visit(Feature f) {
            SimpleFeature feature = (SimpleFeature) f;
            Geometry geometry = (Geometry) feature.getDefaultGeometry();
            if(geometry != null && !geometry.isValid()){
                numInvalidGeometries++;
                System.out.println("Invalid geometry: " + feature.getID());
            }
        }
    }
    ValidationVisitor validationVisitor = new ValidationVisitor();

    // 将检验器和进度条传递给要素集合
    featureCollection.accepts(validationVisitor,progress);
    return validationVisitor.numInvalidGeometries;
};

VALIDgeometry

OpenLayers示例数据下载,请回复关键字:ol数据

全国信息化工程师-GIS 应用水平考试资料,请回复关键字:GIS考试

【GIS之路】 已经接入了智能助手,欢迎关注,欢迎提问。

欢迎访问我的博客网站-长谈GIShttp://shanhaitalk.com

都看到这了,不要忘记点赞、收藏 + 关注

本号不定时更新有关 GIS开发 相关内容,欢迎关注 !

相关推荐
梦帮科技9 小时前
GRAVIS v4.0:基于Web的极速套利架构设计与实时数据流实现
前端·人工智能·rust·自动化·区块链·智能合约·数字货币
爱勇宝9 小时前
办公资料反复修改、补传、交接混乱,我做了个桌面工具来解决这件事
前端·后端·程序员
微信开发api-视频号协议10 小时前
企业微信外部群开发自动化实践过程
java·前端·微信·自动化·企业微信·ipad
甲维斯10 小时前
Fable5:20美金的顶级设计师!
前端·人工智能
kyriewen10 小时前
我同时用了 Claude Code、Cursor 和 Codex,说说三个工具的真实差距——2026 年选错工具比不用 AI 更浪费时间
前端·ai编程·claude
Jackson__10 小时前
为了拯救我的腰椎和颈椎,我做了款浏览器插件!
前端·javascript·开源
闲猫11 小时前
Python FastAPI + SQLAlchemy 入门教程:从零搭建你的第一个 Web 应用
前端·python·fastapi
林小帅11 小时前
NestJS v11 + Prisma v7 ESM 迁移配置解析
前端·javascript·后端
IT_陈寒11 小时前
React的setState竟然不是立刻生效的,害我调试半天
前端·人工智能·后端
简简单单就是我_hehe11 小时前
前端埋点日志解决方案:完整 User-Agent 解析工具实现,爬虫识别、设备品牌、操作系统、浏览器版本全解析(附完整源码)
前端·爬虫