Merge pull request #670 from sudo-panda/feature/symmetric-wkt

Symmetrizing read/write wkt
This commit is contained in:
Adam Wulkiewicz 2021-03-03 14:06:08 +01:00 committed by GitHub
commit 28559c042e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 352 additions and 9 deletions

View File

@ -156,6 +156,8 @@
[import src/examples/io/svg_mapper_custom.cpp]
[import src/examples/io/wkt.cpp]
[import src/examples/io/read_wkt.cpp]
[import src/examples/io/to_wkt.cpp]
[import src/examples/io/from_wkt.cpp]
[import src/examples/strategies/buffer_join_round.cpp]
[import src/examples/strategies/buffer_join_miter.cpp]

View File

@ -719,6 +719,8 @@
<simplelist type="vert" columns="1">
<member><link linkend="geometry.reference.io.wkt.read_wkt">read_wkt</link></member>
<member><link linkend="geometry.reference.io.wkt.wkt">wkt</link></member>
<member><link linkend="geometry.reference.io.wkt.to_wkt">to_wkt</link></member>
<member><link linkend="geometry.reference.io.wkt.from_wkt">from_wkt</link></member>
</simplelist>
</entry>
<entry valign="top">

View File

@ -0,0 +1,23 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2020 Baidyanath Kundu, Haldia, India.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[heading Conformance]
Other libraries refer to this functionality as [*ST_GeomFromText] or [*STGeomFromText].
That is not done here because Boost.Geometry support more text formats. The name GeomFromText
is reserved for future usage, which will then have an indication of the used text format.
[heading Example]
[from_wkt]
[heading See also]
* [link geometry.reference.io.wkt.wkt WKT streaming manipulator]
* [link geometry.reference.io.wkt.read_wkt Read WKT]
* [link geometry.reference.io.wkt.to_wkt To WKT]

View File

@ -19,4 +19,6 @@ is reserved for future usage, which will then have an indication of the used tex
[read_wkt]
[heading See also]
* [link geometry.reference.io.wkt.from_wkt From WKT]
* [link geometry.reference.io.wkt.to_wkt To WKT]
* [link geometry.reference.io.wkt.wkt WKT streaming manipulator]

View File

@ -0,0 +1,25 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2014 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2020 Baidyanath Kundu, Haldia, India.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[def __this_function__ to_wkt]
[heading_conformance_ogc __this_function__..AsText]
[note __this_function__ is not named "AsText" or "as_text" because Boost.Geometry
also supports other textformats (svg, dsv)]
[heading Example]
[to_wkt]
[to_wkt_output]
[heading See also]
* [link geometry.reference.io.wkt.read_wkt Read WKT]
* [link geometry.reference.io.wkt.from_wkt From WKT]
* [link geometry.reference.io.wkt.wkt WKT streaming manipulator]

View File

@ -20,3 +20,5 @@ also supports other textformats (svg, dsv)]
[heading See also]
* [link geometry.reference.io.wkt.read_wkt Read WKT]
* [link geometry.reference.io.wkt.from_wkt From WKT]
* [link geometry.reference.io.wkt.from_wkt To WKT]

View File

@ -18,3 +18,5 @@ exe svg : svg.cpp ;
exe svg_mapper_custom : svg_mapper_custom.cpp ;
exe wkt : wkt.cpp ;
exe read_wkt : read_wkt.cpp ;
exe to_wkt : to_wkt.cpp ;
exe from_wkt : from_wkt.cpp ;

View File

