123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- // Boost.Geometry (aka GGL, Generic Geometry Library)
- // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
- // This file was modified by Oracle on 2013, 2014, 2015, 2019.
- // Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
- // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
- // 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)
- #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
- #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
- #include <boost/mpl/is_sequence.hpp>
- #include <boost/mpl/push_back.hpp>
- #include <boost/mpl/vector.hpp>
- #include <boost/mpl/vector_c.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/tuple/tuple.hpp>
- #include <boost/geometry/algorithms/detail/relate/result.hpp>
- #include <boost/geometry/core/topological_dimension.hpp>
- #include <boost/geometry/core/tag.hpp>
- // TEMP - move this header to geometry/detail
- #include <boost/geometry/index/detail/tuples.hpp>
- namespace boost { namespace geometry
- {
-
- namespace de9im
- {
- /*!
- \brief DE-9IM model intersection matrix.
- \ingroup de9im
- \details This matrix can be used to express spatial relations as defined in
- Dimensionally Extended 9-Intersection Model.
- \qbk{[heading See also]}
- \qbk{* [link geometry.reference.algorithms.relation relation]}
- */
- class matrix
- : public detail::relate::matrix<3, 3>
- {
- #ifdef DOXYGEN_INVOKED
- public:
- /*!
- \brief Initializes all of the matrix elements to F
- */
- matrix();
- /*!
- \brief Subscript operator
- \param index The index of the element
- \return The element
- */
- char operator[](std::size_t index) const;
- /*!
- \brief Returns the iterator to the first element
- \return const RandomAccessIterator
- */
- const_iterator begin() const;
- /*!
- \brief Returns the iterator past the last element
- \return const RandomAccessIterator
- */
- const_iterator end() const;
- /*!
- \brief Returns the number of elements
- \return 9
- */
- static std::size_t size();
- /*!
- \brief Returns raw pointer to elements
- \return const pointer to array of elements
- */
- inline const char * data() const;
- /*!
- \brief Returns std::string containing elements
- \return string containing elements
- */
- inline std::string str() const;
- #endif
- };
- /*!
- \brief DE-9IM model intersection mask.
- \ingroup de9im
- \details This mask can be used to check spatial relations as defined in
- Dimensionally Extended 9-Intersection Model.
- \qbk{[heading See also]}
- \qbk{* [link geometry.reference.algorithms.relate relate]}
- */
- class mask
- : public detail::relate::mask<3, 3>
- {
- typedef detail::relate::mask<3, 3> base_type;
- public:
- /*!
- \brief The constructor.
- \param code The mask pattern.
- */
- inline explicit mask(const char* code)
- : base_type(code)
- {}
-
- /*!
- \brief The constructor.
- \param code The mask pattern.
- */
- inline explicit mask(std::string const& code)
- : base_type(code.c_str(), code.size())
- {}
- };
- // static_mask
- /*!
- \brief DE-9IM model intersection mask (static version).
- \ingroup de9im
- \details This mask can be used to check spatial relations as defined in
- Dimensionally Extended 9-Intersection Model.
- \tparam II Interior/Interior intersection mask element
- \tparam IB Interior/Boundary intersection mask element
- \tparam IE Interior/Exterior intersection mask element
- \tparam BI Boundary/Interior intersection mask element
- \tparam BB Boundary/Boundary intersection mask element
- \tparam BE Boundary/Exterior intersection mask element
- \tparam EI Exterior/Interior intersection mask element
- \tparam EB Exterior/Boundary intersection mask element
- \tparam EE Exterior/Exterior intersection mask element
- \qbk{[heading See also]}
- \qbk{* [link geometry.reference.algorithms.relate relate]}
- */
- template
- <
- char II = '*', char IB = '*', char IE = '*',
- char BI = '*', char BB = '*', char BE = '*',
- char EI = '*', char EB = '*', char EE = '*'
- >
- class static_mask
- : public detail::relate::static_mask
- <
- boost::mpl::vector_c
- <
- char, II, IB, IE, BI, BB, BE, EI, EB, EE
- >,
- 3, 3
- >
- {};
- } // namespace de9im
- namespace detail { namespace de9im
- {
- // a small helper util for ORing static masks
- template
- <
- typename Seq,
- typename T,
- bool IsSeq = boost::mpl::is_sequence<Seq>::value
- >
- struct push_back
- {
- typedef typename boost::mpl::push_back
- <
- Seq,
- T
- >::type type;
- };
- template <typename Seq, typename T>
- struct push_back<Seq, T, false>
- {};
- }} // namespace detail::de9im
- namespace de9im
- {
- inline
- boost::tuples::cons
- <
- mask,
- boost::tuples::cons<mask, boost::tuples::null_type>
- >
- operator||(mask const& m1, mask const& m2)
- {
- namespace bt = boost::tuples;
- return bt::cons<mask, bt::cons<mask, bt::null_type> >
- ( m1, bt::cons<mask, bt::null_type>(m2, bt::null_type()) );
- }
- template <typename Tail>
- inline
- typename index::detail::tuples::push_back
- <
- boost::tuples::cons<mask, Tail>,
- mask
- >::type
- operator||(boost::tuples::cons<mask, Tail> const& t, mask const& m)
- {
- namespace bt = boost::tuples;
- return index::detail::tuples::push_back
- <
- bt::cons<mask, Tail>,
- mask
- >::apply(t, m);
- }
- template
- <
- char II1, char IB1, char IE1,
- char BI1, char BB1, char BE1,
- char EI1, char EB1, char EE1,
- char II2, char IB2, char IE2,
- char BI2, char BB2, char BE2,
- char EI2, char EB2, char EE2
- >
- inline
- boost::mpl::vector<
- static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
- static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
- >
- operator||(static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1> const& ,
- static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2> const& )
- {
- return boost::mpl::vector
- <
- static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
- static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
- >();
- }
- template
- <
- typename Seq,
- char II, char IB, char IE,
- char BI, char BB, char BE,
- char EI, char EB, char EE
- >
- inline
- typename detail::de9im::push_back
- <
- Seq,
- static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
- >::type
- operator||(Seq const& ,
- static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE> const& )
- {
- return typename detail::de9im::push_back
- <
- Seq,
- static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
- >::type();
- }
- } // namespace de9im
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail { namespace de9im
- {
- // PREDEFINED MASKS
- // TODO:
- // 1. specialize for simplified masks if available
- // e.g. for TOUCHES use 1 mask for A/A
- // 2. Think about dimensions > 2 e.g. should TOUCHES be true
- // if the interior of the Areal overlaps the boundary of the Volumetric
- // like it's true for Linear/Areal
- // EQUALS
- template <typename Geometry1, typename Geometry2>
- struct static_mask_equals_type
- {
- typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
- //typedef geometry::de9im::static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
- };
- // DISJOINT
- template <typename Geometry1, typename Geometry2>
- struct static_mask_disjoint_type
- {
- typedef geometry::de9im::static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> type;
- };
- // TOUCHES - NOT P/P
- template
- <
- typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
- std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
- >
- struct static_mask_touches_impl
- {
- typedef boost::mpl::vector
- <
- geometry::de9im::static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
- geometry::de9im::static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
- geometry::de9im::static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
- > type;
- };
- // According to OGC, doesn't apply to P/P
- // Using the above mask the result would be always false
- template <typename Geometry1, typename Geometry2>
- struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
- {
- typedef geometry::detail::relate::false_mask type;
- };
- template <typename Geometry1, typename Geometry2>
- struct static_mask_touches_type
- : static_mask_touches_impl<Geometry1, Geometry2>
- {};
- // WITHIN
- template <typename Geometry1, typename Geometry2>
- struct static_mask_within_type
- {
- typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> type;
- };
- // COVERED_BY (non OGC)
- template <typename Geometry1, typename Geometry2>
- struct static_mask_covered_by_type
- {
- typedef boost::mpl::vector
- <
- geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
- geometry::de9im::static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
- geometry::de9im::static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
- geometry::de9im::static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
- > type;
- };
- // CROSSES
- // dim(G1) < dim(G2) - P/L P/A L/A
- template
- <
- typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
- std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value,
- bool D1LessD2 = (Dim1 < Dim2)
- >
- struct static_mask_crosses_impl
- {
- typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
- };
- // TODO: I'm not sure if this one below should be available!
- // dim(G1) > dim(G2) - L/P A/P A/L
- template
- <
- typename Geometry1, typename Geometry2, std::size_t Dim1, std::size_t Dim2
- >
- struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
- {
- typedef geometry::de9im::static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
- };
- // dim(G1) == dim(G2) - P/P A/A
- template
- <
- typename Geometry1, typename Geometry2, std::size_t Dim
- >
- struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
- {
- typedef geometry::detail::relate::false_mask type;
- };
- // dim(G1) == 1 && dim(G2) == 1 - L/L
- template <typename Geometry1, typename Geometry2>
- struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
- {
- typedef geometry::de9im::static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
- };
- template <typename Geometry1, typename Geometry2>
- struct static_mask_crosses_type
- : static_mask_crosses_impl<Geometry1, Geometry2>
- {};
- // OVERLAPS
- // dim(G1) != dim(G2) - NOT P/P, L/L, A/A
- template
- <
- typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
- std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
- >
- struct static_mask_overlaps_impl
- {
- typedef geometry::detail::relate::false_mask type;
- };
- // dim(G1) == D && dim(G2) == D - P/P A/A
- template <typename Geometry1, typename Geometry2, std::size_t Dim>
- struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
- {
- typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
- };
- // dim(G1) == 1 && dim(G2) == 1 - L/L
- template <typename Geometry1, typename Geometry2>
- struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
- {
- typedef geometry::de9im::static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
- };
- template <typename Geometry1, typename Geometry2>
- struct static_mask_overlaps_type
- : static_mask_overlaps_impl<Geometry1, Geometry2>
- {};
- }} // namespace detail::de9im
- #endif // DOXYGEN_NO_DETAIL
- }} // namespace boost::geometry
- #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
|