100525_labelpatch.diff

Marco Hugentobler, 2010-05-25 04:37 AM

Download (11.7 KB)

View differences:

python/core/qgsmaprenderer.sip (Arbeitskopie)
19 19
  //! called when starting rendering of a layer
20 20
  virtual int prepareLayer(QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx ) = 0;
21 21
  //! called for every feature
22
  virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat ) = 0;
22
  virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ) = 0;
23 23
  //! called when the map is drawn and labels should be placed
24 24
  virtual void drawLabeling( QgsRenderContext& context ) = 0;
25 25
  //! called when we're done with rendering
src/plugins/labeling/labelingguibase.ui (Arbeitskopie)
6 6
   <rect>
7 7
    <x>0</x>
8 8
    <y>0</y>
9
    <width>480</width>
9
    <width>448</width>
10 10
    <height>610</height>
11 11
   </rect>
12 12
  </property>
......
18 18
    <normaloff/>
19 19
   </iconset>
20 20
  </property>
21
  <layout class="QVBoxLayout" name="verticalLayout">
22
   <item>
21
  <layout class="QGridLayout" name="gridLayout_5">
22
   <item row="0" column="0">
23 23
    <widget class="QCheckBox" name="chkEnableLabeling">
24 24
     <property name="text">
25 25
      <string>Label this layer</string>
26 26
     </property>
27 27
    </widget>
28 28
   </item>
29
   <item>
29
   <item row="1" column="0">
30 30
    <layout class="QHBoxLayout" name="horizontalLayout_9">
31 31
     <item>
32 32
      <widget class="QLabel" name="label_6">
......
56 56
     </item>
57 57
    </layout>
58 58
   </item>
59
   <item>
59
   <item row="2" column="0">
60 60
    <widget class="QGroupBox" name="groupBox_4">
61 61
     <property name="title">
62 62
      <string>Placement</string>
......
326 326
     </layout>
327 327
    </widget>
328 328
   </item>
329
   <item>
329
   <item row="3" column="0">
330 330
    <layout class="QGridLayout" name="gridLayout_4">
331 331
     <item row="0" column="0" rowspan="2">
332 332
      <widget class="QGroupBox" name="groupBox">
......
648 648
     </item>
649 649
    </layout>
650 650
   </item>
651
   <item>
651
   <item row="4" column="0">
652 652
    <widget class="QCheckBox" name="chkLabelPerFeaturePart">
653 653
     <property name="text">
654 654
      <string>label every part of multi-part features</string>
655 655
     </property>
656 656
    </widget>
657 657
   </item>
658
   <item>
658
   <item row="5" column="0">
659 659
    <widget class="QCheckBox" name="chkMergeLines">
660 660
     <property name="text">
661 661
      <string>merge connected lines to avoid duplicate labels</string>
662 662
     </property>
663 663
    </widget>
664 664
   </item>
665
   <item>
665
   <item row="6" column="0">
666
    <layout class="QHBoxLayout" name="horizontalLayout_10">
667
     <item>
668
      <widget class="QLabel" name="label_19">
669
       <property name="text">
670
        <string>Suppress labeling of features smaller than</string>
671
       </property>
672
      </widget>
673
     </item>
674
     <item>
675
      <widget class="QDoubleSpinBox" name="mMinSizeSpinBox">
676
       <property name="suffix">
677
        <string> mm</string>
678
       </property>
679
      </widget>
680
     </item>
681
    </layout>
682
   </item>
683
   <item row="7" column="0">
666 684
    <layout class="QHBoxLayout" name="horizontalLayout_2">
667 685
     <item>
668 686
      <widget class="QCheckBox" name="chkNoObstacle">
......
699 717
     </item>
700 718
    </layout>
701 719
   </item>
702
   <item>
720
   <item row="8" column="0">
703 721
    <spacer name="verticalSpacer_2">
704 722
     <property name="orientation">
705 723
      <enum>Qt::Vertical</enum>
......
712 730
     </property>
713 731
    </spacer>
714 732
   </item>
715
   <item>
733
   <item row="9" column="0">
