Ticket #9066: complete-extensions-gis-io-wkb-with-multi.patch

File complete-extensions-gis-io-wkb-with-multi.patch, 79.5 KB (added by Mateusz Loskot, 9 years ago)

Updated last patch from Mats with WKB support for simple and multi-geometries. Added Jamfile.v2 files, fixed compiler warnings and added TODO comment.

  • boost/geometry/algorithms/equals.hpp

     
    3333// For trivial checks
    3434#include <boost/geometry/algorithms/area.hpp>
    3535#include <boost/geometry/algorithms/length.hpp>
     36#include <boost/geometry/algorithms/num_points.hpp>
    3637#include <boost/geometry/util/math.hpp>
    3738#include <boost/geometry/util/select_coordinate_type.hpp>
    3839#include <boost/geometry/util/select_most_precise.hpp>
     
    5051namespace detail { namespace equals
    5152{
    5253
     54struct num_points_check
     55{
     56    template <typename Geometry1, typename Geometry2>
     57    static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
     58    {
     59        return geometry::math::equals(
     60                geometry::num_points(geometry1),
     61                geometry::num_points(geometry2));
     62    }
     63};
    5364
    5465template
    5566<
  • boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp

     
    6868    {
    6969        point      = 1,
    7070        linestring = 2,
    71         polygon    = 3
    72 
    73         // TODO: Not implemented
    74         //multipoint = 4,
    75         //multilinestring = 5,
    76         //multipolygon = 6,
     71        polygon    = 3,
     72        multipoint = 4,
     73        multilinestring = 5,
     74        multipolygon = 6,
    7775        //collection = 7
    7876    };
    7977};
  • boost/geometry/extensions/gis/io/wkb/detail/parser.hpp

     
    107107        byte_order_type::enum_t order)
    108108    {
    109109        boost::uint32_t value;
    110         if (value_parser<boost::uint32_t>::parse(it, end, value, order))
     110        if (!value_parser<boost::uint32_t>::parse(it, end, value, order))
    111111        {
    112             // TODO: Refine the test when multi* geometries are supported
    113 
    114             boost::uint32_t id = value & 0xff;
    115             if (geometry_type::polygon >= id)
    116             {
    117                 type = geometry_type::enum_t(id);
    118                 return true;
    119             }
     112            return false;
    120113        }
    121         return false;
     114       
     115        // TODO: The 0xff mask is to filter out PostGIS EWKB bits from OGC 2D types,
     116        // but this won't work with OGC WKB codes for Z, M, ZM.
     117        boost::uint32_t id = value & 0xff;
     118        type = geometry_type::enum_t(id);
     119       
     120        return true;
    122121    }
    123122};
    124123
     
    163162    }
    164163};
    165164
    166 template <typename P>
     165template <typename Point>
    167166struct point_parser
    168167{
    169168    template <typename Iterator>
    170     static bool parse(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order)
     169    static bool parse(Iterator& it, Iterator end, Point& point, byte_order_type::enum_t order)
    171170    {
    172         // TODO: mloskot - Add assert on point dimension, 2d only
    173 
    174171        geometry_type::enum_t type;
    175         if (geometry_type_parser::parse(it, end, type, order))
     172       
     173        if (!geometry_type_parser::parse(it, end, type, order))
    176174        {
    177             if (geometry_type::point == type && it != end)
    178             {
    179                 parsing_assigner<P, 0, dimension<P>::value>::run(it, end, point, order);
    180             }
    181             return true;
     175            return false;
    182176        }
    183         return false;
     177       
     178        if (geometry_type::point != type)
     179        {
     180            return false;
     181        }
     182       
     183        // Check that the number of double values in the stream is equal
     184        // or greater than the number of expected values in the point
     185       
     186        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     187       
     188        size_type const container_byte_size = dimension<Point>::value * sizeof(double);
     189        size_type const stream_byte_size = std::distance(it,end);
     190       
     191        assert(stream_byte_size >= container_byte_size);
     192       
     193        parsing_assigner<Point, 0, dimension<Point>::value>::run(it, end, point, order);
     194       
     195        return true;
    184196    }
    185197};
    186198
     
    188200struct point_container_parser
    189201{
    190202    template <typename Iterator>
    191     static bool parse(Iterator& it, Iterator end, C& container, byte_order_type::enum_t order)
     203    static bool parse(Iterator& it, Iterator end, C& container, byte_order_type::enum_t order, boost::uint32_t num_points)
    192204    {
    193205        typedef typename point_type<C>::type point_type;
    194206
    195         boost::uint32_t num_points(0);
    196         if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
    197         {
    198             return false;
    199         }
    200 
    201207        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
    202208        assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
    203209
    204210        size_type const container_size = static_cast<size_type>(num_points);
    205         size_type const point_size = dimension<point_type>::value * sizeof(double);
    206211
    207         if (std::distance(it, end) >= (container_size * point_size))
     212        point_type point_buffer;
     213        std::back_insert_iterator<C> output(std::back_inserter(container));
     214
     215        // Read coordinates into point and append point to container
     216        size_type points_parsed = 0;
     217        while (points_parsed < container_size && it != end)
    208218        {
    209             point_type point_buffer;
    210             std::back_insert_iterator<C> output(std::back_inserter(container));
    211 
    212             // Read coordinates into point and append point to line (ring)
    213             size_type points_parsed = 0;
    214             while (points_parsed < container_size && it != end)
    215             {
    216                 parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, order);
    217                 output = point_buffer;
    218                 ++output;
    219                 ++points_parsed;
    220             }
    221 
    222             if (container_size != points_parsed)
    223             {
    224                 return false;
    225             }
     219            parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, order);
     220            output = point_buffer;
     221            ++output;
     222            ++points_parsed;
    226223        }
    227224
    228225        return true;
     
    248245            return false;
    249246        }
    250247
    251         assert(it != end);
    252         return point_container_parser<L>::parse(it, end, linestring, order);
     248        boost::uint32_t num_points(0);
     249        if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
     250        {
     251            return false;
     252        }
     253       
     254        // Check that the number of double values in the stream is equal
     255        // or greater than the number of expected values in the linestring
     256       
     257        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     258       
     259        size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double);
     260        size_type const stream_byte_size = std::distance(it,end);
     261       
     262        assert(stream_byte_size >= container_byte_size);
     263       
     264        return point_container_parser<L>::parse(it, end, linestring, order, num_points);
    253265    }
    254266};
    255267
     
    275287        typedef typename ring_type<Polygon>::type ring_type;
    276288
    277289        std::size_t rings_parsed = 0;
    278         while (rings_parsed < num_rings && it != end) //while (rings_parsed < num_rings && it != end)
     290       
     291        while (rings_parsed < num_rings && it != end)
    279292        {
     293           
     294            boost::uint32_t num_points(0);
     295            if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
     296            {
     297                return false;
     298            }
     299           
    280300            if (0 == rings_parsed)
    281301            {
    282302                ring_type& ring0 = exterior_ring(polygon);
    283                 if (!point_container_parser<ring_type>::parse(it, end, ring0, order))
     303               
     304                if (!point_container_parser<ring_type>::parse(it, end, ring0, order, num_points))
    284305                {
    285306                    return false;
    286307                }
     
    289310            {
    290311                interior_rings(polygon).resize(rings_parsed);
    291312                ring_type& ringN = interior_rings(polygon).back();
    292                 if (!point_container_parser<ring_type>::parse(it, end, ringN, order))
     313               
     314                if (!point_container_parser<ring_type>::parse(it, end, ringN, order, num_points))
    293315                {
    294316                    return false;
    295317                }
    296318            }
     319
    297320            ++rings_parsed;
    298321        }
    299322
    300         if (num_rings != rings_parsed)
    301         {
    302             return false;
    303         }
    304 
    305323        return true;
    306324    }
    307325};
  • boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     11
     12#include <cassert>
     13#include <cstddef>
     14#include <iterator>
     15#include <limits>
     16
     17#include <boost/geometry/extensions/gis/io/wkb/detail/endian.hpp>
     18#include <boost/geometry/extensions/gis/io/wkb/detail/parser.hpp>
     19#include <boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp>
     20
     21#include <boost/geometry/multi/core/point_type.hpp>
     22#include <boost/geometry/multi/core/ring_type.hpp>
     23
     24#include <boost/geometry/multi/core/interior_rings.hpp>
     25
     26namespace boost { namespace geometry
     27{
     28
     29#ifndef DOXYGEN_NO_DETAIL
     30namespace detail { namespace wkb
     31{
     32
     33template <typename MultiPoint>
     34struct multipoint_parser
     35{
     36    template <typename Iterator>
     37    static bool parse(Iterator& it, Iterator end, MultiPoint& multipoint, byte_order_type::enum_t order)
     38    {
     39        typedef typename point_type<MultiPoint>::type point_type;
     40       
     41        geometry_type::enum_t type;
     42        if (!geometry_type_parser::parse(it, end, type, order))
     43        {
     44            return false;
     45        }
     46       
     47        if (geometry_type::multipoint != type)
     48        {
     49            return false;
     50        }
     51       
     52        boost::uint32_t num_points(0);
     53        if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
     54        {
     55            return false;
     56        }
     57       
     58        // Check that the number of double values in the stream is equal
     59        // or greater than the number of expected values in the multipoint
     60       
     61        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     62       
     63        size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double)
     64                                            + num_points * sizeof(boost::uint8_t)
     65                                            + num_points * sizeof(boost::uint32_t);
     66       
     67        size_type const stream_byte_size = std::distance(it,end);
     68       
     69        assert(stream_byte_size >= container_byte_size);
     70       
     71        point_type point_buffer;
     72        std::back_insert_iterator<MultiPoint> output(std::back_inserter(multipoint));
     73       
     74        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     75        assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     76       
     77        boost::uint32_t points_parsed = 0;
     78        while (points_parsed < num_points && it != end)
     79        {
     80            detail::wkb::byte_order_type::enum_t point_byte_order;
     81            if (!detail::wkb::byte_order_parser::parse(it, end, point_byte_order))
     82            {
     83                return false;
     84            }
     85           
     86            geometry_type::enum_t point_type_type;
     87            if (!geometry_type_parser::parse(it, end, point_type_type, point_byte_order))
     88            {
     89                return false;
     90            }
     91           
     92            parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, point_byte_order);
     93           
     94            output = point_buffer;
     95           
     96            ++output;
     97            ++points_parsed;
     98        }
     99        return true;
     100    }
     101};
     102
     103template <typename MultiLinestring>
     104struct multilinestring_parser
     105{
     106    template <typename Iterator>
     107    static bool parse(Iterator& it, Iterator end, MultiLinestring& multilinestring, byte_order_type::enum_t order)
     108    {
     109        typedef typename MultiLinestring::value_type linestring_type;
     110        typedef typename point_type<MultiLinestring>::type point_type;
     111       
     112        geometry_type::enum_t type;
     113        if (!geometry_type_parser::parse(it, end, type, order))
     114        {
     115            return false;
     116        }
     117       
     118        if (geometry_type::multilinestring != type)
     119        {
     120            return false;
     121        }
     122       
     123        boost::uint32_t num_linestrings(0);
     124        if (!value_parser<boost::uint32_t>::parse(it, end, num_linestrings, order))
     125        {
     126            return false;
     127        }
     128       
     129        linestring_type linestring_buffer;
     130        std::back_insert_iterator<MultiLinestring> output(std::back_inserter(multilinestring));
     131       
     132        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     133        assert(num_linestrings <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     134       
     135        boost::uint32_t linestrings_parsed = 0;
     136        while (linestrings_parsed < num_linestrings && it != end)
     137        {
     138            detail::wkb::byte_order_type::enum_t linestring_byte_order;
     139            if (!detail::wkb::byte_order_parser::parse(it, end, linestring_byte_order))
     140            {
     141                return false;
     142            }
     143           
     144            geometry_type::enum_t type;
     145            if (!geometry_type_parser::parse(it, end, type, linestring_byte_order))
     146            {
     147                return false;
     148            }
     149           
     150            if (geometry_type::linestring != type)
     151            {
     152                return false;
     153            }
     154           
     155            boost::uint32_t num_points(0);
     156            if (!value_parser<boost::uint32_t>::parse(it, end, num_points, linestring_byte_order))
     157            {
     158                return false;
     159            }
     160           
     161            // Check that the number of double values in the stream is equal
     162            // or greater than the number of expected values in the linestring
     163           
     164            typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     165           
     166            size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double);
     167            size_type const stream_byte_size = std::distance(it,end);
     168           
     169            assert(stream_byte_size >= container_byte_size);
     170           
     171            return point_container_parser<linestring_type>::parse(it, end, linestring_buffer, linestring_byte_order, num_points);
     172           
     173            output = linestring_buffer;
     174           
     175            ++output;
     176            ++linestrings_parsed;
     177        }
     178        return true;
     179    }
     180};
     181
     182template <typename MultiPolygon>
     183struct multipolygon_parser
     184{
     185    template <typename Iterator>
     186    static bool parse(Iterator& it, Iterator end, MultiPolygon& multipolygon, byte_order_type::enum_t order)
     187    {
     188        typedef typename MultiPolygon::value_type polygon_type;
     189        typedef typename ring_type<MultiPolygon>::type ring_type;
     190       
     191        geometry_type::enum_t multipolygontype;
     192        if (!geometry_type_parser::parse(it, end, multipolygontype, order))
     193        {
     194            return false;
     195        }
     196       
     197        if (geometry_type::multipolygon != multipolygontype)
     198        {
     199            return false;
     200        }
     201       
     202        boost::uint32_t num_polygons(0);
     203        if (!value_parser<boost::uint32_t>::parse(it, end, num_polygons, order))
     204        {
     205            return false;
     206        }
     207       
     208        polygon_type polygon_buffer;
     209        std::back_insert_iterator<MultiPolygon> output(std::back_inserter(multipolygon));
     210       
     211        std::size_t polygons_parsed = 0;
     212        while(polygons_parsed < num_polygons && it != end)
     213        {
     214            detail::wkb::byte_order_type::enum_t polygon_byte_order;
     215            if (!detail::wkb::byte_order_parser::parse(it, end, polygon_byte_order))
     216            {
     217                return false;
     218            }
     219           
     220            geometry_type::enum_t type;
     221            if (!geometry_type_parser::parse(it, end, type, polygon_byte_order))
     222            {
     223                return false;
     224            }
     225           
     226            if (geometry_type::polygon != type)
     227            {
     228                return false;
     229            }
     230
     231            boost::uint32_t num_rings(0);
     232            if (geometry_type::polygon != type ||
     233                !value_parser<boost::uint32_t>::parse(it, end, num_rings, polygon_byte_order))
     234            {
     235                return false;
     236            }
     237           
     238            std::size_t rings_parsed = 0;
     239           
     240            while (rings_parsed < num_rings && it != end)
     241            {
     242                boost::uint32_t num_points(0);
     243                if (!value_parser<boost::uint32_t>::parse(it, end, num_points, polygon_byte_order))
     244                {
     245                    return false;
     246                }
     247               
     248                if (0 == rings_parsed)
     249                {
     250                    ring_type& ring0 = exterior_ring(polygon_buffer);
     251                   
     252                    if (!point_container_parser<ring_type>::parse(it, end, ring0, polygon_byte_order, num_points))
     253                    {
     254                        return false;
     255                    }
     256                }
     257                else
     258                {
     259                    interior_rings(polygon_buffer).resize(rings_parsed);
     260                    ring_type& ringN = interior_rings(polygon_buffer).back();
     261                   
     262                    if (!point_container_parser<ring_type>::parse(it, end, ringN, polygon_byte_order, num_points))
     263                    {
     264                        return false;
     265                    }
     266                }
     267                ++rings_parsed;
     268            }
     269            output = polygon_buffer;
     270            ++output;
     271        }
     272       
     273        return true;
     274    }
     275};
     276
     277}} // namespace detail::wkb
     278#endif // DOXYGEN_NO_IMPL
     279
     280}} // namespace boost::geometry
     281
     282
     283#endif // BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/read_wkb.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     11
     12#include <iterator>
     13
     14#include <boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp>
     15#include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
     16
     17namespace boost { namespace geometry
     18{
     19
     20#ifndef DOXYGEN_NO_DISPATCH
     21namespace dispatch
     22{
     23
     24template <typename Geometry>
     25struct read_wkb<multi_point_tag, Geometry>
     26{
     27    template <typename Iterator>
     28    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     29        detail::wkb::byte_order_type::enum_t order)
     30    {
     31        return detail::wkb::multipoint_parser<Geometry>::parse(it, end, geometry, order);
     32    }
     33};
     34
     35template <typename Geometry>
     36struct read_wkb<multi_linestring_tag, Geometry>
     37{
     38    template <typename Iterator>
     39    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     40        detail::wkb::byte_order_type::enum_t order)
     41    {
     42        return detail::wkb::multilinestring_parser<Geometry>::parse(it, end, geometry, order);
     43    }
     44};
     45
     46template <typename Geometry>
     47struct read_wkb<multi_polygon_tag, Geometry>
     48{
     49    template <typename Iterator>
     50    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     51        detail::wkb::byte_order_type::enum_t order)
     52    {
     53        return detail::wkb::multipolygon_parser<Geometry>::parse(it, end, geometry, order);
     54    }
     55};
     56
     57} // namespace dispatch
     58#endif // DOXYGEN_NO_DISPATCH
     59
     60}} // namespace boost::geometry
     61
     62#endif // BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     11
     12#include <cassert>
     13#include <cstddef>
     14#include <iterator>
     15#include <limits>
     16
     17#include <boost/geometry/extensions/gis/io/wkb/detail/endian.hpp>
     18#include <boost/geometry/extensions/gis/io/wkb/detail/parser.hpp>
     19#include <boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp>
     20
     21#include <boost/geometry/multi/core/point_type.hpp>
     22#include <boost/geometry/multi/core/ring_type.hpp>
     23
     24#include <boost/geometry/multi/core/interior_rings.hpp>
     25
     26namespace boost { namespace geometry
     27{
     28
     29#ifndef DOXYGEN_NO_DETAIL
     30namespace detail { namespace wkb
     31{
     32
     33template <typename MultiPoint>
     34struct multipoint_parser
     35{
     36    template <typename Iterator>
     37    static bool parse(Iterator& it, Iterator end, MultiPoint& multipoint, byte_order_type::enum_t order)
     38    {
     39        typedef typename point_type<MultiPoint>::type point_type;
     40       
     41        geometry_type::enum_t type;
     42        if (!geometry_type_parser::parse(it, end, type, order))
     43        {
     44            return false;
     45        }
     46       
     47        if (geometry_type::multipoint != type)
     48        {
     49            return false;
     50        }
     51       
     52        boost::uint32_t num_points(0);
     53        if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
     54        {
     55            return false;
     56        }
     57       
     58        // Check that the number of double values in the stream is equal
     59        // or greater than the number of expected values in the multipoint
     60       
     61        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     62       
     63        size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double)
     64                                            + num_points * sizeof(boost::uint8_t)
     65                                            + num_points * sizeof(boost::uint32_t);
     66       
     67        size_type const stream_byte_size = std::distance(it,end);
     68       
     69        assert(stream_byte_size >= container_byte_size);
     70       
     71        point_type point_buffer;
     72        std::back_insert_iterator<MultiPoint> output(std::back_inserter(multipoint));
     73       
     74        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     75        assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     76       
     77        boost::uint32_t points_parsed = 0;
     78        while (points_parsed < num_points && it != end)
     79        {
     80            detail::wkb::byte_order_type::enum_t point_byte_order;
     81            if (!detail::wkb::byte_order_parser::parse(it, end, point_byte_order))
     82            {
     83                return false;
     84            }
     85           
     86            geometry_type::enum_t point_type_type;
     87            if (!geometry_type_parser::parse(it, end, point_type_type, point_byte_order))
     88            {
     89                return false;
     90            }
     91           
     92            parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, point_byte_order);
     93           
     94            output = point_buffer;
     95           
     96            ++output;
     97            ++points_parsed;
     98        }
     99        return true;
     100    }
     101};
     102
     103template <typename MultiLinestring>
     104struct multilinestring_parser
     105{
     106    template <typename Iterator>
     107    static bool parse(Iterator& it, Iterator end, MultiLinestring& multilinestring, byte_order_type::enum_t order)
     108    {
     109        typedef typename MultiLinestring::value_type linestring_type;
     110        typedef typename point_type<MultiLinestring>::type point_type;
     111       
     112        geometry_type::enum_t type;
     113        if (!geometry_type_parser::parse(it, end, type, order))
     114        {
     115            return false;
     116        }
     117       
     118        if (geometry_type::multilinestring != type)
     119        {
     120            return false;
     121        }
     122       
     123        boost::uint32_t num_linestrings(0);
     124        if (!value_parser<boost::uint32_t>::parse(it, end, num_linestrings, order))
     125        {
     126            return false;
     127        }
     128       
     129        linestring_type linestring_buffer;
     130        std::back_insert_iterator<MultiLinestring> output(std::back_inserter(multilinestring));
     131       
     132        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     133        assert(num_linestrings <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     134       
     135        boost::uint32_t linestrings_parsed = 0;
     136        while (linestrings_parsed < num_linestrings && it != end)
     137        {
     138            detail::wkb::byte_order_type::enum_t linestring_byte_order;
     139            if (!detail::wkb::byte_order_parser::parse(it, end, linestring_byte_order))
     140            {
     141                return false;
     142            }
     143           
     144            geometry_type::enum_t type;
     145            if (!geometry_type_parser::parse(it, end, type, linestring_byte_order))
     146            {
     147                return false;
     148            }
     149           
     150            if (geometry_type::linestring != type)
     151            {
     152                return false;
     153            }
     154           
     155            boost::uint32_t num_points(0);
     156            if (!value_parser<boost::uint32_t>::parse(it, end, num_points, linestring_byte_order))
     157            {
     158                return false;
     159            }
     160           
     161            // Check that the number of double values in the stream is equal
     162            // or greater than the number of expected values in the linestring
     163           
     164            typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     165           
     166            size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double);
     167            size_type const stream_byte_size = std::distance(it,end);
     168           
     169            assert(stream_byte_size >= container_byte_size);
     170           
     171            return point_container_parser<linestring_type>::parse(it, end, linestring_buffer, linestring_byte_order, num_points);
     172           
     173            output = linestring_buffer;
     174           
     175            ++output;
     176            ++linestrings_parsed;
     177        }
     178        return true;
     179    }
     180};
     181
     182template <typename MultiPolygon>
     183struct multipolygon_parser
     184{
     185    template <typename Iterator>
     186    static bool parse(Iterator& it, Iterator end, MultiPolygon& multipolygon, byte_order_type::enum_t order)
     187    {
     188        typedef typename MultiPolygon::value_type polygon_type;
     189        typedef typename ring_type<MultiPolygon>::type ring_type;
     190       
     191        geometry_type::enum_t multipolygontype;
     192        if (!geometry_type_parser::parse(it, end, multipolygontype, order))
     193        {
     194            return false;
     195        }
     196       
     197        if (geometry_type::multipolygon != multipolygontype)
     198        {
     199            return false;
     200        }
     201       
     202        boost::uint32_t num_polygons(0);
     203        if (!value_parser<boost::uint32_t>::parse(it, end, num_polygons, order))
     204        {
     205            return false;
     206        }
     207       
     208        polygon_type polygon_buffer;
     209        std::back_insert_iterator<MultiPolygon> output(std::back_inserter(multipolygon));
     210       
     211        std::size_t polygons_parsed = 0;
     212        while(polygons_parsed < num_polygons && it != end)
     213        {
     214            detail::wkb::byte_order_type::enum_t polygon_byte_order;
     215            if (!detail::wkb::byte_order_parser::parse(it, end, polygon_byte_order))
     216            {
     217                return false;
     218            }
     219           
     220            geometry_type::enum_t type;
     221            if (!geometry_type_parser::parse(it, end, type, polygon_byte_order))
     222            {
     223                return false;
     224            }
     225           
     226            if (geometry_type::polygon != type)
     227            {
     228                return false;
     229            }
     230
     231            boost::uint32_t num_rings(0);
     232            if (geometry_type::polygon != type ||
     233                !value_parser<boost::uint32_t>::parse(it, end, num_rings, polygon_byte_order))
     234            {
     235                return false;
     236            }
     237           
     238            std::size_t rings_parsed = 0;
     239           
     240            while (rings_parsed < num_rings && it != end)
     241            {
     242                boost::uint32_t num_points(0);
     243                if (!value_parser<boost::uint32_t>::parse(it, end, num_points, polygon_byte_order))
     244                {
     245                    return false;
     246                }
     247               
     248                if (0 == rings_parsed)
     249                {
     250                    ring_type& ring0 = exterior_ring(polygon_buffer);
     251                   
     252                    if (!point_container_parser<ring_type>::parse(it, end, ring0, polygon_byte_order, num_points))
     253                    {
     254                        return false;
     255                    }
     256                }
     257                else
     258                {
     259                    interior_rings(polygon_buffer).resize(rings_parsed);
     260                    ring_type& ringN = interior_rings(polygon_buffer).back();
     261                   
     262                    if (!point_container_parser<ring_type>::parse(it, end, ringN, polygon_byte_order, num_points))
     263                    {
     264                        return false;
     265                    }
     266                }
     267                ++rings_parsed;
     268            }
     269            output = polygon_buffer;
     270            ++output;
     271        }
     272       
     273        return true;
     274    }
     275};
     276
     277}} // namespace detail::wkb
     278#endif // DOXYGEN_NO_IMPL
     279
     280}} // namespace boost::geometry
     281
     282
     283#endif // BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/read_wkb.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     11
     12#include <iterator>
     13
     14#include <boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp>
     15#include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
     16
     17namespace boost { namespace geometry
     18{
     19
     20#ifndef DOXYGEN_NO_DISPATCH
     21namespace dispatch
     22{
     23
     24template <typename Geometry>
     25struct read_wkb<multi_point_tag, Geometry>
     26{
     27    template <typename Iterator>
     28    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     29        detail::wkb::byte_order_type::enum_t order)
     30    {
     31        return detail::wkb::multipoint_parser<Geometry>::parse(it, end, geometry, order);
     32    }
     33};
     34
     35template <typename Geometry>
     36struct read_wkb<multi_linestring_tag, Geometry>
     37{
     38    template <typename Iterator>
     39    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     40        detail::wkb::byte_order_type::enum_t order)
     41    {
     42        return detail::wkb::multilinestring_parser<Geometry>::parse(it, end, geometry, order);
     43    }
     44};
     45
     46template <typename Geometry>
     47struct read_wkb<multi_polygon_tag, Geometry>
     48{
     49    template <typename Iterator>
     50    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     51        detail::wkb::byte_order_type::enum_t order)
     52    {
     53        return detail::wkb::multipolygon_parser<Geometry>::parse(it, end, geometry, order);
     54    }
     55};
     56
     57} // namespace dispatch
     58#endif // DOXYGEN_NO_DISPATCH
     59
     60}} // namespace boost::geometry
     61
     62#endif // BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     11
     12#include <cassert>
     13#include <cstddef>
     14#include <iterator>
     15#include <limits>
     16
     17#include <boost/geometry/extensions/gis/io/wkb/detail/endian.hpp>
     18#include <boost/geometry/extensions/gis/io/wkb/detail/parser.hpp>
     19#include <boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp>
     20
     21#include <boost/geometry/multi/core/point_type.hpp>
     22#include <boost/geometry/multi/core/ring_type.hpp>
     23
     24#include <boost/geometry/multi/core/interior_rings.hpp>
     25
     26namespace boost { namespace geometry
     27{
     28
     29#ifndef DOXYGEN_NO_DETAIL
     30namespace detail { namespace wkb
     31{
     32
     33template <typename MultiPoint>
     34struct multipoint_parser
     35{
     36    template <typename Iterator>
     37    static bool parse(Iterator& it, Iterator end, MultiPoint& multipoint, byte_order_type::enum_t order)
     38    {
     39        typedef typename point_type<MultiPoint>::type point_type;
     40       
     41        geometry_type::enum_t type;
     42        if (!geometry_type_parser::parse(it, end, type, order))
     43        {
     44            return false;
     45        }
     46       
     47        if (geometry_type::multipoint != type)
     48        {
     49            return false;
     50        }
     51       
     52        boost::uint32_t num_points(0);
     53        if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
     54        {
     55            return false;
     56        }
     57       
     58        // Check that the number of double values in the stream is equal
     59        // or greater than the number of expected values in the multipoint
     60       
     61        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     62       
     63        size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double)
     64                                            + num_points * sizeof(boost::uint8_t)
     65                                            + num_points * sizeof(boost::uint32_t);
     66       
     67        size_type const stream_byte_size = std::distance(it,end);
     68       
     69        assert(stream_byte_size >= container_byte_size);
     70       
     71        point_type point_buffer;
     72        std::back_insert_iterator<MultiPoint> output(std::back_inserter(multipoint));
     73       
     74        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     75        assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     76       
     77        boost::uint32_t points_parsed = 0;
     78        while (points_parsed < num_points && it != end)
     79        {
     80            detail::wkb::byte_order_type::enum_t point_byte_order;
     81            if (!detail::wkb::byte_order_parser::parse(it, end, point_byte_order))
     82            {
     83                return false;
     84            }
     85           
     86            geometry_type::enum_t point_type_type;
     87            if (!geometry_type_parser::parse(it, end, point_type_type, point_byte_order))
     88            {
     89                return false;
     90            }
     91           
     92            parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, point_byte_order);
     93           
     94            output = point_buffer;
     95           
     96            ++output;
     97            ++points_parsed;
     98        }
     99        return true;
     100    }
     101};
     102
     103template <typename MultiLinestring>
     104struct multilinestring_parser
     105{
     106    template <typename Iterator>
     107    static bool parse(Iterator& it, Iterator end, MultiLinestring& multilinestring, byte_order_type::enum_t order)
     108    {
     109        typedef typename MultiLinestring::value_type linestring_type;
     110        typedef typename point_type<MultiLinestring>::type point_type;
     111       
     112        geometry_type::enum_t type;
     113        if (!geometry_type_parser::parse(it, end, type, order))
     114        {
     115            return false;
     116        }
     117       
     118        if (geometry_type::multilinestring != type)
     119        {
     120            return false;
     121        }
     122       
     123        boost::uint32_t num_linestrings(0);
     124        if (!value_parser<boost::uint32_t>::parse(it, end, num_linestrings, order))
     125        {
     126            return false;
     127        }
     128       
     129        linestring_type linestring_buffer;
     130        std::back_insert_iterator<MultiLinestring> output(std::back_inserter(multilinestring));
     131       
     132        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     133        assert(num_linestrings <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     134       
     135        boost::uint32_t linestrings_parsed = 0;
     136        while (linestrings_parsed < num_linestrings && it != end)
     137        {
     138            detail::wkb::byte_order_type::enum_t linestring_byte_order;
     139            if (!detail::wkb::byte_order_parser::parse(it, end, linestring_byte_order))
     140            {
     141                return false;
     142            }
     143           
     144            geometry_type::enum_t type;
     145            if (!geometry_type_parser::parse(it, end, type, linestring_byte_order))
     146            {
     147                return false;
     148            }
     149           
     150            if (geometry_type::linestring != type)
     151            {
     152                return false;
     153            }
     154           
     155            boost::uint32_t num_points(0);
     156            if (!value_parser<boost::uint32_t>::parse(it, end, num_points, linestring_byte_order))
     157            {
     158                return false;
     159            }
     160           
     161            // Check that the number of double values in the stream is equal
     162            // or greater than the number of expected values in the linestring
     163           
     164            typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     165           
     166            size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double);
     167            size_type const stream_byte_size = std::distance(it,end);
     168           
     169            assert(stream_byte_size >= container_byte_size);
     170           
     171            return point_container_parser<linestring_type>::parse(it, end, linestring_buffer, linestring_byte_order, num_points);
     172           
     173            output = linestring_buffer;
     174           
     175            ++output;
     176            ++linestrings_parsed;
     177        }
     178        return true;
     179    }
     180};
     181
     182template <typename MultiPolygon>
     183struct multipolygon_parser
     184{
     185    template <typename Iterator>
     186    static bool parse(Iterator& it, Iterator end, MultiPolygon& multipolygon, byte_order_type::enum_t order)
     187    {
     188        typedef typename MultiPolygon::value_type polygon_type;
     189        typedef typename ring_type<MultiPolygon>::type ring_type;
     190       
     191        geometry_type::enum_t multipolygontype;
     192        if (!geometry_type_parser::parse(it, end, multipolygontype, order))
     193        {
     194            return false;
     195        }
     196       
     197        if (geometry_type::multipolygon != multipolygontype)
     198        {
     199            return false;
     200        }
     201       
     202        boost::uint32_t num_polygons(0);
     203        if (!value_parser<boost::uint32_t>::parse(it, end, num_polygons, order))
     204        {
     205            return false;
     206        }
     207       
     208        polygon_type polygon_buffer;
     209        std::back_insert_iterator<MultiPolygon> output(std::back_inserter(multipolygon));
     210       
     211        std::size_t polygons_parsed = 0;
     212        while(polygons_parsed < num_polygons && it != end)
     213        {
     214            detail::wkb::byte_order_type::enum_t polygon_byte_order;
     215            if (!detail::wkb::byte_order_parser::parse(it, end, polygon_byte_order))
     216            {
     217                return false;
     218            }
     219           
     220            geometry_type::enum_t type;
     221            if (!geometry_type_parser::parse(it, end, type, polygon_byte_order))
     222            {
     223                return false;
     224            }
     225           
     226            if (geometry_type::polygon != type)
     227            {
     228                return false;
     229            }
     230
     231            boost::uint32_t num_rings(0);
     232            if (geometry_type::polygon != type ||
     233                !value_parser<boost::uint32_t>::parse(it, end, num_rings, polygon_byte_order))
     234            {
     235                return false;
     236            }
     237           
     238            std::size_t rings_parsed = 0;
     239           
     240            while (rings_parsed < num_rings && it != end)
     241            {
     242                boost::uint32_t num_points(0);
     243                if (!value_parser<boost::uint32_t>::parse(it, end, num_points, polygon_byte_order))
     244                {
     245                    return false;
     246                }
     247               
     248                if (0 == rings_parsed)
     249                {
     250                    ring_type& ring0 = exterior_ring(polygon_buffer);
     251                   
     252                    if (!point_container_parser<ring_type>::parse(it, end, ring0, polygon_byte_order, num_points))
     253                    {
     254                        return false;
     255                    }
     256                }
     257                else
     258                {
     259                    interior_rings(polygon_buffer).resize(rings_parsed);
     260                    ring_type& ringN = interior_rings(polygon_buffer).back();
     261                   
     262                    if (!point_container_parser<ring_type>::parse(it, end, ringN, polygon_byte_order, num_points))
     263                    {
     264                        return false;
     265                    }
     266                }
     267                ++rings_parsed;
     268            }
     269            output = polygon_buffer;
     270            ++output;
     271        }
     272       
     273        return true;
     274    }
     275};
     276
     277}} // namespace detail::wkb
     278#endif // DOXYGEN_NO_IMPL
     279
     280}} // namespace boost::geometry
     281
     282
     283#endif // BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/read_wkb.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     11
     12#include <iterator>
     13
     14#include <boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp>
     15#include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
     16
     17namespace boost { namespace geometry
     18{
     19
     20#ifndef DOXYGEN_NO_DISPATCH
     21namespace dispatch
     22{
     23
     24template <typename Geometry>
     25struct read_wkb<multi_point_tag, Geometry>
     26{
     27    template <typename Iterator>
     28    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     29        detail::wkb::byte_order_type::enum_t order)
     30    {
     31        return detail::wkb::multipoint_parser<Geometry>::parse(it, end, geometry, order);
     32    }
     33};
     34
     35template <typename Geometry>
     36struct read_wkb<multi_linestring_tag, Geometry>
     37{
     38    template <typename Iterator>
     39    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     40        detail::wkb::byte_order_type::enum_t order)
     41    {
     42        return detail::wkb::multilinestring_parser<Geometry>::parse(it, end, geometry, order);
     43    }
     44};
     45
     46template <typename Geometry>
     47struct read_wkb<multi_polygon_tag, Geometry>
     48{
     49    template <typename Iterator>
     50    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     51        detail::wkb::byte_order_type::enum_t order)
     52    {
     53        return detail::wkb::multipolygon_parser<Geometry>::parse(it, end, geometry, order);
     54    }
     55};
     56
     57} // namespace dispatch
     58#endif // DOXYGEN_NO_DISPATCH
     59
     60}} // namespace boost::geometry
     61
     62#endif // BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     11
     12#include <cassert>
     13#include <cstddef>
     14#include <iterator>
     15#include <limits>
     16
     17#include <boost/geometry/extensions/gis/io/wkb/detail/endian.hpp>
     18#include <boost/geometry/extensions/gis/io/wkb/detail/parser.hpp>
     19#include <boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp>
     20
     21#include <boost/geometry/multi/core/point_type.hpp>
     22#include <boost/geometry/multi/core/ring_type.hpp>
     23
     24#include <boost/geometry/multi/core/interior_rings.hpp>
     25
     26namespace boost { namespace geometry
     27{
     28
     29#ifndef DOXYGEN_NO_DETAIL
     30namespace detail { namespace wkb
     31{
     32
     33template <typename MultiPoint>
     34struct multipoint_parser
     35{
     36    template <typename Iterator>
     37    static bool parse(Iterator& it, Iterator end, MultiPoint& multipoint, byte_order_type::enum_t order)
     38    {
     39        typedef typename point_type<MultiPoint>::type point_type;
     40       
     41        geometry_type::enum_t type;
     42        if (!geometry_type_parser::parse(it, end, type, order))
     43        {
     44            return false;
     45        }
     46       
     47        if (geometry_type::multipoint != type)
     48        {
     49            return false;
     50        }
     51       
     52        boost::uint32_t num_points(0);
     53        if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
     54        {
     55            return false;
     56        }
     57       
     58        // Check that the number of double values in the stream is equal
     59        // or greater than the number of expected values in the multipoint
     60       
     61        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     62       
     63        size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double)
     64                                            + num_points * sizeof(boost::uint8_t)
     65                                            + num_points * sizeof(boost::uint32_t);
     66       
     67        size_type const stream_byte_size = std::distance(it,end);
     68       
     69        assert(stream_byte_size >= container_byte_size);
     70       
     71        point_type point_buffer;
     72        std::back_insert_iterator<MultiPoint> output(std::back_inserter(multipoint));
     73       
     74        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     75        assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     76       
     77        boost::uint32_t points_parsed = 0;
     78        while (points_parsed < num_points && it != end)
     79        {
     80            detail::wkb::byte_order_type::enum_t point_byte_order;
     81            if (!detail::wkb::byte_order_parser::parse(it, end, point_byte_order))
     82            {
     83                return false;
     84            }
     85           
     86            geometry_type::enum_t point_type_type;
     87            if (!geometry_type_parser::parse(it, end, point_type_type, point_byte_order))
     88            {
     89                return false;
     90            }
     91           
     92            parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, point_byte_order);
     93           
     94            output = point_buffer;
     95           
     96            ++output;
     97            ++points_parsed;
     98        }
     99        return true;
     100    }
     101};
     102
     103template <typename MultiLinestring>
     104struct multilinestring_parser
     105{
     106    template <typename Iterator>
     107    static bool parse(Iterator& it, Iterator end, MultiLinestring& multilinestring, byte_order_type::enum_t order)
     108    {
     109        typedef typename MultiLinestring::value_type linestring_type;
     110        typedef typename point_type<MultiLinestring>::type point_type;
     111       
     112        geometry_type::enum_t type;
     113        if (!geometry_type_parser::parse(it, end, type, order))
     114        {
     115            return false;
     116        }
     117       
     118        if (geometry_type::multilinestring != type)
     119        {
     120            return false;
     121        }
     122       
     123        boost::uint32_t num_linestrings(0);
     124        if (!value_parser<boost::uint32_t>::parse(it, end, num_linestrings, order))
     125        {
     126            return false;
     127        }
     128       
     129        linestring_type linestring_buffer;
     130        std::back_insert_iterator<MultiLinestring> output(std::back_inserter(multilinestring));
     131       
     132        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     133        assert(num_linestrings <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     134       
     135        boost::uint32_t linestrings_parsed = 0;
     136        while (linestrings_parsed < num_linestrings && it != end)
     137        {
     138            detail::wkb::byte_order_type::enum_t linestring_byte_order;
     139            if (!detail::wkb::byte_order_parser::parse(it, end, linestring_byte_order))
     140            {
     141                return false;
     142            }
     143           
     144            geometry_type::enum_t type;
     145            if (!geometry_type_parser::parse(it, end, type, linestring_byte_order))
     146            {
     147                return false;
     148            }
     149           
     150            if (geometry_type::linestring != type)
     151            {
     152                return false;
     153            }
     154           
     155            boost::uint32_t num_points(0);
     156            if (!value_parser<boost::uint32_t>::parse(it, end, num_points, linestring_byte_order))
     157            {
     158                return false;
     159            }
     160           
     161            // Check that the number of double values in the stream is equal
     162            // or greater than the number of expected values in the linestring
     163           
     164            typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     165           
     166            size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double);
     167            size_type const stream_byte_size = std::distance(it,end);
     168           
     169            assert(stream_byte_size >= container_byte_size);
     170           
     171            return point_container_parser<linestring_type>::parse(it, end, linestring_buffer, linestring_byte_order, num_points);
     172           
     173            output = linestring_buffer;
     174           
     175            ++output;
     176            ++linestrings_parsed;
     177        }
     178        return true;
     179    }
     180};
     181
     182template <typename MultiPolygon>
     183struct multipolygon_parser
     184{
     185    template <typename Iterator>
     186    static bool parse(Iterator& it, Iterator end, MultiPolygon& multipolygon, byte_order_type::enum_t order)
     187    {
     188        typedef typename MultiPolygon::value_type polygon_type;
     189        typedef typename ring_type<MultiPolygon>::type ring_type;
     190       
     191        geometry_type::enum_t multipolygontype;
     192        if (!geometry_type_parser::parse(it, end, multipolygontype, order))
     193        {
     194            return false;
     195        }
     196       
     197        if (geometry_type::multipolygon != multipolygontype)
     198        {
     199            return false;
     200        }
     201       
     202        boost::uint32_t num_polygons(0);
     203        if (!value_parser<boost::uint32_t>::parse(it, end, num_polygons, order))
     204        {
     205            return false;
     206        }
     207       
     208        polygon_type polygon_buffer;
     209        std::back_insert_iterator<MultiPolygon> output(std::back_inserter(multipolygon));
     210       
     211        std::size_t polygons_parsed = 0;
     212        while(polygons_parsed < num_polygons && it != end)
     213        {
     214            detail::wkb::byte_order_type::enum_t polygon_byte_order;
     215            if (!detail::wkb::byte_order_parser::parse(it, end, polygon_byte_order))
     216            {
     217                return false;
     218            }
     219           
     220            geometry_type::enum_t type;
     221            if (!geometry_type_parser::parse(it, end, type, polygon_byte_order))
     222            {
     223                return false;
     224            }
     225           
     226            if (geometry_type::polygon != type)
     227            {
     228                return false;
     229            }
     230
     231            boost::uint32_t num_rings(0);
     232            if (geometry_type::polygon != type ||
     233                !value_parser<boost::uint32_t>::parse(it, end, num_rings, polygon_byte_order))
     234            {
     235                return false;
     236            }
     237           
     238            std::size_t rings_parsed = 0;
     239           
     240            while (rings_parsed < num_rings && it != end)
     241            {
     242                boost::uint32_t num_points(0);
     243                if (!value_parser<boost::uint32_t>::parse(it, end, num_points, polygon_byte_order))
     244                {
     245                    return false;
     246                }
     247               
     248                if (0 == rings_parsed)
     249                {
     250                    ring_type& ring0 = exterior_ring(polygon_buffer);
     251                   
     252                    if (!point_container_parser<ring_type>::parse(it, end, ring0, polygon_byte_order, num_points))
     253                    {
     254                        return false;
     255                    }
     256                }
     257                else
     258                {
     259                    interior_rings(polygon_buffer).resize(rings_parsed);
     260                    ring_type& ringN = interior_rings(polygon_buffer).back();
     261                   
     262                    if (!point_container_parser<ring_type>::parse(it, end, ringN, polygon_byte_order, num_points))
     263                    {
     264                        return false;
     265                    }
     266                }
     267                ++rings_parsed;
     268            }
     269            output = polygon_buffer;
     270            ++output;
     271        }
     272       
     273        return true;
     274    }
     275};
     276
     277}} // namespace detail::wkb
     278#endif // DOXYGEN_NO_IMPL
     279
     280}} // namespace boost::geometry
     281
     282
     283#endif // BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
     11
     12#include <cassert>
     13#include <cstddef>
     14#include <iterator>
     15#include <limits>
     16
     17#include <boost/geometry/extensions/gis/io/wkb/detail/endian.hpp>
     18#include <boost/geometry/extensions/gis/io/wkb/detail/parser.hpp>
     19#include <boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp>
     20
     21#include <boost/geometry/multi/core/point_type.hpp>
     22#include <boost/geometry/multi/core/ring_type.hpp>
     23
     24#include <boost/geometry/multi/core/interior_rings.hpp>
     25
     26namespace boost { namespace geometry
     27{
     28
     29#ifndef DOXYGEN_NO_DETAIL
     30namespace detail { namespace wkb
     31{
     32
     33template <typename MultiPoint>
     34struct multipoint_parser
     35{
     36    template <typename Iterator>
     37    static bool parse(Iterator& it, Iterator end, MultiPoint& multipoint, byte_order_type::enum_t order)
     38    {
     39        typedef typename point_type<MultiPoint>::type point_type;
     40       
     41        geometry_type::enum_t type;
     42        if (!geometry_type_parser::parse(it, end, type, order))
     43        {
     44            return false;
     45        }
     46       
     47        if (geometry_type::multipoint != type)
     48        {
     49            return false;
     50        }
     51       
     52        boost::uint32_t num_points(0);
     53        if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
     54        {
     55            return false;
     56        }
     57       
     58        // Check that the number of double values in the stream is equal
     59        // or greater than the number of expected values in the multipoint
     60       
     61        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     62       
     63        size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double)
     64                                            + num_points * sizeof(boost::uint8_t)
     65                                            + num_points * sizeof(boost::uint32_t);
     66       
     67        size_type const stream_byte_size = std::distance(it,end);
     68       
     69        assert(stream_byte_size >= container_byte_size);
     70       
     71        point_type point_buffer;
     72        std::back_insert_iterator<MultiPoint> output(std::back_inserter(multipoint));
     73       
     74        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     75        assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     76       
     77        boost::uint32_t points_parsed = 0;
     78        while (points_parsed < num_points && it != end)
     79        {
     80            detail::wkb::byte_order_type::enum_t point_byte_order;
     81            if (!detail::wkb::byte_order_parser::parse(it, end, point_byte_order))
     82            {
     83                return false;
     84            }
     85           
     86            geometry_type::enum_t point_type_type;
     87            if (!geometry_type_parser::parse(it, end, point_type_type, point_byte_order))
     88            {
     89                return false;
     90            }
     91           
     92            parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, point_byte_order);
     93           
     94            output = point_buffer;
     95           
     96            ++output;
     97            ++points_parsed;
     98        }
     99        return true;
     100    }
     101};
     102
     103template <typename MultiLinestring>
     104struct multilinestring_parser
     105{
     106    template <typename Iterator>
     107    static bool parse(Iterator& it, Iterator end, MultiLinestring& multilinestring, byte_order_type::enum_t order)
     108    {
     109        typedef typename MultiLinestring::value_type linestring_type;
     110        typedef typename point_type<MultiLinestring>::type point_type;
     111       
     112        geometry_type::enum_t type;
     113        if (!geometry_type_parser::parse(it, end, type, order))
     114        {
     115            return false;
     116        }
     117       
     118        if (geometry_type::multilinestring != type)
     119        {
     120            return false;
     121        }
     122       
     123        boost::uint32_t num_linestrings(0);
     124        if (!value_parser<boost::uint32_t>::parse(it, end, num_linestrings, order))
     125        {
     126            return false;
     127        }
     128       
     129        linestring_type linestring_buffer;
     130        std::back_insert_iterator<MultiLinestring> output(std::back_inserter(multilinestring));
     131       
     132        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     133        assert(num_linestrings <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
     134       
     135        boost::uint32_t linestrings_parsed = 0;
     136        while (linestrings_parsed < num_linestrings && it != end)
     137        {
     138            detail::wkb::byte_order_type::enum_t linestring_byte_order;
     139            if (!detail::wkb::byte_order_parser::parse(it, end, linestring_byte_order))
     140            {
     141                return false;
     142            }
     143           
     144            geometry_type::enum_t type;
     145            if (!geometry_type_parser::parse(it, end, type, linestring_byte_order))
     146            {
     147                return false;
     148            }
     149           
     150            if (geometry_type::linestring != type)
     151            {
     152                return false;
     153            }
     154           
     155            boost::uint32_t num_points(0);
     156            if (!value_parser<boost::uint32_t>::parse(it, end, num_points, linestring_byte_order))
     157            {
     158                return false;
     159            }
     160           
     161            // Check that the number of double values in the stream is equal
     162            // or greater than the number of expected values in the linestring
     163           
     164            typedef typename std::iterator_traits<Iterator>::difference_type size_type;
     165           
     166            size_type const container_byte_size = dimension<point_type>::value * num_points * sizeof(double);
     167            size_type const stream_byte_size = std::distance(it,end);
     168           
     169            assert(stream_byte_size >= container_byte_size);
     170           
     171            return point_container_parser<linestring_type>::parse(it, end, linestring_buffer, linestring_byte_order, num_points);
     172           
     173            output = linestring_buffer;
     174           
     175            ++output;
     176            ++linestrings_parsed;
     177        }
     178        return true;
     179    }
     180};
     181
     182template <typename MultiPolygon>
     183struct multipolygon_parser
     184{
     185    template <typename Iterator>
     186    static bool parse(Iterator& it, Iterator end, MultiPolygon& multipolygon, byte_order_type::enum_t order)
     187    {
     188        typedef typename MultiPolygon::value_type polygon_type;
     189        typedef typename ring_type<MultiPolygon>::type ring_type;
     190       
     191        geometry_type::enum_t multipolygontype;
     192        if (!geometry_type_parser::parse(it, end, multipolygontype, order))
     193        {
     194            return false;
     195        }
     196       
     197        if (geometry_type::multipolygon != multipolygontype)
     198        {
     199            return false;
     200        }
     201       
     202        boost::uint32_t num_polygons(0);
     203        if (!value_parser<boost::uint32_t>::parse(it, end, num_polygons, order))
     204        {
     205            return false;
     206        }
     207       
     208        polygon_type polygon_buffer;
     209        std::back_insert_iterator<MultiPolygon> output(std::back_inserter(multipolygon));
     210       
     211        std::size_t polygons_parsed = 0;
     212        while(polygons_parsed < num_polygons && it != end)
     213        {
     214            detail::wkb::byte_order_type::enum_t polygon_byte_order;
     215            if (!detail::wkb::byte_order_parser::parse(it, end, polygon_byte_order))
     216            {
     217                return false;
     218            }
     219           
     220            geometry_type::enum_t type;
     221            if (!geometry_type_parser::parse(it, end, type, polygon_byte_order))
     222            {
     223                return false;
     224            }
     225           
     226            if (geometry_type::polygon != type)
     227            {
     228                return false;
     229            }
     230
     231            boost::uint32_t num_rings(0);
     232            if (geometry_type::polygon != type ||
     233                !value_parser<boost::uint32_t>::parse(it, end, num_rings, polygon_byte_order))
     234            {
     235                return false;
     236            }
     237           
     238            std::size_t rings_parsed = 0;
     239           
     240            while (rings_parsed < num_rings && it != end)
     241            {
     242                boost::uint32_t num_points(0);
     243                if (!value_parser<boost::uint32_t>::parse(it, end, num_points, polygon_byte_order))
     244                {
     245                    return false;
     246                }
     247               
     248                if (0 == rings_parsed)
     249                {
     250                    ring_type& ring0 = exterior_ring(polygon_buffer);
     251                   
     252                    if (!point_container_parser<ring_type>::parse(it, end, ring0, polygon_byte_order, num_points))
     253                    {
     254                        return false;
     255                    }
     256                }
     257                else
     258                {
     259                    interior_rings(polygon_buffer).resize(rings_parsed);
     260                    ring_type& ringN = interior_rings(polygon_buffer).back();
     261                   
     262                    if (!point_container_parser<ring_type>::parse(it, end, ringN, polygon_byte_order, num_points))
     263                    {
     264                        return false;
     265                    }
     266                }
     267                ++rings_parsed;
     268            }
     269            output = polygon_buffer;
     270            ++output;
     271        }
     272       
     273        return true;
     274    }
     275};
     276
     277}} // namespace detail::wkb
     278#endif // DOXYGEN_NO_IMPL
     279
     280}} // namespace boost::geometry
     281
     282
     283#endif // BOOST_GEOMETRY_MULTI_IO_WKB_DETAIL_PARSER_HPP
  • boost/geometry/extensions/multi/gis/io/wkb/read_wkb.hpp

     
     1// Boost.Geometry (aka GGL, Generic Geometry Library)
     2
     3// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
     4
     5// Use, modification and distribution is subject to the Boost Software License,
     6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7// http://www.boost.org/LICENSE_1_0.txt)
     8
     9#ifndef BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     10#define BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
     11
     12#include <iterator>
     13
     14#include <boost/geometry/extensions/multi/gis/io/wkb/detail/parser.hpp>
     15#include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
     16
     17namespace boost { namespace geometry
     18{
     19
     20#ifndef DOXYGEN_NO_DISPATCH
     21namespace dispatch
     22{
     23
     24template <typename Geometry>
     25struct read_wkb<multi_point_tag, Geometry>
     26{
     27    template <typename Iterator>
     28    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     29        detail::wkb::byte_order_type::enum_t order)
     30    {
     31        return detail::wkb::multipoint_parser<Geometry>::parse(it, end, geometry, order);
     32    }
     33};
     34
     35template <typename Geometry>
     36struct read_wkb<multi_linestring_tag, Geometry>
     37{
     38    template <typename Iterator>
     39    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     40        detail::wkb::byte_order_type::enum_t order)
     41    {
     42        return detail::wkb::multilinestring_parser<Geometry>::parse(it, end, geometry, order);
     43    }
     44};
     45
     46template <typename Geometry>
     47struct read_wkb<multi_polygon_tag, Geometry>
     48{
     49    template <typename Iterator>
     50    static inline bool parse(Iterator& it, Iterator end, Geometry& geometry,
     51        detail::wkb::byte_order_type::enum_t order)
     52    {
     53        return detail::wkb::multipolygon_parser<Geometry>::parse(it, end, geometry, order);
     54    }
     55};
     56
     57} // namespace dispatch
     58#endif // DOXYGEN_NO_DISPATCH
     59
     60}} // namespace boost::geometry
     61
     62#endif // BOOST_GEOMETRY_MULTI_IO_WKB_READ_WKB_HPP
  • boost/geometry/multi/algorithms/equals.hpp

     
    2020#include <boost/geometry/multi/geometries/concepts/check.hpp>
    2121
    2222#include <boost/geometry/algorithms/equals.hpp>
     23#include <boost/geometry/multi/algorithms/num_points.hpp>
    2324
    2425
    2526namespace boost { namespace geometry
     
    2930namespace dispatch
    3031{
    3132
     33template <typename MultiPoint1, typename MultiPoint2, bool Reverse>
     34struct equals
     35    <
     36        MultiPoint1, MultiPoint2,
     37        multi_point_tag, multi_point_tag,
     38        2,
     39        Reverse
     40    >
     41    : detail::equals::equals_by_collection<detail::equals::num_points_check>
     42{};
    3243
     44template <typename MultiLinestring1, typename MultiLinestring2, bool Reverse>
     45struct equals
     46    <
     47        MultiLinestring1, MultiLinestring2,
     48        multi_linestring_tag, multi_linestring_tag,
     49        2,
     50        Reverse
     51    >
     52    : detail::equals::equals_by_collection<detail::equals::length_check>
     53{};
     54
    3355template <typename MultiPolygon1, typename MultiPolygon2, bool Reverse>
    3456struct equals
    3557    <
  • libs/geometry/extensions/test/gis/io/Jamfile.v2

     
     1# Boost.Geometry (aka GGL, Generic Geometry Library)
     2#
     3# Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands.
     4# Copyright (c) 2008-2013 Bruno Lalande, Paris, France.
     5# Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
     6#
     7# Use, modification and distribution is subject to the Boost Software License,
     8# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     9# http://www.boost.org/LICENSE_1_0.txt)
     10
     11build-project wkb ;
     12 No newline at end of file
  • libs/geometry/extensions/test/gis/io/wkb/Jamfile.v2

     
     1# Boost.Geometry (aka GGL, Generic Geometry Library)
     2#
     3# Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands.
     4# Copyright (c) 2008-2013 Bruno Lalande, Paris, France.
     5# Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
     6#
     7# Use, modification and distribution is subject to the Boost Software License,
     8# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     9# http://www.boost.org/LICENSE_1_0.txt)
     10
     11test-suite boost-geometry-extensions-gis-io-wkb
     12    :
     13    [ run read_wkb.cpp ]
     14    ;
  • libs/geometry/extensions/test/gis/io/wkb/read_wkb.cpp

     
    1010#include <iterator>
    1111#include <string>
    1212#include <vector>
     13#include <iostream>
    1314
    1415#include <boost/test/included/test_exec_monitor.hpp>
    1516#include <boost/test/included/unit_test.hpp>
     
    1718#include <boost/cstdint.hpp>
    1819
    1920#include <boost/geometry/algorithms/equals.hpp>
     21#include <boost/geometry/strategies/strategies.hpp>
    2022#include <boost/geometry/geometries/geometries.hpp>
    2123#include <boost/geometry/io/wkt/read.hpp>
    2224#include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
    2325#include <boost/geometry/extensions/gis/io/wkb/utility.hpp>
    2426
     27#include <boost/geometry/multi/algorithms/equals.hpp>
     28#include <boost/geometry/multi/geometries/multi_geometries.hpp>
     29#include <boost/geometry/multi/io/wkt/wkt.hpp>
     30
     31#include <boost/geometry/extensions/multi/gis/io/wkb/read_wkb.hpp>
     32
    2533namespace bg = boost::geometry;
    2634
    2735namespace { // anonymous
     
    3745    std::cout << bg::read_wkb(wkb.begin(), wkb.end(), g_wkb) << std::endl;
    3846}
    3947
     48template <typename Geometry>
     49void test_geometry_parse_failure(std::string const& wkbhex, std::string const& wkt)
     50{
     51    byte_vector wkb;
     52    BOOST_CHECK( bg::hex2wkb(wkbhex, std::back_inserter(wkb)) );
     53    Geometry g_wkb;
     54    BOOST_CHECK( bg::read_wkb(wkb.begin(), wkb.end(), g_wkb) == false );
     55}
     56
    4057template <typename Geometry, bool IsEqual>
    4158void test_geometry_equals(std::string const& wkbhex, std::string const& wkt)
    4259{
     
    4764
    4865    Geometry g_expected;
    4966    bg::read_wkt(wkt, g_expected);
     67   
     68    bool eq = bg::equals(g_wkb, g_expected);
     69   
     70    if(eq != IsEqual)
     71    {
     72        std::cout << "WKT EXPECTED:"<< bg::wkt(g_expected) << std::endl;
     73        std::cout << "WKT ACTUAL:"<< bg::wkt(g_wkb) << std::endl;
     74    }
     75   
     76    BOOST_CHECK( eq == IsEqual );
     77}
     78
     79template <typename Geometry, bool IsEqual>
     80void test_geometry_print(std::string const& wkbhex, std::string const& wkt)
     81{
     82    byte_vector wkb;
     83    BOOST_CHECK( bg::hex2wkb(wkbhex, std::back_inserter(wkb)) );
     84    Geometry g_wkb;
     85    BOOST_CHECK( bg::read_wkb(wkb.begin(), wkb.end(), g_wkb) );
     86
     87    Geometry g_expected;
     88    bg::read_wkt(wkt, g_expected);
     89   
     90    std::cout << "WKT OUT:"<< bg::wkt(g_wkb) << std::endl;
     91   
    5092    BOOST_CHECK( bg::equals(g_wkb, g_expected) == IsEqual );
    5193}
    5294
     
    5395//template <typename P, bool Result>
    5496//void test_polygon_wkt(std::string const& wkt)
    5597//{
    56 //    typedef bg::model::linestring<P> linestring_type;
    57 //    typedef bg::model::polygon<linestring_type> polygon_type;
     98// typedef bg::model::linestring<P> linestring_type;
     99// typedef bg::model::polygon<linestring_type> polygon_type;
    58100//
    59 //    polygon_type poly;
    60 //    bg::read_wkb(wkb, poly);
     101// polygon_type poly;
     102// bg::read_wkb(wkb, poly);
    61103//}
    62104
    63105} // namespace anonymous
     
    66108{
    67109    typedef bg::model::point<double, 2, bg::cs::cartesian> point_type;
    68110    typedef bg::model::linestring<point_type> linestring_type;
     111    typedef bg::model::polygon<point_type> polygon_type;
     112   
     113    typedef bg::model::point<double, 3, bg::cs::cartesian> point_3d_type;
     114    typedef bg::model::linestring<point_3d_type> linestring_3d_type;
     115    typedef bg::model::polygon<point_3d_type> polygon_3d_type;
    69116
    70117    //
    71118    // POINT
     
    104151        "01010000E0E61000005839B4C876BEF33F83C0CAA145B616400000000000002E400000000000C05340",
    105152        "POINT (1.234 5.678)");
    106153
     154//    //// 3D - needs to implement geometry_type handling
     155//   
     156//    // POINT(1.234 5.678 99)
     157//    test_geometry_equals<point_3d_type, true>(
     158//        "01e90300005839b4c876bef33f83c0caa145b616400000000000c05840", "POINT Z (1.234 5.678 99)");
     159   
     160    //
     161    // LineString
     162    //
     163   
     164    test_geometry_equals<linestring_type, true>(
     165      "0102000000030000005839B4C876BEF33F83C0CAA145B616404F401361C333224062A1D634EF3824409CC420B072482A40EB73B515FB2B3040",
     166      "LINESTRING (1.234 5.678, 9.1011 10.1112, 13.1415 16.1718)");
     167   
     168    // LINESTRING (1.234 5.678 99, 9.1011 10.1112 99, 13.1415 16.1718 99) - Z coordinate in a two-dimensional linestring
     169    // Result is LINESTRING (1.234 5.678, 99 9.1011, 10.1112 99)
     170    test_geometry_equals<linestring_type, false>(
     171"0102000080030000005839B4C876BEF33F83C0CAA145B616400000000000C058404F401361C333224062A1D634EF3824400000000000C058409CC420B072482A40EB73B515FB2B30400000000000C05840",
     172      "LINESTRING (1.234 5.678, 9.1011 10.1112, 13.1415 16.1718)");
     173   
     174    //
     175    // Polygon
     176    //
     177   
     178    test_geometry_equals<polygon_type, true>(
     179"010300000001000000050000000000000000005940000000000000694000000000000069400000000000006940000000000000694000000000000079400000000000005940000000000000794000000000000059400000000000006940",
     180    "POLYGON((100 200, 200 200, 200 400, 100 400, 100 200))"
     181    );
     182   
     183    // POLYGON((100 200 99, 200 200 99, 200 400 99, 100 400 99, 100 200 99)) - Z coordinate in a two-dimensional polygon
     184    // Result is POLYGON((100 200,99 200,200 99,200 400,99 100))
     185    test_geometry_equals<polygon_type, false>(
     186"01030000800100000005000000000000000000594000000000000069400000000000C05840000000000000694000000000000069400000000000C05840000000000000694000000000000079400000000000C05840000000000000594000000000000079400000000000C05840000000000000594000000000000069400000000000C05840",
     187    "POLYGON((100 200, 200 200, 200 400, 100 400, 100 200))"
     188    );
     189   
     190    test_geometry_equals<polygon_type, true>(
     191"0103000000020000000500000000000000008041400000000000002440000000000000244000000000000034400000000000002E40000000000000444000000000008046400000000000804640000000000080414000000000000024400400000000000000000034400000000000003E40000000000080414000000000008041400000000000003E40000000000000344000000000000034400000000000003E40",
     192    "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))"
     193    );
     194   
     195    // POLYGON ((35 10 99, 10 20 99, 15 40 99, 45 45 99, 35 10 99),(20 30 99, 35 35 99, 30 20 99, 20 30 99)) - Z coordinate in a two-dimensional polygon
     196    // Result is POLYGON((35 10,99 10,20 99,15 40,99 45),())
     197    test_geometry_equals<polygon_type, false>(
     198"01030000800200000005000000000000000080414000000000000024400000000000C05840000000000000244000000000000034400000000000C058400000000000002E4000000000000044400000000000C05840000000000080464000000000008046400000000000C05840000000000080414000000000000024400000000000C058400400000000000000000034400000000000003E400000000000C05840000000000080414000000000008041400000000000C058400000000000003E4000000000000034400000000000C0584000000000000034400000000000003E400000000000C05840",
     199    "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))"
     200    );
     201   
     202   
     203    //
     204    // Multi Geometries
     205    //
     206   
     207    typedef bg::model::multi_point<point_type> multipoint_type;
     208    typedef bg::model::multi_linestring<linestring_type> multilinestring_type;
     209    typedef bg::model::multi_polygon<polygon_type> multipolygon_type;
     210   
     211    //
     212    // MultiPoint
     213    //
     214   
     215    test_geometry_equals<multipoint_type, true>(
     216    "01040000000100000001010000005839b4c876bef33f83c0caa145b61640",
     217    "MULTIPOINT (1.234 5.678)"
     218    );
     219   
     220    test_geometry_equals<multipoint_type, true>(
     221    "01040000000200000001010000005839B4C876BEF33F83C0CAA145B61640010100000062A1D634EF3824409CC420B072482A40",
     222    "MULTIPOINT (1.234 5.678, 10.1112 13.1415)"
     223    );
     224   
     225    //
     226    // MultiLineString
     227    //
     228   
     229    test_geometry_equals<multilinestring_type, true>(
     230      "0105000000010000000102000000030000005839b4c876bef33f83c0caa145b616404f401361c333224062a1d634ef3824409cc420b072482a40eb73b515fb2b3040",
     231      "MULTILINESTRING((1.234 5.678,9.1011 10.1112,13.1415 16.1718))");
     232    test_geometry_equals<multilinestring_type, true>(
     233      "0105000000020000000102000000030000005839b4c876bef33f83c0caa145b616404f401361c333224062a1d634ef3824409cc420b072482a40eb73b515fb2b30400102000000020000003333333333333340b81e85eb513835403d0ad7a3703d3740c3f5285c8f423940",
     234      "MULTILINESTRING((1.234 5.678,9.1011 10.1112,13.1415 16.1718),(19.2 21.22,23.24 25.26))");
     235
     236   
     237    //
     238    // MultiPolygon
     239    //
     240   
     241    test_geometry_equals<multipolygon_type, true>(
     242"010600000001000000010300000001000000050000000000000000005940000000000000694000000000000069400000000000006940000000000000694000000000000079400000000000005940000000000000794000000000000059400000000000006940",
     243    "MULTIPOLYGON(((100 200,200 200,200 400,100 400,100 200)))"
     244    );
     245   
     246    test_geometry_equals<multipolygon_type, true>(
     247"0106000000010000000103000000020000000500000000000000008041400000000000002440000000000000244000000000000034400000000000002e40000000000000444000000000008046400000000000804640000000000080414000000000000024400400000000000000000034400000000000003e40000000000080414000000000008041400000000000003e40000000000000344000000000000034400000000000003e40",
     248    "MULTIPOLYGON(((35 10,10 20,15 40,45 45,35 10),(20 30,35 35,30 20,20 30)))"
     249    );
     250   
    107251    return 0;
    108252}
  • libs/geometry/extensions/test/gis/Jamfile.v2

     
    88# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    99# http://www.boost.org/LICENSE_1_0.txt)
    1010
     11build-project io ;
    1112build-project latlong ;
    1213build-project projections ;
    1314