基于GeoTools和OSM路网求解两条道路相交点-以长沙市为例
目录
前言
一、基础数据简介
1、QGIS数据展示
2、元数据介绍
二、GeoTools相交求解
1、加载路网数据
2、查找道路信息
3、计算相交点
4、集成调用及输出
三、总结
前言
今天是端午节也是六一儿童节,当端午节碰到儿童节,双节的碰撞。在这祝各位朋友们端午安康,也祝各位大朋友小朋友们儿童节快乐,永葆童真。
随着城市化进程的加速,城市交通网络日益复杂,对于道路信息的精准分析和处理需求也愈发迫切。在长沙市这样的大型城市中,错综复杂的路网系统为城市规划、交通管理、智能导航等多个领域带来了诸多挑战。准确求解两条道路的相交点,作为道路网络分析中的基础且关键环节,对于优化交通流量、规划公交线路、建设智能交通系统等具有重大意义。
传统的道路相交点求解方法往往依赖于人工测量或特定商业软件的支持。然而,人工测量存在效率低下、易受环境因素影响以及成本高昂等问题;而商业软件虽功能强大,但通常价格昂贵且数据格式封闭,难以满足大规模、多样化以及实时性要求较高的城市道路分析需求。在此背景下,GeoTools 和 OSM 路网为我们提供了一种高效、开源且灵活的道路相交点求解方案。
本研究旨在结合 GeoTools 和 OSM 路网数据,探索一套高效、准确且适用于长沙市复杂道路条件的道路相交点求解方法。通过对 OSM 路网数据的获取与预处理,利用 GeoTools 提供的几何分析功能,深入研究道路相交点的判定算法以及相交点坐标的精确计算方法,从而实现对长沙市道路相交点的自动化、批量化的求解。这不仅有助于提升城市交通管理的信息化水平,为交通规划和决策提供科学依据,也为其他城市在类似场景下的道路网络分析提供了一种可借鉴的思路和方法,推动城市地理信息科学领域的发展以及智能交通系统的建设进程。
一、基础数据简介
本节将介绍长沙路网的基本信息,使用QGIS软件来进行基础路网的展示以及元数据的介绍。让大家对基础道路信息有一个基本的了解。
1、QGIS数据展示
在QGIS中进行道路展示时,根据道路的级别进行分类标注,分类规则如下:
点击应用以后可以看到以下制图效果:
可以看到路网的信息比较完备,同时将道路按照不同的等级,如高速、省道、次干道、步行道、车行道等都进行了标注。由于周所周知的原因,OSM数据作为学习使用没有问题,如果要应用生产谨慎。
2、元数据介绍
下面我们对基础路网数据的的元数据进行简单介绍。这里使用的基础路网数据是从全国的路网信息裁剪下来的。裁剪之后的基础信息如下:
序号 | 参数名 | 参数说明 |
1 | 文件格式 | ESRI Shapefile |
2 | 编码 | GBK |
3 | 数据类型 | Line (MultiLineString) |
4 | 空间参考 | EPSG:4326 - WGS 84 - 地理的 |
5 | 数据范围 | 111.8935741910824362,27.8608263279212238 : 114.2082998876577307,28.6640906134622071 |
6 | 单位 | 度 |
7 | 数据量 | 27,575 |
二、GeoTools相交求解
GeoTools 作为一个开源的 Java GIS 工具库,具备强大的地理数据处理和分析能力,能够方便地实现地理数据的读取、转换、几何运算等功能,为道路相交点的求解提供了坚实的算法基础和技术支撑。OpenStreetMap(OSM)路网数据则具有数据丰富、更新及时、覆盖范围广且免费开源等优势,涵盖了长沙市及其周边地区的详细道路信息,包括道路的几何形状、属性信息等,是进行城市道路分析的宝贵数据资源。本节将重点介绍结合GeoTools来讲解如何进行求解的计算,分别从以下步骤展开,加载路网数据、查找道路信息、计算相交点。
1、加载路网数据
首先需要加载所有的路网信息,如果需要使用道路的名称信息,就需要准确的进行属性编码的设置。如果不需要忽略编码的设置,使用Geotools的关键代码如下,这里是个实例,如果需要动态传入字符编码,可以从相关配置文件中读取,可以从博主之前的系列博客中查阅参考:
/*** 加载shp文件*/
private static SimpleFeatureSource loadShapefile(File file) throws Exception {ShapefileDataStore store = new ShapefileDataStore(file.toURI().toURL());store.setCharset(Charset.forName("GBK"));//设置中文字符编码return store.getFeatureSource();
}
2、查找道路信息
加载路网信息后,接下来就需要指定道路的名称来从路网中查找指定的道路,这里需要使用到的GtoTools的过滤查询方法,准确的查找检索道路名称至关重要,核心方法如下:
/**
* 按道路名称过滤要素
*/
private static SimpleFeatureCollection filterRoadsByName(SimpleFeatureSource source, String roadName) throws Exception {FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();Filter filter = ff.equal(ff.property(ROAD_NAME_FIELD), ff.literal(roadName), true);return source.getFeatures(filter);
}
需要注意的是,仅根据道路的名称返回的查询结果可能是多条,在OSM中,一条道路可能会被标记为多段,因此在返回结果中使用SimpleFeatureCollection,表示是一个集合对象。
3、计算相交点
根据道路名称查询到道路的数据结合后,接下来就是使用GeoTools来求解两条路的相交点。核心算法如下:
/**
* 计算两条道路集合的所有交点
*/
private static Set<Point> findIntersections(SimpleFeatureCollection road1, SimpleFeatureCollection road2) {Set<Point> intersections = new HashSet<>();try (SimpleFeatureIterator iter1 = road1.features()) {while (iter1.hasNext()) {SimpleFeature f1 = iter1.next();Geometry geom1 = (Geometry) f1.getDefaultGeometry();// 确保几何体有效if (geom1 == null || geom1.isEmpty()) continue;try (SimpleFeatureIterator iter2 = road2.features()) {while (iter2.hasNext()) {SimpleFeature f2 = iter2.next();Geometry geom2 = (Geometry) f2.getDefaultGeometry();if (geom2 == null || geom2.isEmpty()) continue;// 计算交点(使用OverlayNGRobust提高稳定性)Geometry result = OverlayNGRobust.overlay(geom1, geom2, OverlayNG.INTERSECTION);// 处理不同类型的返回结果processIntersectionGeometry(result, intersections);}}}}return intersections;
}/*** 处理相交几何对象(支持点/多点/线集合)*/private static void processIntersectionGeometry(Geometry geom, Set<Point> output) {if (geom == null || geom.isEmpty()) return;if (geom instanceof Point) {output.add((Point) geom);} else if (geom instanceof MultiPoint) {for (int i = 0; i < geom.getNumGeometries(); i++) {output.add((Point) geom.getGeometryN(i));}} else if (geom instanceof GeometryCollection) {for (int i = 0; i < geom.getNumGeometries(); i++) {processIntersectionGeometry(geom.getGeometryN(i), output);}}// 注意:线-线相交理论上应返回点,但保留此处理增强健壮性}
4、集成调用及输出
最后将上面的方法进行一个完整的示例调用程序演示,这里使用Main方法进行输出,关键代码如下:
// 定义道路名称属性字段(根据实际shp修改)
private static final String ROAD_NAME_FIELD = "name";
public static void main(String[] args) throws Exception {// 1. 加载OSM道路shp文件File shpFile = new File("F:/vector_data/2024年OSM长沙路网/长沙路网OSM2024.shp");SimpleFeatureSource featureSource = loadShapefile(shpFile);// 2. 输入两条道路名称String roadName1 = "金星北路";String roadName2 = "岳麓大道";// 3. 获取两条道路的所有几何线SimpleFeatureCollection road1Features = filterRoadsByName(featureSource, roadName1);SimpleFeatureCollection road2Features = filterRoadsByName(featureSource, roadName2);// 4. 计算所有相交点Set<Point> intersections = findIntersections(road1Features, road2Features);// 5. 输出结果System.out.println("Found " + intersections.size() + " intersections:");for (Point p : intersections) {System.out.printf("POINT (%.6f %.6f)\n", p.getX(), p.getY());}}
运行以下程序后可以看到以下输出:
六月 01, 2025 7:47:22 上午 org.geotools.image.ImageWorker <clinit>
信息: Warp/affine reduction enabled: true
Found 4 intersections:
POINT (112.928802 28.229116)
POINT (112.928655 28.228864)
POINT (112.928634 28.229118)
POINT (112.928817 28.228852)
表示经过我们的计算,两条道路(金星北路和岳麓大道)的相交点坐标如上,这里留两个问题,为什么两条道路的相交点是四个?会不会有更多的情况?下次博文进行讲解。
三、总结
以上就是本文的主要内容, 本研究旨在结合 GeoTools 和 OSM 路网数据,探索一套高效、准确且适用于长沙市复杂道路条件的道路相交点求解方法。通过对 OSM 路网数据的获取与预处理,利用 GeoTools 提供的几何分析功能,深入研究道路相交点的判定算法以及相交点坐标的精确计算方法,从而实现对长沙市道路相交点的自动化、批量化的求解。通过详细的代码讲解,让大家对如何使用Geotools来进行路网的道路的相交点求解有了全面的认识和掌握,当然还有很大的优化空间,比如考虑未相交的情况处理,还有如果是环线如何支持的更好,大范围计算如何空间优化等。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。