123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- // 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
|