^ 关注我,带你一起学GIS ^
前言
❝在GIS开发中,数据的几何有效性直接影响分析结果的准确性。无效的几何(如自相交、空洞或坐标错误)可能导致空间计算失败或输出偏差。无论是Shapefile、GeoJSON还是数据库中的空间数据,几何质检都是数据处理中不可忽视的关键步骤。
本篇教程在之前文章的基础上讲解如何将使用GeoTools
检验Shapefile
数据几何图形的有效性。
开发环境
本文使用如下开发环境,以供参考。
时间:2025年
GeoTools:34-SNAPSHOT
IDE:IDEA2025.1.2
JDK:17
1. 安装依赖
在pom.xml
文件中添加gt-shapefile
和gt-swing
两个依赖。其中gt-shapefile
用于shp
数据的转换处理,gt-swing
属于图形用户界面工具库,用于地理空间数据的可视化、交互操作和地图应用的快速开发。
<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. 创建工具类
在开发工具中创建验证Geometry
类ValidateGeometry
。
在main
方法中调用显示地图方法。
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
的工具栏上添加一个按钮来用于检要素几何对象是否有效(例如多边形边界是否闭合)。
// 显示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
完成几何对象有效性的检验,大部分工作由父类中的辅助方法完成。
// 定义内部嵌套类
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
中的每个要素关联的几何对象是否存在常见问题(例如没有闭合边界的多边形)。
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;
};
❝
OpenLayers示例数据下载,请在公众号后台回复:ol数据
全国信息化工程师-GIS 应用水平考试资料,请在公众号后台回复:GIS考试
❝
GIS之路公众号已经接入了智能助手,欢迎大家前来提问。
欢迎访问我的博客网站-长谈GIS:
http://shanhaitalk.com
都看到这了,不要忘记点赞、收藏+关注 哦!
本号不定时更新有关 GIS开发 相关内容,欢迎关注