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

时间:2018-12-13 16:01:42

标签: java kotlin intersection jts

说明

所以基本上我想知道的是LineString中是否包含MultiLineString(或MultiPolygon)或与之相交。

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

我的问题

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

实现我的目标的步骤:

  1. 将我的LineString从EPSG 3857格式处理为EPSG 4326格式(使用此公式Converting coordinates from EPSG 3857 to 4326 DotSpatial),因为我收到的LineString是EPSG 3857格式。
  2. 阅读我的LineString(使用GeometriesGson,因为它们是GeoJson格式,具体来说是JtsAdapter s)。 这点应该不是问题,因为我用它来检测某个点是否在其他地方的多边形内,并且完全可以正常工作。
  3. 检查我的MultiPolygon是否与任何LineString相交或包含在其中,并注册此MultiPolygon的所有ID。

我的代码:

1。将LineString从EPSG 3857转换为EPSG 4326:

MultiPolygon

2。使用Gson和Jts适配器阅读我的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 }

Geometries

3。执行检查以查看哪些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 } 与我的MultiPolygon相关(通过围堵或通过相交):

LineString

任何帮助都会非常感激!

1 个答案:

答案 0 :(得分:0)

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

所以步骤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
    }
}