~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/core/qgspalobjectpositionmanager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                        qgspalobjectpositionmanager.cpp  -  description
 
3
                        ---------------------------------
 
4
   begin                : October 2008
 
5
   copyright            : (C) 2008 by Marco Hugentobler
 
6
   email                : marco dot hugentobler at karto dot baug dot ethz dot ch
 
7
***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include "qgspalobjectpositionmanager.h"
 
19
#include "qgsgeometry.h"
 
20
#include "qgspalgeometry.h"
 
21
#include "qgsoverlayobject.h"
 
22
#include "qgsrendercontext.h"
 
23
#include "qgsvectorlayer.h"
 
24
#include "qgsvectoroverlay.h"
 
25
#include "pal.h"
 
26
#include "labelposition.h"
 
27
#include "feature.h"
 
28
#include "layer.h"
 
29
 
 
30
QgsPALObjectPositionManager::QgsPALObjectPositionManager(): mNumberOfLayers( 0 )
 
31
{
 
32
 
 
33
}
 
34
 
 
35
QgsPALObjectPositionManager::~QgsPALObjectPositionManager()
 
36
{
 
37
  deletePALGeometries();
 
38
}
 
39
 
 
40
void QgsPALObjectPositionManager::addLayer( QgsVectorLayer* vl, QList<QgsVectorOverlay*>& overlays )
 
41
{
 
42
  if ( overlays.size() < 1 )
 
43
  {
 
44
    return;
 
45
  }
 
46
 
 
47
  //set arrangement based on vector type
 
48
  pal::Arrangement labelArrangement;
 
49
  switch ( vl->geometryType() )
 
50
  {
 
51
    case QGis::Point:
 
52
      labelArrangement = pal::P_POINT;
 
53
      break;
 
54
    case QGis::Line:
 
55
      labelArrangement = pal::P_LINE;
 
56
      break;
 
57
    case QGis::Polygon:
 
58
      labelArrangement = pal::P_HORIZ;
 
59
      break;
 
60
    default:
 
61
      return; //error
 
62
  }
 
63
 
 
64
  pal::Layer* positionLayer = mPositionEngine.addLayer( QString::number( mNumberOfLayers ).toLocal8Bit().data(), -1, -1, labelArrangement, pal::PIXEL, 0.5, true, true, true );
 
65
  ++mNumberOfLayers;
 
66
 
 
67
  if ( !positionLayer )
 
68
  {
 
69
    return;
 
70
  }
 
71
 
 
72
  //register the labeling objects in the layer
 
73
  int objectNr = 0;
 
74
  QList<QgsVectorOverlay*>::const_iterator overlayIt = overlays.begin();
 
75
  for ( ; overlayIt != overlays.end(); ++overlayIt )
 
76
  {
 
77
    if ( !( *overlayIt ) )
 
78
    {
 
79
      continue;
 
80
    }
 
81
 
 
82
    QMap<int, QgsOverlayObject*>* positionObjects = ( *overlayIt )->overlayObjects();
 
83
    if ( !positionObjects )
 
84
    {
 
85
      continue;
 
86
    }
 
87
 
 
88
    QMap<int, QgsOverlayObject*>::const_iterator objectIt = positionObjects->begin();
 
89
    for ( ; objectIt != positionObjects->end(); ++objectIt )
 
90
    {
 
91
      QgsPALGeometry* palGeom = new QgsPALGeometry( objectIt.value() );
 
92
      mPALGeometries.push_back( palGeom ); //insert object into list to delete memory later
 
93
      char* featureLabel = QString::number( objectNr ).toAscii().data();
 
94
      positionLayer->registerFeature( featureLabel, palGeom, objectIt.value()->width(), objectIt.value()->height() );
 
95
      ++objectNr;
 
96
    }
 
97
  }
 
98
}
 
99
 
 
100
void QgsPALObjectPositionManager::findObjectPositions( const QgsRenderContext& renderContext, QGis::UnitType unitType )
 
