Определить, находится ли LineString / MultiLineString внутри многоугольника или пересекает его с помощью библиотеки JTS
Описание
Так что в основном я хотел бы знать, является ли LineString
(или же MultiLineString
) содержится в MultiPolygon
или если это пересекает это.
Я не совсем уверен, что это может повлиять, но реальный сценарий состоит в том, что у меня есть LineString
это представляет собой пешеходную тропу, и мне нужно знать, через какие районы мира (что было бы моим MultiPolygon
s) этот путь проходит? Или в том случае, если он находится внутри одной из областей моего мира, мне нужно знать, в какой области содержится эта область. LineString
,
Моя проблема
Моя проблема здесь в том, что я получаю ложные срабатывания. Если я выполню ту же проверку с Point
(чтобы увидеть, содержится ли он в MultiPolygon
) вместо LineString
, это прекрасно работает.
Шаги для достижения моей цели:
- Обработать мой
LineString
из формата EPSG 3857 в формат EPSG 4326 (используя эту формулу Преобразование координат из EPSG 3857 в 4326 DotSpatial), так какLineString
Я получил это в формате EPSG 3857. - Читай мой
Geometries
(с помощьюGson
а такжеJtsAdapter
, так как они в формате GeoJson, конкретно ониMultiPolygon
с). Эта точка не должна быть проблемой, так как я использую ее для определения, находится ли точка внутри многоугольника где-то еще и работает нормально. - Проверь мой ли
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
}
}