716 734
    <widget class="QDialogButtonBox" name="buttonBox">
717 735
     <property name="orientation">
718 736
      <enum>Qt::Horizontal</enum>
src/plugins/labeling/pallabeling.cpp (Arbeitskopie)
105 105
  bufferColor = Qt::white;
106 106
  labelPerPart = false;
107 107
  mergeLines = false;
108
  minFeatureSize = 0.0;
108 109
}
109 110

  
110 111
LayerSettings::LayerSettings( const LayerSettings& s )
......
125 126
  bufferColor = s.bufferColor;
126 127
  labelPerPart = s.labelPerPart;
127 128
  mergeLines = s.mergeLines;
129
  minFeatureSize = s.minFeatureSize;
128 130

  
129 131
  fontMetrics = NULL;
130 132
  ct = NULL;
......
178 180
  bufferColor = _readColor( layer, "labeling/bufferColor" );
179 181
  labelPerPart = layer->customProperty( "labeling/labelPerPart" ).toBool();
180 182
  mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
183
  minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble();
181 184
}
182 185

  
183 186
void LayerSettings::writeToLayer( QgsVectorLayer* layer )
......
205 208
  _writeColor( layer, "labeling/bufferColor", bufferColor );
206 209
  layer->setCustomProperty( "labeling/labelPerPart", labelPerPart );
207 210
  layer->setCustomProperty( "labeling/mergeLines", mergeLines );
211
  layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize );
208 212
}
209 213

  
214
bool LayerSettings::checkMinimumSizeMM( const QgsRenderContext& ct, QgsGeometry* geom, double minSize ) const
215
{
216
  if ( minSize <= 0 )
217
  {
218
    return true;
219
  }
220

  
221
  if ( !geom )
222
  {
223
    return false;
224
  }
225

  
226
  QGis::GeometryType featureType = geom->type();
227
  if ( featureType == QGis::Point ) //minimum size does not apply to point features
228
  {
229
    return true;
230
  }
231

  
232
  GEOSGeometry* geosGeom = geom->asGeos();
233
  if ( !geosGeom )
234
  {
235
    return true;
236
  }
237

  
238
  double mapUnitsPerMM = ct.mapToPixel().mapUnitsPerPixel() * ct.scaleFactor();
239
  if ( featureType == QGis::Line )
240
  {
241
    double length;
242
    if ( GEOSLength( geosGeom, &length ) )
243
    {
244
      return ( length >= ( minSize * mapUnitsPerMM ) );
245
    }
246
  }
247
  else if ( featureType == QGis::Polygon )
248
  {
249
    double area;
250
    if ( GEOSArea( geosGeom, &area ) )
251
    {
252
      return ( sqrt( area ) >= ( minSize * mapUnitsPerMM ) );
253
    }
254
  }
255
  return true; //should never be reached. Return true in this case to label such geometries anyway.
256
}
257

  
210 258
void LayerSettings::calculateLabelSize( QString text, double& labelX, double& labelY )
211 259
{
212 260
  //QFontMetrics fontMetrics(textFont);
......
219 267
}
220 268

  
221 269

  
222
void LayerSettings::registerFeature( QgsFeature& f )
270
void LayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext& context )
223 271
{
224 272
  QString labelText = f.attributeMap()[fieldIndex].toString();
225 273
  double labelX, labelY; // will receive label size
......
229 277
  if ( ct != NULL ) // reproject the geometry if necessary
230 278
    geom->transform( *ct );
231 279

  
280
  if ( !checkMinimumSizeMM( context, f.geometry(), minFeatureSize ) )
281
  {
282
    return;
283
  }
284

  
232 285
  MyLabel* lbl = new MyLabel( f.id(), labelText, GEOSGeom_clone( geom->asGeos() ) );
233 286

  
234 287
  // record the created geometry - it will be deleted at the end.
......
375 428
}
376 429

  
377 430

  
378
void PalLabeling::registerFeature( QgsVectorLayer* layer, QgsFeature& f )
431
void PalLabeling::registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context )
379 432
{
380
  mActiveLayers[layer].registerFeature( f );
433
  LayerSettings& lyr = mActiveLayers[layer];
434
  lyr.registerFeature( f, context );
381 435
}
382 436

  
383 437

  
src/plugins/labeling/pallabeling.h (Arbeitskopie)
66 66
    QColor bufferColor;
