backward compatibility breakage in boost::geometry::partition apply function

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

backward compatibility breakage in boost::geometry::partition apply function

vish
A change in boost 1_64_0 has broken backward compatibility of the apply() function in boost::geometry::partition. I have used this apply() function in  multiple versions of boost geometry for 6 years up through version 1_62_0. The sample code is provided below. It's a minor modification of a sample Barend gave in a post on labeling intersections in polygons. The codepad links in that post don't work anymore.

Items pasted below are in the following order:
1. Sample code (test.cpp).
2. Compiler command (using VS 2015).
3. Errors with boost_1_64_0.
4. Warnings when compiled with boost_1_62_0 (no errors result).

1. Sample code (test.cpp).

// Boost.Geometry (aka GGL, Generic Geometry Library)
//
// Copyright (c) 2011 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <fstream>
#include <boost/geometry.hpp>
#include <boost/foreach.hpp>
#include <boost/geometry/io/wkt/read.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <iostream>

typedef boost::geometry::model::d2::point_xy<double> Point2D;

class polygon_with_id : public boost::geometry::model::polygon<Point2D>
{
    public :
        int id;

        polygon_with_id(std::string const& wkt, int the_id = 0)
            : id(the_id)
        {
            boost::geometry::read_wkt(wkt, *this);
        }

        polygon_with_id()
            : id(0)
        {}

};


namespace boost { namespace geometry { namespace traits {

typedef ring_type<model::polygon<model::d2::point_xy<double> > >::type ring_of_polygon_with_id;

template<> struct tag<polygon_with_id> { typedef polygon_tag type; };
template<> struct ring_const_type<polygon_with_id> { typedef ring_of_polygon_with_id const& type; };
template<> struct ring_mutable_type<polygon_with_id> { typedef ring_of_polygon_with_id& type; };

template<> struct interior_const_type<polygon_with_id>
{
    typedef std::vector<ring_of_polygon_with_id> const& type;
};

template<> struct interior_mutable_type<polygon_with_id>
{
    typedef std::vector<ring_of_polygon_with_id>& type;
};


template<> struct exterior_ring<polygon_with_id>
{
    static ring_of_polygon_with_id& get(polygon_with_id& p)
    {
        return p.outer();
    }

    static ring_of_polygon_with_id const& get(polygon_with_id const& p)
    {
        return p.outer();
    }
};

template<> struct interior_rings<polygon_with_id>
{
    typedef std::vector<ring_of_polygon_with_id> holes_type;

    static holes_type& get(polygon_with_id& p)
    {
        return p.inners();
    }

    static holes_type const& get(polygon_with_id const& p)
    {
        return p.inners();
    }
};

}}}


struct do_expand
{
    template <typename Box, typename Geometry>
    static inline void apply(Box& total, Geometry const& geometry)
    {
        boost::geometry::expand(total, boost::geometry::return_envelope<Box>(geometry));
    }
};

struct has_overlap
{
    template <typename Box, typename Geometry>
    static inline bool apply(Box const& box, Geometry const& geometry)
    {
        // We're return true if the BOXES are not disjoint (box and polygon might be)
        // (this results just in a few more intersection trials in the visitor, but
        // there is no performance penalty: hardly any difference if we intersect them
        // here or or there).
        return ! boost::geometry::disjoint(box, boost::geometry::return_envelope<Box>(geometry));
    }
};

struct intersection_visitor
{

    intersection_visitor()
    {}

    template <typename Item>
    inline void apply(Item const& owner, Item const& mr)
    {
        boost::geometry::intersection(owner, mr, output);
    }
   
    // A member to save the intersection results
    boost::geometry::model::multi_polygon<polygon_with_id> output;
};


int main()
{

    std::vector<polygon_with_id> owners;
    std::vector<polygon_with_id> mineral_rights;


    owners.push_back(polygon_with_id("POLYGON((0 0.5,0 1,0.5 1,0.5 0.5,0 0.5))"));
    owners.push_back(polygon_with_id("POLYGON((0.5 0.5,0.5 1,1 1,1 0.5,0.5 0.5))"));
    owners.push_back(polygon_with_id("POLYGON((0 0,0 0.5,0.5 0.5,0.5 0,0 0))"));
    owners.push_back(polygon_with_id("POLYGON((0.5 0,0.5 0.5,1 0.5,1 0,0.5 0))"));

    mineral_rights.push_back(polygon_with_id("POLYGON((0.25 0.75,0.25 1.25,0.75 1.25,0.75 0.75,0.25 0.75))"));
    mineral_rights.push_back(polygon_with_id("POLYGON((0.75 0.75,0.75 1.25,1.25 1.25,1.25 0.75,0.75 0.75))"));
    mineral_rights.push_back(polygon_with_id("POLYGON((0.25 0.25,0.25 0.75,0.75 0.75,0.75 0.25,0.25 0.25))"));
    mineral_rights.push_back(polygon_with_id("POLYGON((0.75 0.25,0.75 0.75,1.25 0.75,1.25 0.25,0.75 0.25))"));
   
    std::cout << "n-log-n solution" << std::endl;

    intersection_visitor visitor;

    boost::geometry::partition
        <
            boost::geometry::model::box<Point2D>, do_expand, has_overlap
        >::apply(owners, mineral_rights, visitor, 1);

    return 0;
}



