在java代码中使用边界框过滤器

eh57zj3b  于 2023-05-05  发布在  Java
关注(0)|答案(2)|浏览(161)

我使用Osmosis将osm.pbf文件导入到我的java应用程序中,如下所示:

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 inputStream = FileInputStream(pathToPBF)

    // read from osm pbf file:
    val custom = OsmReader()
    val reader = OsmosisReader(inputStream)
    reader.setSink(custom)
    // initial parsing of the .pbf file:
    reader.run()
    println("Break")
}

我想只读取给定边界框中的节点。然后在命令行中使用Osmosis,你可以使用--bounding-box,但是在代码中如何做同样的事情呢?
目前,我使用JTS将每个节点与边界框相交,但这相当慢。

unhi4e5o

unhi4e5o1#

我试着使用Jacopo的回答中描述的管道,对我来说,管道的构造方式使它无法过滤给定的pbf文件。
对我有用的是下面这段代码。

// Set input stream
val inputStream = FileInputStream("path/to/my/file.osm.pbf")

// Create the bounding box filter
val bbFilter = BoundingBoxFilter(
    IdTrackerType.Dynamic, // ID tracker used internally. This is the default.
    11.5256, // Left lon
    11.5004, // Right lon
    48.84543, // Top lat
    48.8015, // Bottom lat
    true, // Remove ways and relation only partly in bounding box?
    false, // Include all nodes of ways only partly in bounding box.
    false, // Include all nodes and ways of relations only partly in bounding box.
    false // Include all relations that reference relation inside bounding box.
)

// Create your processor
val processor = CustomProcessor()

// Define your pipeline
val reader = OsmosisReader(inputStream)
bbFilter.setSink(processor)
reader.setSink(bbFilter) // This part is important in using the BoundingBoxFilter

// Run
reader.run()

关于此管道工作方式的一些额外信息。
当运行OsmosisReader时,它在给定的接收器中运行process方法,在这种情况下是boundingboxfilter,boundingboxfilter然后过滤给定的数据并从给定的接收器中调用process方法,在这种情况下是customprocessor,这样只有边界框内的项才会到达CustomProcessor。
希望这个答案可以帮助其他人寻找如何使用渗透的boundingboxfilter的信息。

slsn1g29

slsn1g292#

我现在找到了答案:
下面是一个示例,说明如何获取特定bouding框中的所有商店,并将它们存储在列表中的节点、路径和关系的列表中。
我使用kotlin与gradle。
在gradle.kts中:

dependencies {
    implementation("org.openstreetmap.osmosis:osmosis-pbf:0.48.3")
    implementation("org.openstreetmap.osmosis:osmosis-areafilter:0.48.3")
}

代码:

import crosby.binary.osmosis.OsmosisReader
import org.openstreetmap.osmosis.areafilter.v0_6.BoundingBoxFilter
import org.openstreetmap.osmosis.core.container.v0_6.*
import org.openstreetmap.osmosis.core.domain.v0_6.*
import org.openstreetmap.osmosis.core.filter.common.IdTrackerType
import org.openstreetmap.osmosis.core.task.v0_6.Sink
import java.io.FileInputStream

class CustomProcessor : Sink {
    // Here the results will be stored
    val nodes = mutableListOf<Node>()
    val ways = mutableListOf<Way>()
    val relations = mutableListOf<Relation>()

    override fun close() {
        // Close all your readers and such
    }

    override fun initialize(metaData: MutableMap<String, Any>?) {
        // Don't know when to use this
    }

    override fun complete() {
        // If you first put data into storages you can process them here after you have all you need
    }

    override fun process(entityContainer: EntityContainer?) {
        val entity = entityContainer?.entity

        // Filter for shops
        var foundIt = false
        if (entity != null) {
            for (tag in entity.tags) {
                if (tag.key == "shop") {
                    foundIt = true
                    break
                }
            }
        }

        // If the object is a shop
        if (foundIt) {
            if (entity is Node) {
                nodes.add(entity)
            } else if (entity is Way) {
                ways.add(entity)
            } else if (entity is Relation) {
                relations.add(entity)
            } else if (entity is Bound) {
                // We don't store bounds
            } else {
                // Shouldn't be possible
            }
        }
    }
}

fun main(args: Array<String>) {
    // Set input stream
    val inputStream = FileInputStream("path/to/my/file.osm.pbf")

    // Create the bounding box filter
    val bbFilter = BoundingBoxFilter(
        IdTrackerType.Dynamic, // ID tracker used internally. This is the default.
        11.5256, // Left lon
        11.5004, // Right lon
        48.84543, // Top lat
        48.8015, // Bottom lat
        true, // Remove ways and relation only partly in bounding box?
        false, // Include all nodes of ways only partly in bounding box.
        false, // Include all nodes and ways of relations only partly in bounding box.
        false // Include all relations that reference relation inside bounding box.
    )

    // Create your processor
    val processor = CustomProcessor()

    // Define your pipeline
    val reader = OsmosisReader(inputStream)
    bbFilter.setSink(processor)
    reader.setSink(bbFilter)

    // Run
    reader.run()

    // Get your data
    val nodes = processor.nodes
    val ways = processor.ways
    val relations = processor.relations
}

如果你想要的方式和关系的几何,你还需要存储它们组成的节点。这些都没有贴上“商店”的标签。将它们存储在列表中会占用大量的RAM,因此最好使用org.openstreetmap.osmosis. core.store.SimpleObjectStore类。

相关问题