From 8cedde9036ffc5711347397a3bee3f89550541ae Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 20 Aug 2025 15:10:31 +0100 Subject: [PATCH 1/6] Stream_support: Return false if nothing read --- Stream_support/include/CGAL/IO/WKT.h | 29 ++++++++++++++----- .../test/Stream_support/test_WKT.cpp | 13 +++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Stream_support/include/CGAL/IO/WKT.h b/Stream_support/include/CGAL/IO/WKT.h index 2706576b47c..a41cb5b980a 100644 --- a/Stream_support/include/CGAL/IO/WKT.h +++ b/Stream_support/include/CGAL/IO/WKT.h @@ -133,16 +133,19 @@ bool read_multi_point_WKT(std::istream& in, MultiPoint& mp) { std::string line; + bool found = false; while(internal::get_a_new_line(in, line)) { if(line.substr(0, 10).compare("MULTIPOINT") == 0) { CGAL::internal::Geometry_container gc(mp); - internal::read_wkt_or_fail_stream(in, line, gc); + found = internal::read_wkt_or_fail_stream(in, line, gc); break; } } - + if(! found){ + return false; + } return !in.fail(); } @@ -168,16 +171,20 @@ bool read_linestring_WKT(std::istream& in, LineString& polyline) { std::string line; + bool found = false; while(internal::get_a_new_line(in, line)) { if(line.substr(0, 10).compare("LINESTRING") == 0) { CGAL::internal::Geometry_container gc(polyline); - internal::read_wkt_or_fail_stream(in, line, gc); + found = internal::read_wkt_or_fail_stream(in, line, gc); break; } } + if(! found){ + return false; + } return !in.fail(); } @@ -199,6 +206,7 @@ bool read_multi_linestring_WKT(std::istream& in, MultiLineString& mls) { std::string line; + bool found = false; while(internal::get_a_new_line(in, line)) { if(line.substr(0, 15).compare("MULTILINESTRING") == 0) @@ -209,7 +217,7 @@ bool read_multi_linestring_WKT(std::istream& in, std::vector pr_range; CGAL::internal::Geometry_container, boost::geometry::multi_linestring_tag> gc(pr_range); - internal::read_wkt_or_fail_stream(in, line, gc); + found = internal::read_wkt_or_fail_stream(in, line, gc); for(LineString& ls : gc) { mls.push_back(*ls.range); } @@ -237,15 +245,19 @@ bool read_polygon_WKT(std::istream& in, Polygon& polygon) { std::string line; + bool found = false; while(internal::get_a_new_line(in, line)) { if(line.substr(0, 7).compare("POLYGON") == 0) { - internal::read_wkt_or_fail_stream(in, line, polygon); + found = internal::read_wkt_or_fail_stream(in, line, polygon); internal::pop_back_if_equal_to_front(polygon); break; } } + if(! found){ + return false; + } return !in.fail(); } @@ -268,12 +280,13 @@ bool read_multi_polygon_WKT(std::istream& in, MultiPolygon& polygons) { std::string line; + bool found = false; while(internal::get_a_new_line(in, line)) { if(line.substr(0, 12).compare("MULTIPOLYGON") == 0) { CGAL::internal::Geometry_container gc(polygons); - internal::read_wkt_or_fail_stream(in, line, gc); + found = internal::read_wkt_or_fail_stream(in, line, gc); for(auto& p : gc) internal::pop_back_if_equal_to_front(p); @@ -281,7 +294,9 @@ bool read_multi_polygon_WKT(std::istream& in, break; } } - + if(! found){ + return false; + } return !in.fail(); } diff --git a/Stream_support/test/Stream_support/test_WKT.cpp b/Stream_support/test/Stream_support/test_WKT.cpp index 7af1e011668..986bf421adc 100644 --- a/Stream_support/test/Stream_support/test_WKT.cpp +++ b/Stream_support/test/Stream_support/test_WKT.cpp @@ -24,6 +24,17 @@ typedef std::vector MultiPoint typedef std::vector MultiLinestring3; //////////////////////////////////////////////////////////////////////////////////////////////////// +bool test_mismatch() +{ + Point3 p(1,2,3); + MultiPoint3 mq; + std::stringstream ss; + CGAL::IO::write_point_WKT(ss, p); + bool b = CGAL::IO::read_multi_point_WKT(ss, mq); + assert(!b); + return !b; +} + bool test_WKT_3D() { { @@ -337,6 +348,8 @@ int main() assert(ok); ok = test_WKT_3D(); assert(ok); + ok = test_mismatch(); + assert(ok); return EXIT_SUCCESS; } From b23eb7e7b4a2af0b84c1fb07c8cde1ca7668b67d Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 20 Aug 2025 15:32:33 +0100 Subject: [PATCH 2/6] Deal with read_WKT() --- Stream_support/include/CGAL/IO/WKT.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Stream_support/include/CGAL/IO/WKT.h b/Stream_support/include/CGAL/IO/WKT.h index a41cb5b980a..2fa084b6158 100644 --- a/Stream_support/include/CGAL/IO/WKT.h +++ b/Stream_support/include/CGAL/IO/WKT.h @@ -476,6 +476,7 @@ bool read_WKT(std::istream& is, { auto fail = [&is]() { is.clear(is.rdstate() | std::ios::failbit); return false; }; + bool found = false; std::string line; while(is >> std::ws && is.good() && std::getline(is, line)) { @@ -505,44 +506,57 @@ bool read_WKT(std::istream& is, { Point p; if(!IO::read_point_WKT(iss, p) ) return fail(); + found = true; points.push_back(p); } else if(type == "LINESTRING") { LineString l; if(!IO::read_linestring_WKT(iss, l)) return fail(); + found = true; polylines.push_back(std::move(l)); } else if(type == "POLYGON") { Polygon p; if(!IO::read_polygon_WKT(iss, p)) return fail(); - if(!p.outer_boundary().is_empty()) + if(!p.outer_boundary().is_empty()){ + found = true; polygons.push_back(std::move(p)); + } } else if(type == "MULTIPOINT") { MultiPoint mp; if(!IO::read_multi_point_WKT(iss, mp)) return fail(); - for(const Point& point : mp) + for(const Point& point : mp){ points.push_back(point); + found = true; + } } else if(type == "MULTILINESTRING") { MultiLineString mls; if(!IO::read_multi_linestring_WKT(iss, mls)) return fail(); - for(LineString& ls : mls) + for(LineString& ls : mls){ polylines.push_back(std::move(ls)); + found = true; + } } else if(type == "MULTIPOLYGON") { MultiPolygon mp; if(!IO::read_multi_polygon_WKT(iss, mp)) return fail(); - for(Polygon& poly : mp) + for(Polygon& poly : mp){ polygons.push_back(std::move(poly)); + found = true; + } } } + if(!found){ + return false; + } return !is.fail(); } From ef834cc6c12eab716f6053f64b78a02bae2b7e5d Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 20 Aug 2025 16:30:49 +0100 Subject: [PATCH 3/6] Test that 2D wkt data can be read into 3D points/polygons --- .../test/Stream_support/test_WKT.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Stream_support/test/Stream_support/test_WKT.cpp b/Stream_support/test/Stream_support/test_WKT.cpp index 986bf421adc..5a2ff5492c9 100644 --- a/Stream_support/test/Stream_support/test_WKT.cpp +++ b/Stream_support/test/Stream_support/test_WKT.cpp @@ -35,6 +35,31 @@ bool test_mismatch() return !b; } +bool test_read2Dinto3D() +{ + Point p(10,11); + Point3 p3(1,2,3); + std::stringstream ss; + CGAL::IO::write_point_WKT(ss, p); + bool b = CGAL::IO::read_point_WKT(ss, p3); + assert(p.x() == p3.x()); + assert(p.y() == p3.y()); + assert(p3.z() == 0); + + Point q(12,13); + Linestring ls; + Linestring3 ls3; + ls.push_back(p); + ls.push_back(q); + CGAL::IO::write_linestring_WKT(ss, ls); + b = CGAL::IO::read_linestring_WKT(ss, ls3); + assert(ls3[0]==p3); + assert(ls3[1] == Point3(12,13,0)); + assert(b); + return b; +} + + bool test_WKT_3D() { { @@ -350,6 +375,8 @@ int main() assert(ok); ok = test_mismatch(); assert(ok); + ok = test_read2Dinto3D(); + assert(ok); return EXIT_SUCCESS; } From 4510260e36c0303f403aaa2bf097c3eecb27b469 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 11 Sep 2025 08:05:24 +0100 Subject: [PATCH 4/6] Use found --- Stream_support/include/CGAL/IO/WKT.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Stream_support/include/CGAL/IO/WKT.h b/Stream_support/include/CGAL/IO/WKT.h index 2fa084b6158..206d1a5eecc 100644 --- a/Stream_support/include/CGAL/IO/WKT.h +++ b/Stream_support/include/CGAL/IO/WKT.h @@ -225,7 +225,9 @@ bool read_multi_linestring_WKT(std::istream& in, break; } } - + if(! found){ + return false; + } return !in.fail(); } From a95bfa77c8058deec4dc905fad0c4916fe16b796 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 17 Sep 2025 15:27:23 +0100 Subject: [PATCH 5/6] The example can also read in a polygon with 3D points --- Stream_support/examples/Stream_support/read_WKT.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Stream_support/examples/Stream_support/read_WKT.cpp b/Stream_support/examples/Stream_support/read_WKT.cpp index 9c7ed82d578..0ebd9f27bf9 100644 --- a/Stream_support/examples/Stream_support/read_WKT.cpp +++ b/Stream_support/examples/Stream_support/read_WKT.cpp @@ -1,15 +1,17 @@ #include +#include #include #include #include #include -typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Projection_traits_xy_3 Kernel; int main(int argc, char* argv[]) { - typedef CGAL::Point_2 Point; + typedef Kernel::Point_2 Point; typedef std::vector MultiPoint; typedef std::vector LineString; @@ -23,6 +25,7 @@ int main(int argc, char* argv[]) MultiPoint points; MultiLineString polylines; MultiPolygon polygons; + CGAL::IO::read_WKT(is, points,polylines,polygons); for(Point p : points) @@ -30,8 +33,9 @@ int main(int argc, char* argv[]) for(LineString ls : polylines) for(Point p : ls) std::cout< Date: Wed, 17 Sep 2025 16:10:45 +0100 Subject: [PATCH 6/6] CGALlab can now load wkt polygons and display them as polylines --- Lab/demo/Lab/Plugins/IO/WKT_io_plugin.cpp | 59 +++++++++++++++-------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/Lab/demo/Lab/Plugins/IO/WKT_io_plugin.cpp b/Lab/demo/Lab/Plugins/IO/WKT_io_plugin.cpp index 9315f9a85b4..ec3aaa1b3ad 100644 --- a/Lab/demo/Lab/Plugins/IO/WKT_io_plugin.cpp +++ b/Lab/demo/Lab/Plugins/IO/WKT_io_plugin.cpp @@ -2,6 +2,9 @@ #include #include +#include +#include +#include #include #include #include @@ -45,36 +48,50 @@ canLoad(QFileInfo) const { QList CGAL_Lab_wkt_plugin:: load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { + typedef Scene_polylines_item::Point_3 Point_3; + typedef CGAL::Kernel_traits::Kernel K; + typedef std::vector Polyline; + typedef CGAL::Projection_traits_xy_3 Kernel; + typedef CGAL::Polygon_with_holes_2 Polygon; + std::ifstream in(fileinfo.filePath().toUtf8()); - if(!in) - std::cerr << "Error!\n"; - QApplication::setOverrideCursor(Qt::WaitCursor); - - if(fileinfo.size() == 0) + if(!in || fileinfo.size() == 0) { - CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); + CGAL::Three::Three::warning( tr("The file you are trying to load does not exist or is empty.")); ok = false; - QApplication::restoreOverrideCursor(); return QList(); } - std::list > polylines; - bool success = CGAL::IO::read_multi_linestring_WKT (in, polylines); - if(! success){ - in.close(); - in.open(fileinfo.filePath().toUtf8()); - std::vector polyline; - std::cout << " read" << std::endl; - success = CGAL::IO::read_linestring_WKT (in, polyline); - std::cout << " done " << std::boolalpha << success << " " << polyline.size() << std::endl; - if(! success){ - ok = false; - QApplication::restoreOverrideCursor(); - return QList(); - } + QApplication::setOverrideCursor(Qt::WaitCursor); + + std::vector points; + std::list polylines; + std::vector polygons; + bool success = CGAL::IO::read_WKT(in, points, polylines, polygons); + for(const Polygon& p : polygons) + { + Polyline polyline(p.outer_boundary().vertices_begin(), p.outer_boundary().vertices_end()); + polyline.push_back(polyline.front()); polylines.push_back(polyline); + for(auto hit = p.holes_begin(); hit != p.holes_end(); ++hit) + { + Polyline hole(hit->vertices_begin(), hit->vertices_end()); + hole.push_back(hole.front()); + polylines.push_back(hole); + } + } + if(! polygons.empty()){ + CGAL::Three::Three::warning( tr("The polygons will be drawn as polylines")); + } + + if(!success || polylines.empty()) + { + CGAL::Three::Three::warning( tr("The file you are trying to load is not a valid WKT file or is empty")); + ok = false; + QApplication::restoreOverrideCursor(); + return QList(); } Scene_polylines_item* item = new Scene_polylines_item;