2. Compiler command (using VS 2015).

cl   -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE  -D_SCL_SECURE_NO_DEPRECATE -D_USE_MATH_DEFINES -DNOMINMAX -DWIN32_LEAN_AND_MEAN -Dstrcasecmp=_stricmp -Dstrncasecmp=_strnicmp -we4311 -we4473 -we4474 -we4477 -MDd -Zi -Od -nologo -W4 -wd4100 -wd4127 -wd4345 -wd4351 -wd4510 -wd4512 -wd4610 -wd4706 -wd4714 -wd6326 -wd6993 -EHsc -Id:\boost_1_64_0  -DBOOST_ALL_NO_LIB /c test.cpp

3. Errors with boost_1_64_0.

test.cpp
d:\boost_1_64_0\boost/geometry/algorithms/detail/partition.hpp(649): error C2039: 'apply': is not a member of 'std::vector<Polygon,std::allocator<Polygon>>'
        with
        [
            Polygon=polygon_with_id
        ]
d:\boost_1_64_0\boost/geometry/geometries/multi_polygon.hpp(55): note: see declaration of 'std::vector<Polygon,std::allocator<Polygon>>'
        with
        [
            Polygon=polygon_with_id
        ]
d:\boost_1_64_0\boost/geometry/algorithms/detail/partition.hpp(586): note: see reference to function template instantiation 'void boost::geometry::partition<boost::geometry::model::box<Point2D>,do_expand,has_overlap>::apply<ForwardRange,VisitPolicy,ExpandPolicy,OverlapsPolicy,boost::geometry::detail::partition::visit_no_policy>(const ForwardRange &,VisitPolicy &,const ExpandPolicy &,const OverlapsPolicy &,std::size_t,VisitBoxPolicy)' being compiled
        with
        [
            ForwardRange=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            VisitPolicy=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            ExpandPolicy=intersection_visitor,
            OverlapsPolicy=int,
            VisitBoxPolicy=boost::geometry::detail::partition::visit_no_policy
        ]
d:\boost_1_64_0\boost/geometry/algorithms/detail/partition.hpp(585): note: see reference to function template instantiation 'void boost::geometry::partition<boost::geometry::model::box<Point2D>,do_expand,has_overlap>::apply<ForwardRange,VisitPolicy,ExpandPolicy,OverlapsPolicy,boost::geometry::detail::partition::visit_no_policy>(const ForwardRange &,VisitPolicy &,const ExpandPolicy &,const OverlapsPolicy &,std::size_t,VisitBoxPolicy)' being compiled
        with
        [
            ForwardRange=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            VisitPolicy=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            ExpandPolicy=intersection_visitor,
            OverlapsPolicy=int,
            VisitBoxPolicy=boost::geometry::detail::partition::visit_no_policy
        ]
test.cpp(148): note: see reference to function template instantiation 'void boost::geometry::partition<boost::geometry::model::box<Point2D>,do_expand,has_overlap>::apply<std::vector<Polygon,std::allocator<Polygon>>,std::vector<Polygon,std::allocator<Polygon>>,intersection_visitor,int>(const ForwardRange &,VisitPolicy &,const ExpandPolicy &,const OverlapsPolicy &)' being compiled
        with
        [
            Polygon=polygon_with_id,
            ForwardRange=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            VisitPolicy=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            ExpandPolicy=intersection_visitor,
            OverlapsPolicy=int
        ]
test.cpp(148): note: see reference to function template instantiation 'void boost::geometry::partition<boost::geometry::model::box<Point2D>,do_expand,has_overlap>::apply<std::vector<Polygon,std::allocator<Polygon>>,std::vector<Polygon,std::allocator<Polygon>>,intersection_visitor,int>(const ForwardRange &,VisitPolicy &,const ExpandPolicy &,const OverlapsPolicy &)' being compiled
        with
        [
            Polygon=polygon_with_id,
            ForwardRange=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            VisitPolicy=std::vector<polygon_with_id,std::allocator<polygon_with_id>>,
            ExpandPolicy=intersection_visitor,
            OverlapsPolicy=int
        ]

       
