Skip to content

Commit

Permalink
Merge branch 'wkb' into 'master'
Browse files Browse the repository at this point in the history
Add (E)WKB support

See merge request Oslandia/SFCGAL!284
  • Loading branch information
lbartoletti committed Aug 30, 2023
2 parents ae0a12d + 5181f12 commit fc4dc56
Show file tree
Hide file tree
Showing 16 changed files with 1,752 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required( VERSION 2.8 )
project( SFCGAL )

set( CMAKE_DEBUG_POSTFIX "d" )
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)

#
# Cmake policies
Expand Down
9 changes: 9 additions & 0 deletions src/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <SFCGAL/GeometryVisitor.h>
#include <SFCGAL/Point.h>
#include <SFCGAL/detail/GetPointsVisitor.h>
#include <SFCGAL/detail/io/WkbWriter.h>
#include <SFCGAL/detail/io/WktWriter.h>

#include <SFCGAL/algorithm/BoundaryVisitor.h>
Expand Down Expand Up @@ -45,6 +46,14 @@ Geometry::asText(const int &numDecimals) const -> std::string
return oss.str();
}

auto
Geometry::asWkb(boost::endian::order wkbOrder, bool asHex) const -> std::string
{
std::ostringstream oss;
detail::io::WkbWriter writer(oss);
writer.write(*this, wkbOrder, asHex);
return oss.str();
}
///
///
///
Expand Down
13 changes: 12 additions & 1 deletion src/Geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <SFCGAL/config.h>

#include <boost/endian/conversion.hpp>
#include <boost/shared_ptr.hpp>

#include <memory>
Expand Down Expand Up @@ -46,6 +47,10 @@ class ConstGeometryVisitor;