67 67
    bool labelPerPart; // whether to label every feature's part or only the biggest one
68 68
    bool mergeLines;
69
    double minFeatureSize; // minimum feature size to be labelled (in mm)
69 70

  
70 71
    // called from register feature hook
71 72
    void calculateLabelSize( QString text, double& labelX, double& labelY );
72 73

  
73 74
    // implementation of register feature hook
74
    void registerFeature( QgsFeature& f );
75
    void registerFeature( QgsFeature& f, const QgsRenderContext& context );
75 76

  
76 77
    void readFromLayer( QgsVectorLayer* layer );
77 78
    void writeToLayer( QgsVectorLayer* layer );
......
85 86
    const QgsCoordinateTransform* ct;
86 87
    QgsPoint ptZero, ptOne;
87 88
    QList<MyLabel*> geometries;
89

  
90
  private:
91
    /**Checks if a feature is larger than a minimum size (in mm)
92
    @return true if above size, false if below*/
93
    bool checkMinimumSizeMM( const QgsRenderContext& ct, QgsGeometry* geom, double minSize ) const;
88 94
};
89 95

  
90 96
class LabelCandidate
......
128 134
    //! hook called when drawing layer before issuing select()
129 135
    virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx );
130 136
    //! hook called when drawing for every feature in a layer
131
    virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat );
137
    virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );
132 138
    //! called when the map is drawn and labels should be placed
133 139
    virtual void drawLabeling( QgsRenderContext& context );
134 140
    //! called when we're done with rendering
......
145 151

  
146 152
    void initPal();
147 153

  
154

  
148 155
  protected:
149 156
    // temporary hashtable of layer settings, being filled during labeling, cleared once labeling's done
150 157
    QHash<QgsVectorLayer*, LayerSettings> mActiveLayers;
src/plugins/labeling/labelinggui.cpp (Arbeitskopie)
117 117
  chkNoObstacle->setChecked( !lyr.obstacle );
118 118
  chkLabelPerFeaturePart->setChecked( lyr.labelPerPart );
119 119
  chkMergeLines->setChecked( lyr.mergeLines );
120
  mMinSizeSpinBox->setValue( lyr.minFeatureSize );
120 121

  
121 122
  bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 );
122 123
  chkScaleBasedVisibility->setChecked( scaleBased );
......
231 232
  {
232 233
    lyr.bufferSize = 0;
233 234
  }
234

  
235
  lyr.minFeatureSize = mMinSizeSpinBox->value();
235 236
  return lyr;
236 237
}
237 238

  
src/core/qgsvectorlayer.cpp (Arbeitskopie)
741 741

  
742 742
      // labeling - register feature
743 743
      if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
744
        rendererContext.labelingEngine()->registerFeature( this, fet );
744
        rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
745 745

  
746 746
      if ( mEditable )
747 747
      {
......
805 805
    features[sym].append( fet );
806 806

  
807 807
    if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
808
      rendererContext.labelingEngine()->registerFeature( this, fet );
808
      rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
809 809

  
810 810
    if ( mEditable )
811 811
    {
......
1052 1052

  
1053 1053
        if ( labeling && mRenderer->willRenderFeature( &fet ) )
1054 1054
        {
1055
          rendererContext.labelingEngine()->registerFeature( this, fet );
1055
          rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
1056 1056
        }
1057 1057

  
1058 1058
        ++featureCount;
src/core/qgsmaprenderer.h (Arbeitskopie)
53 53
    //! called when starting rendering of a layer
54 54
    virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx ) = 0;
55 55
    //! called for every feature
56
    virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat ) = 0;
56
    virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ) = 0;
57 57
    //! called when the map is drawn and labels should be placed
58 58
    virtual void drawLabeling( QgsRenderContext& context ) = 0;
59 59
    //! called when we're done with rendering