diff options
Diffstat (limited to 'src/boost/libs/geometry/test/to_svg.hpp')
-rw-r--r-- | src/boost/libs/geometry/test/to_svg.hpp | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/src/boost/libs/geometry/test/to_svg.hpp b/src/boost/libs/geometry/test/to_svg.hpp new file mode 100644 index 00000000..ad62e217 --- /dev/null +++ b/src/boost/libs/geometry/test/to_svg.hpp @@ -0,0 +1,412 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// 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) + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +#ifndef BOOST_GEOMETRY_TEST_TO_SVG_HPP +#define BOOST_GEOMETRY_TEST_TO_SVG_HPP + +#include <fstream> + +#include <boost/geometry/io/wkt/read.hpp> +#include <boost/geometry/io/svg/svg_mapper.hpp> +#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp> +#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp> +#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp> +#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp> +#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp> +#include <boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp> +#include <boost/foreach.hpp> + +#include <boost/geometry/algorithms/detail/relate/turns.hpp> + +template <typename G, typename Turns, typename Mapper> +inline void turns_to_svg(Turns const& turns, Mapper & mapper, bool /*enrich*/ = false) +{ + namespace bg = boost::geometry; + + // turn points in orange, + enrichment/traversal info + typedef typename bg::coordinate_type<G>::type coordinate_type; + typedef typename boost::range_value<Turns>::type turn_info; + + // Simple map to avoid two texts at same place (note that can still overlap!) + std::map<std::pair<int, int>, int> offsets; + int index = 0; + int const margin = 5; + + BOOST_FOREACH(turn_info const& turn, turns) + { + int lineheight = 10; + mapper.map(turn.point, "fill:rgb(255,128,0);" + "stroke:rgb(0,0,0);stroke-width:1", 3); + + { + coordinate_type half = 0.5; + coordinate_type ten = 10; + // Map characteristics + // Create a rounded off point + std::pair<int, int> p + = std::make_pair( + boost::numeric_cast<int>(half + + ten * bg::get<0>(turn.point)), + boost::numeric_cast<int>(half + + ten * bg::get<1>(turn.point)) + ); + std::string style = "fill:rgb(0,0,0);font-family:Arial;font-size:12px"; + + if (turn.discarded) + { + style = "fill:rgb(92,92,92);font-family:Arial;font-size:10px"; + lineheight = 6; + } + + //if (! turn.discarded && ! turn.blocked() && ! turn.both(bg::detail::overlay::operation_union)) + //if (! turn.discarded) + { + std::ostringstream out; + out << index + << ": " << bg::method_char(turn.method); + + if ( turn.discarded ) + out << " (discarded)\n"; + else if ( turn.blocked() ) + out << " (blocked)\n"; + else + out << '\n'; + + out << bg::operation_char(turn.operations[0].operation) + <<": seg: " << turn.operations[0].seg_id.source_index + << ' ' << turn.operations[0].seg_id.multi_index + << ' ' << turn.operations[0].seg_id.ring_index + << ' ' << turn.operations[0].seg_id.segment_index << ", "; + out << "other: " << turn.operations[1].seg_id.source_index + << ' ' << turn.operations[1].seg_id.multi_index + << ' ' << turn.operations[1].seg_id.ring_index + << ' ' << turn.operations[1].seg_id.segment_index; + + /*if ( enrich ) + { + out << ", "; + if (turn.operations[0].enriched.next_ip_index != -1) + { + out << "ip: " << turn.operations[0].enriched.next_ip_index; + } + else + { + out << "vx: " << turn.operations[0].enriched.travels_to_vertex_index + << " -> ip: " << turn.operations[0].enriched.travels_to_ip_index; + } + }*/ + + out << '\n'; + + out << bg::operation_char(turn.operations[1].operation) + << ": seg: " << turn.operations[1].seg_id.source_index + << ' ' << turn.operations[1].seg_id.multi_index + << ' ' << turn.operations[1].seg_id.ring_index + << ' ' << turn.operations[1].seg_id.segment_index << ", "; + out << "other: " << turn.operations[0].seg_id.source_index + << ' ' << turn.operations[0].seg_id.multi_index + << ' ' << turn.operations[0].seg_id.ring_index + << ' ' << turn.operations[0].seg_id.segment_index; + + /*if ( enrich ) + { + out << ", "; + if (turn.operations[1].enriched.next_ip_index != -1) + { + out << "ip: " << turn.operations[1].enriched.next_ip_index; + } + else + { + out << "vx: " << turn.operations[1].enriched.travels_to_vertex_index + << " -> ip: " << turn.operations[1].enriched.travels_to_ip_index; + } + }*/ + + //out << std::endl; + + /*out + + << std::setprecision(3) + << "dist: " << boost::numeric_cast<double>(turn.operations[0].enriched.distance) + << " / " << boost::numeric_cast<double>(turn.operations[1].enriched.distance) + << std::endl + << "vis: " << bg::visited_char(turn.operations[0].visited) + << " / " << bg::visited_char(turn.operations[1].visited); + */ + + /* + out << index + << ": " << bg::operation_char(turn.operations[0].operation) + << " " << bg::operation_char(turn.operations[1].operation) + << " (" << bg::method_char(turn.method) << ")" + << (turn.ignore() ? " (ignore) " : " ") + << std::endl + + << "ip: " << turn.operations[0].enriched.travels_to_ip_index + << "/" << turn.operations[1].enriched.travels_to_ip_index; + + if (turn.operations[0].enriched.next_ip_index != -1 + || turn.operations[1].enriched.next_ip_index != -1) + { + out << " [" << turn.operations[0].enriched.next_ip_index + << "/" << turn.operations[1].enriched.next_ip_index + << "]" + ; + } + out << std::endl; + + + out + << "vx:" << turn.operations[0].enriched.travels_to_vertex_index + << "/" << turn.operations[1].enriched.travels_to_vertex_index + << std::endl + + << std::setprecision(3) + << "dist: " << turn.operations[0].enriched.distance + << " / " << turn.operations[1].enriched.distance + << std::endl + */ + + + + offsets[p] += lineheight; + int offset = offsets[p]; + offsets[p] += lineheight * 3; + mapper.text(turn.point, out.str(), style, margin, offset, lineheight); + } + index++; + } + } +} + +template <typename G1, typename P> +inline void geom_to_svg(G1 const& g1, + boost::geometry::svg_mapper<P> & mapper) +{ + mapper.add(g1); + + mapper.map(g1, "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); +} + +template <typename G1, typename G2, typename P> +inline void geom_to_svg(G1 const& g1, G2 const& g2, + boost::geometry::svg_mapper<P> & mapper) +{ + mapper.add(g1); + mapper.add(g2); + + mapper.map(g1, "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); + mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);" + "stroke:rgb(51,51,153);stroke-width:3"); +} + +template <typename G1> +inline void geom_to_svg(G1 const& g1, std::string const& filename) +{ + namespace bg = boost::geometry; + typedef typename bg::point_type<G1>::type mapper_point_type; + + std::ofstream svg(filename.c_str(), std::ios::trunc); + bg::svg_mapper<mapper_point_type> mapper(svg, 500, 500); + + geom_to_svg(g1, mapper); +} + +template <typename G1, typename G2> +inline void geom_to_svg(G1 const& g1, G2 const& g2, std::string const& filename) +{ + namespace bg = boost::geometry; + typedef typename bg::point_type<G1>::type mapper_point_type; + + std::ofstream svg(filename.c_str(), std::ios::trunc); + bg::svg_mapper<mapper_point_type> mapper(svg, 500, 500); + + geom_to_svg(g1, g2, mapper); +} + +template <typename G1> +inline void geom_to_svg(std::string const& wkt1, std::string const& filename) +{ + namespace bg = boost::geometry; + + G1 g1; + bg::read_wkt(wkt1, g1); + geom_to_svg(g1, filename); +} + +template <typename G1, typename G2> +inline void geom_to_svg(std::string const& wkt1, std::string const& wkt2, std::string const& filename) +{ + namespace bg = boost::geometry; + + G1 g1; + G2 g2; + bg::read_wkt(wkt1, g1); + bg::read_wkt(wkt2, g2); + geom_to_svg(g1, g2, filename); +} + +struct to_svg_assign_policy + : boost::geometry::detail::overlay::assign_null_policy +{ + static bool const include_no_turn = false; + static bool const include_degenerate = false; + static bool const include_opposite = false; +}; + +template <typename G> +inline void to_svg(G const& g, std::string const& filename, bool /*sort*/ = true) +{ + namespace bg = boost::geometry; + + typedef typename bg::point_type<G>::type P; + + std::ofstream svg(filename.c_str(), std::ios::trunc); + + bg::svg_mapper<P> mapper(svg, 500, 500); + + mapper.add(g); + + mapper.map(g, "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); + + // GET TURNS + + typedef bg::segment_ratio<double> sr; + typedef bg::detail::overlay::traversal_turn_info<P, sr> turn_info; + typedef bg::detail::overlay::assign_null_policy AssignPolicy; + //typedef to_svg_assign_policy AssignPolicy; + + typedef std::deque<turn_info> Turns; + typedef bg::detail::self_get_turn_points::no_interrupt_policy InterruptPolicy; + + Turns turns; + InterruptPolicy interrupt_policy; + + typedef bg::detail::overlay::get_turn_info<AssignPolicy> TurnPolicy; + + bg::detail::self_get_turn_points::get_turns + < + false, TurnPolicy + >::apply(g, bg::detail::no_rescale_policy(), turns, interrupt_policy); + + turns_to_svg<G>(turns, mapper); +} + +template <typename G1, typename G2> +inline void to_svg(G1 const& g1, G2 const& g2, std::string const& filename, bool sort = true, bool use_old_turns_policy = false, bool enrich = false) +{ + namespace bg = boost::geometry; + + typedef typename bg::point_type<G1>::type mapper_point_type; + + std::ofstream svg(filename.c_str(), std::ios::trunc); + + bg::svg_mapper<mapper_point_type> mapper(svg, 500, 500); + + mapper.add(g1); + mapper.add(g2); + + mapper.map(g1, "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); + mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);" + "stroke:rgb(51,51,153);stroke-width:3"); + + // GET TURNS + + typedef typename bg::detail::relate::turns::get_turns<G1, G2>::turn_info turn_info; + //typedef bg::detail::overlay::traversal_turn_info<P1> turn_info; + //typedef bg::detail::overlay::assign_null_policy AssignPolicy; + typedef to_svg_assign_policy AssignPolicy; + + typedef std::deque<turn_info> Turns; + typedef bg::detail::get_turns::no_interrupt_policy InterruptPolicy; + static const bool Reverse1 = bg::detail::overlay::do_reverse<bg::point_order<G1>::value>::value; + static const bool Reverse2 = bg::detail::overlay::do_reverse<bg::point_order<G2>::value>::value; + + Turns turns; + InterruptPolicy interrupt_policy; + + if ( use_old_turns_policy ) + { + boost::geometry::get_turns + < + Reverse1, Reverse2, AssignPolicy + >(g1, g2, bg::detail::no_rescale_policy(), turns, interrupt_policy); + } + else + { + typedef bg::detail::get_turns::get_turn_info_type + < + G1, G2, AssignPolicy + > TurnPolicy; + + bg::detail::relate::turns::get_turns + < + G1, G2, TurnPolicy + >::apply(turns, g1, g2); + } + + if ( sort ) + { + typedef bg::detail::relate::turns::less + < + 0, + bg::detail::relate::turns::less_op_xxx_linear + < + 0, bg::detail::relate::turns::op_to_int<> + >, + typename bg::cs_tag<G1>::type + > less; + std::sort(boost::begin(turns), boost::end(turns), less()); + } + + /*if ( enrich ) + { + typedef typename bg::strategy::side::services::default_strategy + < + typename bg::cs_tag<G1>::type + >::type side_strategy_type; + + bg::enrich_intersection_points<bg::detail::overlay::do_reverse<bg::point_order<G1>::value>::value, + bg::detail::overlay::do_reverse<bg::point_order<G2>::value>::value> + (turns, bg::detail::overlay::operation_union, + g1, g1, + bg::detail::no_rescale_policy(), + side_strategy_type()); + }*/ + + turns_to_svg<G1>(turns, mapper, enrich); +} + +template <typename G> +inline void to_svg(std::string const& wkt, std::string const& filename) +{ + G g; + boost::geometry::read_wkt(wkt, g); + to_svg(g, filename); +} + +template <typename G1, typename G2> +inline void to_svg(std::string const& wkt1, std::string const& wkt2, std::string const& filename, bool sort = true, bool reverse_by_geometry_id = false, bool enrich = false) +{ + G1 g1; + G2 g2; + boost::geometry::read_wkt(wkt1, g1); + boost::geometry::read_wkt(wkt2, g2); + to_svg(g1, g2, filename, sort, reverse_by_geometry_id, enrich); +} + +#endif // BOOST_GEOMETRY_TEST_TO_SVG_HPP |