Ticket #9217: boost-geometry-wkt-close-ring.patch

File boost-geometry-wkt-close-ring.patch, 2.7 KB (added by Mateusz Loskot, 9 years ago)

Patch to impose last point to be equal to the first one in WKT for polygons

  • boost/geometry/io/wkt/write.hpp

     
    119119{
    120120    template <typename Char, typename Traits>
    121121    static inline void apply(std::basic_ostream<Char, Traits>& os,
    122                 Range const& range)
     122                Range const& range, bool force_closed)
    123123    {
    124124        typedef typename boost::range_iterator<Range const>::type iterator_type;
    125125
     126        typedef stream_coordinate
     127            <
     128                point_type, 0, dimension<point_type>::type::value
     129            > stream_type;
     130
    126131        bool first = true;
    127132
    128133        os << PrefixPolicy::apply();
     
    129134
    130135        // TODO: check EMPTY here
    131136
    132         for (iterator_type it = boost::begin(range);
    133             it != boost::end(range);
    134             ++it)
     137        iterator_type begin = boost::begin(range);
     138        iterator_type end = boost::end(range);
     139        for (iterator_type it = begin; it != end; ++it)
    135140        {
    136141            os << (first ? "" : ",");
    137             stream_coordinate
    138                 <
    139                     point_type, 0, dimension<point_type>::type::value
    140                 >::apply(os, *it);
     142            stream_type::apply(os, *it);
    141143            first = false;
    142144        }
    143145
     146        // optionally, close range to ring by repeating the first point
     147        if (force_closed && geometry::disjoint(*begin, *(end - 1)))
     148        {
     149            os << ",";
     150            stream_type::apply(os, *begin);
     151        }
     152
    144153        os << SuffixPolicy::apply();
    145154    }
    146155
     156    template <typename Char, typename Traits>
     157    static inline void apply(std::basic_ostream<Char, Traits>& os,
     158                Range const& range)
     159    {
     160        apply(os, range, false);
     161    }
     162
    147163private:
    148164    typedef typename boost::range_value<Range>::type point_type;
    149165};
     
    170186                Polygon const& poly)
    171187    {
    172188        typedef typename ring_type<Polygon const>::type ring;
     189        bool const force_closed = true;
    173190
    174191        os << PrefixPolicy::apply();
    175192        // TODO: check EMPTY here
    176193        os << "(";
    177         wkt_sequence<ring>::apply(os, exterior_ring(poly));
     194        wkt_sequence<ring>::apply(os, exterior_ring(poly), force_closed);
    178195
    179196        typename interior_return_type<Polygon const>::type rings
    180197                    = interior_rings(poly);
     
    181198        for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
    182199        {
    183200            os << ",";
    184             wkt_sequence<ring>::apply(os, *it);
     201            wkt_sequence<ring>::apply(os, *it, force_closed);
    185202        }
    186203        os << ")";
    187204    }