4. Warnings when compiled with boost_1_62_0 (no errors result).

d:\boost_1_62_0\boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp(113): warning C4244: 'initializing': conversion from 'const __int64' to 'int', possible loss of data
...
d:\boost_1_62_0\boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp(113): warning C4244: 'initializing': conversion from 'const __int64' to 'const int', possible loss of data
d:\boost_1_62_0\boost/geometry/algorithms/detail/overlay/handle_colocations.hpp(314): warning C4456: declaration of 'it' hides previous local declaration
...
d:\boost_1_62_0\boost/geometry/algorithms/detail/overlay/handle_colocations.hpp(322): warning C4244: '=': conversion from 'const boost::geometry::signed_size_type' to 'int', possible loss of data
d:\boost_1_62_0\boost/geometry/algorithms/detail/overlay/traversal.hpp(142): warning C4457: declaration of 'op' hides function parameter
...
d:\boost_1_62_0\boost/geometry/algorithms/detail/overlay/sort_by_side.hpp(306): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
...
[and more warnings which are omitted]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: backward compatibility breakage in boost::geometry::partition apply function

Boost Geometry mailing list
Hi,

Vish Via Geometry wrote:
A change in boost 1_64_0 has broken backward compatibility of the apply()
function in boost::geometry::partition. I have used this apply() function in 
multiple versions of boost geometry for 6 years up through version 1_62_0.
The sample code is provided below. It's a minor modification of a sample
Barend gave in a post on labeling intersections in polygons. The codepad
links in that post don't work anymore.

Yes, partition was modified recently in order to support strategies.

<snip>

    boost::geometry::partition
        <
            boost::geometry::model::box<Point2D>, do_expand, has_overlap
        >::apply(owners, mineral_rights, visitor, 1);

Now instead of passing do_expand and has_overlap as class template parameters you have to pass them as apply function attributes like that:

boost::geometry::partition
    <
        boost::geometry::model::box<Point2D>
    >::apply(owners, mineral_rights, visitor, do_expand(), has_overlap(), do_expand(), has_overlap(), 1);

This allows to pass non-static strategies inside do_expand and has_overlap.

Adam

_______________________________________________
Geometry mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: backward compatibility breakage in boost::geometry::partition apply function

vish
In reply to this post by vish
Thank you, Adam.

The change you suggested eliminated the compile time error. Now there are 12 warnings. It would be nice if they can be fixed in an updated version.

d:\boost_1_64_0\boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp(159): warning C4244: '=': conversion from 'const boost::geometry::signed_size_type' to 'int', possible loss of data

d:\boost_1_64_0\boost/geometry/algorithms/detail/overlay/handle_colocations.hpp(317): warning C4456: declaration of 'it' hides previous local declaration

d:\boost_1_64_0\boost/geometry/algorithms/detail/overlay/sort_by_side.hpp(234): warning C4244: 'argument': conversion from 'boost::geometry::signed_size_type' to 'int', possible loss of data

d:\boost_1_64_0\boost/geometry/algorithms/detail/overlay/sort_by_side.hpp(235): warning C4244: 'argument': conversion from 'boost::geometry::signed_size_type' to 'int', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(97): warning C4244: 'initializing': conversion from 'coordinate_type' to 'promoted_type', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(97): warning C4244: 'initializing': conversion from 'coordinate_type' to 'const promoted_type', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(98): warning C4244: 'initializing': conversion from 'coordinate_type' to 'promoted_type', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(98): warning C4244: 'initializing': conversion from 'coordinate_type' to 'const promoted_type', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(99): warning C4244: 'initializing': conversion from 'coordinate_type' to 'promoted_type', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(99): warning C4244: 'initializing': conversion from 'coordinate_type' to 'const promoted_type', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(100): warning C4244: 'initializing': conversion from 'coordinate_type' to 'promoted_type', possible loss of data

d:\boost_1_64_0\boost/geometry/strategies/cartesian/side_by_triangle.hpp(100): warning C4244: 'initializing': conversion from 'coordinate_type' to 'const promoted_type', possible loss of data
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: backward compatibility breakage in boost::geometry::partition apply function

Boost Geometry mailing list
Hi Vish,

> The change you suggested eliminated the compile time error. Now there are 12
> warnings. It would be nice if they can be fixed in an updated version.

Good it seems to work again, thanks for the report, and Adam for the
change. I will take care of the warnings in the overlay part, thanks.

Regards, Barend


_______________________________________________
Geometry mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/geometry
Loading...