Skip to content

Commit

Permalink
feat: prepare dsv for geojson
Browse files Browse the repository at this point in the history
  • Loading branch information
barendgehrels committed Dec 6, 2024
1 parent d7698b1 commit e325023
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions include/boost/geometry/io/dsv/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@

#include <boost/geometry/geometries/concepts/check.hpp>

#include <boost/geometry/util/condition.hpp>

namespace boost { namespace geometry
{

Expand All @@ -53,6 +55,7 @@ struct dsv_settings
std::string list_open;
std::string list_close;
std::string list_separator;
bool close_rings{false};

dsv_settings(std::string const& sep
, std::string const& open
Expand All @@ -61,6 +64,7 @@ struct dsv_settings
, std::string const& lopen
, std::string const& lclose
, std::string const& lsep
, bool cr = false
)
: coordinate_separator(sep)
, point_open(open)
Expand All @@ -69,6 +73,7 @@ struct dsv_settings
, list_open(lopen)
, list_close(lclose)
, list_separator(lsep)
, close_rings(cr)
{}
};

Expand Down Expand Up @@ -161,7 +166,7 @@ struct dsv_point
\brief Stream ranges as DSV
\note policy is used to stream prefix/postfix, enabling derived classes to override this
*/
template <typename Range>
template <typename Range, bool Areal>
struct dsv_range
{
template <typename Char, typename Traits>
Expand All @@ -173,20 +178,31 @@ struct dsv_range

os << settings.list_open;

for (auto it = boost::begin(range); it != boost::end(range); ++it)
auto stream_point = [&os, &settings](std::string const& sep, auto const& point)
{
os << (first ? "" : settings.point_separator)
<< settings.point_open;

os << sep << settings.point_open;
stream_coordinate
<
point_type, 0, dimension<point_type>::type::value
>::apply(os, *it, settings);
>::apply(os, point, settings);
os << settings.point_close;
};

for (auto it = boost::begin(range); it != boost::end(range); ++it)
{
stream_point(first ? "" : settings.point_separator, *it);
first = false;
}

if (BOOST_GEOMETRY_CONDITION(Areal))
{
if (settings.close_rings && boost::size(range) > 0)
{
// Close it explicitly
stream_point(settings.point_separator, *boost::begin(range));
}
}

os << settings.list_close;
}

Expand All @@ -211,13 +227,13 @@ struct dsv_poly

os << settings.list_open;

dsv_range<ring_t>::apply(os, exterior_ring(poly), settings);
dsv_range<ring_t, true>::apply(os, exterior_ring(poly), settings);

auto const& rings = interior_rings(poly);
for (auto it = boost::begin(rings); it != boost::end(rings); ++it)
{
os << settings.list_separator;
dsv_range<ring_t>::apply(os, *it, settings);
dsv_range<ring_t, true>::apply(os, *it, settings);
}
os << settings.list_close;
}
Expand Down Expand Up @@ -277,7 +293,7 @@ struct dsv<point_tag, Point>

template <typename Linestring>
struct dsv<linestring_tag, Linestring>
: detail::dsv::dsv_range<Linestring>
: detail::dsv::dsv_range<Linestring, false>
{};

template <typename Box>
Expand All @@ -292,7 +308,7 @@ struct dsv<segment_tag, Segment>

template <typename Ring>
struct dsv<ring_tag, Ring>
: detail::dsv::dsv_range<Ring>
: detail::dsv::dsv_range<Ring, true>
{};

template <typename Polygon>
Expand Down Expand Up @@ -404,14 +420,15 @@ inline detail::dsv::dsv_manipulator<Geometry> dsv(Geometry const& geometry
, std::string const& list_open = "("
, std::string const& list_close = ")"
, std::string const& list_separator = ", "
, bool close_rings = false
)
{
concepts::check<Geometry const>();

return detail::dsv::dsv_manipulator<Geometry>(geometry,
detail::dsv::dsv_settings(coordinate_separator,
point_open, point_close, point_separator,
list_open, list_close, list_separator));
list_open, list_close, list_separator, close_rings));
}

}} // namespace boost::geometry
Expand Down

0 comments on commit e325023

Please sign in to comment.