diff --git a/src/detail/io/WkbReader.cpp b/src/detail/io/WkbReader.cpp index 2837514c..0f1beee7 100644 --- a/src/detail/io/WkbReader.cpp +++ b/src/detail/io/WkbReader.cpp @@ -220,4 +220,27 @@ WkbReader::readInnerPolyhedralSurface() -> PolyhedralSurface return result; } +/** + * Read Solid content from wkb + */ +auto +WkbReader::readInnerSolid() -> Solid +{ + std::vector geoms; + try { + const uint32_t numGeoms{read()}; + for (uint32_t i = 0; i < numGeoms; ++i) { + readWkb(); + if (_geometry != nullptr) { + geoms.push_back(_geometry->as()); + } + } + } catch (std::exception &e) { + std::cerr << e.what(); + return {}; + } + SFCGAL::Solid const result{geoms}; + return result; +} + } // namespace SFCGAL::detail::io diff --git a/src/detail/io/WkbReader.h b/src/detail/io/WkbReader.h index df4f1967..2054a47d 100644 --- a/src/detail/io/WkbReader.h +++ b/src/detail/io/WkbReader.h @@ -14,10 +14,12 @@ #include "SFCGAL/MultiLineString.h" #include "SFCGAL/MultiPoint.h" #include "SFCGAL/MultiPolygon.h" +#include "SFCGAL/MultiSolid.h" #include "SFCGAL/Point.h" #include "SFCGAL/Polygon.h" #include "SFCGAL/PolyhedralSurface.h" #include "SFCGAL/PreparedGeometry.h" +#include "SFCGAL/Solid.h" #include "SFCGAL/Triangle.h" #include "SFCGAL/TriangulatedSurface.h" @@ -227,6 +229,13 @@ class SFCGAL_API WkbReader { return std::unique_ptr( readInnerPolyhedralSurface().clone()); + case TYPE_SOLID: + return std::unique_ptr(readInnerSolid().clone()); + + case TYPE_MULTISOLID: + return std::unique_ptr( + readInnerMultiGeometries().clone()); + default: std::ostringstream oss; oss << "WkbWriter: type '" << geometryType << "' is not supported"; @@ -295,6 +304,12 @@ class SFCGAL_API WkbReader { auto readInnerPolyhedralSurface() -> PolyhedralSurface; + /** + * Read Solid content from wkb + */ + auto + readInnerSolid() -> Solid; + /** * actually reading 3D ? */ diff --git a/src/detail/io/WkbWriter.cpp b/src/detail/io/WkbWriter.cpp index 0ac34715..10e069df 100644 --- a/src/detail/io/WkbWriter.cpp +++ b/src/detail/io/WkbWriter.cpp @@ -12,9 +12,11 @@ #include "SFCGAL/MultiLineString.h" #include "SFCGAL/MultiPoint.h" #include "SFCGAL/MultiPolygon.h" +#include "SFCGAL/MultiSolid.h" #include "SFCGAL/Point.h" #include "SFCGAL/Polygon.h" #include "SFCGAL/PolyhedralSurface.h" +#include "SFCGAL/Solid.h" #include "SFCGAL/Triangle.h" #include "SFCGAL/TriangulatedSurface.h" @@ -71,6 +73,14 @@ WkbWriter::writeRec(const Geometry &g, boost::endian::order wkbOrder) writeInner(g.as(), wkbOrder); return; + case TYPE_SOLID: + writeInner(g.as(), wkbOrder); + return; + + case TYPE_MULTISOLID: + writeInner(g.as(), wkbOrder); + return; + default: std::ostringstream oss; oss << "WkbWriter: type '" << g.geometryType() << "' is not supported"; @@ -278,11 +288,19 @@ WkbWriter::writeInner(const M &g, boost::endian::order wkbOrder) // WkbType writeGeometryType(g, wkbOrder); - // Number of Geometries - toByte(static_cast(g.numGeometries()), wkbOrder); + // Number of Geometries/Shells + if constexpr (std::is_same::value) { + toByte(static_cast(g.numShells()), wkbOrder); - for (size_t i = 0; i < g.numGeometries(); i++) { - writeInner(g.geometryN(i).template as(), wkbOrder); + for (size_t i = 0; i < g.numShells(); i++) { + writeRec(g.shellN(i).template as(), wkbOrder); + } + } else { + toByte(static_cast(g.numGeometries()), wkbOrder); + + for (size_t i = 0; i < g.numGeometries(); i++) { + writeRec(g.geometryN(i).template as(), wkbOrder); + } } } diff --git a/test/unit/SFCGAL/io/WkbWriterTest.cpp b/test/unit/SFCGAL/io/WkbWriterTest.cpp index 17c614fc..ce1383be 100644 --- a/test/unit/SFCGAL/io/WkbWriterTest.cpp +++ b/test/unit/SFCGAL/io/WkbWriterTest.cpp @@ -140,4 +140,23 @@ BOOST_AUTO_TEST_CASE(PostgisEWkb) } } } + +BOOST_AUTO_TEST_CASE(SolidWKB) +{ + std::string cube{"SOLID((((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((1 0 0,1 1 0,1 1 " + "1,1 0 1,1 0 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 " + "1,0 1 1,0 1 0,0 0 0,0 0 1)),((1 0 1,1 1 1,0 1 1,0 0 1,1 0 " + "1)),((1 0 0,1 0 1,0 0 1,0 0 0,1 0 0))))"}; + + std::unique_ptr g(io::readWkt(cube)); + auto wkbBinary = g->asWkb(); + std::unique_ptr g2(io::readWkb(wkbBinary)); + BOOST_CHECK_EQUAL(g->asText(0), g2->asText(0)); + + /* + wkbBinary = g->asWkb(boost::endian::order::native, true); + std::cerr << wkbBinary << "\n"; + */ +} + BOOST_AUTO_TEST_SUITE_END()