namespace SFCGAL {

const uint32_t wkbSRID = 0x20000000;
const uint32_t wkbM = 0x40000000;
const uint32_t wkbZ = 0x80000000;

/**
* [OGC/SFA]8.2.3 "A common list of codes for geometric types"
*
Expand Down Expand Up @@ -73,7 +78,7 @@ enum GeometryType {
// TYPE_SURFACE = 14, //abstract
TYPE_POLYHEDRALSURFACE = 15,
TYPE_TRIANGULATEDSURFACE = 16,
TYPE_TRIANGLE = 17,
TYPE_TRIANGLE = 17,

//-- not official codes
TYPE_SOLID = 101,
Expand Down Expand Up @@ -194,6 +199,12 @@ class SFCGAL_API Geometry {
std::string
asText(const int &numDecimals = -1) const;

/**
* [OGC/SFA]returns the WKB string
*/
std::string
asWkb(boost::endian::order wkbOrder = boost::endian::order::native,
bool asHex = false) const;
/**
* [OGC/SFA]Returns a polygon representing the BBOX of the geometry
* @todo In order to adapt to 3D, would be better to define an "Envelope
Expand Down
12 changes: 12 additions & 0 deletions src/PreparedGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <SFCGAL/PreparedGeometry.h>

#include <SFCGAL/detail/io/WkbWriter.h>
#include <SFCGAL/detail/io/WktWriter.h>

namespace SFCGAL {
Expand Down Expand Up @@ -83,4 +84,15 @@ PreparedGeometry::asEWKT(const int &numDecimals) const -> std::string
writer.write(*_geometry, exactWrite);
return oss.str();
}

auto
PreparedGeometry::asEWKB(boost::endian::order wkbOrder, bool asHex) const
-> std::string
{
std::ostringstream oss;
detail::io::WkbWriter writer(oss);
writer.write(*_geometry, _srid, wkbOrder, asHex);
return oss.str();
}

} // namespace SFCGAL
5 changes: 5 additions & 0 deletions src/PreparedGeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <SFCGAL/Envelope.h>

#include <boost/endian/conversion.hpp>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <boost/serialization/split_member.hpp>
Expand Down Expand Up @@ -101,6 +102,10 @@ class SFCGAL_API PreparedGeometry : public boost::noncopyable {
std::string
asEWKT(const int &numDecimals = -1) const;

auto
asEWKB(boost::endian::order wkbOrder = boost::endian::order::native,
bool asHex = false) const -> std::string;

/**
* Serializer
*/
Expand Down
217 changes: 217 additions & 0 deletions src/detail/io/WkbReader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
// Copyright (c) 2023-2023, Oslandia.
// SPDX-License-Identifier: LGPL-2.0-or-later

#include <SFCGAL/detail/io/WkbReader.h>

#include <SFCGAL/config.h>

#include <SFCGAL/Geometry.h>
#include <SFCGAL/GeometryCollection.h>
#include <SFCGAL/LineString.h>
#include <SFCGAL/MultiLineString.h>
#include <SFCGAL/MultiPoint.h>
#include <SFCGAL/MultiPolygon.h>
#include <SFCGAL/Point.h>
#include <SFCGAL/Polygon.h>
#include <SFCGAL/PolyhedralSurface.h>
#include <SFCGAL/Triangle.h>
#include <SFCGAL/TriangulatedSurface.h>
#include <boost/exception/all.hpp>
#include <exception>

namespace SFCGAL::detail::io {

/**
* Read Point content from wkb
*/
auto
WkbReader::readInnerPoint() -> Point
{
double x{read<double>()};
double y{read<double>()};

if (!(std::isfinite(x) && std::isfinite(y))) {
return {};
}
if (_is3D && _isMeasured) {
double z{read<double>()};
double m{read<double>()};

if (!(std::isfinite(z) && std::isfinite(m))) {
return {};
}
return SFCGAL::Point{x, y, z, m};
}
if (_is3D) {
double z{read<double>()};
if (!(std::isfinite(z))) {
return {};
}
return SFCGAL::Point{x, y, z};
}
if (_isMeasured) {

double m{read<double>()};
if (!(std::isfinite(m))) {
return {};
}
SFCGAL::Point result{x, y};
result.setM(m);
return result;
}
return SFCGAL::Point{x, y};
}

/**
* Read LineString content from wkb
*/
auto
WkbReader::readInnerLineString() -> LineString
{
SFCGAL::LineString result;
try {
const uint32_t numPoints{read<uint32_t>()};
for (uint32_t i = 0; i < numPoints; ++i) {
result.addPoint(readInnerPoint());
}
} catch (std::exception &e) {
std::cerr << e.what();
return {};
}
return result;
}

/**
* Read Polygon content from wkb
*/
auto
WkbReader::readInnerPolygon() -> Polygon
{
SFCGAL::Polygon result;
try {
const uint32_t numRings{read<uint32_t>()};
for (uint32_t i = 0; i < numRings; ++i) {
SFCGAL::LineString ls{readInnerLineString()};

if (i == 0) {
result.setExteriorRing(ls);
} else {
result.addInteriorRing(ls);
}
}
} catch (std::exception &e) {
std::cerr << e.what();
return {};
}
return result;
}

/**
* Read Triangle content from wkb
*/
auto
WkbReader::readInnerTriangle() -> Triangle
{
try {
SFCGAL::Polygon poly{readInnerPolygon()};
if (poly.isEmpty()) {
return {};
}

SFCGAL::LineString geom{poly.exteriorRing()};
if (geom.isEmpty()) {
return {};
}

return SFCGAL::Triangle{geom.pointN(0), geom.pointN(1), geom.pointN(2)};
} catch (std::exception &e) {
std::cerr << e.what();
}
return {};
}

/**
* Read MultiGeometries content from wkb
*/
template <typename M, typename G>
auto
WkbReader::readInnerMultiGeometries() -> M
{
M result;
try {
const uint32_t numGeoms{read<uint32_t>()};
for (uint32_t i = 0; i < numGeoms; ++i) {
readWkb();
G geom{_geometry->template as<G>()};
result.addGeometry(geom);
}
} catch (std::exception &e) {
std::cerr << e.what();
return {};
}
return result;
}

/**
* Read GeometryCollection content from wkb
*/
auto
WkbReader::readInnerGeometryCollection() -> GeometryCollection
{
SFCGAL::GeometryCollection result;
try {
const uint32_t numGeoms{read<uint32_t>()};
for (uint32_t i = 0; i < numGeoms; ++i) {
readWkb();
result.addGeometry(_geometry.release());
}
} catch (std::exception &e) {
std::cerr << e.what();
return {};
}
return result;
}

/**
* Read TriangulatedSurface content from wkb
*/
auto
WkbReader::readInnerTriangulatedSurface() -> TriangulatedSurface
{
SFCGAL::TriangulatedSurface result;
try {
const uint32_t numGeoms{read<uint32_t>()};
for (uint32_t i = 0; i < numGeoms; ++i) {
readWkb();
SFCGAL::Triangle geom{_geometry->as<SFCGAL::Triangle>()};
result.addTriangle(geom);
}
} catch (std::exception &e) {
std::cerr << e.what();
return {};
}
return result;
}

/**
* Read PolyhedralSurface content from wkb
*/
auto
WkbReader::readInnerPolyhedralSurface() -> PolyhedralSurface
{
std::vector<Polygon> geoms;
try {
const uint32_t numGeoms{read<uint32_t>()};
for (uint32_t i = 0; i < numGeoms; ++i) {
readWkb();
geoms.push_back(_geometry->as<SFCGAL::Polygon>());
}
} catch (std::exception &e) {
std::cerr << e.what();
return {};
}
SFCGAL::PolyhedralSurface result{geoms};
return result;
}

} // namespace SFCGAL::detail::io
Loading

0 comments on commit fc4dc56

Please sign in to comment.