101
{
 
102
  //trigger label placement
 
103
  QgsRectangle viewExtent = renderContext.extent();
 
104
  //PAL needs projected view extent
 
105
  if ( renderContext.coordinateTransform() )
 
106
  {
 
107
    viewExtent = renderContext.coordinateTransform()->transformBoundingBox( viewExtent );
 
108
  }
 
109
  double bbox[4]; bbox[0] = viewExtent.xMinimum(); bbox[1] = viewExtent.yMinimum(); bbox[2] = viewExtent.xMaximum(); bbox[3] = viewExtent.yMaximum();
 
110
 
 
111
 
 
112
  //set map units
 
113
  pal::Units mapUnits;
 
114
  switch ( unitType )
 
115
  {
 
116
    case QGis::Meters:
 
117
      mapUnits = pal::METER;
 
118
      break;
 
119
 
 
120
    case QGis::Feet:
 
121
      mapUnits = pal::FOOT;
 
122
      break;
 
123
 
 
124
    case QGis::Degrees:
 
125
      mapUnits = pal::DEGREE;
 
126
      break;
 
127
    default:
 
128
      return;
 
129
  }
 
130
 
 
131
  mPositionEngine.setMapUnit( mapUnits );
 
132
  mPositionEngine.setDpi( renderContext.scaleFactor() * 25.4 );
 
133
 
 
134
  std::list<pal::LabelPosition*>* resultLabelList = mPositionEngine.labeller( renderContext.rendererScale(), bbox, NULL, false );
 
135
 
 
136
  //and read the positions back to the overlay objects
 
137
  if ( !resultLabelList )
 
138
  {
 
139
    return;
 
140
  }
 
141
 
 
142
  //pal geometry that the current label object refers to
 
143
  QgsPALGeometry* referredGeometry = 0;
 
144
  QgsOverlayObject* referredOverlayObject = 0;
 
145
  pal::FeaturePart* referredPart = 0;
 
146
 
 
147
  std::list<pal::LabelPosition*>::iterator labelIt = resultLabelList->begin();
 
148
  for ( ; labelIt != resultLabelList->end(); ++labelIt )
 
149
  {
 
150
    if ( !*labelIt )
 
151
    {
 
152
      continue;
 
153
    }
 
154
 
 
155
    referredPart = ( *labelIt )->getFeaturePart();
 
156
    if ( !referredPart )
 
157
    {
 
158
      continue;
 
159
    }
 
160
    referredGeometry = dynamic_cast<QgsPALGeometry*>( referredPart->getUserGeometry() );
 
161
    if ( !referredGeometry )
 
162
    {
 
163
      continue;
 
164
    }
 
165
    referredOverlayObject = referredGeometry->overlayObjectPtr();
 
166
    if ( !referredOverlayObject )
 
167
    {
 
168
      continue;
 
169
    }
 
170
 
 
171
    pal::LabelPosition* lp = *labelIt;
 
172
 
 
173
    //QGIS takes the coordinates of the middle points
 
174
    double x = ( lp->getX( 0 ) + lp->getX( 1 ) + lp->getX( 2 ) + lp->getX( 3 ) ) / 4;
 
175
    double y = ( lp->getY( 0 ) + lp->getY( 1 ) + lp->getY( 2 ) + lp->getY( 3 ) ) / 4;
 
176
    referredOverlayObject->addPosition( QgsPoint( x, y ) );
 
177
  }
 
178
 
 
179
  //release memory for QgsPALGeometries
 
180
  deletePALGeometries();
 
181
}
 
182
 
 
183
void QgsPALObjectPositionManager::removeLayers()
 
184
{
 
185
  std::list<pal::Layer*>* layerList = mPositionEngine.getLayers();
 
186
  if ( !layerList )
 
187
  {
 
188
    return;
 
189
  }
 
190
 
 
191
  //Iterators get invalid if elements are deleted in a std::list
 
192
  //Therefore we have to get the layer pointers in a first step and remove them in a second
 
193
  QList<pal::Layer*> layersToRemove;
 
194
  std::list<pal::Layer*>::iterator layerIt = layerList->begin();
 
195
  for ( ; layerIt != layerList->end(); ++layerIt )
 
196
  {
 
197
    layersToRemove.push_back( *layerIt );
 
198
  }
 
199
 
 
200
  QList<pal::Layer*>::iterator removeIt = layersToRemove.begin();
 
201
  for ( ; removeIt != layersToRemove.end(); ++removeIt )
 
202
  {
 
203
    mPositionEngine.removeLayer( *removeIt );
 
204
  }
 
205
}
 
206
//Chain, Popmusic tabu chain, Popmusic tabu, Popmusic chain
 
207
void QgsPALObjectPositionManager::setPlacementAlgorithm( const QString& algorithmName )
 
208
{
 
209
  if ( algorithmName == "Popmusic tabu chain" )
 
210
  {
 
211
    mPositionEngine.setSearch( pal::POPMUSIC_TABU_CHAIN );
 
212
  }
 
213
  else if ( algorithmName == "Popmusic tabu" )
 
214
  {
 
215
    mPositionEngine.setSearch( pal::POPMUSIC_TABU );
 
216
  }
 
217
  else if ( algorithmName == "Popmusic chain" )
 
218
  {
 
219
    mPositionEngine.setSearch( pal::POPMUSIC_CHAIN );
 
220
  }
 
221
  else //default is "Chain"
 
222
  {
 
223
    mPositionEngine.setSearch( pal::CHAIN );
 
224
  }
 
225
}
 
226
 
 
227
void QgsPALObjectPositionManager::deletePALGeometries()
 
228
{
 
229
  QList<QgsPALGeometry*>::iterator geomIt = mPALGeometries.begin();
 
230
  for ( ; geomIt != mPALGeometries.end(); ++geomIt )
 
231
  {
 
232
    delete( *geomIt );
 
233
  }
 
234
  mPALGeometries.clear();
 
235
}