diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a8c2e361ffd..9f3e2a362d5c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ set(netconvertlibs - netwrite netimport netbuild foreign_eulerspiral ${GDAL_LIBRARY} netimport_vissim netimport_vissim_typeloader netimport_vissim_tempstructs ${commonlibs} ${TCMALLOC_LIBRARY}) + netwrite netimport netbuild foreign_eulerspiral ${GDAL_LIBRARY} netimport_vissim netimport_vissim_typeloader netimport_vissim_tempstructs ${commonlibs} ${TCMALLOC_LIBRARY} ${GEOS_LIBRARY}) set(sumolibs traciserver netload microsim_cfmodels microsim_engine microsim_lcmodels microsim_devices microsim_trigger microsim_output microsim_transportables microsim_actions diff --git a/src/netbuild/NBNetBuilder.cpp b/src/netbuild/NBNetBuilder.cpp index b6be16f2a485..acb7a3d8c79c 100644 --- a/src/netbuild/NBNetBuilder.cpp +++ b/src/netbuild/NBNetBuilder.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -712,6 +713,20 @@ NBNetBuilder::compute(OptionsCont& oc, const std::set& explicitTurn WRITE_WARNING(TL("Network contains very large coordinates and will probably flicker in the GUI. Check for outlying nodes and make sure the network is shifted to the coordinate origin")); } + for (std::map::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) { + const PositionVector& junctionShape = it->second->getShape(); + if (!isValid(junctionShape)) { + WRITE_WARNINGF(TL("Node % has invalid geometry"), it->second->getID()); + } + const std::vector& walkingAreas = it->second->getWalkingAreas(); + for (std::vector::const_iterator itwa = walkingAreas.begin(); itwa != walkingAreas.end(); ++itwa) { + const PositionVector& walkingAreaShape = itwa->shape; + if (!isValid(walkingAreaShape)) { + WRITE_WARNINGF(TL("Walking area % of node % has invalid geometry"), itwa->id, it->second->getID()); + } + } + } + // clean up OSM processing params if (oc.exists("osm-files") && oc.isSet("osm-files")) { for (auto item : myEdgeCont) { @@ -765,6 +780,23 @@ NBNetBuilder::mirrorX() { } +bool +NBNetBuilder::isValid(const PositionVector& shape) const { + GEOSCoordSequence* coordinateSequence = GEOSCoordSeq_create((unsigned int)shape.size(), 2); + for (int i = 0; i < (int)shape.size(); i++) { + GEOSCoordSeq_setXY(coordinateSequence, i, shape[i].x(), shape[i].y()); + } + GEOSGeometry* geometry = GEOSGeom_createLinearRing(coordinateSequence); + char isValid = GEOSisValid(geometry); + GEOSGeom_destroy(geometry); + if (isValid == 1) { + return true; + } else { + return false; + } +} + + bool NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) { Position orig(from); diff --git a/src/netbuild/NBNetBuilder.h b/src/netbuild/NBNetBuilder.h index 5b9bfb3d9758..141ac24b1bd4 100644 --- a/src/netbuild/NBNetBuilder.h +++ b/src/netbuild/NBNetBuilder.h @@ -260,6 +260,12 @@ class NBNetBuilder { /// @brief mirror the network along the X-axis void mirrorX(); + /// @brief check if the node is valid according to GEOS + /// @link https://libgeos.org/doxygen/geos__c_8h.html#ae65e55acad28e2b55d793730dd1d4e06 + /// @param node a pointer to the NBNode instance to be validated + /// @return whether the node is valid or not + bool isValid(const PositionVector& shape) const; + private: /// @brief invalidated copy constructor NBNetBuilder(const NBNetBuilder& s); diff --git a/src/netgen/CMakeLists.txt b/src/netgen/CMakeLists.txt index 1f445b15d16d..d53c65e50d3a 100644 --- a/src/netgen/CMakeLists.txt +++ b/src/netgen/CMakeLists.txt @@ -15,7 +15,7 @@ set(netgenerate_SRCS add_executable(netgenerate ${netgenerate_SRCS}) set_target_properties(netgenerate PROPERTIES OUTPUT_NAME netgenerate${BINARY_SUFFIX}) set_target_properties(netgenerate PROPERTIES OUTPUT_NAME_DEBUG netgenerate${BINARY_SUFFIX}D) -target_link_libraries(netgenerate netbuild netimport netwrite ${GDAL_LIBRARY} ${commonlibs} ${TCMALLOC_LIBRARY}) +target_link_libraries(netgenerate netbuild netimport netwrite ${GDAL_LIBRARY} ${commonlibs} ${TCMALLOC_LIBRARY} ${GEOS_LIBRARY}) add_dependencies(netgenerate generate-version-h install_dll) install(TARGETS netgenerate RUNTIME DESTINATION bin) diff --git a/unittest/src/netbuild/CMakeLists.txt b/unittest/src/netbuild/CMakeLists.txt index ee41b1eb21d7..e7936dcff5e8 100644 --- a/unittest/src/netbuild/CMakeLists.txt +++ b/unittest/src/netbuild/CMakeLists.txt @@ -1,2 +1,2 @@ add_executable(testnetbuild NBHeightMapperTest.cpp NBTrafficLightLogicTest.cpp) -setTestProperties(testnetbuild netbuild ${GDAL_LIBRARY}) +setTestProperties(testnetbuild netbuild ${GDAL_LIBRARY} ${GEOS_LIBRARY})