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

Описание

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

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

Моя проблема

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

Шаги, чтобы выполнить мойцель:

  1. Обработка my 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 Ответ

0 голосов
/ 14 декабря 2018

Хорошо, я очень неправильно получил 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
    }
}
...