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:
LineString
from EPSG 3857 format to EPSG 4326 format (using this formula Converting coordinates from EPSG 3857 to 4326 DotSpatial ), since the LineString
I received it was in the EPSG 3857 format. Geometries
(using Gson
and JtsAdapter
, since they are in GeoJson format, concretely they are MultiPolygon
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. LineString
intersects or is contained by any of the MultiPolygon
s and register all the IDs of this MultiPolygon
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!
Alright, I got very wrongly the MultiLineString
conversion from EPSG 3857 format to EPSG 4326 format. Basically, I wasn't converting the MultiLineString
, only the first coordinate was being converted. But there are many Geometry
objectes inside a MultiLineString
and each of them has many coordinates.
So steps 2 and 3 were correct.
The original conversion was:
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
}
}
But should have been:
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
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.