Description
So basically what I would like to know is whether a LineString
(or MultiLineString
) is contained in a MultiPolygon
or if it intersects it.
I'm not entirely sure that it might affect, but the real case scenario is that I have a LineString
that represents a hiking track, and I need to know through which world areas (which would be my MultiPolygon
s) is that track going through. Or in the case it is inside of one of my world areas, I need to know which area is containing that LineString
.
My problem
My issue here is that I'm getting false positives. If I perform the same check with a Point
(to see if it is contained in a MultiPolygon
), instead of a LineString
, it works perfectly fine.
Steps to accomplish my goal:
- Process my
LineString
from EPSG 3857 format to EPSG 4326 format (using this formula Converting coordinates from EPSG 3857 to 4326 DotSpatial ), since theLineString
I received it was in the EPSG 3857 format. - Read my
Geometries
(usingGson
andJtsAdapter
, since they are in GeoJson format, concretely they areMultiPolygon
s). This point shouldn't be the problem, since I use it to detect if a Point is inside a Polygon somewhere else, and works totally OK. - Check whether my
LineString
intersects or is contained by any of theMultiPolygon
s and register all the IDs of thisMultiPolygon
s.
My code:
1.Convert my LineString from EPSG 3857 to 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.Read my Geometries
using Gson and Jts adapter:
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.Perform the check to see which MultiPolygon
s are related (either by containment or by intersection) with my LineString
:
val geometryIds = ArrayList<Long>()
geometries.forEach { geometryId, mapBoundaries ->
if (routeAsLineString.intersects(mapBoundaries) || mapBoundaries.contains(routeAsLineString)) {
geometryIds.add(geometryId)
}
}
Any help would be very thankful!