QGIS API Documentation  2.15.0-Master (af20121)
qgsvectorlayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayer.cpp
3  --------------------
4  begin : Oct 29, 2003
5  copyright : (C) 2003 by Gary E.Sherman
6  email : sherman at mrcc.com
7 
8  This class implements a generic means to display vector layers. The features
9  and attributes are read from the data store using a "data provider" plugin.
10  QgsVectorLayer can be used with any data store for which an appropriate
11  plugin is available.
12 
13 ***************************************************************************/
14 
15 /***************************************************************************
16  * *
17  * This program is free software; you can redistribute it and/or modify *
18  * it under the terms of the GNU General Public License as published by *
19  * the Free Software Foundation; either version 2 of the License, or *
20  * (at your option) any later version. *
21  * *
22  ***************************************************************************/
23 
24 #include <limits>
25 
26 #include <QImage>
27 #include <QPainter>
28 #include <QPainterPath>
29 #include <QPolygonF>
30 #include <QProgressDialog>
31 #include <QSettings>
32 #include <QString>
33 #include <QDomNode>
34 #include <QVector>
35 
36 #include "qgsvectorlayer.h"
37 #include "qgsactionmanager.h"
38 #include "qgis.h" //for globals
39 #include "qgsapplication.h"
40 #include "qgsclipper.h"
41 #include "qgsconditionalstyle.h"
43 #include "qgscoordinatetransform.h"
44 #include "qgscurvev2.h"
45 #include "qgsdatasourceuri.h"
47 #include "qgsfeature.h"
48 #include "qgsfeaturerequest.h"
49 #include "qgsfield.h"
50 #include "qgsgeometrycache.h"
51 #include "qgsgeometry.h"
52 #include "qgslabel.h"
53 #include "qgslegacyhelpers.h"
54 #include "qgslogger.h"
55 #include "qgsmaplayerlegend.h"
56 #include "qgsmaplayerregistry.h"
57 #include "qgsmaptopixel.h"
58 #include "qgsmessagelog.h"
59 #include "qgsogcutils.h"
60 #include "qgspoint.h"
61 #include "qgsproject.h"
62 #include "qgsproviderregistry.h"
63 #include "qgsrectangle.h"
64 #include "qgsrelationmanager.h"
65 #include "qgsrendercontext.h"
66 #include "qgsvectordataprovider.h"
72 #include "qgsvectorlayerlabeling.h"
73 #include "qgsvectorlayerrenderer.h"
75 #include "qgspointv2.h"
76 #include "qgsrendererv2.h"
77 #include "qgssymbolv2.h"
78 #include "qgssymbollayerv2.h"
80 #include "qgsdiagramrendererv2.h"
81 #include "qgsstylev2.h"
83 #include "qgspallabeling.h"
84 #include "qgssimplifymethod.h"
85 #include "qgsexpressioncontext.h"
86 
87 #include "diagram/qgsdiagram.h"
88 
89 #ifdef TESTPROVIDERLIB
90 #include <dlfcn.h>
91 #endif
92 
93 typedef bool saveStyle_t(
94  const QString& uri,
95  const QString& qmlStyle,
96  const QString& sldStyle,
97  const QString& styleName,
98  const QString& styleDescription,
99  const QString& uiFileContent,
100  bool useAsDefault,
101  QString& errCause
102 );
103 
105  const QString& uri,
106  QString& errCause
107 );
108 
109 typedef int listStyles_t(
110  const QString& uri,
111  QStringList &ids,
112  QStringList &names,
113  QStringList &descriptions,
114  QString& errCause
115 );
116 
118  const QString& uri,
119  QString styleID,
120  QString& errCause
121 );
122 
123 QgsVectorLayer::QgsVectorLayer( const QString& vectorLayerPath,
124  const QString& baseName,
125  const QString& providerKey,
126  bool loadDefaultStyleFlag )
127  : QgsMapLayer( VectorLayer, baseName, vectorLayerPath )
128  , mDataProvider( nullptr )
129  , mProviderKey( providerKey )
130  , mReadOnly( false )
131  , mEditFormConfig( new QgsEditFormConfig( this ) )
132  , mWkbType( QGis::WKBUnknown )
133  , mRendererV2( nullptr )
134  , mLabel( nullptr )
135  , mLabelOn( false )
136  , mLabeling( new QgsVectorLayerSimpleLabeling )
137  , mLabelFontNotFoundNotified( false )
138  , mFeatureBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal feature blending
139  , mLayerTransparency( 0 )
140  , mVertexMarkerOnlyForSelection( false )
141  , mCache( new QgsGeometryCache() )
142  , mEditBuffer( nullptr )
143  , mJoinBuffer( nullptr )
144  , mExpressionFieldBuffer( nullptr )
145  , mDiagramRenderer( nullptr )
146  , mDiagramLayerSettings( nullptr )
147  , mValidExtent( false )
148  , mLazyExtent( true )
149  , mSymbolFeatureCounted( false )
150  , mEditCommandActive( false )
151 
152 {
153  mActions = new QgsActionManager( this );
154  mConditionalStyles = new QgsConditionalLayerStyles();
155 
156  // if we're given a provider type, try to create and bind one to this layer
157  if ( ! mProviderKey.isEmpty() )
158  {
159  setDataSource( vectorLayerPath, baseName, providerKey, loadDefaultStyleFlag );
160  }
161 
162  connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( selectionChanged() ) );
163  connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( repaintRequested() ) );
164 
165  // Default simplify drawing settings
166  QSettings settings;
167  mSimplifyMethod.setSimplifyHints( static_cast< QgsVectorSimplifyMethod::SimplifyHints >( settings.value( "/qgis/simplifyDrawingHints", static_cast< int>( mSimplifyMethod.simplifyHints() ) ).toInt() ) );
168  mSimplifyMethod.setThreshold( settings.value( "/qgis/simplifyDrawingTol", mSimplifyMethod.threshold() ).toFloat() );
169  mSimplifyMethod.setForceLocalOptimization( settings.value( "/qgis/simplifyLocal", mSimplifyMethod.forceLocalOptimization() ).toBool() );
170  mSimplifyMethod.setMaximumScale( settings.value( "/qgis/simplifyMaxScale", mSimplifyMethod.maximumScale() ).toFloat() );
171 } // QgsVectorLayer ctor
172 
173 
174 
176 {
177  QgsDebugMsg( "entered." );
178 
179  emit layerDeleted();
180 
181  mValid = false;
182 
183  delete mDataProvider;
184  delete mEditBuffer;
185  delete mJoinBuffer;
186  delete mExpressionFieldBuffer;
187  delete mCache;
188  delete mLabel; // old deprecated implementation
189  delete mLabeling;
190  delete mDiagramLayerSettings;
191  delete mDiagramRenderer;
192 
193  delete mActions;
194 
195  delete mRendererV2;
196  delete mConditionalStyles;
197 }
198 
200 {
201  if ( mDataProvider )
202  {
203  return mDataProvider->storageType();
204  }
205  return nullptr;
206 }
207 
208 
210 {
211  if ( mDataProvider )
212  {
213  return mDataProvider->capabilitiesString();
214  }
215  return nullptr;
216 }
217 
219 {
220  if ( mDataProvider )
221  {
222  return mDataProvider->dataComment();
223  }
224  return QString();
225 }
226 
227 
229 {
230  return mProviderKey;
231 }
232 
237 {
238  if ( !hasGeometryType() )
239  return;
240 
241  // If fldName is provided, use it as the display field, otherwise
242  // determine the field index for the feature column of the identify
243  // dialog. We look for fields containing "name" first and second for
244  // fields containing "id". If neither are found, the first field
245  // is used as the node.
246  QString idxName = "";
247  QString idxId = "";
248 
249  if ( !fldName.isEmpty() )
250  {
251  mDisplayField = fldName;
252  }
253  else
254  {
255  int fieldsSize = mUpdatedFields.size();
256 
257  Q_FOREACH ( const QgsField& field, mUpdatedFields )
258  {
259  QString fldName = field.name();
260  QgsDebugMsg( "Checking field " + fldName + " of " + QString::number( fieldsSize ) + " total" );
261 
262  // Check the fields and keep the first one that matches.
263  // We assume that the user has organized the data with the
264  // more "interesting" field names first. As such, name should
265  // be selected before oldname, othername, etc.
266  if ( fldName.indexOf( "name", 0, Qt::CaseInsensitive ) > -1 )
267  {
268  if ( idxName.isEmpty() )
269  {
270  idxName = fldName;
271  }
272  }
273  if ( fldName.indexOf( "descrip", 0, Qt::CaseInsensitive ) > -1 )
274  {
275  if ( idxName.isEmpty() )
276  {
277  idxName = fldName;
278  }
279  }
280  if ( fldName.indexOf( "id", 0, Qt::CaseInsensitive ) > -1 )
281  {
282  if ( idxId.isEmpty() )
283  {
284  idxId = fldName;
285  }
286  }
287  }
288 
289  //if there were no fields in the dbf just return - otherwise qgis segfaults!
290  if ( fieldsSize == 0 )
291  return;
292 
293  if ( idxName.length() > 0 )
294  {
295  mDisplayField = idxName;
296  }
297  else
298  {
299  if ( idxId.length() > 0 )
300  {
301  mDisplayField = idxId;
302  }
303  else
304  {
305  mDisplayField = mUpdatedFields.at( 0 ).name();
306  }
307  }
308 
309  }
310 }
311 
312 // NOTE this is a temporary method added by Tim to prevent label clipping
313 // which was occurring when labeller was called in the main draw loop
314 // This method will probably be removed again in the near future!
316 {
317  if ( !hasGeometryType() )
318  return;
319 
320  QgsDebugMsg( "Starting draw of labels: " + id() );
321 
322  if ( mRendererV2 && mLabelOn && mLabel &&
323  mLabel->isInScaleRange( rendererContext.rendererScale() ) )
324  {
325  QgsAttributeList attributes;
326  Q_FOREACH ( const QString& attrName, mRendererV2->usedAttributes() )
327  {
328  int attrNum = fieldNameIndex( attrName );
329  attributes.append( attrNum );
330  }
331  // make sure the renderer is ready for classification ("symbolForFeature")
332  mRendererV2->startRender( rendererContext, fields() );
333 
334  // Add fields required for labels
335  mLabel->addRequiredFields( attributes );
336 
337  QgsDebugMsg( "Selecting features based on view extent" );
338 
339  int featureCount = 0;
340 
341  try
342  {
343  // select the records in the extent. The provider sets a spatial filter
344  // and sets up the selection set for retrieval
346  .setFilterRect( rendererContext.extent() )
347  .setSubsetOfAttributes( attributes ) );
348 
349  QgsFeature fet;
350  while ( fit.nextFeature( fet ) )
351  {
352  if ( mRendererV2->willRenderFeature( fet, rendererContext ) )
353  {
354  bool sel = mSelectedFeatureIds.contains( fet.id() );
355  mLabel->renderLabel( rendererContext, fet, sel, nullptr );
356  }
357  featureCount++;
358  }
359  }
360  catch ( QgsCsException &e )
361  {
362  Q_UNUSED( e );
363  QgsDebugMsg( "Error projecting label locations" );
364  }
365 
366  if ( mRendererV2 )
367  {
368  mRendererV2->stopRender( rendererContext );
369  }
370 
371  QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
372  }
373 }
374 
376 {
377  if ( mDataProvider )
378  {
379  mDataProvider->reloadData();
380  updateFields();
381  }
382 }
383 
385 {
386  return new QgsVectorLayerRenderer( this, rendererContext );
387 }
388 
389 bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
390 {
391  QgsVectorLayerRenderer renderer( this, rendererContext );
392  return renderer.render();
393 }
394 
396 {
398  {
399  p.setPen( QColor( 50, 100, 120, 200 ) );
400  p.setBrush( QColor( 200, 200, 210, 120 ) );
401  p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
402  }
403  else if ( type == QgsVectorLayer::Cross )
404  {
405  p.setPen( QColor( 255, 0, 0 ) );
406  p.drawLine( x - m, y + m, x + m, y - m );
407  p.drawLine( x - m, y - m, x + m, y + m );
408  }
409 }
410 
412 {
413  mSelectedFeatureIds.insert( fid );
414 
415  emit selectionChanged( QgsFeatureIds() << fid, QgsFeatureIds(), false );
416 }
417 
418 void QgsVectorLayer::select( const QgsFeatureIds& featureIds )
419 {
420  mSelectedFeatureIds.unite( featureIds );
421 
422  emit selectionChanged( featureIds, QgsFeatureIds(), false );
423 }
424 
426 {
427  mSelectedFeatureIds.remove( fid );
428 
429  emit selectionChanged( QgsFeatureIds(), QgsFeatureIds() << fid, false );
430 }
431 
432 void QgsVectorLayer::deselect( const QgsFeatureIds& featureIds )
433 {
434  mSelectedFeatureIds.subtract( featureIds );
435 
436  emit selectionChanged( QgsFeatureIds(), featureIds, false );
437 }
438 
439 void QgsVectorLayer::select( QgsRectangle & rect, bool addToSelection )
440 {
441  selectByRect( rect, addToSelection ? AddToSelection : SetSelection );
442 }
443 
445 {
446  // normalize the rectangle
447  rect.normalize();
448 
449  QgsFeatureIds newSelection;
450 
452  .setFilterRect( rect )
454  .setSubsetOfAttributes( QgsAttributeList() ) );
455 
456  QgsFeature feat;
457  while ( features.nextFeature( feat ) )
458  {
459  newSelection << feat.id();
460  }
461  features.close();
462 
463  selectByIds( newSelection, behaviour );
464 }
465 
467 {
468  QgsFeatureIds newSelection;
469 
470  QgsExpressionContext context;
474 
475  if ( behaviour == SetSelection || behaviour == AddToSelection )
476  {
478  .setExpressionContext( context )
481 
482  QgsFeatureIterator features = getFeatures( request );
483 
484  if ( behaviour == AddToSelection )
485  {
486  newSelection = selectedFeaturesIds();
487  }
488  QgsFeature feat;
489  while ( features.nextFeature( feat ) )
490  {
491  newSelection << feat.id();
492  }
493  features.close();
494  }
495  else if ( behaviour == IntersectSelection || behaviour == RemoveFromSelection )
496  {
497  QgsExpression exp( expression );
498  exp.prepare( &context );
499 
500  QgsFeatureIds oldSelection = selectedFeaturesIds();
501  QgsFeatureRequest request = QgsFeatureRequest().setFilterFids( oldSelection );
502 
503  //refine request
504  if ( !exp.needsGeometry() )
506  request.setSubsetOfAttributes( exp.referencedColumns(), fields() );
507 
508  QgsFeatureIterator features = getFeatures( request );
509  QgsFeature feat;
510  while ( features.nextFeature( feat ) )
511  {
512  context.setFeature( feat );
513  bool matches = exp.evaluate( &context ).toBool();
514 
515  if ( matches && behaviour == IntersectSelection )
516  {
517  newSelection << feat.id();
518  }
519  else if ( !matches && behaviour == RemoveFromSelection )
520  {
521  newSelection << feat.id();
522  }
523  }
524  }
525 
526  selectByIds( newSelection );
527 }
528 
530 {
531  QgsFeatureIds newSelection;
532 
533  switch ( behaviour )
534  {
535  case SetSelection:
536  newSelection = ids;
537  break;
538 
539  case AddToSelection:
540  newSelection = mSelectedFeatureIds + ids;
541  break;
542 
543  case RemoveFromSelection:
544  newSelection = mSelectedFeatureIds - ids;
545  break;
546 
547  case IntersectSelection:
548  newSelection = mSelectedFeatureIds.intersect( ids );
549  break;
550  }
551 
552  QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - newSelection;
553  mSelectedFeatureIds = newSelection;
554 
555  emit selectionChanged( newSelection, deselectedFeatures, true );
556 }
557 
559 {
560  QgsFeatureIds intersectingIds = selectIds & deselectIds;
561  if ( !intersectingIds.isEmpty() )
562  {
563  QgsDebugMsg( "Trying to select and deselect the same item at the same time. Unsure what to do. Selecting dubious items." );
564  }
565 
566  mSelectedFeatureIds -= deselectIds;
567  mSelectedFeatureIds += selectIds;
568 
569  emit selectionChanged( selectIds, deselectIds - intersectingIds, false );
570 }
571 
573 {
575  ids.subtract( mSelectedFeatureIds );
576  selectByIds( ids );
577 }
578 
580 {
582 }
583 
585 {
587  .setFlags( QgsFeatureRequest::NoGeometry )
588  .setSubsetOfAttributes( QgsAttributeList() ) );
589 
590  QgsFeatureIds ids;
591 
592  QgsFeature fet;
593  while ( fit.nextFeature( fet ) )
594  {
595  ids << fet.id();
596  }
597 
598  return ids;
599 }
600 
602 {
603  // normalize the rectangle
604  rect.normalize();
605 
607  .setFilterRect( rect )
609  .setSubsetOfAttributes( QgsAttributeList() ) );
610 
611  QgsFeatureIds selectIds;
612  QgsFeatureIds deselectIds;
613 
614  QgsFeature fet;
615  while ( fit.nextFeature( fet ) )
616  {
617  if ( mSelectedFeatureIds.contains( fet.id() ) )
618  {
619  deselectIds << fet.id();
620  }
621  else
622  {
623  selectIds << fet.id();
624  }
625  }
626 
627  modifySelection( selectIds, deselectIds );
628 }
629 
631 {
632  if ( mSelectedFeatureIds.isEmpty() )
633  return;
634 
636 }
637 
639 {
640  return mDataProvider;
641 }
642 
644 {
645  return mDataProvider;
646 }
647 
649 {
650  if ( mValid && mDataProvider && mDataProvider->encoding() != encoding )
651  {
652  mDataProvider->setEncoding( encoding );
653  updateFields();
654  }
655 }
656 
658 {
659  delete mDiagramRenderer;
660  mDiagramRenderer = r;
661  emit rendererChanged();
662 }
663 
665 {
666  if ( mValid && mDataProvider )
667  {
668  QGis::WkbType type = mDataProvider->geometryType();
669  return static_cast< QGis::GeometryType >( QgsWKBTypes::geometryType( static_cast< QgsWKBTypes::Type >( type ) ) );
670  }
671  else
672  {
673  QgsDebugMsg( "invalid layer or pointer to mDataProvider is null" );
674  }
675 
676  // We shouldn't get here, and if we have, other things are likely to
677  // go wrong. Code that uses the type() return value should be
678  // rewritten to cope with a value of QGis::Unknown. To make this
679  // need known, the following message is printed every time we get
680  // here.
681  QgsDebugMsg( "WARNING: This code should never be reached. Problems may occur..." );
682 
683  return QGis::UnknownGeometry;
684 }
685 
687 {
689  return t != QGis::NoGeometry && t != QGis::UnknownGeometry;
690 }
691 
693 {
694  return mWkbType;
695 }
696 
698 {
699  if ( !mValid || mSelectedFeatureIds.isEmpty() ) //no selected features
700  {
701  return QgsRectangle( 0, 0, 0, 0 );
702  }
703 
704  QgsRectangle r, retval;
705  retval.setMinimal();
706 
707  QgsFeature fet;
708  if ( mDataProvider->capabilities() & QgsVectorDataProvider::SelectAtId )
709  {
711  .setFilterFids( mSelectedFeatureIds )
712  .setSubsetOfAttributes( QgsAttributeList() ) );
713 
714  while ( fit.nextFeature( fet ) )
715  {
716  if ( !fet.constGeometry() || fet.constGeometry()->isEmpty() )
717  continue;
718  r = fet.constGeometry()->boundingBox();
719  retval.combineExtentWith( &r );
720  }
721  }
722  else
723  {
725  .setSubsetOfAttributes( QgsAttributeList() ) );
726 
727  while ( fit.nextFeature( fet ) )
728  {
729  if ( mSelectedFeatureIds.contains( fet.id() ) )
730  {
731  if ( fet.constGeometry() )
732  {
733  r = fet.constGeometry()->boundingBox();
734  retval.combineExtentWith( &r );
735  }
736  }
737  }
738  }
739 
740  if ( retval.width() == 0.0 || retval.height() == 0.0 )
741  {
742  // If all of the features are at the one point, buffer the
743  // rectangle a bit. If they are all at zero, do something a bit
744  // more crude.
745 
746  if ( retval.xMinimum() == 0.0 && retval.xMaximum() == 0.0 &&
747  retval.yMinimum() == 0.0 && retval.yMaximum() == 0.0 )
748  {
749  retval.set( -1.0, -1.0, 1.0, 1.0 );
750  }
751  }
752 
753  return retval;
754 }
755 
757 {
758  if ( !mLabeling )
759  return false;
760 
761  // for simple labeling the mode can be "no labels" - so we need to check
762  // in properties whether we are really enabled or not
763  if ( mLabeling->type() == "simple" )
764  return customProperty( "labeling/enabled", QVariant( false ) ).toBool();
765 
766  // for other labeling implementations we always assume that labeling is enabled
767  return true;
768 }
769 
771 {
772  if ( !mDiagramRenderer || !mDiagramLayerSettings )
773  return false;
774 
775  QList<QgsDiagramSettings> settingList = mDiagramRenderer->diagramSettings();
776  if ( !settingList.isEmpty() )
777  {
778  return settingList.at( 0 ).enabled;
779  }
780  return false;
781 }
782 
784 {
785  if ( !mSymbolFeatureCounted )
786  return -1;
787 
788  return mSymbolFeatureCountMap.value( symbol );
789 }
790 
795 {
796  public:
797 
800  : mDialog( dialog )
801  {
802  }
803 
804  virtual bool mustStop() const
805  {
806  if ( mDialog->isVisible() )
807  {
808  // So that we get a chance of hitting the Abort button
809 #ifdef Q_OS_LINUX
810  // For some reason on Windows hasPendingEvents() always return true,
811  // but one iteration is actually enough on Windows to get good interactivity
812  // whereas on Linux we must allow for far more iterations.
813  // For safety limit the number of iterations
814  int nIters = 0;
815  while ( QCoreApplication::hasPendingEvents() && ++nIters < 100 )
816 #endif
817  {
819  }
820  return mDialog->wasCanceled();
821  }
822  return false;
823  }
824 
825  private:
826  QProgressDialog* mDialog;
827 };
828 
829 bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
830 {
831  if ( mSymbolFeatureCounted )
832  return true;
833 
834  mSymbolFeatureCountMap.clear();
835 
836  if ( !mValid )
837  {
838  QgsDebugMsg( "invoked with invalid layer" );
839  return false;
840  }
841  if ( !mDataProvider )
842  {
843  QgsDebugMsg( "invoked with null mDataProvider" );
844  return false;
845  }
846  if ( !mRendererV2 )
847  {
848  QgsDebugMsg( "invoked with null mRendererV2" );
849  return false;
850  }
851 
852  QgsLegendSymbolList symbolList = mRendererV2->legendSymbolItems();
853  QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
854 
855  for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
856  {
857  mSymbolFeatureCountMap.insert( symbolIt->second, 0 );
858  }
859 
860  long nFeatures = featureCount();
861 
862  QWidget* mainWindow = nullptr;
863  Q_FOREACH ( QWidget* widget, qApp->topLevelWidgets() )
864  {
865  if ( widget->objectName() == "QgisApp" )
866  {
867  mainWindow = widget;
868  break;
869  }
870  }
871 
872  QProgressDialog progressDialog( tr( "Updating feature count for layer %1" ).arg( name() ), tr( "Abort" ), 0, nFeatures, mainWindow );
873  progressDialog.setWindowTitle( tr( "QGIS" ) );
874  progressDialog.setWindowModality( Qt::WindowModal );
875  if ( showProgress )
876  {
877  // Properly initialize to 0 as recommended in doc so that the evaluation
878  // of the total time properly works
879  progressDialog.setValue( 0 );
880  }
881  int featuresCounted = 0;
882 
884  QgsVectorLayerInterruptionCheckerDuringCountSymbolFeatures interruptionCheck( &progressDialog );
885  if ( showProgress )
886  {
887  fit.setInterruptionChecker( &interruptionCheck );
888  }
889 
890  // Renderer (rule based) may depend on context scale, with scale is ignored if 0
891  QgsRenderContext renderContext;
892  renderContext.setRendererScale( 0 );
896 
897  mRendererV2->startRender( renderContext, fields() );
898 
899  QgsFeature f;
900  QTime time;
901  time.start();
902  while ( fit.nextFeature( f ) )
903  {
904  renderContext.expressionContext().setFeature( f );
905  QgsSymbolV2List featureSymbolList = mRendererV2->originalSymbolsForFeature( f, renderContext );
906  for ( QgsSymbolV2List::iterator symbolIt = featureSymbolList.begin(); symbolIt != featureSymbolList.end(); ++symbolIt )
907  {
908  mSymbolFeatureCountMap[*symbolIt] += 1;
909  }
910  ++featuresCounted;
911 
912  if ( showProgress )
913  {
914  // Refresh progress every 50 features or second
915  if (( featuresCounted % 50 == 0 ) || time.elapsed() > 1000 )
916  {
917  time.restart();
918  if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
919  {
920  progressDialog.setMaximum( 0 );
921  }
922  progressDialog.setValue( featuresCounted );
923  }
924  // So that we get a chance of hitting the Abort button
925 #ifdef Q_OS_LINUX
926  // For some reason on Windows hasPendingEvents() always return true,
927  // but one iteration is actually enough on Windows to get good interactivity
928  // whereas on Linux we must allow for far more iterations.
929  // For safety limit the number of iterations
930  int nIters = 0;
931  while ( QCoreApplication::hasPendingEvents() && ++nIters < 100 )
932 #endif
933  {
935  }
936  if ( progressDialog.wasCanceled() )
937  {
938  mSymbolFeatureCountMap.clear();
939  mRendererV2->stopRender( renderContext );
940  return false;
941  }
942  }
943  }
944  mRendererV2->stopRender( renderContext );
945  progressDialog.setValue( nFeatures );
946  mSymbolFeatureCounted = true;
947  return true;
948 }
949 
951 {
952  mValidExtent = false;
953 }
954 
956 {
958  mValidExtent = true;
959 }
960 
962 {
963  QgsRectangle rect;
964  rect.setMinimal();
965 
966  if ( !hasGeometryType() )
967  return rect;
968 
969  if ( !mValidExtent && mLazyExtent && mDataProvider )
970  {
971  // get the extent
972  QgsRectangle mbr = mDataProvider->extent();
973 
974  // show the extent
975  QgsDebugMsg( "Extent of layer: " + mbr.toString() );
976  // store the extent
977  setExtent( mbr );
978 
979  mLazyExtent = false;
980  }
981 
982  if ( mValidExtent )
983  return QgsMapLayer::extent();
984 
985  if ( !mValid || !mDataProvider )
986  {
987  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
988  return rect;
989  }
990 
991  if ( !mEditBuffer ||
992  ( mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mChangedGeometries.isEmpty() ) ||
993  QgsDataSourceURI( mDataProvider->dataSourceUri() ).useEstimatedMetadata() )
994  {
995  mDataProvider->updateExtents();
996 
997  // get the extent of the layer from the provider
998  // but only when there are some features already
999  if ( mDataProvider->featureCount() != 0 )
1000  {
1001  QgsRectangle r = mDataProvider->extent();
1002  rect.combineExtentWith( &r );
1003  }
1004 
1005  if ( mEditBuffer )
1006  {
1007  for ( QgsFeatureMap::const_iterator it = mEditBuffer->mAddedFeatures.constBegin(); it != mEditBuffer->mAddedFeatures.constEnd(); ++it )
1008  {
1009  if ( it->constGeometry() )
1010  {
1011  QgsRectangle r = it->constGeometry()->boundingBox();
1012  rect.combineExtentWith( &r );
1013  }
1014  }
1015  }
1016  }
1017  else
1018  {
1020  .setSubsetOfAttributes( QgsAttributeList() ) );
1021 
1022  QgsFeature fet;
1023  while ( fit.nextFeature( fet ) )
1024  {
1025  if ( fet.constGeometry() && fet.constGeometry()->type() != QGis::UnknownGeometry )
1026  {
1027  QgsRectangle bb = fet.constGeometry()->boundingBox();
1028  rect.combineExtentWith( &bb );
1029  }
1030  }
1031  }
1032 
1033  if ( rect.xMinimum() > rect.xMaximum() && rect.yMinimum() > rect.yMaximum() )
1034  {
1035  // special case when there are no features in provider nor any added
1036  rect = QgsRectangle(); // use rectangle with zero coordinates
1037  }
1038 
1039  setExtent( rect );
1040 
1041  // Send this (hopefully) up the chain to the map canvas
1042  emit recalculateExtents();
1043 
1044  return rect;
1045 }
1046 
1048 {
1049  if ( !mValid || !mDataProvider )
1050  {
1051  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
1052  return nullptr;
1053  }
1054  return mDataProvider->subsetString();
1055 }
1056 
1058 {
1059  if ( !mValid || !mDataProvider )
1060  {
1061  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
1062  return false;
1063  }
1064 
1065  bool res = mDataProvider->setSubsetString( subset );
1066 
1067  // get the updated data source string from the provider
1068  mDataSource = mDataProvider->dataSourceUri();
1069  updateExtents();
1070  updateFields();
1071 
1072  if ( res )
1073  emit repaintRequested();
1074 
1075  return res;
1076 }
1077 
1079 {
1080  if ( mValid && mDataProvider && !mEditBuffer && ( hasGeometryType() && geometryType() != QGis::Point ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && renderContext.useRenderingOptimization() )
1081  {
1082  double maximumSimplificationScale = mSimplifyMethod.maximumScale();
1083 
1084  // check maximum scale at which generalisation should be carried out
1085  if ( maximumSimplificationScale > 1 && renderContext.rendererScale() <= maximumSimplificationScale )
1086  return false;
1087 
1088  return true;
1089  }
1090  return false;
1091 }
1092 
1094 {
1095  return mConditionalStyles;
1096 }
1097 
1099 {
1100  if ( !mValid || !mDataProvider )
1101  return QgsFeatureIterator();
1102 
1103  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( new QgsVectorLayerFeatureSource( this ), true, request ) );
1104 }
1105 
1106 
1107 bool QgsVectorLayer::addFeature( QgsFeature& f, bool alsoUpdateExtent )
1108 {
1109  Q_UNUSED( alsoUpdateExtent ); // TODO[MD]
1110  if ( !mValid || !mEditBuffer || !mDataProvider )
1111  return false;
1112 
1113  bool success = mEditBuffer->addFeature( f );
1114 
1115  if ( success )
1116  updateExtents();
1117 
1118  return success;
1119 }
1120 
1122 {
1123  QgsFeatureRequest req;
1124  req.setFilterFid( f.id() );
1125  if ( !f.constGeometry() )
1127  if ( f.attributes().isEmpty() )
1129 
1130  QgsFeature current;
1131  if ( !getFeatures( req ).nextFeature( current ) )
1132  {
1133  QgsDebugMsg( QString( "feature %1 could not be retrieved" ).arg( f.id() ) );
1134  return false;
1135  }
1136 
1137  if ( f.constGeometry() && current.constGeometry() && f.constGeometry() != current.constGeometry() && !f.constGeometry()->isGeosEqual( *current.constGeometry() ) )
1138  {
1139  if ( !changeGeometry( f.id(), f.geometry() ) )
1140  {
1141  QgsDebugMsg( QString( "geometry of feature %1 could not be changed." ).arg( f.id() ) );
1142  return false;
1143  }
1144  }
1145 
1146  QgsAttributes fa = f.attributes();
1147  QgsAttributes ca = current.attributes();
1148 
1149  for ( int attr = 0; attr < fa.count(); ++attr )
1150  {
1151  if ( fa.at( attr ) != ca.at( attr ) )
1152  {
1153  if ( !changeAttributeValue( f.id(), attr, fa.at( attr ), ca.at( attr ) ) )
1154  {
1155  QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( f.id() ) );
1156  return false;
1157  }
1158  }
1159  }
1160 
1161  return true;
1162 }
1163 
1164 
1165 bool QgsVectorLayer::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
1166 {
1167  if ( !mValid || !mEditBuffer || !mDataProvider )
1168  return false;
1169 
1170  QgsVectorLayerEditUtils utils( this );
1171  bool result = utils.insertVertex( x, y, atFeatureId, beforeVertex );
1172  if ( result )
1173  updateExtents();
1174  return result;
1175 }
1176 
1177 
1178 bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
1179 {
1180  if ( !mValid || !mEditBuffer || !mDataProvider )
1181  return false;
1182 
1183  QgsVectorLayerEditUtils utils( this );
1184  bool result = utils.moveVertex( x, y, atFeatureId, atVertex );
1185 
1186  if ( result )
1187  updateExtents();
1188  return result;
1189 }
1190 
1191 bool QgsVectorLayer::moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex )
1192 {
1193  if ( !mValid || !mEditBuffer || !mDataProvider )
1194  return false;
1195 
1196  QgsVectorLayerEditUtils utils( this );
1197  bool result = utils.moveVertex( p, atFeatureId, atVertex );
1198 
1199  if ( result )
1200  updateExtents();
1201  return result;
1202 }
1203 
1204 bool QgsVectorLayer::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
1205 {
1206  QgsVectorLayer::EditResult res = deleteVertexV2( atFeatureId, atVertex );
1207  bool result = ( res == QgsVectorLayer::Success || res == QgsVectorLayer::EmptyGeometry );
1208 
1209  if ( result )
1210  updateExtents();
1211  return result;
1212 }
1213 
1215 {
1216  if ( !mValid || !mEditBuffer || !mDataProvider )
1218 
1219  QgsVectorLayerEditUtils utils( this );
1220  EditResult result = utils.deleteVertexV2( featureId, vertex );
1221 
1222  if ( result == Success )
1223  updateExtents();
1224  return result;
1225 }
1226 
1227 
1229 {
1230  if ( !mValid || !mDataProvider || !( mDataProvider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
1231  {
1232  return false;
1233  }
1234 
1235  if ( !isEditable() )
1236  {
1237  return false;
1238  }
1239 
1240  int deleted = 0;
1241  int count = mSelectedFeatureIds.size();
1242  // Make a copy since deleteFeature modifies mSelectedFeatureIds
1243  QgsFeatureIds selectedFeatures( mSelectedFeatureIds );
1244  Q_FOREACH ( QgsFeatureId fid, selectedFeatures )
1245  {
1246  deleted += deleteFeature( fid ); // removes from selection
1247  }
1248 
1249  triggerRepaint();
1250  updateExtents();
1251 
1252  if ( deletedCount )
1253  {
1254  *deletedCount = deleted;
1255  }
1256 
1257  return deleted == count;
1258 }
1259 
1261 {
1262  if ( !mValid || !mEditBuffer || !mDataProvider )
1263  return 6;
1264 
1265  QgsVectorLayerEditUtils utils( this );
1266  int result = 5;
1267 
1268  //first try with selected features
1269  if ( !mSelectedFeatureIds.isEmpty() )
1270  {
1271  result = utils.addRing( ring, mSelectedFeatureIds, featureId );
1272  }
1273 
1274  if ( result != 0 )
1275  {
1276  //try with all intersecting features
1277  result = utils.addRing( ring, QgsFeatureIds(), featureId );
1278  }
1279 
1280  return result;
1281 }
1282 
1284 {
1285  if ( !mValid || !mEditBuffer || !mDataProvider )
1286  {
1287  delete ring;
1288  return 6;
1289  }
1290 
1291  if ( !ring )
1292  {
1293  return 1;
1294  }
1295 
1296  if ( !ring->isClosed() )
1297  {
1298  delete ring;
1299  return 2;
1300  }
1301 
1302  QgsVectorLayerEditUtils utils( this );
1303  int result = 5;
1304 
1305  //first try with selected features
1306  if ( !mSelectedFeatureIds.isEmpty() )
1307  {
1308  result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), mSelectedFeatureIds, featureId );
1309  }
1310 
1311  if ( result != 0 )
1312  {
1313  //try with all intersecting features
1314  result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), QgsFeatureIds(), featureId );
1315  }
1316 
1317  delete ring;
1318  return result;
1319 }
1320 
1322 {
1323  if ( !mValid || !mEditBuffer || !mDataProvider )
1324  return 7;
1325 
1326  //number of selected features must be 1
1327 
1328  if ( mSelectedFeatureIds.size() < 1 )
1329  {
1330  QgsDebugMsg( "Number of selected features <1" );
1331  return 4;
1332  }
1333  else if ( mSelectedFeatureIds.size() > 1 )
1334  {
1335  QgsDebugMsg( "Number of selected features >1" );
1336  return 5;
1337  }
1338 
1339  QgsVectorLayerEditUtils utils( this );
1340  int result = utils.addPart( points, *mSelectedFeatureIds.constBegin() );
1341 
1342  if ( result == 0 )
1343  updateExtents();
1344  return result;
1345 }
1346 
1348 {
1349  if ( !mValid || !mEditBuffer || !mDataProvider )
1350  return 7;
1351 
1352  //number of selected features must be 1
1353 
1354  if ( mSelectedFeatureIds.size() < 1 )
1355  {
1356  QgsDebugMsg( "Number of selected features <1" );
1357  return 4;
1358  }
1359  else if ( mSelectedFeatureIds.size() > 1 )
1360  {
1361  QgsDebugMsg( "Number of selected features >1" );
1362  return 5;
1363  }
1364 
1365  QgsVectorLayerEditUtils utils( this );
1366  int result = utils.addPart( points, *mSelectedFeatureIds.constBegin() );
1367 
1368  if ( result == 0 )
1369  updateExtents();
1370  return result;
1371 }
1372 
1374 {
1375  if ( !mValid || !mEditBuffer || !mDataProvider )
1376  return 7;
1377 
1378  //number of selected features must be 1
1379 
1380  if ( mSelectedFeatureIds.size() < 1 )
1381  {
1382  QgsDebugMsg( "Number of selected features <1" );
1383  return 4;
1384  }
1385  else if ( mSelectedFeatureIds.size() > 1 )
1386  {
1387  QgsDebugMsg( "Number of selected features >1" );
1388  return 5;
1389  }
1390 
1391  QgsVectorLayerEditUtils utils( this );
1392  int result = utils.addPart( ring, *mSelectedFeatureIds.constBegin() );
1393 
1394  if ( result == 0 )
1395  updateExtents();
1396  return result;
1397 }
1398 
1399 int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy )
1400 {
1401  if ( !mValid || !mEditBuffer || !mDataProvider )
1402  return -1;
1403 
1404  QgsVectorLayerEditUtils utils( this );
1405  int result = utils.translateFeature( featureId, dx, dy );
1406 
1407  if ( result == 0 )
1408  updateExtents();
1409  return result;
1410 }
1411 
1412 int QgsVectorLayer::splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1413 {
1414  if ( !mValid || !mEditBuffer || !mDataProvider )
1415  return -1;
1416 
1417  QgsVectorLayerEditUtils utils( this );
1418  return utils.splitParts( splitLine, topologicalEditing );
1419 }
1420 
1421 int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1422 {
1423  if ( !mValid || !mEditBuffer || !mDataProvider )
1424  return -1;
1425 
1426  QgsVectorLayerEditUtils utils( this );
1427  return utils.splitFeatures( splitLine, topologicalEditing );
1428 }
1429 
1431 {
1432  if ( !hasGeometryType() )
1433  return 1;
1434 
1435  int returnValue = 0;
1436 
1437  //first test if geom really has type polygon or multipolygon
1438  if ( geom->type() != QGis::Polygon )
1439  {
1440  return 1;
1441  }
1442 
1443  //get bounding box of geom
1444  QgsRectangle geomBBox = geom->boundingBox();
1445 
1446  //get list of features that intersect this bounding box
1448  .setFilterRect( geomBBox )
1450  .setSubsetOfAttributes( QgsAttributeList() ) );
1451 
1452  QgsFeature f;
1453  while ( fit.nextFeature( f ) )
1454  {
1455  if ( ignoreFeatures.contains( f.id() ) )
1456  {
1457  continue;
1458  }
1459 
1460  //call geometry->makeDifference for each feature
1461  const QgsGeometry *currentGeom = f.constGeometry();
1462  if ( currentGeom )
1463  {
1464  if ( geom->makeDifference( currentGeom ) != 0 )
1465  {
1466  returnValue = 2;
1467  }
1468  }
1469  }
1470 
1471  return returnValue;
1472 }
1473 
1475 {
1476  if ( !mValid || !mEditBuffer || !mDataProvider )
1477  return -1;
1478 
1479  QgsVectorLayerEditUtils utils( this );
1480  return utils.addTopologicalPoints( geom );
1481 }
1482 
1484 {
1485  if ( !mValid || !mEditBuffer || !mDataProvider )
1486  return -1;
1487 
1488  QgsVectorLayerEditUtils utils( this );
1489  return utils.addTopologicalPoints( p );
1490 }
1491 
1493 {
1494  return mLabel;
1495 }
1496 
1498 {
1499  return mLabel;
1500 }
1501 
1503 {
1504  mLabelOn = on;
1505 }
1506 
1508 {
1509  return mLabelOn;
1510 }
1511 
1513 {
1514  if ( mLabeling == labeling )
1515  return;
1516 
1517  delete mLabeling;
1518  mLabeling = labeling;
1519 }
1520 
1522 {
1523  if ( !mValid || !mDataProvider )
1524  {
1525  return false;
1526  }
1527 
1528  // allow editing if provider supports any of the capabilities
1529  if ( !( mDataProvider->capabilities() & QgsVectorDataProvider::EditingCapabilities ) )
1530  {
1531  return false;
1532  }
1533 
1534  if ( mReadOnly )
1535  {
1536  return false;
1537  }
1538 
1539  if ( mEditBuffer )
1540  {
1541  // editing already underway
1542  return false;
1543  }
1544 
1545  emit beforeEditingStarted();
1546 
1547  mDataProvider->enterUpdateMode();
1548 
1549  if ( mDataProvider->transaction() )
1550  {
1551  mEditBuffer = new QgsVectorLayerEditPassthrough( this );
1552  }
1553  else
1554  {
1555  mEditBuffer = new QgsVectorLayerEditBuffer( this );
1556  }
1557  // forward signals
1558  connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( invalidateSymbolCountedFlag() ) );
1559  connect( mEditBuffer, SIGNAL( layerModified() ), this, SIGNAL( layerModified() ) ); // TODO[MD]: necessary?
1560  //connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( triggerRepaint() ) ); // TODO[MD]: works well?
1561  connect( mEditBuffer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SIGNAL( featureAdded( QgsFeatureId ) ) );
1562  connect( mEditBuffer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( onFeatureDeleted( QgsFeatureId ) ) );
1563  connect( mEditBuffer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
1564  connect( mEditBuffer, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ), this, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ) );
1565  connect( mEditBuffer, SIGNAL( attributeAdded( int ) ), this, SIGNAL( attributeAdded( int ) ) );
1566  connect( mEditBuffer, SIGNAL( attributeDeleted( int ) ), this, SIGNAL( attributeDeleted( int ) ) );
1567 
1568  connect( mEditBuffer, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ),
1569  this, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ) );
1570 
1571  connect( mEditBuffer, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ),
1572  this, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ) );
1573 
1574  connect( mEditBuffer, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ), this, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ) );
1575  connect( mEditBuffer, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ), this, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ) );
1576 
1577  connect( mEditBuffer, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ),
1578  this, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ) );
1579 
1580  connect( mEditBuffer, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ),
1581  this, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ) );
1582 
1583  updateFields();
1584 
1585  emit editingStarted();
1586 
1587  return true;
1588 }
1589 
1590 bool QgsVectorLayer::readXml( const QDomNode& layer_node )
1591 {
1592  QgsDebugMsg( QString( "Datasource in QgsVectorLayer::readXml: " ) + mDataSource.toLocal8Bit().data() );
1593 
1594  //process provider key
1595  QDomNode pkeyNode = layer_node.namedItem( "provider" );
1596 
1597  if ( pkeyNode.isNull() )
1598  {
1599  mProviderKey = "";
1600  }
1601  else
1602  {
1603  QDomElement pkeyElt = pkeyNode.toElement();
1604  mProviderKey = pkeyElt.text();
1605  }
1606 
1607  // determine type of vector layer
1608  if ( !mProviderKey.isNull() )
1609  {
1610  // if the provider string isn't empty, then we successfully
1611  // got the stored provider
1612  }
1613  else if ( mDataSource.contains( "dbname=" ) )
1614  {
1615  mProviderKey = "postgres";
1616  }
1617  else
1618  {
1619  mProviderKey = "ogr";
1620  }
1621 
1622  if ( !setDataProvider( mProviderKey ) )
1623  {
1624  return false;
1625  }
1626 
1627  QDomElement mapLayerNode = layer_node.toElement();
1628  if ( mapLayerNode.attribute( "readOnly", "0" ).toInt() == 1 )
1629  mReadOnly = true;
1630 
1631  QDomElement pkeyElem = pkeyNode.toElement();
1632  if ( !pkeyElem.isNull() )
1633  {
1634  QString encodingString = pkeyElem.attribute( "encoding" );
1635  if ( !encodingString.isEmpty() )
1636  {
1637  mDataProvider->setEncoding( encodingString );
1638  }
1639  }
1640 
1641  //load vector joins
1642  if ( !mJoinBuffer )
1643  {
1644  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1645  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1646  }
1647  mJoinBuffer->readXml( layer_node );
1648 
1649  if ( !mExpressionFieldBuffer )
1650  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1651  mExpressionFieldBuffer->readXml( layer_node );
1652 
1653  updateFields();
1654  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1655 
1656  QDomNode prevExpNode = layer_node.namedItem( "previewExpression" );
1657 
1658  if ( prevExpNode.isNull() )
1659  {
1660  mDisplayExpression = "";
1661  }
1662  else
1663  {
1664  QDomElement prevExpElem = prevExpNode.toElement();
1665  mDisplayExpression = prevExpElem.text();
1666  }
1667 
1668  QString errorMsg;
1669  if ( !readSymbology( layer_node, errorMsg ) )
1670  {
1671  return false;
1672  }
1673 
1674  readStyleManager( layer_node );
1675 
1676 
1678 
1679  return mValid; // should be true if read successfully
1680 
1681 } // void QgsVectorLayer::readXml
1682 
1683 
1684 void QgsVectorLayer::setDataSource( const QString& dataSource, const QString& baseName, const QString& provider, bool loadDefaultStyleFlag )
1685 {
1686  QGis::GeometryType oldGeomType = geometryType();
1687 
1688  mDataSource = dataSource;
1689  mLayerName = capitaliseLayerName( baseName );
1691  setDataProvider( provider );
1692 
1693  if ( !mValid )
1694  return;
1695 
1696  // Always set crs
1698 
1699  // reset style if loading default style, style is missing, or geometry type has changed
1700  if ( !rendererV2() || !legend() || oldGeomType != geometryType() || loadDefaultStyleFlag )
1701  {
1702  // check if there is a default style / propertysheet defined
1703  // for this layer and if so apply it
1704  bool defaultLoadedFlag = false;
1705  if ( loadDefaultStyleFlag )
1706  {
1707  loadDefaultStyle( defaultLoadedFlag );
1708  }
1709 
1710  // if the default style failed to load or was disabled use some very basic defaults
1711  if ( !defaultLoadedFlag && hasGeometryType() )
1712  {
1713  // add single symbol renderer
1715  }
1716 
1718  }
1719 
1720  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1721  emit repaintRequested();
1722 }
1723 
1724 
1725 bool QgsVectorLayer::setDataProvider( QString const & provider )
1726 {
1727  mProviderKey = provider; // XXX is this necessary? Usually already set
1728  // XXX when execution gets here.
1729 
1730  //XXX - This was a dynamic cast but that kills the Windows
1731  // version big-time with an abnormal termination error
1732  delete mDataProvider;
1733  mDataProvider = ( QgsVectorDataProvider* )( QgsProviderRegistry::instance()->provider( provider, mDataSource ) );
1734  connect( mDataProvider, SIGNAL( raiseError( QString ) ), this, SIGNAL( raiseError( QString ) ) );
1735 
1736  if ( !mDataProvider )
1737  {
1738  QgsDebugMsg( " unable to get data provider" );
1739  return false;
1740  }
1741 
1742  QgsDebugMsg( "Instantiated the data provider plugin" );
1743 
1744  mValid = mDataProvider->isValid();
1745  if ( !mValid )
1746  {
1747  QgsDebugMsg( "Invalid provider plugin " + QString( mDataSource.toUtf8() ) );
1748  return false;
1749  }
1750 
1751  // TODO: Check if the provider has the capability to send fullExtentCalculated
1752  connect( mDataProvider, SIGNAL( fullExtentCalculated() ), this, SLOT( updateExtents() ) );
1753 
1754  // get and store the feature type
1755  mWkbType = mDataProvider->geometryType();
1756 
1757  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1758  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1759  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1760  updateFields();
1761 
1762  // look at the fields in the layer and set the primary
1763  // display field using some real fuzzy logic
1764  setDisplayField();
1765 
1766  if ( mProviderKey == "postgres" )
1767  {
1768  QgsDebugMsg( "Beautifying layer name " + name() );
1769 
1770  // adjust the display name for postgres layers
1771  QRegExp reg( "\"[^\"]+\"\\.\"([^\"]+)\"( \\([^)]+\\))?" );
1772  if ( reg.indexIn( name() ) >= 0 )
1773  {
1774  QStringList stuff = reg.capturedTexts();
1775  QString lName = stuff[1];
1776 
1778 
1780  for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
1781  ;
1782 
1783  if ( it != layers.constEnd() && stuff.size() > 2 )
1784  {
1785  lName += '.' + stuff[2].mid( 2, stuff[2].length() - 3 );
1786  }
1787 
1788  if ( !lName.isEmpty() )
1789  setLayerName( lName );
1790  }
1791 
1792  QgsDebugMsg( "Beautified layer name " + name() );
1793 
1794  // deal with unnecessary schema qualification to make v.in.ogr happy
1795  mDataSource = mDataProvider->dataSourceUri();
1796  }
1797  else if ( mProviderKey == "osm" )
1798  {
1799  // make sure that the "observer" has been removed from URI to avoid crashes
1800  mDataSource = mDataProvider->dataSourceUri();
1801  }
1802  else if ( provider == "ogr" )
1803  {
1804  // make sure that the /vsigzip or /vsizip is added to uri, if applicable
1805  mDataSource = mDataProvider->dataSourceUri();
1806  if ( mDataSource.right( 10 ) == "|layerid=0" )
1807  mDataSource.chop( 10 );
1808  }
1809 
1810  // label
1811  mLabel = new QgsLabel( mDataProvider->fields() );
1812  mLabelOn = false;
1813 
1814  connect( mDataProvider, SIGNAL( dataChanged() ), this, SIGNAL( dataChanged() ) );
1815  connect( mDataProvider, SIGNAL( dataChanged() ), this, SLOT( removeSelection() ) );
1816 
1817  return true;
1818 } // QgsVectorLayer:: setDataProvider
1819 
1820 
1821 
1822 
1823 /* virtual */
1825  QDomDocument & document )
1826 {
1827  // first get the layer element so that we can append the type attribute
1828 
1829  QDomElement mapLayerNode = layer_node.toElement();
1830 
1831  if ( mapLayerNode.isNull() || ( "maplayer" != mapLayerNode.nodeName() ) )
1832  {
1833  QgsDebugMsg( "can't find <maplayer>" );
1834  return false;
1835  }
1836 
1837  mapLayerNode.setAttribute( "type", "vector" );
1838 
1839  // set the geometry type
1840  mapLayerNode.setAttribute( "geometry", QGis::vectorGeometryType( geometryType() ) );
1841 
1842  // add provider node
1843  if ( mDataProvider )
1844  {
1845  QDomElement provider = document.createElement( "provider" );
1846  provider.setAttribute( "encoding", mDataProvider->encoding() );
1847  QDomText providerText = document.createTextNode( providerType() );
1848  provider.appendChild( providerText );
1849  layer_node.appendChild( provider );
1850  }
1851 
1852  // save readonly state
1853  mapLayerNode.setAttribute( "readOnly", mReadOnly );
1854 
1855  // save preview expression
1856  QDomElement prevExpElem = document.createElement( "previewExpression" );
1857  QDomText prevExpText = document.createTextNode( mDisplayExpression );
1858  prevExpElem.appendChild( prevExpText );
1859  layer_node.appendChild( prevExpElem );
1860 
1861  //save joins
1862  mJoinBuffer->writeXml( layer_node, document );
1863 
1864  // dependencies
1865  QDomElement dependenciesElement = document.createElement( "layerDependencies" );
1866  Q_FOREACH ( QString layerId, layerDependencies() )
1867  {
1868  QDomElement depElem = document.createElement( "layer" );
1869  depElem.setAttribute( "id", layerId );
1870  dependenciesElement.appendChild( depElem );
1871  }
1872  layer_node.appendChild( dependenciesElement );
1873 
1874  // save expression fields
1875  mExpressionFieldBuffer->writeXml( layer_node, document );
1876 
1877  writeStyleManager( layer_node, document );
1878 
1879  // renderer specific settings
1880  QString errorMsg;
1881  return writeSymbology( layer_node, document, errorMsg );
1882 } // bool QgsVectorLayer::writeXml
1883 
1884 
1885 bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
1886 {
1887  readStyle( node, errorMessage );
1888 
1889  // process the attribute actions
1890  mActions->readXML( node );
1891 
1892  mEditFormConfig->readXml( node );
1893 
1894  QDomNode annotationFormNode = node.namedItem( "annotationform" );
1895  if ( !annotationFormNode.isNull() )
1896  {
1897  QDomElement e = annotationFormNode.toElement();
1898  mAnnotationForm = QgsProject::instance()->readPath( e.text() );
1899  }
1900 
1901  mAttributeAliasMap.clear();
1902  QDomNode aliasesNode = node.namedItem( "aliases" );
1903  if ( !aliasesNode.isNull() )
1904  {
1905  QDomElement aliasElem;
1906 
1907  QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( "alias" );
1908  for ( int i = 0; i < aliasNodeList.size(); ++i )
1909  {
1910  aliasElem = aliasNodeList.at( i ).toElement();
1911 
1912  QString field;
1913  if ( aliasElem.hasAttribute( "field" ) )
1914  {
1915  field = aliasElem.attribute( "field" );
1916  }
1917  else
1918  {
1919  int index = aliasElem.attribute( "index" ).toInt();
1920 
1921  if ( index >= 0 && index < fields().count() )
1922  field = fields().at( index ).name();
1923  }
1924 
1925  mAttributeAliasMap.insert( field, aliasElem.attribute( "name" ) );
1926  }
1927  }
1928 
1929  //Attributes excluded from WMS and WFS
1930  mExcludeAttributesWMS.clear();
1931  QDomNode excludeWMSNode = node.namedItem( "excludeAttributesWMS" );
1932  if ( !excludeWMSNode.isNull() )
1933  {
1934  QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( "attribute" );
1935  for ( int i = 0; i < attributeNodeList.size(); ++i )
1936  {
1937  mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
1938  }
1939  }
1940 
1941  mExcludeAttributesWFS.clear();
1942  QDomNode excludeWFSNode = node.namedItem( "excludeAttributesWFS" );
1943  if ( !excludeWFSNode.isNull() )
1944  {
1945  QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( "attribute" );
1946  for ( int i = 0; i < attributeNodeList.size(); ++i )
1947  {
1948  mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
1949  }
1950  }
1951 
1952  mEditFormConfig->readXml( node );
1953 
1954  mAttributeTableConfig.readXml( node );
1955 
1956  mConditionalStyles->readXml( node );
1957 
1958  return true;
1959 }
1960 
1961 bool QgsVectorLayer::readStyle( const QDomNode &node, QString &errorMessage )
1962 {
1963  emit readCustomSymbology( node.toElement(), errorMessage );
1964 
1965  if ( hasGeometryType() )
1966  {
1967  // try renderer v2 first
1968  QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
1969  if ( !rendererElement.isNull() )
1970  {
1971  QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
1972  if ( !r )
1973  return false;
1974 
1975  setRendererV2( r );
1976  }
1977  else
1978  {
1980  if ( !r )
1982 
1983  setRendererV2( r );
1984  }
1985 
1986  QDomElement labelingElement = node.firstChildElement( "labeling" );
1987  if ( !labelingElement.isNull() )
1988  {
1991  }
1992 
1993  // get and set the display field if it exists.
1994  QDomNode displayFieldNode = node.namedItem( "displayfield" );
1995  if ( !displayFieldNode.isNull() )
1996  {
1997  QDomElement e = displayFieldNode.toElement();
1998  setDisplayField( e.text() );
1999  }
2000 
2001  // get and set the blend mode if it exists
2002  QDomNode blendModeNode = node.namedItem( "blendMode" );
2003  if ( !blendModeNode.isNull() )
2004  {
2005  QDomElement e = blendModeNode.toElement();
2006  setBlendMode( QgsMapRenderer::getCompositionMode( static_cast< QgsMapRenderer::BlendMode >( e.text().toInt() ) ) );
2007  }
2008 
2009  // get and set the feature blend mode if it exists
2010  QDomNode featureBlendModeNode = node.namedItem( "featureBlendMode" );
2011  if ( !featureBlendModeNode.isNull() )
2012  {
2013  QDomElement e = featureBlendModeNode.toElement();
2014  setFeatureBlendMode( QgsMapRenderer::getCompositionMode( static_cast< QgsMapRenderer::BlendMode >( e.text().toInt() ) ) );
2015  }
2016 
2017  // get and set the layer transparency if it exists
2018  QDomNode layerTransparencyNode = node.namedItem( "layerTransparency" );
2019  if ( !layerTransparencyNode.isNull() )
2020  {
2021  QDomElement e = layerTransparencyNode.toElement();
2022  setLayerTransparency( e.text().toInt() );
2023  }
2024 
2025  // use scale dependent visibility flag
2026  QDomElement e = node.toElement();
2027  if ( mLabel )
2028  {
2029  mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
2030  mLabel->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
2031  mLabel->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
2032  }
2033 
2034  // get the simplification drawing settings
2035  mSimplifyMethod.setSimplifyHints( static_cast< QgsVectorSimplifyMethod::SimplifyHints >( e.attribute( "simplifyDrawingHints", "1" ).toInt() ) );
2036  mSimplifyMethod.setThreshold( e.attribute( "simplifyDrawingTol", "1" ).toFloat() );
2037  mSimplifyMethod.setForceLocalOptimization( e.attribute( "simplifyLocal", "1" ).toInt() );
2038  mSimplifyMethod.setMaximumScale( e.attribute( "simplifyMaxScale", "1" ).toFloat() );
2039 
2040  //also restore custom properties (for labeling-ng)
2041  readCustomProperties( node, "labeling" );
2042 
2043  // Test if labeling is on or off
2044  QDomNode labelnode = node.namedItem( "label" );
2045  QDomElement element = labelnode.toElement();
2046  int hasLabelsEnabled = element.text().toInt();
2048  if ( hasLabelsEnabled < 1 )
2049  {
2050  enableLabels( false );
2051  }
2052  else
2053  {
2054  enableLabels( true );
2055  }
2057 
2058  QDomNode labelattributesnode = node.namedItem( "labelattributes" );
2059 
2060  if ( !labelattributesnode.isNull() && mLabel )
2061  {
2062  QgsDebugMsg( "calling readXML" );
2063  mLabel->readXML( labelattributesnode );
2064  }
2065 
2066  //diagram renderer and diagram layer settings
2067  delete mDiagramRenderer;
2068  mDiagramRenderer = nullptr;
2069  QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
2070  if ( !singleCatDiagramElem.isNull() )
2071  {
2072  mDiagramRenderer = new QgsSingleCategoryDiagramRenderer();
2073  mDiagramRenderer->readXML( singleCatDiagramElem, this );
2074  }
2075  QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
2076  if ( !linearDiagramElem.isNull() )
2077  {
2078  mDiagramRenderer = new QgsLinearlyInterpolatedDiagramRenderer();
2079  mDiagramRenderer->readXML( linearDiagramElem, this );
2080  }
2081 
2082  if ( mDiagramRenderer )
2083  {
2084  QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
2085  if ( !diagramSettingsElem.isNull() )
2086  {
2087  delete mDiagramLayerSettings;
2088  mDiagramLayerSettings = new QgsDiagramLayerSettings();
2089  mDiagramLayerSettings->readXML( diagramSettingsElem, this );
2090  }
2091  }
2092  }
2093  return true;
2094 }
2095 
2096 bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2097 {
2098  ( void )writeStyle( node, doc, errorMessage );
2099 
2100  // FIXME
2101  // edittypes are written to the layerNode
2102  // by slot QgsEditorWidgetRegistry::writeMapLayer()
2103  // triggered by signal QgsProject::writeMapLayer()
2104  // still other editing settings are written here,
2105  // although they are not part of symbology either
2106 
2107  QDomElement afField = doc.createElement( "annotationform" );
2108  QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
2109  afField.appendChild( afText );
2110  node.appendChild( afField );
2111 
2112  //attribute aliases
2113  if ( !mAttributeAliasMap.isEmpty() )
2114  {
2115  QDomElement aliasElem = doc.createElement( "aliases" );
2116  QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
2117  for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
2118  {
2119  int idx = fieldNameIndex( a_it.key() );
2120  if ( idx < 0 )
2121  continue;
2122 
2123  QDomElement aliasEntryElem = doc.createElement( "alias" );
2124  aliasEntryElem.setAttribute( "field", a_it.key() );
2125  aliasEntryElem.setAttribute( "index", idx );
2126  aliasEntryElem.setAttribute( "name", a_it.value() );
2127  aliasElem.appendChild( aliasEntryElem );
2128  }
2129  node.appendChild( aliasElem );
2130  }
2131 
2132  //exclude attributes WMS
2133  QDomElement excludeWMSElem = doc.createElement( "excludeAttributesWMS" );
2134  QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
2135  for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
2136  {
2137  QDomElement attrElem = doc.createElement( "attribute" );
2138  QDomText attrText = doc.createTextNode( *attWMSIt );
2139  attrElem.appendChild( attrText );
2140  excludeWMSElem.appendChild( attrElem );
2141  }
2142  node.appendChild( excludeWMSElem );
2143 
2144  //exclude attributes WFS
2145  QDomElement excludeWFSElem = doc.createElement( "excludeAttributesWFS" );
2146  QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
2147  for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
2148  {
2149  QDomElement attrElem = doc.createElement( "attribute" );
2150  QDomText attrText = doc.createTextNode( *attWFSIt );
2151  attrElem.appendChild( attrText );
2152  excludeWFSElem.appendChild( attrElem );
2153  }
2154  node.appendChild( excludeWFSElem );
2155 
2156  // add attribute actions
2157  mActions->writeXML( node, doc );
2158  mAttributeTableConfig.writeXml( node );
2159  mEditFormConfig->writeXml( node );
2160  mConditionalStyles->writeXml( node, doc );
2161 
2162  return true;
2163 }
2164 
2165 bool QgsVectorLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage ) const
2166 {
2167  QDomElement mapLayerNode = node.toElement();
2168 
2169  emit writeCustomSymbology( mapLayerNode, doc, errorMessage );
2170 
2171  if ( hasGeometryType() )
2172  {
2173  QDomElement rendererElement = mRendererV2->save( doc );
2174  node.appendChild( rendererElement );
2175 
2176  if ( mLabeling )
2177  {
2178  QDomElement labelingElement = mLabeling->save( doc );
2179  node.appendChild( labelingElement );
2180  }
2181 
2182  // use scale dependent visibility flag
2183  if ( mLabel )
2184  {
2185  mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
2186  mapLayerNode.setAttribute( "minLabelScale", QString::number( mLabel->minScale() ) );
2187  mapLayerNode.setAttribute( "maxLabelScale", QString::number( mLabel->maxScale() ) );
2188  }
2189 
2190  // save the simplification drawing settings
2191  mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) );
2192  mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) );
2193  mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 );
2194  mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) );
2195 
2196  //save customproperties (for labeling ng)
2197  writeCustomProperties( node, doc );
2198 
2199  // add the blend mode field
2200  QDomElement blendModeElem = doc.createElement( "blendMode" );
2202  blendModeElem.appendChild( blendModeText );
2203  node.appendChild( blendModeElem );
2204 
2205  // add the feature blend mode field
2206  QDomElement featureBlendModeElem = doc.createElement( "featureBlendMode" );
2208  featureBlendModeElem.appendChild( featureBlendModeText );
2209  node.appendChild( featureBlendModeElem );
2210 
2211  // add the layer transparency
2212  QDomElement layerTransparencyElem = doc.createElement( "layerTransparency" );
2213  QDomText layerTransparencyText = doc.createTextNode( QString::number( layerTransparency() ) );
2214  layerTransparencyElem.appendChild( layerTransparencyText );
2215  node.appendChild( layerTransparencyElem );
2216 
2217  // add the display field
2218  QDomElement dField = doc.createElement( "displayfield" );
2219  QDomText dFieldText = doc.createTextNode( displayField() );
2220  dField.appendChild( dFieldText );
2221  node.appendChild( dField );
2222 
2223  // add label node
2224  QDomElement labelElem = doc.createElement( "label" );
2225  QDomText labelText = doc.createTextNode( "" );
2226 
2228  if ( hasLabelsEnabled() )
2229  {
2230  labelText.setData( "1" );
2231  }
2232  else
2233  {
2234  labelText.setData( "0" );
2235  }
2237  labelElem.appendChild( labelText );
2238 
2239  node.appendChild( labelElem );
2240 
2241  // Now we get to do all that all over again for QgsLabel
2242 
2243  if ( mLabel )
2244  {
2245  QString fieldname = mLabel->labelField( QgsLabel::Text );
2246  if ( fieldname != "" )
2247  {
2248  dField = doc.createElement( "labelfield" );
2249  dFieldText = doc.createTextNode( fieldname );
2250  dField.appendChild( dFieldText );
2251  node.appendChild( dField );
2252  }
2253 
2254  mLabel->writeXML( node, doc );
2255  }
2256 
2257  if ( mDiagramRenderer )
2258  {
2259  mDiagramRenderer->writeXML( mapLayerNode, doc, this );
2260  if ( mDiagramLayerSettings )
2261  mDiagramLayerSettings->writeXML( mapLayerNode, doc, this );
2262  }
2263  }
2264  return true;
2265 }
2266 
2267 bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
2268 {
2269  // get the Name element
2270  QDomElement nameElem = node.firstChildElement( "Name" );
2271  if ( nameElem.isNull() )
2272  {
2273  errorMessage = "Warning: Name element not found within NamedLayer while it's required.";
2274  }
2275 
2276  if ( hasGeometryType() )
2277  {
2278  QgsFeatureRendererV2* r = QgsFeatureRendererV2::loadSld( node, geometryType(), errorMessage );
2279  if ( !r )
2280  return false;
2281 
2282  setRendererV2( r );
2283 
2284  // labeling
2285  readSldLabeling( node );
2286  }
2287  return true;
2288 }
2289 
2290 
2291 bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2292 {
2293  Q_UNUSED( errorMessage );
2294 
2295  // store the Name element
2296  QDomElement nameNode = doc.createElement( "se:Name" );
2297  nameNode.appendChild( doc.createTextNode( name() ) );
2298  node.appendChild( nameNode );
2299 
2300  if ( hasGeometryType() )
2301  {
2302  node.appendChild( mRendererV2->writeSld( doc, name() ) );
2303  }
2304  return true;
2305 }
2306 
2307 
2309 {
2310  if ( !mEditBuffer || !mDataProvider )
2311  {
2312  return false;
2313  }
2314 
2315  updateExtents();
2316 
2317  bool result = mEditBuffer->changeGeometry( fid, geom );
2318 
2319  if ( result )
2320  updateExtents();
2321  return result;
2322 }
2323 
2324 
2325 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant& value, bool emitSignal )
2326 {
2327  Q_UNUSED( emitSignal );
2328  return changeAttributeValue( fid, field, value );
2329 }
2330 
2331 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
2332 {
2333  if ( !mEditBuffer || !mDataProvider )
2334  return false;
2335 
2336  return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
2337 }
2338 
2340 {
2341  if ( !mEditBuffer || !mDataProvider )
2342  return false;
2343 
2344  return mEditBuffer->addAttribute( field );
2345 }
2346 
2348 {
2349  if ( attIndex < 0 || attIndex >= fields().count() )
2350  return;
2351 
2352  QString name = fields().at( attIndex ).name();
2353  if ( mAttributeAliasMap.contains( name ) )
2354  {
2355  mAttributeAliasMap.remove( name );
2356  emit layerModified();
2357  }
2358 }
2359 
2360 void QgsVectorLayer::addAttributeAlias( int attIndex, const QString& aliasString )
2361 {
2362  if ( attIndex < 0 || attIndex >= fields().count() )
2363  return;
2364 
2365  QString name = fields().at( attIndex ).name();
2366 
2367  mAttributeAliasMap.insert( name, aliasString );
2368  emit layerModified(); // TODO[MD]: should have a different signal?
2369 }
2370 
2371 QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
2372 {
2373  if ( attributeIndex < 0 || attributeIndex >= fields().count() )
2374  return QString();
2375 
2376  QString name = fields().at( attributeIndex ).name();
2377 
2378  return mAttributeAliasMap.value( name, QString() );
2379 }
2380 
2382 {
2383  QString displayName = attributeAlias( attributeIndex );
2384  if ( displayName.isEmpty() )
2385  {
2386  if ( attributeIndex >= 0 && attributeIndex < mUpdatedFields.count() )
2387  {
2388  displayName = mUpdatedFields.at( attributeIndex ).name();
2389  }
2390  }
2391  return displayName;
2392 }
2393 
2395 {
2396  if ( index < 0 || index >= fields().count() )
2397  return false;
2398 
2399  if ( mUpdatedFields.fieldOrigin( index ) == QgsFields::OriginExpression )
2400  {
2401  removeExpressionField( index );
2402  return true;
2403  }
2404 
2405  if ( !mEditBuffer || !mDataProvider )
2406  return false;
2407 
2408  return mEditBuffer->deleteAttribute( index );
2409 }
2410 
2412 {
2413  bool deleted = false;
2414 
2415  // Remove multiple occurrences of same attribute
2416  attrs = attrs.toSet().toList();
2417 
2418  qSort( attrs.begin(), attrs.end(), qGreater<int>() );
2419 
2420  Q_FOREACH ( int attr, attrs )
2421  {
2422  if ( deleteAttribute( attr ) )
2423  {
2424  deleted = true;
2425  }
2426  }
2427 
2428  return deleted;
2429 }
2430 
2432 {
2433  if ( !mEditBuffer )
2434  return false;
2435 
2436  bool res = mEditBuffer->deleteFeature( fid );
2437  if ( res )
2438  {
2439  mSelectedFeatureIds.remove( fid ); // remove it from selection
2440  updateExtents();
2441  }
2442 
2443  return res;
2444 }
2445 
2447 {
2448  if ( !mEditBuffer )
2449  return false;
2450 
2451  bool res = mEditBuffer->deleteFeatures( fids );
2452 
2453  if ( res )
2454  {
2455  mSelectedFeatureIds.subtract( fids ); // remove it from selection
2456  updateExtents();
2457  }
2458 
2459  return res;
2460 }
2461 
2463 {
2464  QgsAttributeList pkAttributesList;
2465 
2466  QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
2467  for ( int i = 0; i < mUpdatedFields.count(); ++i )
2468  {
2469  if ( mUpdatedFields.fieldOrigin( i ) == QgsFields::OriginProvider &&
2470  providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
2471  pkAttributesList << i;
2472  }
2473 
2474  return pkAttributesList;
2475 }
2476 
2478 {
2479  return mDataProvider->featureCount() +
2480  ( mEditBuffer ? mEditBuffer->mAddedFeatures.size() - mEditBuffer->mDeletedFeatureIds.size() : 0 );
2481 }
2482 
2484 {
2485  mCommitErrors.clear();
2486 
2487  if ( !mDataProvider )
2488  {
2489  mCommitErrors << tr( "ERROR: no provider" );
2490  return false;
2491  }
2492 
2493  if ( !mEditBuffer )
2494  {
2495  mCommitErrors << tr( "ERROR: layer not editable" );
2496  return false;
2497  }
2498 
2499  emit beforeCommitChanges();
2500 
2501  bool success = mEditBuffer->commitChanges( mCommitErrors );
2502 
2503  if ( success )
2504  {
2505  delete mEditBuffer;
2506  mEditBuffer = nullptr;
2507  undoStack()->clear();
2508  emit editingStopped();
2509  }
2510  else
2511  {
2512  QgsMessageLog::logMessage( tr( "Commit errors:\n %1" ).arg( mCommitErrors.join( "\n " ) ) );
2513  }
2514 
2515  if ( mCache )
2516  {
2517  mCache->deleteCachedGeometries();
2518  }
2519 
2520  updateFields();
2521  mDataProvider->updateExtents();
2522 
2523  mDataProvider->leaveUpdateMode();
2524 
2525  emit repaintRequested();
2526 
2527  return success;
2528 }
2529 
2531 {
2532  return mCommitErrors;
2533 }
2534 
2535 bool QgsVectorLayer::rollBack( bool deleteBuffer )
2536 {
2537  if ( !mEditBuffer )
2538  {
2539  return false;
2540  }
2541 
2542  bool rollbackExtent = !mEditBuffer->mDeletedFeatureIds.isEmpty() ||
2543  !mEditBuffer->mAddedFeatures.isEmpty() ||
2544  !mEditBuffer->mChangedGeometries.isEmpty();
2545 
2546  emit beforeRollBack();
2547 
2548  mEditBuffer->rollBack();
2549 
2550  if ( isModified() )
2551  {
2552  // new undo stack roll back method
2553  // old method of calling every undo could cause many canvas refreshes
2554  undoStack()->setIndex( 0 );
2555  }
2556 
2557  updateFields();
2558 
2559  if ( deleteBuffer )
2560  {
2561  delete mEditBuffer;
2562  mEditBuffer = nullptr;
2563  undoStack()->clear();
2564  }
2565  emit editingStopped();
2566 
2567  if ( mCache )
2568  {
2569  mCache->deleteCachedGeometries();
2570  }
2571 
2572  if ( rollbackExtent )
2573  updateExtents();
2574 
2575  mDataProvider->leaveUpdateMode();
2576 
2577  emit repaintRequested();
2578  return true;
2579 }
2580 
2582 {
2583  selectByIds( ids, SetSelection );
2584 }
2585 
2587 {
2588  return mSelectedFeatureIds.size();
2589 }
2590 
2592 {
2593  return mSelectedFeatureIds;
2594 }
2595 
2597 {
2598  QgsFeatureList features;
2599  QgsFeature f;
2600 
2601  if ( mSelectedFeatureIds.count() <= 8 )
2602  {
2603  // for small amount of selected features, fetch them directly
2604  // because request with FilterFids would go iterate over the whole layer
2605  Q_FOREACH ( QgsFeatureId fid, mSelectedFeatureIds )
2606  {
2607  getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
2608  features << f;
2609  }
2610  }
2611  else
2612  {
2614 
2615  while ( it.nextFeature( f ) )
2616  {
2617  features.push_back( f );
2618  }
2619  }
2620 
2621  return features;
2622 }
2623 
2625 {
2626  if ( mSelectedFeatureIds.isEmpty() )
2627  return QgsFeatureIterator();
2628 
2629  if ( geometryType() == QGis::NoGeometry )
2631 
2632  if ( mSelectedFeatureIds.count() == 1 )
2633  request.setFilterFid( *mSelectedFeatureIds.constBegin() );
2634  else
2635  request.setFilterFids( mSelectedFeatureIds );
2636 
2637  return getFeatures( request );
2638 }
2639 
2640 bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
2641 {
2642  if ( !mEditBuffer || !mDataProvider )
2643  return false;
2644 
2645  bool res = mEditBuffer->addFeatures( features );
2646 
2647  if ( makeSelected )
2648  {
2649  QgsFeatureIds ids;
2650 
2651  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
2652  ids << iter->id();
2653 
2654  selectByIds( ids );
2655  }
2656 
2657  updateExtents();
2658 
2659  return res;
2660 }
2661 
2662 
2663 bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
2664 {
2665  if ( !hasGeometryType() )
2666  return false;
2667 
2669  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
2670 
2671  if ( result != 0 )
2672  {
2673  return false;
2674  }
2675 
2676  if ( snapResults.size() < 1 )
2677  {
2678  return false;
2679  }
2680 
2682  point.setX( snap_it.value().snappedVertex.x() );
2683  point.setY( snap_it.value().snappedVertex.y() );
2684  return true;
2685 }
2686 
2687 
2688 int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snappingTolerance,
2689  QMultiMap<double, QgsSnappingResult>& snappingResults,
2690  QgsSnapper::SnappingType snap_to )
2691 {
2692  if ( !hasGeometryType() )
2693  return 1;
2694 
2695  if ( snappingTolerance <= 0 || !mDataProvider )
2696  {
2697  return 1;
2698  }
2699 
2700  QgsRectangle searchRect( startPoint.x() - snappingTolerance, startPoint.y() - snappingTolerance,
2701  startPoint.x() + snappingTolerance, startPoint.y() + snappingTolerance );
2702  double sqrSnappingTolerance = snappingTolerance * snappingTolerance;
2703 
2704  int n = 0;
2705  QgsFeature f;
2706 
2707  if ( mCache->cachedGeometriesRect().contains( searchRect ) )
2708  {
2709  QgsGeometryMap& cachedGeometries = mCache->cachedGeometries();
2710  for ( QgsGeometryMap::iterator it = cachedGeometries.begin(); it != cachedGeometries.end() ; ++it )
2711  {
2712  QgsGeometry* g = &( it.value() );
2713  if ( g->boundingBox().intersects( searchRect ) )
2714  {
2715  snapToGeometry( startPoint, it.key(), g, sqrSnappingTolerance, snappingResults, snap_to );
2716  ++n;
2717  }
2718  }
2719  }
2720  else
2721  {
2722  // snapping outside cached area
2723 
2725  .setFilterRect( searchRect )
2727  .setSubsetOfAttributes( QgsAttributeList() ) );
2728 
2729  while ( fit.nextFeature( f ) )
2730  {
2731  snapToGeometry( startPoint, f.id(), f.constGeometry(), sqrSnappingTolerance, snappingResults, snap_to );
2732  ++n;
2733  }
2734  }
2735 
2736  return n == 0 ? 2 : 0;
2737 }
2738 
2739 void QgsVectorLayer::snapToGeometry( const QgsPoint& startPoint,
2740  QgsFeatureId featureId,
2741  const QgsGeometry* geom,
2742  double sqrSnappingTolerance,
2743  QMultiMap<double, QgsSnappingResult>& snappingResults,
2744  QgsSnapper::SnappingType snap_to ) const
2745 {
2746  if ( !geom )
2747  {
2748  return;
2749  }
2750 
2751  int atVertex, beforeVertex, afterVertex;
2752  double sqrDistVertexSnap, sqrDistSegmentSnap;
2753  QgsPoint snappedPoint;
2754  QgsSnappingResult snappingResultVertex;
2755  QgsSnappingResult snappingResultSegment;
2756 
2757  if ( snap_to == QgsSnapper::SnapToVertex || snap_to == QgsSnapper::SnapToVertexAndSegment )
2758  {
2759  snappedPoint = geom->closestVertex( startPoint, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
2760  if ( sqrDistVertexSnap < sqrSnappingTolerance )
2761  {
2762  snappingResultVertex.snappedVertex = snappedPoint;
2763  snappingResultVertex.snappedVertexNr = atVertex;
2764  snappingResultVertex.beforeVertexNr = beforeVertex;
2765  if ( beforeVertex != -1 ) // make sure the vertex is valid
2766  {
2767  snappingResultVertex.beforeVertex = geom->vertexAt( beforeVertex );
2768  }
2769  snappingResultVertex.afterVertexNr = afterVertex;
2770  if ( afterVertex != -1 ) // make sure the vertex is valid
2771  {
2772  snappingResultVertex.afterVertex = geom->vertexAt( afterVertex );
2773  }
2774  snappingResultVertex.snappedAtGeometry = featureId;
2775  snappingResultVertex.layer = this;
2776  snappingResults.insert( sqrt( sqrDistVertexSnap ), snappingResultVertex );
2777  return;
2778  }
2779  }
2780  if ( snap_to == QgsSnapper::SnapToSegment || snap_to == QgsSnapper::SnapToVertexAndSegment ) // snap to segment
2781  {
2782  if ( geometryType() != QGis::Point ) // cannot snap to segment for points/multipoints
2783  {
2784  sqrDistSegmentSnap = geom->closestSegmentWithContext( startPoint, snappedPoint, afterVertex, nullptr, crs().geographicFlag() ? 1e-12 : 1e-8 );
2785 
2786  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
2787  {
2788  snappingResultSegment.snappedVertex = snappedPoint;
2789  snappingResultSegment.snappedVertexNr = -1;
2790  snappingResultSegment.beforeVertexNr = afterVertex - 1;
2791  snappingResultSegment.afterVertexNr = afterVertex;
2792  snappingResultSegment.snappedAtGeometry = featureId;
2793  snappingResultSegment.beforeVertex = geom->vertexAt( afterVertex - 1 );
2794  snappingResultSegment.afterVertex = geom->vertexAt( afterVertex );
2795  snappingResultSegment.layer = this;
2796  snappingResults.insert( sqrt( sqrDistSegmentSnap ), snappingResultSegment );
2797  }
2798  }
2799  }
2800 }
2801 
2803 {
2804  QgsVectorLayerEditUtils utils( this );
2805  return utils.insertSegmentVerticesForSnap( snapResults );
2806 }
2807 
2808 
2810 {
2811  QgsDebugMsg( "----- Computing Coordinate System" );
2812 
2813  //
2814  // Get the layers project info and set up the QgsCoordinateTransform
2815  // for this layer
2816  //
2817 
2818  if ( hasGeometryType() )
2819  {
2820  // get CRS directly from provider
2821  setCrs( mDataProvider->crs() );
2822  }
2823  else
2824  {
2826  }
2827 }
2828 
2829 
2831 {
2832  return mDisplayField;
2833 }
2834 
2836 {
2837  mDisplayExpression = displayExpression;
2838 }
2839 
2841 {
2842  return mDisplayExpression;
2843 }
2844 
2846 {
2847  return ( mEditBuffer && mDataProvider );
2848 }
2849 
2851 {
2852  return geometryType() != QGis::NoGeometry;
2853 }
2854 
2856 {
2857  return mReadOnly;
2858 }
2859 
2860 bool QgsVectorLayer::setReadOnly( bool readonly )
2861 {
2862  // exit if the layer is in editing mode
2863  if ( readonly && mEditBuffer )
2864  return false;
2865 
2866  mReadOnly = readonly;
2867  return true;
2868 }
2869 
2871 {
2872  emit beforeModifiedCheck();
2873  return mEditBuffer && mEditBuffer->isModified();
2874 }
2875 
2877 {
2878  if ( idx < 0 || idx >= mUpdatedFields.count() )
2879  return Hidden;
2880 
2882  return QgsLegacyHelpers::convertEditType( editorWidgetV2( idx ), editorWidgetV2Config( idx ), this, mUpdatedFields[ idx ].name() );
2884 }
2885 
2887 {
2888  if ( idx < 0 || idx >= mUpdatedFields.count() )
2889  return;
2890 
2892 
2894  const QString widgetType = QgsLegacyHelpers::convertEditType( type, cfg, this, mUpdatedFields[idx].name() );
2895 
2896  setEditorWidgetV2( idx, widgetType );
2897  setEditorWidgetV2Config( idx, cfg );
2899 }
2900 
2902 {
2903  mAnnotationForm = ui;
2904 }
2905 
2907 {
2909  return editorWidgetV2Config( idx );
2911 }
2912 
2914 {
2916  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2917  return RangeData(
2918  cfg.value( "Min" ),
2919  cfg.value( "Max" ),
2920  cfg.value( "Step" )
2921  );
2923 }
2924 
2926 {
2928  return editorWidgetV2Config( idx ).value( "DateFormat" ).toString();
2930 }
2931 
2933 {
2935  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2936  return QSize( cfg.value( "Width" ).toInt(), cfg.value( "Height" ).toInt() );
2938 }
2939 
2941 {
2942  if ( !hasGeometryType() )
2943  return;
2944 
2945  if ( r != mRendererV2 )
2946  {
2947  delete mRendererV2;
2948  mRendererV2 = r;
2949  mSymbolFeatureCounted = false;
2950  mSymbolFeatureCountMap.clear();
2951 
2952  emit rendererChanged();
2953  }
2954 }
2955 
2957 {
2958  if ( !mDataProvider )
2959  {
2960  return;
2961  }
2962  if ( !mDataProvider->transaction() )
2963  {
2964  undoStack()->beginMacro( text );
2965  mEditCommandActive = true;
2966  emit editCommandStarted( text );
2967  }
2968 }
2969 
2971 {
2972  if ( !mDataProvider )
2973  {
2974  return;
2975  }
2976  if ( !mDataProvider->transaction() )
2977  {
2978  undoStack()->endMacro();
2979  mEditCommandActive = false;
2980  if ( !mDeletedFids.isEmpty() )
2981  {
2982  emit featuresDeleted( mDeletedFids );
2983  mDeletedFids.clear();
2984  }
2985  emit editCommandEnded();
2986  }
2987 }
2988 
2990 {
2991  if ( !mDataProvider )
2992  {
2993  return;
2994  }
2995  if ( !mDataProvider->transaction() )
2996  {
2997  undoStack()->endMacro();
2998  undoStack()->undo();
2999  mEditCommandActive = false;
3000  mDeletedFids.clear();
3001  emit editCommandDestroyed();
3002  }
3003 }
3004 
3005 
3006 void QgsVectorLayer::setCheckedState( int idx, const QString& checked, const QString& unchecked )
3007 {
3010  cfg["CheckedState"] = checked;
3011  cfg["UncheckedState"] = unchecked;
3012  setEditorWidgetV2Config( idx, cfg );
3014 }
3015 
3016 int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
3017 {
3018  return fields().fieldNameIndex( fieldName );
3019 }
3020 
3022 {
3023  return mJoinBuffer && mJoinBuffer->addJoin( joinInfo );
3024 }
3025 
3027 {
3028  removeJoin( theLayerId );
3029 }
3030 
3031 bool QgsVectorLayer::removeJoin( const QString& joinLayerId )
3032 {
3033  bool res = false;
3034  if ( mJoinBuffer )
3035  {
3036  res = mJoinBuffer->removeJoin( joinLayerId );
3037  }
3038  return res;
3039 }
3040 
3042 {
3043  if ( mJoinBuffer )
3044  return mJoinBuffer->vectorJoins();
3045  else
3046  return QList< QgsVectorJoinInfo >();
3047 }
3048 
3050 {
3051  emit beforeAddingExpressionField( fld.name() );
3052  mExpressionFieldBuffer->addExpression( exp, fld );
3053  updateFields();
3054  int idx = mUpdatedFields.indexFromName( fld.name() );
3055  emit attributeAdded( idx );
3056  return idx;
3057 }
3058 
3060 {
3061  emit beforeRemovingExpressionField( index );
3062  int oi = mUpdatedFields.fieldOriginIndex( index );
3063  mExpressionFieldBuffer->removeExpression( oi );
3064  updateFields();
3065  emit attributeDeleted( index );
3066 }
3067 
3069 {
3070  int oi = mUpdatedFields.fieldOriginIndex( index );
3071  return mExpressionFieldBuffer->expressions().value( oi ).expression;
3072 }
3073 
3075 {
3076  int oi = mUpdatedFields.fieldOriginIndex( index );
3077  mExpressionFieldBuffer->updateExpression( oi, exp );
3078 }
3079 
3081 {
3082  if ( !mDataProvider )
3083  return;
3084 
3085  QgsFields oldFields = mUpdatedFields;
3086 
3087  mUpdatedFields = mDataProvider->fields();
3088 
3089  // added / removed fields
3090  if ( mEditBuffer )
3091  mEditBuffer->updateFields( mUpdatedFields );
3092 
3093  // joined fields
3094  if ( mJoinBuffer && mJoinBuffer->containsJoins() )
3095  mJoinBuffer->updateFields( mUpdatedFields );
3096 
3097  if ( mExpressionFieldBuffer )
3098  mExpressionFieldBuffer->updateFields( mUpdatedFields );
3099 
3100  if ( oldFields != mUpdatedFields )
3101  {
3102  emit updatedFields();
3103  mEditFormConfig->setFields( mUpdatedFields );
3104  }
3105 }
3106 
3107 
3109 {
3110  if ( mJoinBuffer->containsJoins() )
3111  {
3112  mJoinBuffer->createJoinCaches();
3113  }
3114 }
3115 
3117 {
3118  uniqueValues.clear();
3119  if ( !mDataProvider )
3120  {
3121  return;
3122  }
3123 
3124  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3125  if ( origin == QgsFields::OriginUnknown )
3126  {
3127  return;
3128  }
3129 
3130  if ( origin == QgsFields::OriginProvider ) //a provider field
3131  {
3132  mDataProvider->uniqueValues( index, uniqueValues, limit );
3133 
3134  if ( mEditBuffer )
3135  {
3136  QSet<QString> vals;
3137  Q_FOREACH ( const QVariant& v, uniqueValues )
3138  {
3139  vals << v.toString();
3140  }
3141 
3142  QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
3143  while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
3144  {
3145  it.next();
3146  QVariant v = it.value().value( index );
3147  if ( v.isValid() )
3148  {
3149  QString vs = v.toString();
3150  if ( !vals.contains( vs ) )
3151  {
3152  vals << vs;
3153  uniqueValues << v;
3154  }
3155  }
3156  }
3157  }
3158 
3159  return;
3160  }
3161  else if ( origin == QgsFields::OriginJoin )
3162  {
3163  int sourceLayerIndex;
3164  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3165  Q_ASSERT( join );
3166 
3168 
3169  if ( vl )
3170  vl->dataProvider()->uniqueValues( sourceLayerIndex, uniqueValues, limit );
3171 
3172  return;
3173  }
3174  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3175  {
3176  // the layer is editable, but in certain cases it can still be avoided going through all features
3177  if ( origin == QgsFields::OriginEdit && mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mAddedFeatures.isEmpty() && !mEditBuffer->mDeletedAttributeIds.contains( index ) && mEditBuffer->mChangedAttributeValues.isEmpty() )
3178  {
3179  mDataProvider->uniqueValues( index, uniqueValues, limit );
3180  return;
3181  }
3182 
3183  // we need to go through each feature
3184  QgsAttributeList attList;
3185  attList << index;
3186 
3188  .setFlags( QgsFeatureRequest::NoGeometry )
3189  .setSubsetOfAttributes( attList ) );
3190 
3191  QgsFeature f;
3192  QVariant currentValue;
3194  while ( fit.nextFeature( f ) )
3195  {
3196  currentValue = f.attribute( index );
3197  val.insert( currentValue.toString(), currentValue );
3198  if ( limit >= 0 && val.size() >= limit )
3199  {
3200  break;
3201  }
3202  }
3203 
3204  uniqueValues = val.values();
3205  return;
3206  }
3207 
3208  Q_ASSERT_X( false, "QgsVectorLayer::uniqueValues()", "Unknown source of the field!" );
3209 }
3210 
3212 {
3213  if ( !mDataProvider )
3214  {
3215  return QVariant();
3216  }
3217 
3218  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3219  if ( origin == QgsFields::OriginUnknown )
3220  {
3221  return QVariant();
3222  }
3223 
3224  if ( origin == QgsFields::OriginProvider ) //a provider field
3225  {
3226  return mDataProvider->minimumValue( index );
3227  }
3228  else if ( origin == QgsFields::OriginJoin )
3229  {
3230  int sourceLayerIndex;
3231  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3232  Q_ASSERT( join );
3233 
3235  Q_ASSERT( vl );
3236 
3237  return vl->minimumValue( sourceLayerIndex );
3238  }
3239  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3240  {
3241  // the layer is editable, but in certain cases it can still be avoided going through all features
3242  if ( origin == QgsFields::OriginEdit &&
3243  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3244  mEditBuffer->mAddedFeatures.isEmpty() && !
3245  mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3246  mEditBuffer->mChangedAttributeValues.isEmpty() )
3247  {
3248  return mDataProvider->minimumValue( index );
3249  }
3250 
3251  // we need to go through each feature
3252  QgsAttributeList attList;
3253  attList << index;
3254 
3256  .setFlags( QgsFeatureRequest::NoGeometry )
3257  .setSubsetOfAttributes( attList ) );
3258 
3259  QgsFeature f;
3261  double currentValue = 0;
3262  while ( fit.nextFeature( f ) )
3263  {
3264  currentValue = f.attribute( index ).toDouble();
3265  if ( currentValue < minimumValue )
3266  {
3267  minimumValue = currentValue;
3268  }
3269  }
3270  return QVariant( minimumValue );
3271  }
3272 
3273  Q_ASSERT_X( false, "QgsVectorLayer::minimumValue()", "Unknown source of the field!" );
3274  return QVariant();
3275 }
3276 
3278 {
3279  if ( !mDataProvider )
3280  {
3281  return QVariant();
3282  }
3283 
3284  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3285  if ( origin == QgsFields::OriginUnknown )
3286  {
3287  return QVariant();
3288  }
3289 
3290  if ( origin == QgsFields::OriginProvider ) //a provider field
3291  {
3292  return mDataProvider->maximumValue( index );
3293  }
3294  else if ( origin == QgsFields::OriginJoin )
3295  {
3296  int sourceLayerIndex;
3297  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3298  Q_ASSERT( join );
3299 
3301  Q_ASSERT( vl );
3302 
3303  return vl->maximumValue( sourceLayerIndex );
3304  }
3305  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3306  {
3307  // the layer is editable, but in certain cases it can still be avoided going through all features
3308  if ( origin == QgsFields::OriginEdit &&
3309  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3310  mEditBuffer->mAddedFeatures.isEmpty() &&
3311  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3312  mEditBuffer->mChangedAttributeValues.isEmpty() )
3313  {
3314  return mDataProvider->maximumValue( index );
3315  }
3316 
3317  // we need to go through each feature
3318  QgsAttributeList attList;
3319  attList << index;
3320 
3322  .setFlags( QgsFeatureRequest::NoGeometry )
3323  .setSubsetOfAttributes( attList ) );
3324 
3325  QgsFeature f;
3327  double currentValue = 0;
3328  while ( fit.nextFeature( f ) )
3329  {
3330  currentValue = f.attribute( index ).toDouble();
3331  if ( currentValue > maximumValue )
3332  {
3333  maximumValue = currentValue;
3334  }
3335  }
3336  return QVariant( maximumValue );
3337  }
3338 
3339  Q_ASSERT_X( false, "QgsVectorLayer::maximumValue()", "Unknown source of the field!" );
3340  return QVariant();
3341 }
3342 
3344  const QgsAggregateCalculator::AggregateParameters& parameters, QgsExpressionContext* context, bool* ok )
3345 {
3346  if ( ok )
3347  *ok = false;
3348 
3349  if ( !mDataProvider )
3350  {
3351  return QVariant();
3352  }
3353 
3354  // test if we are calculating based on a field
3355  int attrIndex = mUpdatedFields.fieldNameIndex( fieldOrExpression );
3356  if ( attrIndex >= 0 )
3357  {
3358  // aggregate is based on a field - if it's a provider field, we could possibly hand over the calculation
3359  // to the provider itself
3360  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( attrIndex );
3361  if ( origin == QgsFields::OriginProvider )
3362  {
3363  bool providerOk = false;
3364  QVariant val = mDataProvider->aggregate( aggregate, attrIndex, parameters, context, providerOk );
3365  if ( providerOk )
3366  {
3367  // provider handled calculation
3368  if ( ok )
3369  *ok = true;
3370  return val;
3371  }
3372  }
3373  }
3374 
3375  // fallback to using aggregate calculator to determine aggregate
3376  QgsAggregateCalculator c( this );
3377  c.setParameters( parameters );
3378  return c.calculate( aggregate, fieldOrExpression, context, ok );
3379 }
3380 
3381 QList<QVariant> QgsVectorLayer::getValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly )
3382 {
3383  QList<QVariant> values;
3384 
3385  QScopedPointer<QgsExpression> expression;
3386  QgsExpressionContext context;
3387 
3388  int attrNum = fieldNameIndex( fieldOrExpression );
3389 
3390  if ( attrNum == -1 )
3391  {
3392  // try to use expression
3393  expression.reset( new QgsExpression( fieldOrExpression ) );
3397 
3398  if ( expression->hasParserError() || !expression->prepare( &context ) )
3399  {
3400  ok = false;
3401  return values;
3402  }
3403  }
3404 
3405  QgsFeature f;
3406  QStringList lst;
3407  if ( expression.isNull() )
3408  lst.append( fieldOrExpression );
3409  else
3410  lst = expression->referencedColumns();
3411 
3413  .setFlags(( expression && expression->needsGeometry() ) ?
3416  .setSubsetOfAttributes( lst, fields() );
3417 
3418  QgsFeatureIterator fit;
3419  if ( !selectedOnly )
3420  {
3421  fit = getFeatures( request );
3422  }
3423  else
3424  {
3425  fit = selectedFeaturesIterator( request );
3426  }
3427 
3428  // create list of non-null attribute values
3429  while ( fit.nextFeature( f ) )
3430  {
3431  if ( expression )
3432  {
3433  context.setFeature( f );
3434  QVariant v = expression->evaluate( &context );
3435  values << v;
3436  }
3437  else
3438  {
3439  values << f.attribute( attrNum );
3440  }
3441  }
3442  ok = true;
3443  return values;
3444 }
3445 
3446 QList<double> QgsVectorLayer::getDoubleValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly, int* nullCount )
3447 {
3448  QList<double> values;
3449 
3450  if ( nullCount )
3451  *nullCount = 0;
3452 
3453  QList<QVariant> variantValues = getValues( fieldOrExpression, ok, selectedOnly );
3454  if ( !ok )
3455  return values;
3456 
3457  bool convertOk;
3458  Q_FOREACH ( const QVariant& value, variantValues )
3459  {
3460  double val = value.toDouble( &convertOk );
3461  if ( convertOk )
3462  values << val;
3463  else if ( value.isNull() )
3464  {
3465  if ( nullCount )
3466  *nullCount += 1;
3467  }
3468  }
3469  ok = true;
3470  return values;
3471 }
3472 
3473 
3476 {
3477  mFeatureBlendMode = featureBlendMode;
3478  emit featureBlendModeChanged( featureBlendMode );
3479 }
3480 
3482 QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
3483 {
3484  return mFeatureBlendMode;
3485 }
3486 
3489 {
3490  mLayerTransparency = layerTransparency;
3491  emit layerTransparencyChanged( layerTransparency );
3492 }
3493 
3496 {
3497  return mLayerTransparency;
3498 }
3499 
3500 
3501 
3502 void QgsVectorLayer::readSldLabeling( const QDomNode& node )
3503 {
3504  QDomElement element = node.toElement();
3505  if ( element.isNull() )
3506  return;
3507 
3508  QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
3509  if ( userStyleElem.isNull() )
3510  {
3511  QgsDebugMsg( "Info: UserStyle element not found." );
3512  return;
3513  }
3514 
3515  QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
3516  if ( featureTypeStyleElem.isNull() )
3517  {
3518  QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
3519  return;
3520  }
3521 
3522  // use last rule
3523  QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
3524  if ( ruleElem.isNull() )
3525  {
3526  QgsDebugMsg( "Info: Rule element not found." );
3527  return;
3528  }
3529 
3530  // use last text symbolizer
3531  QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3532  if ( textSymbolizerElem.isNull() )
3533  {
3534  QgsDebugMsg( "Info: TextSymbolizer element not found." );
3535  return;
3536  }
3537 
3538  // Label
3539  setCustomProperty( "labeling/enabled", false );
3540  QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3541  if ( !labelElem.isNull() )
3542  {
3543  QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3544  if ( !propertyNameElem.isNull() )
3545  {
3546  // enable labeling
3547  setCustomProperty( "labeling", "pal" );
3548  setCustomProperty( "labeling/enabled", true );
3549 
3550  // set labeling defaults
3551  setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3552  setCustomProperty( "labeling/fontItalic", false );
3553  setCustomProperty( "labeling/fontSize", 10 );
3554  setCustomProperty( "labeling/fontSizeInMapUnits", false );
3555  setCustomProperty( "labeling/fontBold", false );
3556  setCustomProperty( "labeling/fontUnderline", false );
3557  setCustomProperty( "labeling/textColorR", 0 );
3558  setCustomProperty( "labeling/textColorG", 0 );
3559  setCustomProperty( "labeling/textColorB", 0 );
3560  setCustomProperty( "labeling/textTransp", 0 );
3561  setCustomProperty( "labeling/bufferDraw", false );
3562  setCustomProperty( "labeling/bufferSize", 1 );
3563  setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3564  setCustomProperty( "labeling/bufferColorR", 255 );
3565  setCustomProperty( "labeling/bufferColorG", 255 );
3566  setCustomProperty( "labeling/bufferColorB", 255 );
3567  setCustomProperty( "labeling/bufferTransp", 0 );
3568  setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3569  setCustomProperty( "labeling/xOffset", 0 );
3570  setCustomProperty( "labeling/yOffset", 0 );
3571  setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3572  setCustomProperty( "labeling/angleOffset", 0 );
3573 
3574  // label attribute
3575  QString labelAttribute = propertyNameElem.text();
3576  setCustomProperty( "labeling/fieldName", labelAttribute );
3577  setCustomProperty( "labeling/isExpression", false );
3578 
3579  int fieldIndex = fieldNameIndex( labelAttribute );
3580  if ( fieldIndex == -1 )
3581  {
3582  // label attribute is not in columns, check if it is an expression
3583  QgsExpression exp( labelAttribute );
3584  if ( !exp.hasEvalError() )
3585  {
3586  setCustomProperty( "labeling/isExpression", true );
3587  }
3588  else
3589  {
3590  QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3591  }
3592  }
3593  }
3594  else
3595  {
3596  QgsDebugMsg( "Info: PropertyName element not found." );
3597  return;
3598  }
3599  }
3600  else
3601  {
3602  QgsDebugMsg( "Info: Label element not found." );
3603  return;
3604  }
3605 
3606  // Font
3607  QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3608  if ( !fontElem.isNull() )
3609  {
3610  QString cssName;
3611  QString elemText;
3612  QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3613  while ( !cssElem.isNull() )
3614  {
3615  cssName = cssElem.attribute( "name", "not_found" );
3616  if ( cssName != "not_found" )
3617  {
3618  elemText = cssElem.text();
3619  if ( cssName == "font-family" )
3620  {
3621  setCustomProperty( "labeling/fontFamily", elemText );
3622  }
3623  else if ( cssName == "font-style" )
3624  {
3625  setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3626  }
3627  else if ( cssName == "font-size" )
3628  {
3629  bool ok;
3630  int fontSize = elemText.toInt( &ok );
3631  if ( ok )
3632  {
3633  setCustomProperty( "labeling/fontSize", fontSize );
3634  }
3635  }
3636  else if ( cssName == "font-weight" )
3637  {
3638  setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3639  }
3640  else if ( cssName == "font-underline" )
3641  {
3642  setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3643  }
3644  }
3645 
3646  cssElem = cssElem.nextSiblingElement( "CssParameter" );
3647  }
3648  }
3649 
3650  // Fill
3651  QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3652  if ( textColor.isValid() )
3653  {
3654  setCustomProperty( "labeling/textColorR", textColor.red() );
3655  setCustomProperty( "labeling/textColorG", textColor.green() );
3656  setCustomProperty( "labeling/textColorB", textColor.blue() );
3657  setCustomProperty( "labeling/textTransp", 100 - static_cast< int >( 100 * textColor.alphaF() ) );
3658  }
3659 
3660  // Halo
3661  QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3662  if ( !haloElem.isNull() )
3663  {
3664  setCustomProperty( "labeling/bufferDraw", true );
3665  setCustomProperty( "labeling/bufferSize", 1 );
3666 
3667  QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3668  if ( !radiusElem.isNull() )
3669  {
3670  bool ok;
3671  double bufferSize = radiusElem.text().toDouble( &ok );
3672  if ( ok )
3673  {
3674  setCustomProperty( "labeling/bufferSize", bufferSize );
3675  }
3676  }
3677 
3678  QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3679  if ( bufferColor.isValid() )
3680  {
3681  setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3682  setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3683  setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3684  setCustomProperty( "labeling/bufferTransp", 100 - static_cast< int >( 100 * bufferColor.alphaF() ) );
3685  }
3686  }
3687 
3688  // LabelPlacement
3689  QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3690  if ( !labelPlacementElem.isNull() )
3691  {
3692  // PointPlacement
3693  QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3694  if ( !pointPlacementElem.isNull() )
3695  {
3696  setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3697 
3698  QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3699  if ( !displacementElem.isNull() )
3700  {
3701  QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3702  if ( !displacementXElem.isNull() )
3703  {
3704  bool ok;
3705  double xOffset = displacementXElem.text().toDouble( &ok );
3706  if ( ok )
3707  {
3708  setCustomProperty( "labeling/xOffset", xOffset );
3709  }
3710  }
3711  QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3712  if ( !displacementYElem.isNull() )
3713  {
3714  bool ok;
3715  double yOffset = displacementYElem.text().toDouble( &ok );
3716  if ( ok )
3717  {
3718  setCustomProperty( "labeling/yOffset", yOffset );
3719  }
3720  }
3721  }
3722 
3723  QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3724  if ( !rotationElem.isNull() )
3725  {
3726  bool ok;
3727  double rotation = rotationElem.text().toDouble( &ok );
3728  if ( ok )
3729  {
3730  setCustomProperty( "labeling/angleOffset", rotation );
3731  }
3732  }
3733  }
3734  }
3735 }
3736 
3738 {
3739  return mAttributeTableConfig;
3740 }
3741 
3743 {
3744  mAttributeTableConfig = attributeTableConfig;
3745 }
3746 
3748 {
3749  if ( !mDiagramLayerSettings )
3750  mDiagramLayerSettings = new QgsDiagramLayerSettings();
3751  *mDiagramLayerSettings = s;
3752 }
3753 
3755 {
3756  QString myMetadata = "<html><body>";
3757 
3758  //-------------
3759 
3760  myMetadata += "<p class=\"subheaderglossy\">";
3761  myMetadata += tr( "General" );
3762  myMetadata += "</p>\n";
3763 
3764  // data comment
3765  if ( !( dataComment().isEmpty() ) )
3766  {
3767  myMetadata += "<p class=\"glossy\">" + tr( "Layer comment" ) + "</p>\n";
3768  myMetadata += "<p>";
3769  myMetadata += dataComment();
3770  myMetadata += "</p>\n";
3771  }
3772 
3773  //storage type
3774  myMetadata += "<p class=\"glossy\">" + tr( "Storage type of this layer" ) + "</p>\n";
3775  myMetadata += "<p>";
3776  myMetadata += storageType();
3777  myMetadata += "</p>\n";
3778 
3779  if ( dataProvider() )
3780  {
3781  //provider description
3782  myMetadata += "<p class=\"glossy\">" + tr( "Description of this provider" ) + "</p>\n";
3783  myMetadata += "<p>";
3784  myMetadata += dataProvider()->description().replace( '\n', "<br>" );
3785  myMetadata += "</p>\n";
3786  }
3787 
3788  // data source
3789  myMetadata += "<p class=\"glossy\">" + tr( "Source for this layer" ) + "</p>\n";
3790  myMetadata += "<p>";
3791  myMetadata += publicSource();
3792  myMetadata += "</p>\n";
3793 
3794  //geom type
3795 
3797 
3798  if ( type < 0 || type > QGis::NoGeometry )
3799  {
3800  QgsDebugMsg( "Invalid vector type" );
3801  }
3802  else
3803  {
3804  QString typeString( QGis::vectorGeometryType( geometryType() ) );
3805 
3806  myMetadata += "<p class=\"glossy\">" + tr( "Geometry type of the features in this layer" ) + "</p>\n";
3807  myMetadata += "<p>";
3808  myMetadata += typeString;
3809  myMetadata += "</p>\n";
3810  }
3811 
3812  QgsAttributeList pkAttrList = pkAttributeList();
3813  if ( !pkAttrList.isEmpty() )
3814  {
3815  myMetadata += "<p class=\"glossy\">" + tr( "Primary key attributes" ) + "</p>\n";
3816  myMetadata += "<p>";
3817  Q_FOREACH ( int idx, pkAttrList )
3818  {
3819  myMetadata += fields().at( idx ).name() + ' ';
3820  }
3821  myMetadata += "</p>\n";
3822  }
3823 
3824 
3825  //feature count
3826  myMetadata += "<p class=\"glossy\">" + tr( "The number of features in this layer" ) + "</p>\n";
3827  myMetadata += "<p>";
3828  myMetadata += QString::number( featureCount() );
3829  myMetadata += "</p>\n";
3830  //capabilities
3831  myMetadata += "<p class=\"glossy\">" + tr( "Capabilities of this layer" ) + "</p>\n";
3832  myMetadata += "<p>";
3833  myMetadata += capabilitiesString();
3834  myMetadata += "</p>\n";
3835 
3836  //-------------
3837 
3838  QgsRectangle myExtent = extent();
3839  myMetadata += "<p class=\"subheaderglossy\">";
3840  myMetadata += tr( "Extents" );
3841  myMetadata += "</p>\n";
3842 
3843  //extents in layer cs TODO...maybe make a little nested table to improve layout...
3844  myMetadata += "<p class=\"glossy\">" + tr( "In layer spatial reference system units" ) + "</p>\n";
3845  myMetadata += "<p>";
3846  // Try to be a bit clever over what number format we use for the
3847  // extents. Some people don't like it using scientific notation when the
3848  // numbers get large, but for small numbers this is the more practical
3849  // option (so we can't force the format to 'f' for all values).
3850  // The scheme:
3851  // - for all numbers with more than 5 digits, force non-scientific notation
3852  // and 2 digits after the decimal point.
3853  // - for all smaller numbers let the OS decide which format to use (it will
3854  // generally use non-scientific unless the number gets much less than 1).
3855 
3856  if ( !myExtent.isEmpty() )
3857  {
3858  QString xMin, yMin, xMax, yMax;
3859  double changeoverValue = 99999; // The 'largest' 5 digit number
3860  if ( qAbs( myExtent.xMinimum() ) > changeoverValue )
3861  {
3862  xMin = QString( "%1" ).arg( myExtent.xMinimum(), 0, 'f', 2 );
3863  }
3864  else
3865  {
3866  xMin = QString( "%1" ).arg( myExtent.xMinimum() );
3867  }
3868  if ( qAbs( myExtent.yMinimum() ) > changeoverValue )
3869  {
3870  yMin = QString( "%1" ).arg( myExtent.yMinimum(), 0, 'f', 2 );
3871  }
3872  else
3873  {
3874  yMin = QString( "%1" ).arg( myExtent.yMinimum() );
3875  }
3876  if ( qAbs( myExtent.xMaximum() ) > changeoverValue )
3877  {
3878  xMax = QString( "%1" ).arg( myExtent.xMaximum(), 0, 'f', 2 );
3879  }
3880  else
3881  {
3882  xMax = QString( "%1" ).arg( myExtent.xMaximum() );
3883  }
3884  if ( qAbs( myExtent.yMaximum() ) > changeoverValue )
3885  {
3886  yMax = QString( "%1" ).arg( myExtent.yMaximum(), 0, 'f', 2 );
3887  }
3888  else
3889  {
3890  yMax = QString( "%1" ).arg( myExtent.yMaximum() );
3891  }
3892 
3893  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3894  .arg( xMin, yMin, xMax, yMax );
3895  }
3896  else
3897  {
3898  myMetadata += tr( "unknown extent" );
3899  }
3900 
3901  myMetadata += "</p>\n";
3902 
3903  //extents in project cs
3904 
3905  try
3906  {
3907 #if 0
3908  // TODO: currently disabled, will revisit later [MD]
3909  QgsRectangle myProjectedExtent = coordinateTransform->transformBoundingBox( extent() );
3910  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3911  myMetadata += "<p>";
3912  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3913  .arg( myProjectedExtent.xMinimum() )
3914  .arg( myProjectedExtent.yMinimum() )
3915  .arg( myProjectedExtent.xMaximum() )
3916  .arg( myProjectedExtent.yMaximum() );
3917  myMetadata += "</p>\n";
3918 #endif
3919 
3920  //
3921  // Display layer spatial ref system
3922  //
3923  myMetadata += "<p class=\"glossy\">" + tr( "Layer Spatial Reference System" ) + "</p>\n";
3924  myMetadata += "<p>";
3925  myMetadata += crs().toProj4().replace( '"', " \"" );
3926  myMetadata += "</p>\n";
3927 
3928  //
3929  // Display project (output) spatial ref system
3930  //
3931 #if 0
3932  // TODO: disabled for now, will revisit later [MD]
3933  //myMetadata += "<tr><td bgcolor=\"gray\">";
3934  myMetadata += "<p class=\"glossy\">" + tr( "Project (Output) Spatial Reference System" ) + "</p>\n";
3935  myMetadata += "<p>";
3936  myMetadata += coordinateTransform->destCRS().toProj4().replace( '"', " \"" );
3937  myMetadata += "</p>\n";
3938 #endif
3939  }
3940  catch ( QgsCsException &cse )
3941  {
3942  Q_UNUSED( cse );
3943  QgsDebugMsg( cse.what() );
3944 
3945  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3946  myMetadata += "<p>";
3947  myMetadata += tr( "(Invalid transformation of layer extents)" );
3948  myMetadata += "</p>\n";
3949 
3950  }
3951 
3952 #if 0
3953  //
3954  // Add the info about each field in the attribute table
3955  //
3956  myMetadata += "<p class=\"glossy\">" + tr( "Attribute field info" ) + "</p>\n";
3957  myMetadata += "<p>";
3958 
3959  // Start a nested table in this trow
3960  myMetadata += "<table width=\"100%\">";
3961  myMetadata += "<tr><th>";
3962  myMetadata += tr( "Field" );
3963  myMetadata += "</th>";
3964  myMetadata += "<th>";
3965  myMetadata += tr( "Type" );
3966  myMetadata += "</th>";
3967  myMetadata += "<th>";
3968  myMetadata += tr( "Length" );
3969  myMetadata += "</th>";
3970  myMetadata += "<th>";
3971  myMetadata += tr( "Precision" );
3972  myMetadata += "</th>";
3973  myMetadata += "<th>";
3974  myMetadata += tr( "Comment" );
3975  myMetadata += "</th>";
3976 
3977  //get info for each field by looping through them
3978  const QgsFields& myFields = pendingFields();
3979  for ( int i = 0, n = myFields.size(); i < n; ++i )
3980  {
3981  const QgsField& myField = fields[i];
3982 
3983  myMetadata += "<tr><td>";
3984  myMetadata += myField.name();
3985  myMetadata += "</td>";
3986  myMetadata += "<td>";
3987  myMetadata += myField.typeName();
3988  myMetadata += "</td>";
3989  myMetadata += "<td>";
3990  myMetadata += QString( "%1" ).arg( myField.length() );
3991  myMetadata += "</td>";
3992  myMetadata += "<td>";
3993  myMetadata += QString( "%1" ).arg( myField.precision() );
3994  myMetadata += "</td>";
3995  myMetadata += "<td>";
3996  myMetadata += QString( "%1" ).arg( myField.comment() );
3997  myMetadata += "</td></tr>";
3998  }
3999 
4000  //close field list
4001  myMetadata += "</table>"; //end of nested table
4002 #endif
4003 
4004  myMetadata += "</body></html>";
4005  return myMetadata;
4006 }
4007 
4009 {
4010  mSymbolFeatureCounted = false;
4011 }
4012 
4013 void QgsVectorLayer::onJoinedFieldsChanged()
4014 {
4015  // some of the fields of joined layers have changed -> we need to update this layer's fields too
4016  updateFields();
4017 }
4018 
4019 void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid )
4020 {
4021  if ( mEditCommandActive )
4022  mDeletedFids << fid;
4023  else
4024  emit featuresDeleted( QgsFeatureIds() << fid );
4025 
4026  emit featureDeleted( fid );
4027 }
4028 
4030 {
4031  if ( mEditFormConfig->widgetType( idx ) == "ValueRelation" )
4032  {
4033  QgsEditorWidgetConfig cfg = mEditFormConfig->widgetConfig( idx );
4034 
4035  return ValueRelationData( cfg.value( "Layer" ).toString(),
4036  cfg.value( "Key" ).toString(),
4037  cfg.value( "Value" ).toString(),
4038  cfg.value( "AllowNull" ).toBool(),
4039  cfg.value( "OrderByValue" ).toBool(),
4040  cfg.value( "AllowMulti" ).toBool(),
4041  cfg.value( "FilterExpression" ).toString()
4042  );
4043  }
4044  else
4045  {
4046  return ValueRelationData();
4047  }
4048 }
4049 
4051 {
4052  return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
4053 }
4054 
4056 {
4057  QDomElement elem = doc.createElement( "attributeEditorContainer" );
4058  elem.setAttribute( "name", mName );
4059  elem.setAttribute( "columnCount", mColumnCount );
4060 
4061  Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
4062  {
4063  elem.appendChild( child->toDomElement( doc ) );
4064  }
4065  return elem;
4066 }
4067 
4069 {
4070  mChildren.append( widget );
4071 }
4072 
4074 {
4075  mName = name;
4076 }
4077 
4079 {
4081 
4082  Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
4083  {
4084  if ( elem->type() == type )
4085  {
4086  results.append( elem );
4087  }
4088 
4089  if ( elem->type() == AeTypeContainer )
4090  {
4091  QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
4092  if ( cont )
4093  results += cont->findElements( type );
4094  }
4095  }
4096 
4097  return results;
4098 }
4099 
4101 {
4102  QDomElement elem = doc.createElement( "attributeEditorField" );
4103  elem.setAttribute( "name", mName );
4104  elem.setAttribute( "index", mIdx );
4105  return elem;
4106 }
4107 
4109 {
4111  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
4112  if ( !myLib )
4113  {
4114  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
4115  return -1;
4116  }
4117  listStyles_t* listStylesExternalMethod = reinterpret_cast< listStyles_t * >( cast_to_fptr( myLib->resolve( "listStyles" ) ) );
4118 
4119  if ( !listStylesExternalMethod )
4120  {
4121  delete myLib;
4122  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "listStyles" );
4123  return -1;
4124  }
4125 
4126  return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
4127 }
4128 
4130 {
4132  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
4133  if ( !myLib )
4134  {
4135  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
4136  return QObject::tr( "" );
4137  }
4138  getStyleById_t* getStyleByIdMethod = reinterpret_cast< getStyleById_t * >( cast_to_fptr( myLib->resolve( "getStyleById" ) ) );
4139 
4140  if ( !getStyleByIdMethod )
4141  {
4142  delete myLib;
4143  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "getStyleById" );
4144  return QObject::tr( "" );
4145  }
4146 
4147  return getStyleByIdMethod( mDataSource, styleId, msgError );
4148 }
4149 
4150 
4151 void QgsVectorLayer::saveStyleToDatabase( const QString& name, const QString& description,
4152  bool useAsDefault, const QString& uiFileContent, QString &msgError )
4153 {
4154 
4155  QString sldStyle, qmlStyle;
4157  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
4158  if ( !myLib )
4159  {
4160  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
4161  return;
4162  }
4163  saveStyle_t* saveStyleExternalMethod = reinterpret_cast< saveStyle_t * >( cast_to_fptr( myLib->resolve( "saveStyle" ) ) );
4164 
4165  if ( !saveStyleExternalMethod )
4166  {
4167  delete myLib;
4168  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "saveStyle" );
4169  return;
4170  }
4171 
4172  QDomDocument qmlDocument, sldDocument;
4173  this->exportNamedStyle( qmlDocument, msgError );
4174  if ( !msgError.isNull() )
4175  {
4176  return;
4177  }
4178  qmlStyle = qmlDocument.toString();
4179 
4180  this->exportSldStyle( sldDocument, msgError );
4181  if ( !msgError.isNull() )
4182  {
4183  return;
4184  }
4185  sldStyle = sldDocument.toString();
4186 
4187  saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
4188  description, uiFileContent, useAsDefault, msgError );
4189 }
4190 
4191 
4192 
4193 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag )
4194 {
4195  return loadNamedStyle( theURI, theResultFlag, false );
4196 }
4197 
4198 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag, bool loadFromLocalDB )
4199 {
4200  QgsDataSourceURI dsUri( theURI );
4201  if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
4202  {
4204  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
4205  if ( myLib )
4206  {
4207  loadStyle_t* loadStyleExternalMethod = reinterpret_cast< loadStyle_t * >( cast_to_fptr( myLib->resolve( "loadStyle" ) ) );
4208  if ( loadStyleExternalMethod )
4209  {
4210  QString qml, errorMsg;
4211  qml = loadStyleExternalMethod( mDataSource, errorMsg );
4212  if ( !qml.isEmpty() )
4213  {
4215  theResultFlag = applyNamedStyle( qml, errorMsg );
4217  return QObject::tr( "Loaded from Provider" );
4218  }
4219  }
4220  }
4221  }
4222 
4223  return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
4224 }
4225 
4226 bool QgsVectorLayer::applyNamedStyle( const QString& namedStyle, QString& errorMsg )
4227 {
4228  QDomDocument myDocument( "qgis" );
4229  myDocument.setContent( namedStyle );
4230 
4231  return importNamedStyle( myDocument, errorMsg );
4232 }
4233 
4234 
4236 {
4237  QDomElement elem = doc.createElement( "attributeEditorRelation" );
4238  elem.setAttribute( "name", mName );
4239  elem.setAttribute( "relation", mRelation.id() );
4240  return elem;
4241 }
4242 
4244 {
4245  mRelation = relationManager->relation( mRelationId );
4246  return mRelation.isValid();
4247 }
4248 
4250 {
4251  if ( mDataProvider )
4252  {
4253  return mDataProvider->layerDependencies();
4254  }
4255  return QSet<QString>();
4256 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
Q_DECL_DEPRECATED bool deleteVertex(QgsFeatureId atFeatureId, int atVertex)
Deletes a vertex from a feature.
QObject * child(const char *objName, const char *inheritsClass, bool recursiveSearch) const
void setExtent(const QgsRectangle &rect) override
Set the extent.
bool draw(QgsRenderContext &rendererContext) override
Draws the layer.
virtual QString subsetString()
Get the string (typically sql) used to define a subset of the layer.
virtual Q_DECL_DEPRECATED bool applyNamedStyle(const QString &namedStyle, QString &errorMsg)
Will load a named style from a provided QML string.
Class for parsing and evaluation of expressions (formerly called "search strings").
void updateFields()
Assembles mUpdatedFields considering provider fields, joined fields and added fields.
Q_DECL_DEPRECATED int removePolygonIntersections(QgsGeometry *geom, const QgsFeatureIds &ignoreFeatures=QgsFeatureIds())
Changes the specified geometry such that it has no intersections with other polygon (or multipolygon)...
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
void clear()
Wrapper for iterator of features from vector data provider or vector layer.
bool isValid() const
Returns the validity of this relation.
void featuresDeleted(const QgsFeatureIds &fids)
Emitted when features have been deleted.
void selectAll()
Select all the features.
QDomNodeList elementsByTagName(const QString &tagname) const
QString database() const
Returns the database.
bool intersects(const QgsRectangle &rect) const
returns true when rectangle intersects with other rectangle
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
#define RENDERER_TAG_NAME
Definition: qgsrendererv2.h:49
static unsigned index
bool addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.
static QgsProviderRegistry * instance(const QString &pluginPath=QString::null)
Means of accessing canonical single instance.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:49
bool init(QgsRelationManager *relManager)
Initializes the relation from the id.
const QList< QgsVectorJoinInfo > vectorJoins() const
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
bool isEmpty() const
test if rectangle is empty.
iterator insert(const Key &key, const T &value)
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
bool readSymbology(const QDomNode &node, QString &errorMessage) override
Read the symbology for the current layer from the Dom node supplied.
field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfield.h:201
float threshold() const
Gets the simplification threshold of the vector layer managed.
QgsFeatureList selectedFeatures()
Get a copy of the user-selected features.
QgsMapLayer::LayerType type() const
Get the type of the layer.
Definition: qgsmaplayer.cpp:97
void setName(const QString &name)
Change the name of this container.
virtual bool writeXml(QDomNode &layer_node, QDomDocument &doc) override
Write vector layer specific state to project file Dom node.
QStringList referencedColumns() const
Get list of columns referenced by the expression.
This is an abstract base class for any elements of a drag and drop form.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
bool diagramsEnabled() const
Returns whether the layer contains diagrams which are enabled and should be drawn.
virtual bool mustStop() const
return true if the iterator must stop as soon as possible
GeometryType
Definition: qgis.h:115
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
void readCustomProperties(const QDomNode &layerNode, const QString &keyStartsWith="")
Read custom properties from project file.
qreal alphaF() const
QString name() const
Get the display name of the layer.
void selectByRect(QgsRectangle &rect, SelectBehaviour behaviour=SetSelection)
Select features found within the search rectangle (in layer&#39;s coordinates)
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example...
QDomNode appendChild(const QDomNode &newChild)
void beforeRollBack()
Is emitted, before changes are rolled back.
void beginEditCommand(const QString &text)
Create edit command for undo/redo operations.
bool readStyle(const QDomNode &node, QString &errorMessage) override
Read the style for the current layer from the Dom node supplied.
Use exact geometry intersection (slower) instead of bounding boxes.
static QgsFeatureRendererV2 * loadSld(const QDomNode &node, QGis::GeometryType geomType, QString &errorMessage)
Create a new renderer according to the information contained in the UserStyle element of a SLD style ...
void setMaximum(int maximum)
void push_back(const T &value)
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
QVariant maximumValue(int index)
Returns maximum value for an attribute column or invalid variant in case of error.
Modify current selection to include only select features which match.
Renders the diagrams for all features with the same settings.
QString capabilitiesString() const
Returns the above in friendly format.
Q_DECL_DEPRECATED const QString editorWidgetV2(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
QString attribute(const QString &name, const QString &defValue) const
bool hasPendingEvents()
void setWindowModality(Qt::WindowModality windowModality)
Q_DECL_DEPRECATED bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfield.h:202
int addTopologicalPoints(const QgsGeometry *geom)
Adds topological points for every vertex of the geometry.
void beginMacro(const QString &text)
void layerTransparencyChanged(int layerTransparency)
Signal emitted when setLayerTransparency() is called.
QgsVectorLayerInterruptionCheckerDuringCountSymbolFeatures(QProgressDialog *dialog)
Constructor.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:197
bool deleteFeature(QgsFeatureId fid)
Delete a feature from the layer (but does not commit it)
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:439
QgsFields fields() const
Returns the list of fields of this layer.
void clear()
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Returns unique values for column.
QString toString(int indent) const
int fieldNameIndex(const QString &fieldName) const
Look up field&#39;s index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:534
double rendererScale() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
friend class QgsVectorLayerFeatureSource
void setForceLocalOptimization(bool localOptimization)
Sets where the simplification executes, after fetch the geometries from provider, or when supported...
double closestSegmentWithContext(const QgsPoint &point, QgsPoint &minDistPoint, int &afterVertex, double *leftOf=nullptr, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
void invertSelectionInRectangle(QgsRectangle &rect)
Invert selection of features found within the search rectangle (in layer&#39;s coordinates) ...
bool commitChanges()
Attempts to commit any changes to disk.
void setRendererV2(QgsFeatureRendererV2 *r)
Set renderer which will be invoked to represent this layer.
int size() const
virtual void setEncoding(const QString &e)
Set encoding used for accessing data from layer.
bool startEditing()
Make layer editable.
const_iterator constBegin() const
void setRendererScale(double scale)
const T & at(int i) const
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
VertexMarkerType
Editing vertex markers.
void removeExpressionField(int index)
Remove an expression field.
void setFeatureBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering each feature.
Q_DECL_DEPRECATED void select(QgsRectangle &rect, bool addToSelection)
Select features found within the search rectangle (in layer&#39;s coordinates)
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:504
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:104
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
int makeDifference(const QgsGeometry *other)
Changes this geometry such that it does not intersect the other geometry.
virtual QList< QgsDiagramSettings > diagramSettings() const =0
Returns list with all diagram settings in the renderer.
static QgsMapRenderer::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
Q_DECL_DEPRECATED QString dateFormat(int idx)
Access date format.
SimplifyHint
Simplification flags for fast rendering of features.
Utility class for calculating aggregates for a field (or expression) over the features from a vector ...
bool deleteAttributes(QList< int > attrs)
Deletes a list of attribute fields (but does not commit it)
void setLabeling(QgsAbstractVectorLayerLabeling *labeling)
Set labeling configuration.
void readCustomSymbology(const QDomElement &element, QString &errorMessage)
Signal emitted whenever the symbology (QML-file) for this layer is being read.
QDomElement nextSiblingElement(const QString &tagName) const
QgsConditionalLayerStyles * conditionalStyles() const
Return the conditional styles that are set for this layer.
bool deleteFeatures(const QgsFeatureIds &fids)
Deletes a set of features from the layer (but does not commit it)
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
Q_DECL_DEPRECATED QMap< QString, QVariant > valueMap(int idx)
Access value map.
T value() const
virtual void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Return unique values of an attribute.
Container of fields for a vector layer.
Definition: qgsfield.h:193
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
void setDiagramRenderer(QgsDiagramRendererV2 *r)
Sets diagram rendering object (takes ownership)
void setLayerTransparency(int layerTransparency)
Set the transparency for the vector layer.
QSet< T > & subtract(const QSet< T > &other)
ValueRelationData valueRelation(int idx)
Access value relation widget data.
void beforeRemovingExpressionField(int idx)
Will be emitted, when an expression field is going to be deleted from this vector layer...
virtual QSet< QString > layerDependencies() const
Get the list of layer ids on which this layer depends.
static const char * vectorGeometryType(GeometryType type)
description strings for geometry types
Definition: qgis.cpp:435
WkbType
Used for symbology operations.
Definition: qgis.h:61
const QgsRectangle & extent() const
QSet< T > toSet() const
void remAttributeAlias(int attIndex)
Removes an alias (a display name) for attributes to display in dialogs.
QList< double > getDoubleValues(const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=nullptr)
Fetches all double values from a specified field name or expression.
QString comment() const
Returns the field comment.
Definition: qgsfield.cpp:109
The QGis class provides global constants for use throughout the application.
Definition: qgis.h:40
Set selection, removing any existing selection.
void setDisplayExpression(const QString &displayExpression)
Set the preview expression, used to create a human readable preview string.
bool addFeature(QgsFeature &f, bool alsoUpdateExtent=true)
Adds a feature.
virtual QList< QString > usedAttributes()=0
Returns a set of attributes required for this renderer.
void selectByIds(const QgsFeatureIds &ids, SelectBehaviour behaviour=SetSelection)
Select matching features using a list of feature IDs.
field comes from the underlying data provider of the vector layer (originIndex = index in provider&#39;s ...
Definition: qgsfield.h:200
Edit operation resulted in an empty geometry.
QString expressionField(int index)
Returns the expressoin used for a given expression field.
int addPart(const QList< QgsPoint > &ring, QgsFeatureId featureId)
Adds a new part polygon to a multipart feature.
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QString & remove(int position, int n)
QList< QgsRelation > referencingRelations(int idx)
Get relations, where the foreign key is on this layer.
void drawLine(const QLineF &line)
static const int EditingCapabilities
Bitmask of all provider&#39;s editing capabilities.
virtual ~QgsVectorLayer()
Destructor.
virtual QgsCurveV2 * clone() const override=0
Clones the geometry by performing a deep copy.
Q_DECL_DEPRECATED void setCheckedState(int idx, const QString &checked, const QString &notChecked)
Set string representing &#39;true&#39; for a checkbox.
const QString displayExpression()
Get the preview expression, used to create a human readable preview string.
void beforeCommitChanges()
Is emitted, before changes are commited to the data provider.
virtual Q_DECL_DEPRECATED bool isReadOnly() const override
Returns true if the provider is in read-only mode.
void chop(int n)
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
double toDouble(bool *ok) const
void committedAttributesDeleted(const QString &layerId, const QgsAttributeList &deletedAttributes)
Signals emitted after committing changes.
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
QVariant minimumValue(int index)
Returns minimum value for an attribute column or invalid variant in case of error.
void selectByExpression(const QString &expression, SelectBehaviour behaviour=SetSelection)
Select matching features using an expression.
bool insertVertex(double x, double y, QgsFeatureId atFeatureId, int beforeVertex)
Insert a new vertex before the given vertex number, in the given ring, item (first number is index 0)...
void setSimplifyHints(const SimplifyHints &simplifyHints)
Sets the simplification hints of the vector layer managed.
virtual Q_DECL_DEPRECATED bool willRenderFeature(QgsFeature &feat)
Returns whether the renderer will render a feature or not.
QString tr(const char *sourceText, const char *disambiguation, int n)
void featureDeleted(QgsFeatureId fid)
Emitted when a feature has been deleted.
QString readPath(QString filename) const
Turn filename read from the project file to an absolute path.
void editCommandEnded()
Signal emitted, when an edit command successfully ended.
void writeCustomSymbology(QDomElement &element, QDomDocument &doc, QString &errorMessage) const
Signal emitted whenever the symbology (QML-file) for this layer is being written. ...
QString mLayerName
Name of the layer - used for display.
Definition: qgsmaplayer.h:726
void invertSelection()
Select not selected features and deselect selected ones.
void setParameters(const AggregateParameters &parameters)
Sets all aggregate parameters from a parameter bundle.
double x() const
Get the x value of the point.
Definition: qgspoint.h:185
it has not been specified where the field comes from
Definition: qgsfield.h:199
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
QMap< QString, QgsMapLayer * > mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
int size() const
QgsMapLayer * mapLayer(const QString &theLayerId)
Retrieve a pointer to a loaded layer by id.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
Needs to be called when a new render cycle is started.
bool isNull() const
virtual void updateExtents()
Update the extents for the layer.
Evaluates and returns the diagram settings relating to a diagram for a specific feature.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
void removeSelection()
Clear selection.
Manages joined fields for a vector layer.
void reset(T *other)
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints.
virtual void stopRender(QgsRenderContext &context)=0
Needs to be called when a render cycle has finished to clean up.
void clear()
static QString capitaliseLayerName(const QString &name)
A convenience function to (un)capitalise the layer name.
Interface that can be optionaly attached to an iterator so its nextFeature() implementaton can check ...
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
QDomElement toElement() const
virtual QDomElement toDomElement(QDomDocument &doc) const override
Will serialize this containers information into a QDomElement for saving it in an XML file...
Q_DECL_DEPRECATED void setEditorWidgetV2(int attrIdx, const QString &widgetType)
Set the editor widget type for a field.
void setData(const QString &v)
int indexIn(const QString &str, int offset, CaretMode caretMode) const
virtual int listStylesInDatabase(QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError)
Lists all the style in db split into related to the layer and not related to.
SnappingType
Snap to vertex, to segment or both.
Definition: qgssnapper.h:66
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QString encoding() const
Get encoding which is used for accessing data.
virtual QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) override
Return new instance of QgsMapLayerRenderer that will be used for rendering of given context...
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Set feature ID that should be fetched.
void setValue(int progress)
QgsFields pendingFields() const
Returns the list of fields of this layer.
void setDataSource(const QString &dataSource, const QString &baseName, const QString &provider, bool loadDefaultStyleFlag=false)
Update the data source of the layer.
QgsFeatureRendererV2 * rendererV2()
Return renderer V2.
int elapsed() const
virtual QDomElement toDomElement(QDomDocument &doc) const override
Will serialize this elements information into a QDomElement for saving it in an XML file...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
void geometryChanged(QgsFeatureId fid, QgsGeometry &geom)
QString number(int n, int base)
int count(const T &value) const
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
void processEvents(QFlags< QEventLoop::ProcessEventsFlag > flags)
bool simplifyDrawingCanbeApplied(const QgsRenderContext &renderContext, QgsVectorSimplifyMethod::SimplifyHint simplifyHint) const
Returns whether the VectorLayer can apply the specified simplification hint.
void append(const T &value)
void setIndex(int idx)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:94
void deselect(const QgsFeatureId featureId)
Deselect feature by its ID.
void layerDeleted()
TODO QGIS3: remove in favor of QObject::destroyed.
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features.
QString & insert(int position, QChar ch)
bool writeSld(QDomNode &node, QDomDocument &doc, QString &errorMessage) const
QgsRectangle extent() override
Return the extent of the layer.
void readStyleManager(const QDomNode &layerNode)
Read style manager&#39;s configuration (if any).
bool rollBack(bool deleteBuffer=true)
Stop editing and discard the edits.
QString text() const
int toInt(bool *ok) const
bool isNull() const
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:202
const QgsAbstractVectorLayerLabeling * labeling() const
Access to labeling configuration.
QgsDataProvider * provider(const QString &providerKey, const QString &dataSource)
Create an instance of the provider.
bool hasAttribute(const QString &name) const
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:187
QString attributeDisplayName(int attributeIndex) const
Convenience function that returns the attribute alias if defined or the field name else...
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
QString capabilitiesString() const
Capabilities for this layer in a friendly format.
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
The attribute value should not be shown in the attribute form.
void featureBlendModeChanged(QPainter::CompositionMode blendMode)
Signal emitted when setFeatureBlendMode() is called.
virtual QString dataComment() const
Return a short comment for the data that this provider is providing access to (e.g.
Represents the result of a snapping operation.
Definition: qgssnapper.h:36
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer&#39;s spatial reference system.
int red() const
void setPen(const QColor &color)
QStringList capturedTexts() const
void drawEllipse(const QRectF &rectangle)
void setAttribute(const QString &name, const QString &value)
int addTopologicalPoints(const QgsGeometry *geom)
Adds topological points for every vertex of the geometry.
Q_DECL_DEPRECATED EditType editType(int idx)
Get edit type.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
void writeStyleManager(QDomNode &layerNode, QDomDocument &doc) const
Write style manager&#39;s configuration (if exists).
int snapWithContext(const QgsPoint &startPoint, double snappingTolerance, QMultiMap< double, QgsSnappingResult > &snappingResults, QgsSnapper::SnappingType snap_to)
Snaps to segment or vertex within given tolerance.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
bool writeStyle(QDomNode &node, QDomDocument &doc, QString &errorMessage) const override
Write just the style information for the layer into the document.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspointv2.h:34
int toInt(bool *ok, int base) const
virtual void setExtent(const QgsRectangle &rect)
Set the extent.
bool isEmpty() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void committedFeaturesAdded(const QString &layerId, const QgsFeatureList &addedFeatures)
QString nodeName() const
int addPart(const QList< QgsPoint > &ring)
Adds a new part polygon to a multipart feature.
bool isEmpty() const
const_iterator constEnd() const
bool deleteAttribute(int attr)
Delete an attribute field (but does not commit it)
void editingStopped()
Is emitted, when edited changes successfully have been written to the data provider.
void beforeEditingStarted()
Is emitted, before editing on this layer is started.
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
QgsPoint closestVertex(const QgsPoint &point, int &atVertex, int &beforeVertex, int &afterVertex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
bool moveVertex(double x, double y, QgsFeatureId atFeatureId, int atVertex)
Moves the vertex at the given position number, ring and item (first number is index 0)...
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
Arranges candidates in a circle around a point (or centroid of a polygon).
void triggerRepaint()
Will advice the map canvas (and any other interested party) that this layer requires to be repainted...
static void logMessage(const QString &message, const QString &tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
This class wraps a request for features to a vector layer (or directly its vector data provider)...
virtual bool isSpatial() const override
Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated w...
QList< int > QgsAttributeList
AttributeEditorType type() const
The type of this element.
void destroyEditCommand()
Destroy active command and reverts all changes in it.
void setBrush(const QBrush &brush)
void setDisplayField(const QString &fldName="")
Set the primary display field to be used in the identify results dialog.
int restart()
void writeCustomProperties(QDomNode &layerNode, QDomDocument &doc) const
Write custom properties to project file.
Storage and management of actions associated with a layer.
const T & value() const
const QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
Definition: qgis.cpp:74
QMap< Key, T >::iterator insert(const Key &key, const T &value)
const QString displayField() const
Returns the primary display field name used in the identify results dialog.
const_iterator constEnd() const
bool setReadOnly(bool readonly=true)
Make layer read-only (editing disabled) or not.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
Change feature&#39;s geometry.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
int afterVertexNr
The index of the vertex after snappedVertex or -1 if no such vertex.
Definition: qgssnapper.h:52
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
virtual bool importNamedStyle(QDomDocument &doc, QString &errorMsg)
Import the properties of this layer from a QDomDocument.
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer.
iterator end()
static QgsFeatureRendererV2 * defaultRenderer(QGis::GeometryType geomType)
return a new renderer - used by default in vector layers
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
void rendererChanged()
Signal emitted when renderer is changed.
virtual QGis::WkbType geometryType() const =0
Get feature type.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or a null string if there is no alias.
Fast access to features using their ID.
QgsFeatureId snappedAtGeometry
Index of the snapped geometry.
Definition: qgssnapper.h:54
bool mValid
Indicates if the layer is valid and can be drawn.
Definition: qgsmaplayer.h:720
bool useRenderingOptimization() const
Returns true if the rendering optimization (geometry simplification) can be executed.
QList< QVariant > getValues(const QString &fieldOrExpression, bool &ok, bool selectedOnly=false)
Fetches all values from a specified field name or expression.
static QPainter::CompositionMode getCompositionMode(BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
void raiseError(const QString &msg)
Signals an error related to this vector layer.
void editingStarted()
Is emitted, when editing on this layer has started.
static void drawVertexMarker(double x, double y, QPainter &p, QgsVectorLayer::VertexMarkerType type, int vertexSize)
Draws a vertex symbol at (screen) coordinates x, y.
bool addFeatures(QgsFeatureList features, bool makeSelected=true)
Insert a copy of the given features into the layer (but does not commit it)
A class to represent a point.
Definition: qgspoint.h:117
iterator begin()
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &value, bool emitSignal)
Changes an attribute value (but does not commit it)
void addAttributeAlias(int attIndex, const QString &aliasString)
Sets an alias (a display name) for attributes to display in dialogs.
Q_DECL_DEPRECATED void setEditorWidgetV2Config(int attrIdx, const QgsEditorWidgetConfig &config)
Set the editor widget config for a field.
void endEditCommand()
Finish edit command and add it to undo/redo stack.
void committedAttributeValuesChanges(const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues)
QString right(int n) const
const QStringList & commitErrors()
QDomText createTextNode(const QString &value)
int green() const
void invalidateSymbolCountedFlag()
iterator end()
QByteArray toLocal8Bit() const
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, eg both MultiPolygon and CurvePolygon would have a PolygonG...
Definition: qgswkbtypes.h:573
QgsPoint beforeVertex
The layer coordinates of the vertex before snappedVertex.
Definition: qgssnapper.h:44
bool forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported...
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
QgsPoint afterVertex
The layer coordinates of the vertex after snappedVertex.
Definition: qgssnapper.h:49
QDomNode namedItem(const QString &name) const
bool contains(QChar ch, Qt::CaseSensitivity cs) const
void editCommandDestroyed()
Signal emitted, whan an edit command is destroyed.
void setX(double x)
Sets the x value of the point.
Definition: qgspoint.h:162
int addExpressionField(const QString &exp, const QgsField &fld)
Add a new field which is calculated by the expression specified.
void setMaximumScale(float maximumScale)
Sets the maximum scale at which the layer should be simplified.
QVariant aggregate(QgsAggregateCalculator::Aggregate aggregate, const QString &fieldOrExpression, const QgsAggregateCalculator::AggregateParameters &parameters=QgsAggregateCalculator::AggregateParameters(), QgsExpressionContext *context=nullptr, bool *ok=nullptr)
Calculates an aggregated value from the layer&#39;s features.
void setY(double y)
Sets the y value of the point.
Definition: qgspoint.h:170
virtual void reload() override
Synchronises with changes in the datasource.
bool contains(const T &value) const
bool countSymbolFeatures(bool showProgress=true)
Count features for symbols.
A class to render labels.
Definition: qgslabel.h:51
static QgsMapLayerLegend * defaultVectorLegend(QgsVectorLayer *vl)
Create new legend implementation for vector layer.
A registry / canonical manager of data providers.
void setProviderEncoding(const QString &encoding)
Sets the textencoding of the data provider.
QgsExpressionContext & expressionContext()
Gets the expression context.
virtual QString loadNamedStyle(const QString &theURI, bool &theResultFlag, bool loadFromLocalDb)
Load a named style from file/local db/datasource db.
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:76
Implementation of threaded rendering for vector layers.
const_iterator constBegin() const
bool isInScaleRange(double scale) const
Return true if the label is visible at the given scale.
Definition: qgslabel.cpp:1418
Stores the settings for rendering of all diagrams for a layer.
bool contains(const T &value) const
int layerTransparency() const
Returns the current transparency for the vector layer.
QgsMapLayerLegend * legend() const
Can be null.
bool isNull() const
QgsAttributeList pkAttributeList() const
Returns list of attributes making up the primary key.
QgsFeatureIterator selectedFeaturesIterator(QgsFeatureRequest request=QgsFeatureRequest())
Get an iterator of the selected features.
QLibrary * providerLibrary(const QString &providerKey) const
int snappedVertexNr
The vertex index of snappedVertex or -1 if no such vertex number (e.g.
Definition: qgssnapper.h:42
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:505
const Key key(const T &value) const
bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
bool snapPoint(QgsPoint &point, double tolerance)
Snaps a point to the closest vertex if there is one within the snapping tolerance.
bool removeJoin(const QString &joinLayerId)
Removes a vector layer join.
void addRequiredFields(QgsAttributeList &fields) const
add vector of required fields to existing list of fields
Definition: qgslabel.cpp:459
Q_DECL_DEPRECATED void setEditType(int idx, EditType edit)
Set edit type.
bool isNull() const
EditResult deleteVertexV2(QgsFeatureId featureId, int vertex)
Deletes a vertex from a feature.
virtual void exportNamedStyle(QDomDocument &doc, QString &errorMsg)
Export the properties of this layer as named style in a QDomDocument.
bool updateFeature(QgsFeature &f)
Updates an existing feature.
SelectBehaviour
Selection behaviour.
void selectionChanged()
This signal is emitted when selection was changed.
bool insertVertex(double x, double y, QgsFeatureId atFeatureId, int beforeVertex)
Insert a new vertex before the given vertex number, in the given ring, item (first number is index 0)...
virtual bool render() override
Do the rendering (based on data stored in the class)
QString providerType() const
Return the provider type for this layer.
QString & replace(int position, int n, QChar after)
Add selection to current selection.
void renderLabel(QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=nullptr)
render label
Definition: qgslabel.cpp:72
int blue() const
QString what() const
Definition: qgsexception.h:36
const T & at(int i) const
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QVariant value(const QString &key, const QVariant &defaultValue) const
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer.
long featureCount() const
Returns feature count including changes which have not yet been committed If you need only the count ...
Q_DECL_DEPRECATED QSize widgetSize(int idx)
Access widget size for photo and webview widget.
void beforeAddingExpressionField(const QString &fieldName)
Will be emitted, when an expression field is going to be added to this vector layer.
int addRing(const QList< QgsPoint > &ring, const QgsFeatureIds &targetFeatureIds=QgsFeatureIds(), QgsFeatureId *modifiedFeatureId=nullptr)
Adds a ring to polygon/multipolygon features.
Contains information about the context of a rendering operation.
Buffers information about expression fields for a vector layer.
QString getStyleById_t(const QString &uri, QString styleID, QString &errCause)
void save(QTextStream &str, int indent) const
virtual QDomElement toDomElement(QDomDocument &doc) const =0
Is reimplemented in classes inheriting from this to serialize it.
void editCommandStarted(const QString &text)
Signal emitted when a new edit command has been started.
QString loadStyle_t(const QString &uri, QString &errCause)
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:271
QgsVectorLayer(const QString &path=QString::null, const QString &baseName=QString::null, const QString &providerLib=QString::null, bool loadDefaultStyleFlag=true)
Constructor - creates a vector layer.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Set feature IDs that should be fetched.
bool remove(const T &value)
void setAnnotationForm(const QString &ui)
Set annotation form for layer.
QSet< T > & unite(const QSet< T > &other)
QString mDataSource
Data source description string, varies by layer type.
Definition: qgsmaplayer.h:723
virtual QString loadDefaultStyle(bool &theResultFlag)
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
void * resolve(const char *symbol)
static Q_DECL_DEPRECATED const QString convertEditType(QgsVectorLayer::EditType editType, QgsEditorWidgetConfig &cfg, QgsVectorLayer *vl, const QString &name, const QDomElement &editTypeElement=QDomElement())
QSet< T > & intersect(const QSet< T > &other)
QgsVectorLayer::EditResult deleteVertexV2(QgsFeatureId featureId, int vertex)
Deletes a vertex from a feature.
Q_DECL_DEPRECATED const QgsEditorWidgetConfig editorWidgetV2Config(int fieldIdx) const
Get the configuration for the editor widget used to represent the field at the given index...
Q_DECL_DEPRECATED void setSelectedFeatures(const QgsFeatureIds &ids)
Change selection to the new set of features.
void endMacro()
bool isEmpty() const
QVariant calculate(Aggregate aggregate, const QString &fieldOrExpression, QgsExpressionContext *context=nullptr, bool *ok=nullptr) const
Calculates the value of an aggregate.
This class manages a set of relations between layers.
static QgsFeatureRendererV2 * load(QDomElement &symbologyElem)
create a renderer from XML element
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:27
virtual void reloadData()
Reloads the data from the source.
void beforeModifiedCheck() const
Is emitted, when layer is checked for modifications.
bool deleteSelectedFeatures(int *deletedCount=nullptr)
Deletes the selected features.
Q_DECL_DEPRECATED RangeData range(int idx)
Access range widget config data.
Edit operation was successful.
static QgsAbstractVectorLayerLabeling * create(const QDomElement &element)
Try to create instance of an implementation based on the XML data.
The QgsConditionalLayerStyles class holds conditional style information for a layer.
bool moveVertex(double x, double y, QgsFeatureId atFeatureId, int atVertex)
Moves the vertex at the given position number, ring and item (first number is index 0)...
void repaintRequested()
By emitting this signal the layer tells that either appearance or content have been changed and any v...
void committedAttributesAdded(const QString &layerId, const QList< QgsField > &addedAttributes)
const QChar at(int position) const
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &)
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:388
void setWindowTitle(const QString &)
QDomElement firstChildElement(const QString &tagName) const
QgsPoint snappedVertex
The coordinates of the snapping result.
Definition: qgssnapper.h:39
QDomElement lastChildElement(const QString &tagName) const
Class for storing a coordinate reference system (CRS)
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:99
friend class QgsVectorLayerEditBuffer
int count(const T &value) const
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
QgsLabel * label()
Get the label rendering properties associated with this layer.
int size() const
Return number of items.
Definition: qgsfield.cpp:370
virtual QString description() const =0
Return description.
Q_DECL_DEPRECATED bool hasLabelsEnabled() const
Label is on.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
QList< T > values() const
QList< T > mid(int pos, int length) const
This is a container for attribute editors, used to group them visually in the attribute form if it is...
void recalculateExtents()
This is used to send a request that any mapcanvas using this layer update its extents.
int length() const
virtual QDomElement toDomElement(QDomDocument &doc) const override
Will serialize this elements information into a QDomElement for saving it in an XML file...
virtual bool setSubsetString(const QString &subset)
Set the string (typically sql) used to define a subset of the layer.
bool toBool() const
char * data()
virtual QString getStyleFromDatabase(const QString &styleId, QString &msgError)
Will return the named style corresponding to style id provided.
bool isEmpty() const
bool readSld(const QDomNode &node, QString &errorMessage) override
Basic implementation of the labeling interface.
void undo()
qint64 QgsFeatureId
Definition: qgsfeature.h:31
void dataChanged()
Data of layer changed.
static QColor colorFromOgcFill(const QDomElement &fillElement)
Parse XML with OGC fill into QColor.
double y() const
Get the y value of the point.
Definition: qgspoint.h:193
Base class for utility classes that encapsulate information necessary for rendering of map layers...
void setLayerName(const QString &name)
Set the display name of the layer.
const QgsCoordinateReferenceSystem & crs() const
Returns layer&#39;s spatial reference system.
bool isValid() const
Remove from current selection.
void start()
virtual QString loadNamedStyle(const QString &theURI, bool &theResultFlag)
Retrieve a named style for this layer if one exists (either as a .qml file on disk or as a record in ...
double toDouble(bool *ok) const
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage) const override
Write the symbology for the layer into the docment provided.
virtual void addChildElement(QgsAttributeEditorElement *element)
Add a child element to this container.
bool isEmpty() const
Returns true if the geometry is empty (ie, contains no underlying geometry accessible via geometry)...
void checkJoinLayerRemove(const QString &theLayerId)
Check if there is a join with a layer that will be removed.
void(*)() cast_to_fptr(void *p)
Definition: qgis.h:272
virtual QString type() const =0
Unique type string of the labeling configuration implementation.
QString dataComment() const
Returns a comment for the data in the layer.
Edit failed due to invalid layer.
Custom exception class for Coordinate Reference System related exceptions.
QUndoStack * undoStack()
Return pointer to layer&#39;s undo stack.
QString metadata() override
Obtain Metadata for this layer.
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
int size() const
QgsVectorDataProvider * dataProvider()
Returns the data provider.
int splitParts(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
const_iterator constEnd() const
void normalize()
Normalize the rectangle so it has non-negative width/height.
float maximumScale() const
Gets the maximum scale at which the layer should be simplified.
QDomElement createElement(const QString &tagName)
bool nextFeature(QgsFeature &f)
This is a container for configuration of the attribute table.
const_iterator constBegin() const
void setCoordinateSystem()
Setup the coordinate system transformation for the layer.
This is the base class for vector data providers.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
Geometry is not required. It may still be returned if e.g. required for a filter condition.
virtual bool readXml(const QDomNode &layer_node) override
Reads vector layer specific state from project file Dom node.
void setLegend(QgsMapLayerLegend *legend)
Assign a legend controller to the map layer.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:207
int addRing(const QList< QgsPoint > &ring, QgsFeatureId *featureId=nullptr)
Adds a ring to polygon/multipolygon features.
void committedGeometriesChanges(const QString &layerId, const QgsGeometryMap &changedGeometries)
A vector of attributes.
Definition: qgsfeature.h:115
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QgsFeatureIds allFeatureIds()
Get all feature Ids.
static QgsFeatureRendererV2 * readOldRenderer(const QDomNode &layerNode, QGis::GeometryType geomType)
Read old renderer definition from XML and create matching new renderer.
virtual QgsRectangle extent()
Return the extent of the layer.
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
QgsAttributeTableConfig attributeTableConfig() const
Get the attribute table configuration object.
Definition: