File indexing completed on 2025-12-16 09:49:54
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COLOCATE_CLUSTERS_HPP
0010 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COLOCATE_CLUSTERS_HPP
0011
0012 #include <boost/geometry/core/access.hpp>
0013 #include <boost/geometry/core/cs.hpp>
0014 #include <boost/geometry/core/coordinate_type.hpp>
0015 #include <boost/geometry/core/tags.hpp>
0016
0017 namespace boost { namespace geometry
0018 {
0019
0020 #ifndef DOXYGEN_NO_DETAIL
0021 namespace detail { namespace overlay
0022 {
0023
0024
0025 template
0026 <
0027 typename Point,
0028 typename CoordinateType = geometry::coordinate_type_t<Point>,
0029 typename CsTag = geometry::cs_tag_t<Point>,
0030 bool IsIntegral = std::is_integral<CoordinateType>::value
0031 >
0032 struct cluster_colocator
0033 {
0034 template <typename TurnIndices, typename Turns>
0035 static inline void apply(TurnIndices const& indices, Turns& turns)
0036 {
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 auto it = indices.begin();
0047 auto const& first_point = turns[*it].point;
0048 for (++it; it != indices.end(); ++it)
0049 {
0050 turns[*it].point = first_point;
0051 }
0052 }
0053 };
0054
0055
0056
0057 template <typename Point, typename CoordinateType>
0058 struct cluster_colocator<Point, CoordinateType, geometry::cartesian_tag, false>
0059 {
0060 template <typename TurnIndices, typename Turns>
0061 static inline void apply(TurnIndices const& indices, Turns& turns)
0062 {
0063 CoordinateType centroid_0 = 0;
0064 CoordinateType centroid_1 = 0;
0065 for (auto const& index : indices)
0066 {
0067 centroid_0 += geometry::get<0>(turns[index].point);
0068 centroid_1 += geometry::get<1>(turns[index].point);
0069 }
0070 centroid_0 /= indices.size();
0071 centroid_1 /= indices.size();
0072 for (auto const& index : indices)
0073 {
0074 geometry::set<0>(turns[index].point, centroid_0);
0075 geometry::set<1>(turns[index].point, centroid_1);
0076 }
0077 }
0078 };
0079
0080
0081
0082
0083
0084 template <typename Clusters, typename Turns>
0085 inline void colocate_clusters(Clusters const& clusters, Turns& turns)
0086 {
0087 for (auto const& pair : clusters)
0088 {
0089 auto const& turn_indices = pair.second.turn_indices;
0090 if (turn_indices.size() < 2)
0091 {
0092
0093 continue;
0094 }
0095 using point_t = decltype(turns[*turn_indices.begin()].point);
0096 cluster_colocator<point_t>::apply(turn_indices, turns);
0097 }
0098 }
0099
0100
0101 }}
0102 #endif
0103
0104
0105 }}
0106
0107 #endif