Branch data Line data Source code
1 : : /***************************************************************************
2 : : parlrtree.h
3 : : ------------------------
4 : : Date : December 2019
5 : : Copyright : (C) 2019 by Nyall Dawson
6 : : Email : nyall dot dawson at gmail dot com
7 : : ***************************************************************************
8 : : * *
9 : : * This program is free software; you can redistribute it and/or modify *
10 : : * it under the terms of the GNU General Public License as published by *
11 : : * the Free Software Foundation; either version 2 of the License, or *
12 : : * (at your option) any later version. *
13 : : * *
14 : : ***************************************************************************/
15 : :
16 : : #include "RTree.h"
17 : : #include "qgsrectangle.h"
18 : : #include <array>
19 : :
20 : : #ifndef QGSPALRTREE_H
21 : : #define QGSPALRTREE_H
22 : :
23 : : #define SIP_NO_FILE
24 : :
25 : : /**
26 : : * \ingroup core
27 : : * \class PalRtree
28 : : *
29 : : * \brief A rtree spatial index for use in the pal labeling engine.
30 : : *
31 : : * \note Not available in Python bindings.
32 : : * \since QGIS 3.12
33 : : */
34 : : template <typename T>
35 : 0 : class PalRtree : public RTree<T *, float, 2, float>
36 : : {
37 : : public:
38 : :
39 : : /**
40 : : * Constructor for PalRtree. The \a maxBounds argument specifies the maximum bounding box
41 : : * for all coordinates which will be stored in the index.
42 : : */
43 : 0 : PalRtree( const QgsRectangle &maxBounds )
44 : 0 : : mXMin( maxBounds.xMinimum() )
45 : 0 : , mYMin( maxBounds.yMinimum() )
46 : 0 : , mXRes( ( std::numeric_limits< float >::max() - 1 ) / ( maxBounds.xMaximum() - maxBounds.xMinimum() ) )
47 : 0 : , mYRes( ( std::numeric_limits< float >::max() - 1 ) / ( maxBounds.yMaximum() - maxBounds.yMinimum() ) )
48 : 0 : , mMaxBounds( maxBounds )
49 : 0 : {
50 : :
51 : 0 : }
52 : :
53 : : /**
54 : : * Inserts new \a data into the spatial index, with the specified \a bounds.
55 : : *
56 : : * Ownership of \a data is not transferred, and it is the caller's responsibility to ensure that
57 : : * it exists for the lifetime of the spatial index.
58 : : */
59 : 0 : void insert( T *data, const QgsRectangle &bounds )
60 : : {
61 : 0 : std::array< float, 4 > scaledBounds = scaleBounds( bounds );
62 : 0 : this->Insert(
63 : 0 : {
64 : 0 : scaledBounds[0], scaledBounds[ 1]
65 : : },
66 : 0 : {
67 : 0 : scaledBounds[2], scaledBounds[3]
68 : : },
69 : : data );
70 : 0 : }
71 : :
72 : : /**
73 : : * Removes existing \a data from the spatial index, with the specified \a bounds.
74 : : *
75 : : * \a data is not deleted, and it is the caller's responsibility to ensure that
76 : : * it is appropriately cleaned up.
77 : : */
78 : 0 : void remove( T *data, const QgsRectangle &bounds )
79 : : {
80 : 0 : std::array< float, 4 > scaledBounds = scaleBounds( bounds );
81 : 0 : this->Remove(
82 : 0 : {
83 : 0 : scaledBounds[0], scaledBounds[ 1]
84 : : },
85 : 0 : {
86 : 0 : scaledBounds[2], scaledBounds[3]
87 : : },
88 : : data );
89 : 0 : }
90 : :
91 : : /**
92 : : * Performs an intersection check against the index, for data intersecting the specified \a bounds.
93 : : *
94 : : * The \a callback function will be called once for each matching data object encountered.
95 : : */
96 : 0 : bool intersects( const QgsRectangle &bounds, const std::function< bool( T *data )> &callback ) const
97 : : {
98 : 0 : std::array< float, 4 > scaledBounds = scaleBounds( bounds );
99 : 0 : this->Search(
100 : 0 : {
101 : 0 : scaledBounds[0], scaledBounds[ 1]
102 : : },
103 : 0 : {
104 : 0 : scaledBounds[2], scaledBounds[3]
105 : : },
106 : 0 : callback );
107 : 0 : return true;
108 : 0 : }
109 : :
110 : : private:
111 : :
112 : : // Coordinates are scaled inside the index so that they cover the maximum range for float values
113 : : double mXMin = 0;
114 : : double mYMin = 0;
115 : : double mXRes = 1;
116 : : double mYRes = 1;
117 : : const QgsRectangle mMaxBounds;
118 : 0 : std::array<float, 4> scaleBounds( const QgsRectangle &bounds ) const
119 : : {
120 : 0 : return
121 : 0 : {
122 : 0 : static_cast< float >( ( std::max( bounds.xMinimum(), mMaxBounds.xMinimum() ) - mXMin ) / mXRes ),
123 : 0 : static_cast< float >( ( std::max( bounds.yMinimum(), mMaxBounds.yMinimum() ) - mYMin ) / mYRes ),
124 : 0 : static_cast< float >( ( std::min( bounds.xMaximum(), mMaxBounds.xMaximum() ) - mXMin ) / mXRes ),
125 : 0 : static_cast< float >( ( std::min( bounds.yMaximum(), mMaxBounds.yMaximum() ) - mYMin ) / mYRes )
126 : : };
127 : : }
128 : : };
129 : :
130 : : #endif
131 : :
|