You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java代码中用Osmosis实现边界框过滤读取OSM PBF节点

解决方案:使用Osmosis内置的BoundingBoxFilter实现高效边界过滤

不需要自己用JTS逐个判断节点,Osmosis本身提供了和命令行--bounding-box参数对应的BoundingBoxFilter组件,它能在流式解析阶段直接过滤掉边界框外的实体,效率和命令行完全一致。

修改后的代码示例

data class MapObject(
    val lat: Double,
    val lon: Double,
    val id: Long
)

class OsmReader : Sink {
    val data = mutableListOf<MapObject>()

    override fun close() {}
    override fun complete() {}
    override fun initialize(metaData: MutableMap<String, Any>?) {}

    override fun process(entityContainer: EntityContainer?) {
        if (entityContainer is NodeContainer) {
            val node = entityContainer.entity
            data.add(MapObject(node.latitude, node.longitude, node.id))
        }
    }
}

fun readOSM(pathToPBF: String) {
    // 定义目标边界框参数:最小纬度、最大纬度、最小经度、最大经度
    val minLat = 39.90
    val maxLat = 39.92
    val minLon = 116.38
    val maxLon = 116.40

    val inputStream = FileInputStream(pathToPBF)

    // 1. 创建自定义sink
    val customSink = OsmReader()
    // 2. 创建边界框过滤器,配置参数
    val bboxFilter = BoundingBoxFilter().apply {
        setLeft(minLon)
        setRight(maxLon)
        setBottom(minLat)
        setTop(maxLat)
        // 只处理节点,关闭way和关系的处理以提升效率
        processNodes = true
        processWays = false
        processRelations = false
        // 将过滤器的输出指向自定义sink
        setSink(customSink)
    }
    // 3. 创建PBF读取器,将输出指向过滤器
    val reader = OsmosisReader(inputStream)
    reader.setSink(bboxFilter)

    // 启动处理流程
    reader.run()
    
    println("读取到符合条件的节点数量:${customSink.data.size}")
}

关键说明

  • BoundingBoxFilter会在数据从PBF文件读取后立即过滤,只有边界框内的节点才会被传递到你的自定义OsmReader,避免了加载所有节点再判断的性能开销
  • 通过设置processNodes、processWays、processRelations可以精准控制需要处理的实体类型,进一步提升处理速度
  • 边界框的坐标顺序要注意:left对应最小经度,right对应最大经度,bottom对应最小纬度,top对应最大纬度

内容的提问来源于stack exchange,提问作者Jacopo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:25:46