@ -0,0 +1,36 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2020 Baidyanath Kundu, Haldia, India.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[from_wkt
//` Shows the usage of from_wkt
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/polygon.hpp>
int main()
{
using point_type = boost::geometry::model::d2::point_xy<double>;
using box_type = boost::geometry::model::box<point_type>;
using segment_type = boost::geometry::model::segment<point_type>;
using polygon_type = boost::geometry::model::polygon<point_type>;
using linestring_type = boost::geometry::model::linestring<point_type>;
auto const a = boost::geometry::from_wkt<point_type>("POINT(1 2)");
auto const d = boost::geometry::from_wkt<box_type>("BOX(0 0,3 3)");
auto const e = boost::geometry::from_wkt<segment_type>("SEGMENT(1 0,3 4)");
auto const c = boost::geometry::from_wkt<polygon_type>("POLYGON((0 0,0 7,4 2,2 0,0 0))");
auto const b = boost::geometry::from_wkt<linestring_type>("LINESTRING(0 0,2 2,3 1)");
return 0;
}
//]

View File

@ -0,0 +1,64 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Baidyanath Kundu, Haldia, India.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[to_wkt
//` Shows the usage of to_wkt
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
int main()
{
namespace geom = boost::geometry;
typedef geom::model::d2::point_xy<double> point_type;
point_type point = geom::make<point_type>(3, 2);
geom::model::polygon<point_type> polygon;
geom::append(geom::exterior_ring(polygon), geom::make<point_type>(0, 0));
geom::append(geom::exterior_ring(polygon), geom::make<point_type>(0, 4));
geom::append(geom::exterior_ring(polygon), geom::make<point_type>(4, 4));
geom::append(geom::exterior_ring(polygon), geom::make<point_type>(4, 0));
geom::append(geom::exterior_ring(polygon), geom::make<point_type>(0, 0));
std::cout << boost::geometry::to_wkt(point) << std::endl;
std::cout << boost::geometry::to_wkt(polygon) << std::endl;
point_type point_frac = geom::make<point_type>(3.141592654, 27.18281828);
geom::model::polygon<point_type> polygon_frac;
geom::append(geom::exterior_ring(polygon_frac), geom::make<point_type>(0.00000, 0.00000));
geom::append(geom::exterior_ring(polygon_frac), geom::make<point_type>(0.00000, 4.00001));
geom::append(geom::exterior_ring(polygon_frac), geom::make<point_type>(4.00001, 4.00001));
geom::append(geom::exterior_ring(polygon_frac), geom::make<point_type>(4.00001, 0.00000));
geom::append(geom::exterior_ring(polygon_frac), geom::make<point_type>(0.00000, 0.00000));
std::cout << boost::geometry::to_wkt(point_frac, 3) << std::endl;
std::cout << boost::geometry::to_wkt(polygon_frac, 3) << std::endl;
return 0;
}
//]
//[to_wkt_output
/*`
Output:
[pre
POINT(3 2)
POLYGON((0 0,0 4,4 4,4 0,0 0))
POINT(3.14 27.2)
POLYGON((0 0,0 4,4 4,4 0,0 0))
]
*/
//]

View File

@ -42,7 +42,9 @@ int main()
/*`
Output:
[pre
POINT(3 6)
POINT(3 2)
POLYGON((0 0,0 4,4 4,4 0,0 0))
POINT(3.14 27.2)
POLYGON((0 0,0 4,4 4,4 0,0 0))
]

View File

@ -4,6 +4,7 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020 Baidyanath Kundu, Haldia, India
// This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
@ -911,6 +912,23 @@ inline void read_wkt(std::string const& wkt, Geometry& geometry)
dispatch::read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
}
/*!
\brief Parses OGC Well-Known Text (\ref WKT) into a geometry (any geometry) and returns it
\ingroup wkt
\tparam Geometry \tparam_geometry
\param wkt string containing \ref WKT
\ingroup wkt
\qbk{[include reference/io/from_wkt.qbk]}
*/
template <typename Geometry>
inline Geometry from_wkt(std::string const& wkt)
{
Geometry geometry;
geometry::concepts::check<Geometry>();
dispatch::read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
return geometry;
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_IO_WKT_READ_HPP

View File

@ -4,6 +4,7 @@
// Copyright (c) 2008-2017 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2017 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020 Baidyanath Kundu, Haldia, India.
// This file was modified by Oracle on 2015-2020.
// Modifications copyright (c) 2015-2020, Oracle and/or its affiliates.
@ -558,6 +559,31 @@ inline wkt_manipulator<Geometry> wkt(Geometry const& geometry)
return wkt_manipulator<Geometry>(geometry);
}
/*!
\brief WKT-string formulating function
\tparam Geometry \tparam_geometry
\param geometry \param_geometry
\param significant_digits Specifies the no of significant digits to use in the output wkt
\ingroup wkt
\qbk{[include reference/io/to_wkt.qbk]}
*/
template <typename Geometry>
inline std::string to_wkt(Geometry const& geometry)
{
std::stringstream ss;
ss << boost::geometry::wkt(geometry);
return ss.str();
}
template <typename Geometry>
inline std::string to_wkt(Geometry const& geometry, int significant_digits)
{
std::stringstream ss;
ss.precision(significant_digits);
ss << boost::geometry::wkt(geometry);
return ss.str();
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif

View File

@ -28,6 +28,7 @@
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/make.hpp>
#include <boost/geometry/algorithms/length.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/perimeter.hpp>
@ -48,14 +49,33 @@ void check_wkt(G const& geometry, std::string const& expected)
}
template <typename G>
void test_wkt(std::string const& wkt, std::string const& expected,
void check_to_wkt(G const& geometry, std::string const& expected)
{
std::string out_string;
out_string = bg::to_wkt(geometry);
BOOST_CHECK_EQUAL(boost::to_upper_copy(out_string),
boost::to_upper_copy(expected));
}
template <typename G>
void check_precise_to_wkt(G const& geometry, std::string const& expected,
int significant_digits)
{
std::string out_string;
out_string = bg::to_wkt(geometry, significant_digits);
BOOST_CHECK_EQUAL(boost::to_upper_copy(out_string),
boost::to_upper_copy(expected));
}
template <typename G>
void test_wkt_read_write(std::string const& wkt, std::string const& expected,
std::size_t n, double len = 0, double ar = 0, double peri = 0)
{
G geometry;
bg::read_wkt(wkt, geometry);
/*
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "n=" << bg::num_points(geometry)
<< " dim=" << bg::topological_dimension<G>::value
<< " length=" << bg::length(geometry)
@ -63,7 +83,7 @@ void test_wkt(std::string const& wkt, std::string const& expected,
<< " perimeter=" << bg::perimeter(geometry)
<< std::endl << "\t\tgeometry=" << dsv(geometry)
<< std::endl;
*/
#endif
BOOST_CHECK_EQUAL(bg::num_points(geometry), n);
if (n > 0)
@ -77,6 +97,44 @@ void test_wkt(std::string const& wkt, std::string const& expected,
check_wkt(boost::variant<G>(geometry), expected);
}
template <typename G>
void test_wkt_to_from(std::string const& wkt, std::string const& expected,
std::size_t n, double len = 0, double ar = 0, double peri = 0)
{
G geometry;
geometry = bg::from_wkt<G>(wkt);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "n=" << bg::num_points(geometry)
<< " dim=" << bg::topological_dimension<G>::value
<< " length=" << bg::length(geometry)
<< " area=" << bg::area(geometry)
<< " perimeter=" << bg::perimeter(geometry)
<< std::endl << "\t\tgeometry=" << dsv(geometry)
<< std::endl;
#endif
BOOST_CHECK_EQUAL(bg::num_points(geometry), n);
if (n > 0)
{
BOOST_CHECK_CLOSE(double(bg::length(geometry)), len, 0.0001);
BOOST_CHECK_CLOSE(double(bg::area(geometry)), ar, 0.0001);
BOOST_CHECK_CLOSE(double(bg::perimeter(geometry)), peri, 0.0001);
}
check_to_wkt(geometry, expected);
check_to_wkt(boost::variant<G>(geometry), expected);
}
template <typename G>
void test_wkt(std::string const& wkt, std::string const& expected,
std::size_t n, double len = 0, double ar = 0, double peri = 0)
{
test_wkt_read_write<G>(wkt, expected, n, len, ar, peri);
test_wkt_to_from<G>(wkt, expected, n, len, ar, peri);
}
template <typename G>
void test_wkt(std::string const& wkt,
std::size_t n, double len = 0, double ar = 0, double peri = 0)
@ -85,7 +143,7 @@ void test_wkt(std::string const& wkt,
}
template <typename G>
void test_relaxed_wkt(std::string const& wkt, std::string const& expected)
void test_relaxed_wkt_read_write(std::string const& wkt, std::string const& expected)
{
std::string e;
G geometry;
@ -96,17 +154,72 @@ void test_relaxed_wkt(std::string const& wkt, std::string const& expected)
BOOST_CHECK_EQUAL(boost::to_upper_copy(out.str()), boost::to_upper_copy(expected));
}
template <typename G>
void test_relaxed_wkt_to_from(std::string const& wkt, std::string const& expected)
{
std::string e;
G geometry;
geometry = bg::from_wkt<G>(wkt);
std::string out;
out = bg::to_wkt(geometry);
BOOST_CHECK_EQUAL(boost::to_upper_copy(out), boost::to_upper_copy(expected));
}
template <typename G>
void test_wrong_wkt(std::string const& wkt, std::string const& start)
void test_relaxed_wkt(std::string const& wkt, std::string const& expected)
{
test_relaxed_wkt_read_write<G>(wkt, expected);
test_relaxed_wkt_to_from<G>(wkt, expected);
}
template <typename G>
void test_wrong_wkt_read_write(std::string const& wkt, std::string const& start)
{
std::string e("no exception");
G geometry;
try
{
bg::read_wkt(wkt, geometry);
bg::read_wkt<G>(wkt, geometry);
}
catch(bg::read_wkt_exception const& ex)
{
e = ex.what();
boost::to_lower(e);
}
catch(...)
{
e = "other exception";
}
bool check = true;
#if defined(HAVE_TTMATH)
// For ttmath we skip bad lexical casts
typedef typename bg::coordinate_type<G>::type ct;
if (boost::is_same<ct, ttmath_big>::type::value
&& boost::starts_with(start, "bad lexical cast"))
{
check = false;
}
#endif
if (check)
{
BOOST_CHECK_MESSAGE(boost::starts_with(e, start), " Expected:"
<< start << " Got:" << e << " with WKT: " << wkt);
}
}
template <typename G>
void test_wrong_wkt_to_from(std::string const& wkt, std::string const& start)
{
std::string e("no exception");
G geometry;
try
{
geometry = bg::from_wkt<G>(wkt);
}
catch(bg::read_wkt_exception const& ex)
{
@ -122,6 +235,13 @@ void test_wrong_wkt(std::string const& wkt, std::string const& start)
<< start << " Got:" << e << " with WKT: " << wkt);
}
template <typename G>
void test_wrong_wkt(std::string const& wkt, std::string const& start)
{
test_wrong_wkt_read_write<G>(wkt, start);
test_wrong_wkt_to_from<G>(wkt, start);
}
template <typename G>
void test_wkt_output_iterator(std::string const& wkt)
{
@ -129,7 +249,19 @@ void test_wkt_output_iterator(std::string const& wkt)
bg::read_wkt<G>(wkt, std::back_inserter(geometry));
}
void test_precise_to_wkt()
{
typedef boost::geometry::model::d2::point_xy<double> point_type;
point_type point = boost::geometry::make<point_type>(1.2345, 6.7890);
boost::geometry::model::polygon<point_type> polygon;
boost::geometry::append(boost::geometry::exterior_ring(polygon), boost::geometry::make<point_type>(0.00000, 0.00000));
boost::geometry::append(boost::geometry::exterior_ring(polygon), boost::geometry::make<point_type>(0.00000, 4.00001));
boost::geometry::append(boost::geometry::exterior_ring(polygon), boost::geometry::make<point_type>(4.00001, 4.00001));
boost::geometry::append(boost::geometry::exterior_ring(polygon), boost::geometry::make<point_type>(4.00001, 0.00000));
boost::geometry::append(boost::geometry::exterior_ring(polygon), boost::geometry::make<point_type>(0.00000, 0.00000));
check_precise_to_wkt(point,"POINT(1.23 6.79)",3);
check_precise_to_wkt(polygon,"POLYGON((0 0,0 4,4 4,4 0,0 0))",3);
}
#ifndef GEOMETRY_TEST_MULTI
template <typename T>
@ -193,6 +325,8 @@ void test_all()
test_wkt<bg::model::polygon<P> >("POLYGON((),(),())", 0);
// which all make no valid geometries, but they can exist.
// These WKT's are incomplete or abnormal but they are considered OK
test_relaxed_wkt<P>("POINT(1)", "POINT(1 0)");
test_relaxed_wkt<P>("POINT()", "POINT(0 0)");
@ -245,6 +379,11 @@ int test_main(int, char* [])
{
test_all<double>();
test_all<int>();
test_precise_to_wkt();
#if defined(HAVE_TTMATH)
test_all<ttmath_big>();
#endif
return 0;
}