繁体   English   中英

使用JTS库检测LineString / MultiLineString是否在多边形内部或与之相交

[英]Detect if a LineString / MultiLineString is inside a Polygon or if it intersects it using JTS library

描述

因此,基本上我想知道的是MultiPolygon是否包含LineString (或MultiLineString )或与之相交。

我不确定是否会影响它,但实际情况是我有一个代表远足径的LineString ,我需要知道该径穿过哪个世界区域(这就是我的MultiPolygon ) 。 或者,如果它在我的世界区域之一之内,我需要知道哪个区域包含该LineString

我的问题

我在这里的问题是我得到了误报 如果我对Point进行相同的检查(以查看它是否包含在MultiPolygon ),而不是LineString ,则可以正常工作。

完成我的目标的步骤:

  1. 将我的LineString从EPSG 3857格式处理为EPSG 4326格式(使用此公式将坐标从EPSG 3857转换为4326 DotSpatial ),因为我收到的LineString是EPSG 3857格式。
  2. 阅读我的Geometries (使用GsonJtsAdapter ,因为它们是GeoJson格式,具体来说是MultiPolygon )。 这一点应该不是问题,因为我使用它来检测Point是否在其他地方的Polygon内部,并且可以正常工作。
  3. 检查我的LineString是否相交或包含在任何MultiPolygon并注册此MultiPolygon的所有ID。

我的代码:

1,将我的LineString从EPSG 3857转换为EPSG 4326:

private fun reprojectFromEpsg3857ToEpsg4326(geometry: Geometry): Geometry
{
    val e = 2.7182818284
    val X = 20037508.34

    if (geometry is LineString) {
        for (i in 0 until geometry.numPoints) {
            val coordinate = geometry.getCoordinateN(i)
            geometry.getCoordinateN(i).x = (coordinate.x * 180) / X
            geometry.getCoordinateN(i).y = coordinate.y / (X / 180)
            geometry.getCoordinateN(i).y = ((Math.atan(Math.pow(e, ((PI / 180) * geometry.getCoordinateN(i).y)))) / (PI / 360)) - 90
        }
    } else if (geometry is MultiLineString) {
        try {
            for (i in 0 until geometry.numGeometries) {
                for (j in 0 until geometry.getGeometryN(i).coordinates.size) {
                    val coordinate = geometry.getGeometryN(i).coordinates[i]
                    geometry.getGeometryN(i).coordinates[i].x = (coordinate.x * 180) / X
                    geometry.getGeometryN(i).coordinates[i].y = coordinate.y / (X / 180)
                    geometry.getGeometryN(i).coordinates[i].y = ((Math.atan(Math.pow(e,((PI / 180) * geometry.getGeometryN(i).coordinates[i].y)))) / (PI / 360)) - 90
                }
            }
        } catch (e: ArrayIndexOutOfBoundsException) {

        }
    }

    return geometry
}

2.使用Gson和Jts适配器阅读我的Geometries

private fun getGeometries(gson: Gson): HashMap<Long, Geometry>
{
    val geoJsonGeometries = HashMap<Long, Geometry>()
    val geometriesFolder = File("geometries-folder")

    geometriesFolder.listFiles(getFilenameFilter("geojson")).forEach {
        val reader = FileReader(it)
        var geometry = gson.fromJson(reader, Geometry::class.java)

        if (geometry.geometryType == "GeometryCollection") {
            geometry = geometry.getGeometryN(0)
        }

        val geometryId = java.lang.Long.parseLong(it.name.replace(".geojson", ""))
        geoJsonGeometries[geometryId] = geometry
    }

    return geoJsonGeometries
}

3.执行检查以查看哪些MultiPolygon与我的LineString相关(通过包含或通过相交):

val geometryIds = ArrayList<Long>()
geometries.forEach { geometryId, mapBoundaries ->
    if (routeAsLineString.intersects(mapBoundaries) || mapBoundaries.contains(routeAsLineString)) {
        geometryIds.add(geometryId)
    }
}

任何帮助将非常感激!

好吧,我非常错误地将MultiLineString从EPSG 3857格式转换为EPSG 4326格式。 基本上,我不是在转换MultiLineString ,只是在转换第一个坐标。 但是, MultiLineString有许多Geometry对象,每个对象都有许多坐标。

因此,步骤2和3是正确的。

原始转换为:

for (i in 0 until geometry.numGeometries) {
    for (j in 0 until geometry.getGeometryN(i).coordinates.size) {
        val coordinate = geometry.getGeometryN(i).coordinates[i]
        geometry.getGeometryN(i).coordinates[i].x = (coordinate.x * 180) / X
        geometry.getGeometryN(i).coordinates[i].y = coordinate.y / (X / 180)
        geometry.getGeometryN(i).coordinates[i].y = ((Math.atan(Math.pow(e,((PI / 180) * geometry.getGeometryN(i).coordinates[i].y)))) / (PI / 360)) - 90
    }
}

但应该是:

for (i in 0 until geometry.numGeometries) {
    for (j in 0 until geometry.getGeometryN(i).coordinates.size) {
        val coordinate = geometry.getGeometryN(i).coordinates[j]
        geometry.getGeometryN(i).coordinates[j].x = (coordinate.x * 180) / X
        geometry.getGeometryN(i).coordinates[j].y = coordinate.y / (X / 180)
        geometry.getGeometryN(i).coordinates[j].y = ((Math.atan(Math.pow(e,((PI / 180) * geometry.getGeometryN(i).coordinates[j].y)))) / (PI / 360)) - 90
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM