QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgslabelsearchtree.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslabelsearchtree.cpp
3  ---------------------
4  begin : November 2010
5  copyright : (C) 2010 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
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 #include "qgslabelsearchtree.h"
16 #include "labelposition.h"
17 
18 bool searchCallback( QgsLabelPosition* pos, void* context )
19 {
20  QList<QgsLabelPosition*>* list = static_cast< QList<QgsLabelPosition*>* >( context );
21  list->push_back( pos );
22  return true;
23 }
24 
26 {
27 }
28 
30 {
31  clear();
32 }
33 
34 void QgsLabelSearchTree::label( const QgsPoint& p, QList<QgsLabelPosition*>& posList )
35 {
36  double c_min[2]; c_min[0] = p.x() - 0.1; c_min[1] = p.y() - 0.1;
37  double c_max[2]; c_max[0] = p.x() + 0.1; c_max[1] = p.y() + 0.1;
38 
39  QList<QgsLabelPosition*> searchResults;
40  mSpatialIndex.Search( c_min, c_max, searchCallback, &searchResults );
41 
42  //tolerance +-0.1 could be high in case of degree crs, so check if p is really contained in the results
43  posList.clear();
44  QList<QgsLabelPosition*>::const_iterator resultIt = searchResults.constBegin();
45  for ( ; resultIt != searchResults.constEnd(); ++resultIt )
46  {
47  if (( *resultIt )->labelRect.contains( p ) )
48  {
49  posList.push_back( *resultIt );
50  }
51  }
52 }
53 
54 void QgsLabelSearchTree::labelsInRect( const QgsRectangle& r, QList<QgsLabelPosition*>& posList )
55 {
56  double c_min[2]; c_min[0] = r.xMinimum(); c_min[1] = r.yMinimum();
57  double c_max[2]; c_max[0] = r.xMaximum(); c_max[1] = r.yMaximum();
58 
59  QList<QgsLabelPosition*> searchResults;
60  mSpatialIndex.Search( c_min, c_max, searchCallback, &searchResults );
61 
62  posList.clear();
63  QList<QgsLabelPosition*>::const_iterator resultIt = searchResults.constBegin();
64  for ( ; resultIt != searchResults.constEnd(); ++resultIt )
65  {
66  posList.push_back( *resultIt );
67  }
68 }
69 
70 bool QgsLabelSearchTree::insertLabel( LabelPosition* labelPos, int featureId, const QString& layerName, const QString& labeltext, const QFont& labelfont, bool diagram, bool pinned )
71 {
72  if ( !labelPos )
73  {
74  return false;
75  }
76 
77  double c_min[2];
78  double c_max[2];
79  labelPos->getBoundingBox( c_min, c_max );
80 
81  QVector<QgsPoint> cornerPoints;
82  for ( int i = 0; i < 4; ++i )
83  {
84  cornerPoints.push_back( QgsPoint( labelPos->getX( i ), labelPos->getY( i ) ) );
85  }
86  QgsLabelPosition* newEntry = new QgsLabelPosition( featureId, labelPos->getAlpha(), cornerPoints, QgsRectangle( c_min[0], c_min[1], c_max[0], c_max[1] ),
87  labelPos->getWidth(), labelPos->getHeight(), layerName, labeltext, labelfont, labelPos->getUpsideDown(), diagram, pinned );
88  mSpatialIndex.Insert( c_min, c_max, newEntry );
89  return true;
90 }
91 
93 {
94  RTree<QgsLabelPosition*, double, 2, double>::Iterator indexIt;
95  mSpatialIndex.GetFirst( indexIt );
96  while ( !mSpatialIndex.IsNull( indexIt ) )
97  {
98  delete mSpatialIndex.GetAt( indexIt );
99  mSpatialIndex.GetNext( indexIt );
100  }
101  mSpatialIndex.RemoveAll();
102 }