Определить, находится ли LineString / MultiLineString внутри многоугольника или пересекает его с помощью библиотеки JTS

Описание

Так что в основном я хотел бы знать, является ли LineString (или же MultiLineString) содержится в MultiPolygon или если это пересекает это.

Я не совсем уверен, что это может повлиять, но реальный сценарий состоит в том, что у меня есть LineString это представляет собой пешеходную тропу, и мне нужно знать, через какие районы мира (что было бы моим MultiPolygon s) этот путь проходит? Или в том случае, если он находится внутри одной из областей моего мира, мне нужно знать, в какой области содержится эта область. LineString,

Моя проблема

Моя проблема здесь в том, что я получаю ложные срабатывания. Если я выполню ту же проверку с Point (чтобы увидеть, содержится ли он в MultiPolygon) вместо LineString, это прекрасно работает.

Шаги для достижения моей цели:

  1. Обработать мой LineString из формата EPSG 3857 в формат EPSG 4326 (используя эту формулу Преобразование координат из EPSG 3857 в 4326 DotSpatial), так как LineString Я получил это в формате EPSG 3857.
  2. Читай мой Geometries (с помощью Gson а также JtsAdapter, так как они в формате GeoJson, конкретно они MultiPolygon с). Эта точка не должна быть проблемой, так как я использую ее для определения, находится ли точка внутри многоугольника где-то еще и работает нормально.
  3. Проверь мой ли LineString пересекается или содержится любым из MultiPolygon s и зарегистрируйте все идентификаторы этого MultiPolygon s.

Мой код:

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. Читайте мой Geometries используя Gson и Jts адаптер:

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 s связаны (или сдерживанием или пересечением) с моим LineString :

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

Любая помощь будет очень благодарна!

1 ответ

Хорошо, я получил очень неправильно 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
    }
}
Другие вопросы по тегам