QGIS API Documentation  2.13.0-Master
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 "qgsattributeaction.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 QgsAttributeAction( 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  for ( int idx = 0; idx < mUpdatedFields.count(); ++idx )
258  {
259  QString fldName = mUpdatedFields.at( idx ).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->scaleBasedVisibility() ||
324  ( mLabel->minScale() <= rendererContext.rendererScale() &&
325  rendererContext.rendererScale() <= mLabel->maxScale() ) ) )
326  {
327  QgsAttributeList attributes;
328  Q_FOREACH ( const QString& attrName, mRendererV2->usedAttributes() )
329  {
330  int attrNum = fieldNameIndex( attrName );
331  attributes.append( attrNum );
332  }
333  // make sure the renderer is ready for classification ("symbolForFeature")
334  mRendererV2->startRender( rendererContext, fields() );
335 
336  // Add fields required for labels
337  mLabel->addRequiredFields( attributes );
338 
339  QgsDebugMsg( "Selecting features based on view extent" );
340 
341  int featureCount = 0;
342 
343  try
344  {
345  // select the records in the extent. The provider sets a spatial filter
346  // and sets up the selection set for retrieval
348  .setFilterRect( rendererContext.extent() )
349  .setSubsetOfAttributes( attributes ) );
350 
351  QgsFeature fet;
352  while ( fit.nextFeature( fet ) )
353  {
354  if ( mRendererV2->willRenderFeature( fet, rendererContext ) )
355  {
356  bool sel = mSelectedFeatureIds.contains( fet.id() );
357  mLabel->renderLabel( rendererContext, fet, sel, nullptr );
358  }
359  featureCount++;
360  }
361  }
362  catch ( QgsCsException &e )
363  {
364  Q_UNUSED( e );
365  QgsDebugMsg( "Error projecting label locations" );
366  }
367 
368  if ( mRendererV2 )
369  {
370  mRendererV2->stopRender( rendererContext );
371  }
372 
373  QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
374  }
375 }
376 
378 {
379  if ( mDataProvider )
380  {
381  mDataProvider->reloadData();
382  }
383 }
384 
386 {
387  return new QgsVectorLayerRenderer( this, rendererContext );
388 }
389 
390 bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
391 {
392  QgsVectorLayerRenderer renderer( this, rendererContext );
393  return renderer.render();
394 }
395 
397 {
399  {
400  p.setPen( QColor( 50, 100, 120, 200 ) );
401  p.setBrush( QColor( 200, 200, 210, 120 ) );
402  p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
403  }
404  else if ( type == QgsVectorLayer::Cross )
405  {
406  p.setPen( QColor( 255, 0, 0 ) );
407  p.drawLine( x - m, y + m, x + m, y - m );
408  p.drawLine( x - m, y - m, x + m, y + m );
409  }
410 }
411 
413 {
414  mSelectedFeatureIds.insert( fid );
415 
416  emit selectionChanged( QgsFeatureIds() << fid, QgsFeatureIds(), false );
417 }
418 
419 void QgsVectorLayer::select( const QgsFeatureIds& featureIds )
420 {
421  mSelectedFeatureIds.unite( featureIds );
422 
423  emit selectionChanged( featureIds, QgsFeatureIds(), false );
424 }
425 
427 {
428  mSelectedFeatureIds.remove( fid );
429 
430  emit selectionChanged( QgsFeatureIds(), QgsFeatureIds() << fid, false );
431 }
432 
433 void QgsVectorLayer::deselect( const QgsFeatureIds& featureIds )
434 {
435  mSelectedFeatureIds.subtract( featureIds );
436 
437  emit selectionChanged( QgsFeatureIds(), featureIds, false );
438 }
439 
440 void QgsVectorLayer::select( QgsRectangle & rect, bool addToSelection )
441 {
442  // normalize the rectangle
443  rect.normalize();
444 
445  //select all the elements
447  .setFilterRect( rect )
449  .setSubsetOfAttributes( QgsAttributeList() ) );
450 
451  QgsFeatureIds ids;
452 
453  QgsFeature f;
454  while ( fit.nextFeature( f ) )
455  {
456  ids << f.id();
457  }
458 
459  if ( !addToSelection )
460  {
461  setSelectedFeatures( mSelectedFeatureIds + ids );
462  }
463  else
464  {
465  select( ids );
466  }
467 }
468 
470 {
471  QgsFeatureIds intersectingIds = selectIds & deselectIds;
472  if ( !intersectingIds.isEmpty() )
473  {
474  QgsDebugMsg( "Trying to select and deselect the same item at the same time. Unsure what to do. Selecting dubious items." );
475  }
476 
477  mSelectedFeatureIds -= deselectIds;
478  mSelectedFeatureIds += selectIds;
479 
480  emit selectionChanged( selectIds, deselectIds - intersectingIds, false );
481 }
482 
484 {
486  ids.subtract( mSelectedFeatureIds );
487  setSelectedFeatures( ids );
488 }
489 
491 {
493 }
494 
496 {
498  .setFlags( QgsFeatureRequest::NoGeometry )
499  .setSubsetOfAttributes( QgsAttributeList() ) );
500 
501  QgsFeatureIds ids;
502 
503  QgsFeature fet;
504  while ( fit.nextFeature( fet ) )
505  {
506  ids << fet.id();
507  }
508 
509  return ids;
510 }
511 
513 {
514  // normalize the rectangle
515  rect.normalize();
516 
518  .setFilterRect( rect )
520  .setSubsetOfAttributes( QgsAttributeList() ) );
521 
522  QgsFeatureIds selectIds;
523  QgsFeatureIds deselectIds;
524 
525  QgsFeature fet;
526  while ( fit.nextFeature( fet ) )
527  {
528  if ( mSelectedFeatureIds.contains( fet.id() ) )
529  {
530  deselectIds << fet.id();
531  }
532  else
533  {
534  selectIds << fet.id();
535  }
536  }
537 
538  modifySelection( selectIds, deselectIds );
539 }
540 
542 {
543  if ( mSelectedFeatureIds.isEmpty() )
544  return;
545 
547 }
548 
550 {
551  return mDataProvider;
552 }
553 
555 {
556  return mDataProvider;
557 }
558 
560 {
561  if ( mValid && mDataProvider && mDataProvider->encoding() != encoding )
562  {
563  mDataProvider->setEncoding( encoding );
564  updateFields();
565  }
566 }
567 
569 {
570  delete mDiagramRenderer;
571  mDiagramRenderer = r;
572  emit rendererChanged();
573 }
574 
576 {
577  if ( mValid && mDataProvider )
578  {
579  QGis::WkbType type = mDataProvider->geometryType();
580  return static_cast< QGis::GeometryType >( QgsWKBTypes::geometryType( static_cast< QgsWKBTypes::Type >( type ) ) );
581  }
582  else
583  {
584  QgsDebugMsg( "invalid layer or pointer to mDataProvider is null" );
585  }
586 
587  // We shouldn't get here, and if we have, other things are likely to
588  // go wrong. Code that uses the type() return value should be
589  // rewritten to cope with a value of QGis::Unknown. To make this
590  // need known, the following message is printed every time we get
591  // here.
592  QgsDebugMsg( "WARNING: This code should never be reached. Problems may occur..." );
593 
594  return QGis::UnknownGeometry;
595 }
596 
598 {
600  return t != QGis::NoGeometry && t != QGis::UnknownGeometry;
601 }
602 
604 {
605  return mWkbType;
606 }
607 
609 {
610  if ( !mValid || mSelectedFeatureIds.isEmpty() ) //no selected features
611  {
612  return QgsRectangle( 0, 0, 0, 0 );
613  }
614 
615  QgsRectangle r, retval;
616  retval.setMinimal();
617 
618  QgsFeature fet;
619  if ( mDataProvider->capabilities() & QgsVectorDataProvider::SelectAtId )
620  {
622  .setFilterFids( mSelectedFeatureIds )
623  .setSubsetOfAttributes( QgsAttributeList() ) );
624 
625  while ( fit.nextFeature( fet ) )
626  {
627  if ( !fet.constGeometry() || fet.constGeometry()->isEmpty() )
628  continue;
629  r = fet.constGeometry()->boundingBox();
630  retval.combineExtentWith( &r );
631  }
632  }
633  else
634  {
636  .setSubsetOfAttributes( QgsAttributeList() ) );
637 
638  while ( fit.nextFeature( fet ) )
639  {
640  if ( mSelectedFeatureIds.contains( fet.id() ) )
641  {
642  if ( fet.constGeometry() )
643  {
644  r = fet.constGeometry()->boundingBox();
645  retval.combineExtentWith( &r );
646  }
647  }
648  }
649  }
650 
651  if ( retval.width() == 0.0 || retval.height() == 0.0 )
652  {
653  // If all of the features are at the one point, buffer the
654  // rectangle a bit. If they are all at zero, do something a bit
655  // more crude.
656 
657  if ( retval.xMinimum() == 0.0 && retval.xMaximum() == 0.0 &&
658  retval.yMinimum() == 0.0 && retval.yMaximum() == 0.0 )
659  {
660  retval.set( -1.0, -1.0, 1.0, 1.0 );
661  }
662  }
663 
664  return retval;
665 }
666 
668 {
669  if ( !mLabeling )
670  return false;
671 
672  // for simple labeling the mode can be "no labels" - so we need to check
673  // in properties whether we are really enabled or not
674  if ( mLabeling->type() == "simple" )
675  return customProperty( "labeling/enabled", QVariant( false ) ).toBool();
676 
677  // for other labeling implementations we always assume that labeling is enabled
678  return true;
679 }
680 
682 {
683  if ( !mDiagramRenderer || !mDiagramLayerSettings )
684  return false;
685 
686  QList<QgsDiagramSettings> settingList = mDiagramRenderer->diagramSettings();
687  if ( !settingList.isEmpty() )
688  {
689  return settingList.at( 0 ).enabled;
690  }
691  return false;
692 }
693 
695 {
696  if ( !mSymbolFeatureCounted )
697  return -1;
698 
699  return mSymbolFeatureCountMap.value( symbol );
700 }
701 
702 bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
703 {
704  if ( mSymbolFeatureCounted )
705  return true;
706 
707  mSymbolFeatureCountMap.clear();
708 
709  if ( !mValid )
710  {
711  QgsDebugMsg( "invoked with invalid layer" );
712  return false;
713  }
714  if ( !mDataProvider )
715  {
716  QgsDebugMsg( "invoked with null mDataProvider" );
717  return false;
718  }
719  if ( !mRendererV2 )
720  {
721  QgsDebugMsg( "invoked with null mRendererV2" );
722  return false;
723  }
724 
725  QgsLegendSymbolList symbolList = mRendererV2->legendSymbolItems();
726  QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
727 
728  for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
729  {
730  mSymbolFeatureCountMap.insert( symbolIt->second, 0 );
731  }
732 
733  long nFeatures = featureCount();
734  QProgressDialog progressDialog( tr( "Updating feature count for layer %1" ).arg( name() ), tr( "Abort" ), 0, nFeatures );
735  progressDialog.setWindowTitle( tr( "QGIS" ) );
736  progressDialog.setWindowModality( Qt::WindowModal );
737  int featuresCounted = 0;
738 
740 
741  // Renderer (rule based) may depend on context scale, with scale is ignored if 0
742  QgsRenderContext renderContext;
743  renderContext.setRendererScale( 0 );
747 
748  mRendererV2->startRender( renderContext, fields() );
749 
750  QgsFeature f;
751  while ( fit.nextFeature( f ) )
752  {
753  renderContext.expressionContext().setFeature( f );
754  QgsSymbolV2List featureSymbolList = mRendererV2->originalSymbolsForFeature( f, renderContext );
755  for ( QgsSymbolV2List::iterator symbolIt = featureSymbolList.begin(); symbolIt != featureSymbolList.end(); ++symbolIt )
756  {
757  mSymbolFeatureCountMap[*symbolIt] += 1;
758  }
759  ++featuresCounted;
760 
761  if ( showProgress )
762  {
763  if ( featuresCounted % 50 == 0 )
764  {
765  if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
766  {
767  progressDialog.setMaximum( 0 );
768  }
769  progressDialog.setValue( featuresCounted );
770  if ( progressDialog.wasCanceled() )
771  {
772  mSymbolFeatureCountMap.clear();
773  mRendererV2->stopRender( renderContext );
774  return false;
775  }
776  }
777  }
778  }
779  mRendererV2->stopRender( renderContext );
780  progressDialog.setValue( nFeatures );
781  mSymbolFeatureCounted = true;
782  return true;
783 }
784 
786 {
787  mValidExtent = false;
788 }
789 
791 {
793  mValidExtent = true;
794 }
795 
797 {
798  QgsRectangle rect;
799  rect.setMinimal();
800 
801  if ( !hasGeometryType() )
802  return rect;
803 
804  if ( !mValidExtent && mLazyExtent && mDataProvider )
805  {
806  // get the extent
807  QgsRectangle mbr = mDataProvider->extent();
808 
809  // show the extent
810  QString s = mbr.toString();
811 
812  QgsDebugMsg( "Extent of layer: " + s );
813  // store the extent
814  setExtent( mbr );
815 
816  mLazyExtent = false;
817  }
818 
819  if ( mValidExtent )
820  return QgsMapLayer::extent();
821 
822  if ( !mValid || !mDataProvider )
823  {
824  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
825  return rect;
826  }
827 
828  if ( !mEditBuffer || ( mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mChangedGeometries.isEmpty() ) )
829  {
830  mDataProvider->updateExtents();
831 
832  // get the extent of the layer from the provider
833  // but only when there are some features already
834  if ( mDataProvider->featureCount() != 0 )
835  {
836  QgsRectangle r = mDataProvider->extent();
837  rect.combineExtentWith( &r );
838  }
839 
840  if ( mEditBuffer )
841  {
842  for ( QgsFeatureMap::const_iterator it = mEditBuffer->mAddedFeatures.constBegin(); it != mEditBuffer->mAddedFeatures.constEnd(); ++it )
843  {
844  if ( it->constGeometry() )
845  {
846  QgsRectangle r = it->constGeometry()->boundingBox();
847  rect.combineExtentWith( &r );
848  }
849  }
850  }
851  }
852  else
853  {
855  .setSubsetOfAttributes( QgsAttributeList() ) );
856 
857  QgsFeature fet;
858  while ( fit.nextFeature( fet ) )
859  {
860  if ( fet.constGeometry() && fet.constGeometry()->type() != QGis::UnknownGeometry )
861  {
862  QgsRectangle bb = fet.constGeometry()->boundingBox();
863  rect.combineExtentWith( &bb );
864  }
865  }
866  }
867 
868  if ( rect.xMinimum() > rect.xMaximum() && rect.yMinimum() > rect.yMaximum() )
869  {
870  // special case when there are no features in provider nor any added
871  rect = QgsRectangle(); // use rectangle with zero coordinates
872  }
873 
874  setExtent( rect );
875 
876  // Send this (hopefully) up the chain to the map canvas
877  emit recalculateExtents();
878 
879  return rect;
880 }
881 
883 {
884  if ( !mValid || !mDataProvider )
885  {
886  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
887  return nullptr;
888  }
889  return mDataProvider->subsetString();
890 }
891 
893 {
894  if ( !mValid || !mDataProvider )
895  {
896  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
897  return false;
898  }
899 
900  bool res = mDataProvider->setSubsetString( subset );
901 
902  // get the updated data source string from the provider
903  mDataSource = mDataProvider->dataSourceUri();
904  updateExtents();
905 
906  if ( res )
907  emit repaintRequested();
908 
909  return res;
910 }
911 
913 {
914  if ( mValid && mDataProvider && !mEditBuffer && ( hasGeometryType() && geometryType() != QGis::Point ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && renderContext.useRenderingOptimization() )
915  {
916  double maximumSimplificationScale = mSimplifyMethod.maximumScale();
917 
918  // check maximum scale at which generalisation should be carried out
919  if ( maximumSimplificationScale > 1 && renderContext.rendererScale() <= maximumSimplificationScale )
920  return false;
921 
922  return true;
923  }
924  return false;
925 }
926 
928 {
929  return mConditionalStyles;
930 }
931 
933 {
934  if ( !mValid || !mDataProvider )
935  return QgsFeatureIterator();
936 
937  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( new QgsVectorLayerFeatureSource( this ), true, request ) );
938 }
939 
940 
941 bool QgsVectorLayer::addFeature( QgsFeature& f, bool alsoUpdateExtent )
942 {
943  Q_UNUSED( alsoUpdateExtent ); // TODO[MD]
944  if ( !mValid || !mEditBuffer || !mDataProvider )
945  return false;
946 
947  bool success = mEditBuffer->addFeature( f );
948 
949  if ( success )
950  updateExtents();
951 
952  return success;
953 }
954 
956 {
957  QgsFeatureRequest req;
958  req.setFilterFid( f.id() );
959  if ( !f.constGeometry() )
961  if ( f.attributes().isEmpty() )
963 
964  QgsFeature current;
965  if ( !getFeatures( req ).nextFeature( current ) )
966  {
967  QgsDebugMsg( QString( "feature %1 could not be retrieved" ).arg( f.id() ) );
968  return false;
969  }
970 
971  if ( f.constGeometry() && current.constGeometry() && f.constGeometry() != current.constGeometry() && !f.constGeometry()->isGeosEqual( *current.constGeometry() ) )
972  {
973  if ( !changeGeometry( f.id(), f.geometry() ) )
974  {
975  QgsDebugMsg( QString( "geometry of feature %1 could not be changed." ).arg( f.id() ) );
976  return false;
977  }
978  }
979 
980  QgsAttributes fa = f.attributes();
981  QgsAttributes ca = current.attributes();
982 
983  for ( int attr = 0; attr < fa.count(); ++attr )
984  {
985  if ( fa.at( attr ) != ca.at( attr ) )
986  {
987  if ( !changeAttributeValue( f.id(), attr, fa.at( attr ), ca.at( attr ) ) )
988  {
989  QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( f.id() ) );
990  return false;
991  }
992  }
993  }
994 
995  return true;
996 }
997 
998 
999 bool QgsVectorLayer::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
1000 {
1001  if ( !mValid || !mEditBuffer || !mDataProvider )
1002  return false;
1003 
1004  QgsVectorLayerEditUtils utils( this );
1005  return utils.insertVertex( x, y, atFeatureId, beforeVertex );
1006 }
1007 
1008 
1009 bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
1010 {
1011  if ( !mValid || !mEditBuffer || !mDataProvider )
1012  return false;
1013 
1014  QgsVectorLayerEditUtils utils( this );
1015  return utils.moveVertex( x, y, atFeatureId, atVertex );
1016 }
1017 
1018 bool QgsVectorLayer::moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex )
1019 {
1020  if ( !mValid || !mEditBuffer || !mDataProvider )
1021  return false;
1022 
1023  QgsVectorLayerEditUtils utils( this );
1024  return utils.moveVertex( p, atFeatureId, atVertex );
1025 }
1026 
1027 bool QgsVectorLayer::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
1028 {
1029  QgsVectorLayer::EditResult res = deleteVertexV2( atFeatureId, atVertex );
1031 }
1032 
1034 {
1035  if ( !mValid || !mEditBuffer || !mDataProvider )
1037 
1038  QgsVectorLayerEditUtils utils( this );
1039  return utils.deleteVertexV2( featureId, vertex );
1040 }
1041 
1042 
1044 {
1045  if ( !mValid || !mDataProvider || !( mDataProvider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
1046  {
1047  return false;
1048  }
1049 
1050  if ( !isEditable() )
1051  {
1052  return false;
1053  }
1054 
1055  int deleted = 0;
1056  int count = mSelectedFeatureIds.size();
1057  // Make a copy since deleteFeature modifies mSelectedFeatureIds
1058  QgsFeatureIds selectedFeatures( mSelectedFeatureIds );
1059  Q_FOREACH ( QgsFeatureId fid, selectedFeatures )
1060  {
1061  deleted += deleteFeature( fid ); // removes from selection
1062  }
1063 
1064  triggerRepaint();
1065  updateExtents();
1066 
1067  if ( deletedCount )
1068  {
1069  *deletedCount = deleted;
1070  }
1071 
1072  return deleted == count;
1073 }
1074 
1076 {
1077  if ( !mValid || !mEditBuffer || !mDataProvider )
1078  return 6;
1079 
1080  QgsVectorLayerEditUtils utils( this );
1081  int result = 5;
1082 
1083  //first try with selected features
1084  if ( !mSelectedFeatureIds.isEmpty() )
1085  {
1086  result = utils.addRing( ring, mSelectedFeatureIds, featureId );
1087  }
1088 
1089  if ( result != 0 )
1090  {
1091  //try with all intersecting features
1092  result = utils.addRing( ring, QgsFeatureIds(), featureId );
1093  }
1094 
1095  return result;
1096 }
1097 
1099 {
1100  if ( !mValid || !mEditBuffer || !mDataProvider )
1101  {
1102  delete ring;
1103  return 6;
1104  }
1105 
1106  if ( !ring )
1107  {
1108  return 1;
1109  }
1110 
1111  if ( !ring->isClosed() )
1112  {
1113  delete ring;
1114  return 2;
1115  }
1116 
1117  QgsVectorLayerEditUtils utils( this );
1118  int result = 5;
1119 
1120  //first try with selected features
1121  if ( !mSelectedFeatureIds.isEmpty() )
1122  {
1123  result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), mSelectedFeatureIds, featureId );
1124  }
1125 
1126  if ( result != 0 )
1127  {
1128  //try with all intersecting features
1129  result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), QgsFeatureIds(), featureId );
1130  }
1131 
1132  delete ring;
1133  return result;
1134 }
1135 
1137 {
1138  if ( !mValid || !mEditBuffer || !mDataProvider )
1139  return 7;
1140 
1141  //number of selected features must be 1
1142 
1143  if ( mSelectedFeatureIds.size() < 1 )
1144  {
1145  QgsDebugMsg( "Number of selected features <1" );
1146  return 4;
1147  }
1148  else if ( mSelectedFeatureIds.size() > 1 )
1149  {
1150  QgsDebugMsg( "Number of selected features >1" );
1151  return 5;
1152  }
1153 
1154  QgsVectorLayerEditUtils utils( this );
1155  return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
1156 }
1157 
1159 {
1160  if ( !mValid || !mEditBuffer || !mDataProvider )
1161  return 7;
1162 
1163  //number of selected features must be 1
1164 
1165  if ( mSelectedFeatureIds.size() < 1 )
1166  {
1167  QgsDebugMsg( "Number of selected features <1" );
1168  return 4;
1169  }
1170  else if ( mSelectedFeatureIds.size() > 1 )
1171  {
1172  QgsDebugMsg( "Number of selected features >1" );
1173  return 5;
1174  }
1175 
1176  QgsVectorLayerEditUtils utils( this );
1177  return utils.addPart( ring, *mSelectedFeatureIds.constBegin() );
1178 }
1179 
1180 int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy )
1181 {
1182  if ( !mValid || !mEditBuffer || !mDataProvider )
1183  return -1;
1184 
1185  QgsVectorLayerEditUtils utils( this );
1186  return utils.translateFeature( featureId, dx, dy );
1187 }
1188 
1189 int QgsVectorLayer::splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1190 {
1191  if ( !mValid || !mEditBuffer || !mDataProvider )
1192  return -1;
1193 
1194  QgsVectorLayerEditUtils utils( this );
1195  return utils.splitParts( splitLine, topologicalEditing );
1196 }
1197 
1198 int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1199 {
1200  if ( !mValid || !mEditBuffer || !mDataProvider )
1201  return -1;
1202 
1203  QgsVectorLayerEditUtils utils( this );
1204  return utils.splitFeatures( splitLine, topologicalEditing );
1205 }
1206 
1208 {
1209  if ( !hasGeometryType() )
1210  return 1;
1211 
1212  int returnValue = 0;
1213 
1214  //first test if geom really has type polygon or multipolygon
1215  if ( geom->type() != QGis::Polygon )
1216  {
1217  return 1;
1218  }
1219 
1220  //get bounding box of geom
1221  QgsRectangle geomBBox = geom->boundingBox();
1222 
1223  //get list of features that intersect this bounding box
1225  .setFilterRect( geomBBox )
1227  .setSubsetOfAttributes( QgsAttributeList() ) );
1228 
1229  QgsFeature f;
1230  while ( fit.nextFeature( f ) )
1231  {
1232  if ( ignoreFeatures.contains( f.id() ) )
1233  {
1234  continue;
1235  }
1236 
1237  //call geometry->makeDifference for each feature
1238  const QgsGeometry *currentGeom = f.constGeometry();
1239  if ( currentGeom )
1240  {
1241  if ( geom->makeDifference( currentGeom ) != 0 )
1242  {
1243  returnValue = 2;
1244  }
1245  }
1246  }
1247 
1248  return returnValue;
1249 }
1250 
1252 {
1253  if ( !mValid || !mEditBuffer || !mDataProvider )
1254  return -1;
1255 
1256  QgsVectorLayerEditUtils utils( this );
1257  return utils.addTopologicalPoints( geom );
1258 }
1259 
1261 {
1262  if ( !mValid || !mEditBuffer || !mDataProvider )
1263  return -1;
1264 
1265  QgsVectorLayerEditUtils utils( this );
1266  return utils.addTopologicalPoints( p );
1267 }
1268 
1270 {
1271  return mLabel;
1272 }
1273 
1275 {
1276  return mLabel;
1277 }
1278 
1280 {
1281  mLabelOn = on;
1282 }
1283 
1285 {
1286  return mLabelOn;
1287 }
1288 
1290 {
1291  if ( mLabeling == labeling )
1292  return;
1293 
1294  delete mLabeling;
1295  mLabeling = labeling;
1296 }
1297 
1299 {
1300  if ( !mValid || !mDataProvider )
1301  {
1302  return false;
1303  }
1304 
1305  // allow editing if provider supports any of the capabilities
1306  if ( !( mDataProvider->capabilities() & QgsVectorDataProvider::EditingCapabilities ) )
1307  {
1308  return false;
1309  }
1310 
1311  if ( mReadOnly )
1312  {
1313  return false;
1314  }
1315 
1316  if ( mEditBuffer )
1317  {
1318  // editing already underway
1319  return false;
1320  }
1321 
1322  emit beforeEditingStarted();
1323 
1324  if ( mDataProvider->transaction() )
1325  {
1326  mEditBuffer = new QgsVectorLayerEditPassthrough( this );
1327  }
1328  else
1329  {
1330  mEditBuffer = new QgsVectorLayerEditBuffer( this );
1331  }
1332  // forward signals
1333  connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( invalidateSymbolCountedFlag() ) );
1334  connect( mEditBuffer, SIGNAL( layerModified() ), this, SIGNAL( layerModified() ) ); // TODO[MD]: necessary?
1335  //connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( triggerRepaint() ) ); // TODO[MD]: works well?
1336  connect( mEditBuffer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SIGNAL( featureAdded( QgsFeatureId ) ) );
1337  connect( mEditBuffer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( onFeatureDeleted( QgsFeatureId ) ) );
1338  connect( mEditBuffer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
1339  connect( mEditBuffer, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ), this, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ) );
1340  connect( mEditBuffer, SIGNAL( attributeAdded( int ) ), this, SIGNAL( attributeAdded( int ) ) );
1341  connect( mEditBuffer, SIGNAL( attributeDeleted( int ) ), this, SIGNAL( attributeDeleted( int ) ) );
1342 
1343  connect( mEditBuffer, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ),
1344  this, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ) );
1345 
1346  connect( mEditBuffer, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ),
1347  this, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ) );
1348 
1349  connect( mEditBuffer, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ), this, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ) );
1350  connect( mEditBuffer, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ), this, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ) );
1351 
1352  connect( mEditBuffer, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ),
1353  this, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ) );
1354 
1355  connect( mEditBuffer, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ),
1356  this, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ) );
1357 
1358  updateFields();
1359 
1360  emit editingStarted();
1361 
1362  return true;
1363 }
1364 
1365 bool QgsVectorLayer::readXml( const QDomNode& layer_node )
1366 {
1367  QgsDebugMsg( QString( "Datasource in QgsVectorLayer::readXml: " ) + mDataSource.toLocal8Bit().data() );
1368 
1369  //process provider key
1370  QDomNode pkeyNode = layer_node.namedItem( "provider" );
1371 
1372  if ( pkeyNode.isNull() )
1373  {
1374  mProviderKey = "";
1375  }
1376  else
1377  {
1378  QDomElement pkeyElt = pkeyNode.toElement();
1379  mProviderKey = pkeyElt.text();
1380  }
1381 
1382  // determine type of vector layer
1383  if ( !mProviderKey.isNull() )
1384  {
1385  // if the provider string isn't empty, then we successfully
1386  // got the stored provider
1387  }
1388  else if ( mDataSource.contains( "dbname=" ) )
1389  {
1390  mProviderKey = "postgres";
1391  }
1392  else
1393  {
1394  mProviderKey = "ogr";
1395  }
1396 
1397  if ( !setDataProvider( mProviderKey ) )
1398  {
1399  return false;
1400  }
1401 
1402  QDomElement pkeyElem = pkeyNode.toElement();
1403  if ( !pkeyElem.isNull() )
1404  {
1405  QString encodingString = pkeyElem.attribute( "encoding" );
1406  if ( !encodingString.isEmpty() )
1407  {
1408  mDataProvider->setEncoding( encodingString );
1409  }
1410  }
1411 
1412  //load vector joins
1413  if ( !mJoinBuffer )
1414  {
1415  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1416  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1417  }
1418  mJoinBuffer->readXml( layer_node );
1419 
1420  if ( !mExpressionFieldBuffer )
1421  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1422  mExpressionFieldBuffer->readXml( layer_node );
1423 
1424  updateFields();
1425  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1426 
1427  QDomNode prevExpNode = layer_node.namedItem( "previewExpression" );
1428 
1429  if ( prevExpNode.isNull() )
1430  {
1431  mDisplayExpression = "";
1432  }
1433  else
1434  {
1435  QDomElement prevExpElem = prevExpNode.toElement();
1436  mDisplayExpression = prevExpElem.text();
1437  }
1438 
1439  QString errorMsg;
1440  if ( !readSymbology( layer_node, errorMsg ) )
1441  {
1442  return false;
1443  }
1444 
1445  readStyleManager( layer_node );
1446 
1447 
1449 
1450  return mValid; // should be true if read successfully
1451 
1452 } // void QgsVectorLayer::readXml
1453 
1454 
1455 void QgsVectorLayer::setDataSource( const QString& dataSource, const QString& baseName, const QString& provider, bool loadDefaultStyleFlag )
1456 {
1457  QGis::GeometryType oldGeomType = geometryType();
1458 
1459  mDataSource = dataSource;
1460  mLayerName = capitaliseLayerName( baseName );
1462  setDataProvider( provider );
1463 
1464  if ( !mValid )
1465  return;
1466 
1467  // Always set crs
1469 
1470  // reset style if loading default style, style is missing, or geometry type has changed
1471  if ( !rendererV2() || !legend() || oldGeomType != geometryType() || loadDefaultStyleFlag )
1472  {
1473  // check if there is a default style / propertysheet defined
1474  // for this layer and if so apply it
1475  bool defaultLoadedFlag = false;
1476  if ( loadDefaultStyleFlag )
1477  {
1478  loadDefaultStyle( defaultLoadedFlag );
1479  }
1480 
1481  // if the default style failed to load or was disabled use some very basic defaults
1482  if ( !defaultLoadedFlag && hasGeometryType() )
1483  {
1484  // add single symbol renderer
1486  }
1487 
1489  }
1490 
1491  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1492  emit repaintRequested();
1493 }
1494 
1495 
1496 bool QgsVectorLayer::setDataProvider( QString const & provider )
1497 {
1498  mProviderKey = provider; // XXX is this necessary? Usually already set
1499  // XXX when execution gets here.
1500 
1501  //XXX - This was a dynamic cast but that kills the Windows
1502  // version big-time with an abnormal termination error
1503  delete mDataProvider;
1504  mDataProvider = ( QgsVectorDataProvider* )( QgsProviderRegistry::instance()->provider( provider, mDataSource ) );
1505 
1506  if ( !mDataProvider )
1507  {
1508  QgsDebugMsg( " unable to get data provider" );
1509  return false;
1510  }
1511 
1512  QgsDebugMsg( "Instantiated the data provider plugin" );
1513 
1514  mValid = mDataProvider->isValid();
1515  if ( !mValid )
1516  {
1517  QgsDebugMsg( "Invalid provider plugin " + QString( mDataSource.toUtf8() ) );
1518  return false;
1519  }
1520 
1521  // TODO: Check if the provider has the capability to send fullExtentCalculated
1522  connect( mDataProvider, SIGNAL( fullExtentCalculated() ), this, SLOT( updateExtents() ) );
1523 
1524  // get and store the feature type
1525  mWkbType = mDataProvider->geometryType();
1526 
1527  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1528  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1529  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1530  updateFields();
1531 
1532  // look at the fields in the layer and set the primary
1533  // display field using some real fuzzy logic
1534  setDisplayField();
1535 
1536  if ( mProviderKey == "postgres" )
1537  {
1538  QgsDebugMsg( "Beautifying layer name " + name() );
1539 
1540  // adjust the display name for postgres layers
1541  QRegExp reg( "\"[^\"]+\"\\.\"([^\"]+)\"( \\([^)]+\\))?" );
1542  if ( reg.indexIn( name() ) >= 0 )
1543  {
1544  QStringList stuff = reg.capturedTexts();
1545  QString lName = stuff[1];
1546 
1548 
1550  for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
1551  ;
1552 
1553  if ( it != layers.constEnd() && stuff.size() > 2 )
1554  {
1555  lName += '.' + stuff[2].mid( 2, stuff[2].length() - 3 );
1556  }
1557 
1558  if ( !lName.isEmpty() )
1559  setLayerName( lName );
1560  }
1561 
1562  QgsDebugMsg( "Beautified layer name " + name() );
1563 
1564  // deal with unnecessary schema qualification to make v.in.ogr happy
1565  mDataSource = mDataProvider->dataSourceUri();
1566  }
1567  else if ( mProviderKey == "osm" )
1568  {
1569  // make sure that the "observer" has been removed from URI to avoid crashes
1570  mDataSource = mDataProvider->dataSourceUri();
1571  }
1572  else if ( provider == "ogr" )
1573  {
1574  // make sure that the /vsigzip or /vsizip is added to uri, if applicable
1575  mDataSource = mDataProvider->dataSourceUri();
1576  if ( mDataSource.right( 10 ) == "|layerid=0" )
1577  mDataSource.chop( 10 );
1578  }
1579 
1580  // label
1581  mLabel = new QgsLabel( mDataProvider->fields() );
1582  mLabelOn = false;
1583 
1584  connect( mDataProvider, SIGNAL( dataChanged() ), this, SIGNAL( dataChanged() ) );
1585  connect( mDataProvider, SIGNAL( dataChanged() ), this, SLOT( removeSelection() ) );
1586 
1587  return true;
1588 } // QgsVectorLayer:: setDataProvider
1589 
1590 
1591 
1592 
1593 /* virtual */
1595  QDomDocument & document )
1596 {
1597  // first get the layer element so that we can append the type attribute
1598 
1599  QDomElement mapLayerNode = layer_node.toElement();
1600 
1601  if ( mapLayerNode.isNull() || ( "maplayer" != mapLayerNode.nodeName() ) )
1602  {
1603  QgsDebugMsg( "can't find <maplayer>" );
1604  return false;
1605  }
1606 
1607  mapLayerNode.setAttribute( "type", "vector" );
1608 
1609  // set the geometry type
1610  mapLayerNode.setAttribute( "geometry", QGis::vectorGeometryType( geometryType() ) );
1611 
1612  // add provider node
1613  if ( mDataProvider )
1614  {
1615  QDomElement provider = document.createElement( "provider" );
1616  provider.setAttribute( "encoding", mDataProvider->encoding() );
1617  QDomText providerText = document.createTextNode( providerType() );
1618  provider.appendChild( providerText );
1619  layer_node.appendChild( provider );
1620  }
1621 
1622  // save preview expression
1623  QDomElement prevExpElem = document.createElement( "previewExpression" );
1624  QDomText prevExpText = document.createTextNode( mDisplayExpression );
1625  prevExpElem.appendChild( prevExpText );
1626  layer_node.appendChild( prevExpElem );
1627 
1628  //save joins
1629  mJoinBuffer->writeXml( layer_node, document );
1630 
1631  // dependencies
1632  QDomElement dependenciesElement = document.createElement( "layerDependencies" );
1633  Q_FOREACH ( QString layerId, layerDependencies() )
1634  {
1635  QDomElement depElem = document.createElement( "layer" );
1636  depElem.setAttribute( "id", layerId );
1637  dependenciesElement.appendChild( depElem );
1638  }
1639  layer_node.appendChild( dependenciesElement );
1640 
1641  // save expression fields
1642  mExpressionFieldBuffer->writeXml( layer_node, document );
1643 
1644  writeStyleManager( layer_node, document );
1645 
1646  // renderer specific settings
1647  QString errorMsg;
1648  return writeSymbology( layer_node, document, errorMsg );
1649 } // bool QgsVectorLayer::writeXml
1650 
1651 
1652 bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
1653 {
1654  emit readCustomSymbology( node.toElement(), errorMessage );
1655 
1656  if ( hasGeometryType() )
1657  {
1658  // try renderer v2 first
1659  QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
1660  if ( !rendererElement.isNull() )
1661  {
1662  QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
1663  if ( !r )
1664  return false;
1665 
1666  setRendererV2( r );
1667  }
1668  else
1669  {
1671  if ( !r )
1673 
1674  setRendererV2( r );
1675  }
1676 
1677  QDomElement labelingElement = node.firstChildElement( "labeling" );
1678  if ( !labelingElement.isNull() )
1679  {
1682  }
1683 
1684  // get and set the display field if it exists.
1685  QDomNode displayFieldNode = node.namedItem( "displayfield" );
1686  if ( !displayFieldNode.isNull() )
1687  {
1688  QDomElement e = displayFieldNode.toElement();
1689  setDisplayField( e.text() );
1690  }
1691 
1692  // get and set the blend mode if it exists
1693  QDomNode blendModeNode = node.namedItem( "blendMode" );
1694  if ( !blendModeNode.isNull() )
1695  {
1696  QDomElement e = blendModeNode.toElement();
1697  setBlendMode( QgsMapRenderer::getCompositionMode( static_cast< QgsMapRenderer::BlendMode >( e.text().toInt() ) ) );
1698  }
1699 
1700  // get and set the feature blend mode if it exists
1701  QDomNode featureBlendModeNode = node.namedItem( "featureBlendMode" );
1702  if ( !featureBlendModeNode.isNull() )
1703  {
1704  QDomElement e = featureBlendModeNode.toElement();
1705  setFeatureBlendMode( QgsMapRenderer::getCompositionMode( static_cast< QgsMapRenderer::BlendMode >( e.text().toInt() ) ) );
1706  }
1707 
1708  // get and set the layer transparency if it exists
1709  QDomNode layerTransparencyNode = node.namedItem( "layerTransparency" );
1710  if ( !layerTransparencyNode.isNull() )
1711  {
1712  QDomElement e = layerTransparencyNode.toElement();
1713  setLayerTransparency( e.text().toInt() );
1714  }
1715 
1716  // use scale dependent visibility flag
1717  QDomElement e = node.toElement();
1718  if ( mLabel )
1719  {
1720  mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
1721  mLabel->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
1722  mLabel->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
1723  }
1724 
1725  // get the simplification drawing settings
1726  mSimplifyMethod.setSimplifyHints( static_cast< QgsVectorSimplifyMethod::SimplifyHints >( e.attribute( "simplifyDrawingHints", "1" ).toInt() ) );
1727  mSimplifyMethod.setThreshold( e.attribute( "simplifyDrawingTol", "1" ).toFloat() );
1728  mSimplifyMethod.setForceLocalOptimization( e.attribute( "simplifyLocal", "1" ).toInt() );
1729  mSimplifyMethod.setMaximumScale( e.attribute( "simplifyMaxScale", "1" ).toFloat() );
1730 
1731  //also restore custom properties (for labeling-ng)
1732  readCustomProperties( node, "labeling" );
1733 
1734  // Test if labeling is on or off
1735  QDomNode labelnode = node.namedItem( "label" );
1736  QDomElement element = labelnode.toElement();
1737  int hasLabelsEnabled = element.text().toInt();
1739  if ( hasLabelsEnabled < 1 )
1740  {
1741  enableLabels( false );
1742  }
1743  else
1744  {
1745  enableLabels( true );
1746  }
1748 
1749  QDomNode labelattributesnode = node.namedItem( "labelattributes" );
1750 
1751  if ( !labelattributesnode.isNull() && mLabel )
1752  {
1753  QgsDebugMsg( "calling readXML" );
1754  mLabel->readXML( labelattributesnode );
1755  }
1756 
1757  //diagram renderer and diagram layer settings
1758  delete mDiagramRenderer;
1759  mDiagramRenderer = nullptr;
1760  QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
1761  if ( !singleCatDiagramElem.isNull() )
1762  {
1763  mDiagramRenderer = new QgsSingleCategoryDiagramRenderer();
1764  mDiagramRenderer->readXML( singleCatDiagramElem, this );
1765  }
1766  QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
1767  if ( !linearDiagramElem.isNull() )
1768  {
1769  mDiagramRenderer = new QgsLinearlyInterpolatedDiagramRenderer();
1770  mDiagramRenderer->readXML( linearDiagramElem, this );
1771  }
1772 
1773  if ( mDiagramRenderer )
1774  {
1775  QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
1776  if ( !diagramSettingsElem.isNull() )
1777  {
1778  delete mDiagramLayerSettings;
1779  mDiagramLayerSettings = new QgsDiagramLayerSettings();
1780  mDiagramLayerSettings->readXML( diagramSettingsElem, this );
1781  }
1782  }
1783  }
1784 
1785  // process the attribute actions
1786  mActions->readXML( node );
1787 
1788  mEditFormConfig->readXml( node );
1789 
1790  QDomNode annotationFormNode = node.namedItem( "annotationform" );
1791  if ( !annotationFormNode.isNull() )
1792  {
1793  QDomElement e = annotationFormNode.toElement();
1794  mAnnotationForm = QgsProject::instance()->readPath( e.text() );
1795  }
1796 
1797  mAttributeAliasMap.clear();
1798  QDomNode aliasesNode = node.namedItem( "aliases" );
1799  if ( !aliasesNode.isNull() )
1800  {
1801  QDomElement aliasElem;
1802 
1803  QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( "alias" );
1804  for ( int i = 0; i < aliasNodeList.size(); ++i )
1805  {
1806  aliasElem = aliasNodeList.at( i ).toElement();
1807 
1808  QString field;
1809  if ( aliasElem.hasAttribute( "field" ) )
1810  {
1811  field = aliasElem.attribute( "field" );
1812  }
1813  else
1814  {
1815  int index = aliasElem.attribute( "index" ).toInt();
1816 
1817  if ( index >= 0 && index < fields().count() )
1818  field = fields().at( index ).name();
1819  }
1820 
1821  mAttributeAliasMap.insert( field, aliasElem.attribute( "name" ) );
1822  }
1823  }
1824 
1825  //Attributes excluded from WMS and WFS
1826  mExcludeAttributesWMS.clear();
1827  QDomNode excludeWMSNode = node.namedItem( "excludeAttributesWMS" );
1828  if ( !excludeWMSNode.isNull() )
1829  {
1830  QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( "attribute" );
1831  for ( int i = 0; i < attributeNodeList.size(); ++i )
1832  {
1833  mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
1834  }
1835  }
1836 
1837  mExcludeAttributesWFS.clear();
1838  QDomNode excludeWFSNode = node.namedItem( "excludeAttributesWFS" );
1839  if ( !excludeWFSNode.isNull() )
1840  {
1841  QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( "attribute" );
1842  for ( int i = 0; i < attributeNodeList.size(); ++i )
1843  {
1844  mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
1845  }
1846  }
1847 
1848  mEditFormConfig->readXml( node );
1849 
1850  mConditionalStyles->readXml( node );
1851 
1852  return true;
1853 }
1854 
1855 bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
1856 {
1857  QDomElement mapLayerNode = node.toElement();
1858 
1859  emit writeCustomSymbology( mapLayerNode, doc, errorMessage );
1860 
1861  if ( hasGeometryType() )
1862  {
1863  QDomElement rendererElement = mRendererV2->save( doc );
1864  node.appendChild( rendererElement );
1865 
1866  if ( mLabeling )
1867  {
1868  QDomElement labelingElement = mLabeling->save( doc );
1869  node.appendChild( labelingElement );
1870  }
1871 
1872  // use scale dependent visibility flag
1873  if ( mLabel )
1874  {
1875  mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
1876  mapLayerNode.setAttribute( "minLabelScale", QString::number( mLabel->minScale() ) );
1877  mapLayerNode.setAttribute( "maxLabelScale", QString::number( mLabel->maxScale() ) );
1878  }
1879 
1880  // save the simplification drawing settings
1881  mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) );
1882  mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) );
1883  mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 );
1884  mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) );
1885 
1886  //save customproperties (for labeling ng)
1887  writeCustomProperties( node, doc );
1888 
1889  // add the blend mode field
1890  QDomElement blendModeElem = doc.createElement( "blendMode" );
1892  blendModeElem.appendChild( blendModeText );
1893  node.appendChild( blendModeElem );
1894 
1895  // add the feature blend mode field
1896  QDomElement featureBlendModeElem = doc.createElement( "featureBlendMode" );
1898  featureBlendModeElem.appendChild( featureBlendModeText );
1899  node.appendChild( featureBlendModeElem );
1900 
1901  // add the layer transparency
1902  QDomElement layerTransparencyElem = doc.createElement( "layerTransparency" );
1903  QDomText layerTransparencyText = doc.createTextNode( QString::number( layerTransparency() ) );
1904  layerTransparencyElem.appendChild( layerTransparencyText );
1905  node.appendChild( layerTransparencyElem );
1906 
1907  // add the display field
1908  QDomElement dField = doc.createElement( "displayfield" );
1909  QDomText dFieldText = doc.createTextNode( displayField() );
1910  dField.appendChild( dFieldText );
1911  node.appendChild( dField );
1912 
1913  // add label node
1914  QDomElement labelElem = doc.createElement( "label" );
1915  QDomText labelText = doc.createTextNode( "" );
1916 
1918  if ( hasLabelsEnabled() )
1919  {
1920  labelText.setData( "1" );
1921  }
1922  else
1923  {
1924  labelText.setData( "0" );
1925  }
1927  labelElem.appendChild( labelText );
1928 
1929  node.appendChild( labelElem );
1930 
1931  // Now we get to do all that all over again for QgsLabel
1932 
1933  if ( mLabel )
1934  {
1935  QString fieldname = mLabel->labelField( QgsLabel::Text );
1936  if ( fieldname != "" )
1937  {
1938  dField = doc.createElement( "labelfield" );
1939  dFieldText = doc.createTextNode( fieldname );
1940  dField.appendChild( dFieldText );
1941  node.appendChild( dField );
1942  }
1943 
1944  mLabel->writeXML( node, doc );
1945  }
1946 
1947  if ( mDiagramRenderer )
1948  {
1949  mDiagramRenderer->writeXML( mapLayerNode, doc, this );
1950  if ( mDiagramLayerSettings )
1951  mDiagramLayerSettings->writeXML( mapLayerNode, doc, this );
1952  }
1953  }
1954 
1955  // FIXME
1956  // edittypes are written to the layerNode
1957  // by slot QgsEditorWidgetRegistry::writeMapLayer()
1958  // triggered by signal QgsProject::writeMapLayer()
1959  // still other editing settings are written here,
1960  // although they are not part of symbology either
1961 
1962  QDomElement afField = doc.createElement( "annotationform" );
1963  QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
1964  afField.appendChild( afText );
1965  node.appendChild( afField );
1966 
1967  //attribute aliases
1968  if ( !mAttributeAliasMap.isEmpty() )
1969  {
1970  QDomElement aliasElem = doc.createElement( "aliases" );
1971  QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
1972  for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
1973  {
1974  int idx = fieldNameIndex( a_it.key() );
1975  if ( idx < 0 )
1976  continue;
1977 
1978  QDomElement aliasEntryElem = doc.createElement( "alias" );
1979  aliasEntryElem.setAttribute( "field", a_it.key() );
1980  aliasEntryElem.setAttribute( "index", idx );
1981  aliasEntryElem.setAttribute( "name", a_it.value() );
1982  aliasElem.appendChild( aliasEntryElem );
1983  }
1984  node.appendChild( aliasElem );
1985  }
1986 
1987  //exclude attributes WMS
1988  QDomElement excludeWMSElem = doc.createElement( "excludeAttributesWMS" );
1989  QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
1990  for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
1991  {
1992  QDomElement attrElem = doc.createElement( "attribute" );
1993  QDomText attrText = doc.createTextNode( *attWMSIt );
1994  attrElem.appendChild( attrText );
1995  excludeWMSElem.appendChild( attrElem );
1996  }
1997  node.appendChild( excludeWMSElem );
1998 
1999  //exclude attributes WFS
2000  QDomElement excludeWFSElem = doc.createElement( "excludeAttributesWFS" );
2001  QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
2002  for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
2003  {
2004  QDomElement attrElem = doc.createElement( "attribute" );
2005  QDomText attrText = doc.createTextNode( *attWFSIt );
2006  attrElem.appendChild( attrText );
2007  excludeWFSElem.appendChild( attrElem );
2008  }
2009  node.appendChild( excludeWFSElem );
2010 
2011  // add attribute actions
2012  mActions->writeXML( node, doc );
2013 
2014  mEditFormConfig->writeXml( node );
2015 
2016  mConditionalStyles->writeXml( node, doc );
2017 
2018  return true;
2019 }
2020 
2021 bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
2022 {
2023  // get the Name element
2024  QDomElement nameElem = node.firstChildElement( "Name" );
2025  if ( nameElem.isNull() )
2026  {
2027  errorMessage = "Warning: Name element not found within NamedLayer while it's required.";
2028  }
2029 
2030  if ( hasGeometryType() )
2031  {
2032  QgsFeatureRendererV2* r = QgsFeatureRendererV2::loadSld( node, geometryType(), errorMessage );
2033  if ( !r )
2034  return false;
2035 
2036  setRendererV2( r );
2037 
2038  // labeling
2039  readSldLabeling( node );
2040  }
2041  return true;
2042 }
2043 
2044 
2045 bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2046 {
2047  Q_UNUSED( errorMessage );
2048 
2049  // store the Name element
2050  QDomElement nameNode = doc.createElement( "se:Name" );
2051  nameNode.appendChild( doc.createTextNode( name() ) );
2052  node.appendChild( nameNode );
2053 
2054  if ( hasGeometryType() )
2055  {
2056  node.appendChild( mRendererV2->writeSld( doc, name() ) );
2057  }
2058  return true;
2059 }
2060 
2061 
2063 {
2064  if ( !mEditBuffer || !mDataProvider )
2065  {
2066  return false;
2067  }
2068 
2069  updateExtents();
2070 
2071  return mEditBuffer->changeGeometry( fid, geom );
2072 }
2073 
2074 
2075 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant& value, bool emitSignal )
2076 {
2077  Q_UNUSED( emitSignal );
2078  return changeAttributeValue( fid, field, value );
2079 }
2080 
2081 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
2082 {
2083  if ( !mEditBuffer || !mDataProvider )
2084  return false;
2085 
2086  return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
2087 }
2088 
2090 {
2091  if ( !mEditBuffer || !mDataProvider )
2092  return false;
2093 
2094  return mEditBuffer->addAttribute( field );
2095 }
2096 
2098 {
2099  if ( attIndex < 0 || attIndex >= fields().count() )
2100  return;
2101 
2102  QString name = fields().at( attIndex ).name();
2103  if ( mAttributeAliasMap.contains( name ) )
2104  {
2105  mAttributeAliasMap.remove( name );
2106  emit layerModified();
2107  }
2108 }
2109 
2110 void QgsVectorLayer::addAttributeAlias( int attIndex, const QString& aliasString )
2111 {
2112  if ( attIndex < 0 || attIndex >= fields().count() )
2113  return;
2114 
2115  QString name = fields().at( attIndex ).name();
2116 
2117  mAttributeAliasMap.insert( name, aliasString );
2118  emit layerModified(); // TODO[MD]: should have a different signal?
2119 }
2120 
2121 QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
2122 {
2123  if ( attributeIndex < 0 || attributeIndex >= fields().count() )
2124  return "";
2125 
2126  QString name = fields().at( attributeIndex ).name();
2127 
2128  return mAttributeAliasMap.value( name, "" );
2129 }
2130 
2132 {
2133  QString displayName = attributeAlias( attributeIndex );
2134  if ( displayName.isEmpty() )
2135  {
2136  if ( attributeIndex >= 0 && attributeIndex < mUpdatedFields.count() )
2137  {
2138  displayName = mUpdatedFields[attributeIndex].name();
2139  }
2140  }
2141  return displayName;
2142 }
2143 
2145 {
2146  if ( index < 0 || index >= fields().count() )
2147  return false;
2148 
2149  if ( mUpdatedFields.fieldOrigin( index ) == QgsFields::OriginExpression )
2150  {
2151  removeExpressionField( index );
2152  return true;
2153  }
2154 
2155  if ( !mEditBuffer || !mDataProvider )
2156  return false;
2157 
2158  return mEditBuffer->deleteAttribute( index );
2159 }
2160 
2162 {
2163  bool deleted = false;
2164 
2165  // Remove multiple occurrences of same attribute
2166  attrs = attrs.toSet().toList();
2167 
2168  qSort( attrs.begin(), attrs.end(), qGreater<int>() );
2169 
2170  Q_FOREACH ( int attr, attrs )
2171  {
2172  if ( deleteAttribute( attr ) )
2173  {
2174  deleted = true;
2175  }
2176  }
2177 
2178  return deleted;
2179 }
2180 
2182 {
2183  if ( !mEditBuffer )
2184  return false;
2185 
2186  bool res = mEditBuffer->deleteFeature( fid );
2187  if ( res )
2188  mSelectedFeatureIds.remove( fid ); // remove it from selection
2189 
2190  updateExtents();
2191 
2192  return res;
2193 }
2194 
2196 {
2197  if ( !mEditBuffer )
2198  return false;
2199 
2200  bool res = mEditBuffer->deleteFeatures( fids );
2201 
2202  if ( res )
2203  mSelectedFeatureIds.subtract( fids ); // remove it from selection
2204 
2205  updateExtents();
2206 
2207  return res;
2208 }
2209 
2211 {
2212  QgsAttributeList pkAttributesList;
2213 
2214  QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
2215  for ( int i = 0; i < mUpdatedFields.count(); ++i )
2216  {
2217  if ( mUpdatedFields.fieldOrigin( i ) == QgsFields::OriginProvider &&
2218  providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
2219  pkAttributesList << i;
2220  }
2221 
2222  return pkAttributesList;
2223 }
2224 
2226 {
2227  return mDataProvider->featureCount() +
2228  ( mEditBuffer ? mEditBuffer->mAddedFeatures.size() - mEditBuffer->mDeletedFeatureIds.size() : 0 );
2229 }
2230 
2232 {
2233  mCommitErrors.clear();
2234 
2235  if ( !mDataProvider )
2236  {
2237  mCommitErrors << tr( "ERROR: no provider" );
2238  return false;
2239  }
2240 
2241  if ( !mEditBuffer )
2242  {
2243  mCommitErrors << tr( "ERROR: layer not editable" );
2244  return false;
2245  }
2246 
2247  emit beforeCommitChanges();
2248 
2249  bool success = mEditBuffer->commitChanges( mCommitErrors );
2250 
2251  if ( success )
2252  {
2253  delete mEditBuffer;
2254  mEditBuffer = nullptr;
2255  undoStack()->clear();
2256  emit editingStopped();
2257  }
2258  else
2259  {
2260  QgsMessageLog::logMessage( tr( "Commit errors:\n %1" ).arg( mCommitErrors.join( "\n " ) ) );
2261  }
2262 
2263  if ( mCache )
2264  {
2265  mCache->deleteCachedGeometries();
2266  }
2267 
2268  updateFields();
2269  mDataProvider->updateExtents();
2270 
2271  emit repaintRequested();
2272 
2273  return success;
2274 }
2275 
2277 {
2278  return mCommitErrors;
2279 }
2280 
2281 bool QgsVectorLayer::rollBack( bool deleteBuffer )
2282 {
2283  if ( !mEditBuffer )
2284  {
2285  return false;
2286  }
2287 
2288  emit beforeRollBack();
2289 
2290  mEditBuffer->rollBack();
2291 
2292  if ( isModified() )
2293  {
2294  // new undo stack roll back method
2295  // old method of calling every undo could cause many canvas refreshes
2296  undoStack()->setIndex( 0 );
2297  }
2298 
2299  updateFields();
2300 
2301  if ( deleteBuffer )
2302  {
2303  delete mEditBuffer;
2304  mEditBuffer = nullptr;
2305  undoStack()->clear();
2306  }
2307  emit editingStopped();
2308 
2309  if ( mCache )
2310  {
2311  mCache->deleteCachedGeometries();
2312  }
2313 
2314  emit repaintRequested();
2315  return true;
2316 }
2317 
2319 {
2320  QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - ids;
2321 
2322  mSelectedFeatureIds = ids;
2323 
2324  emit selectionChanged( ids, deselectedFeatures, true );
2325 }
2326 
2328 {
2329  return mSelectedFeatureIds.size();
2330 }
2331 
2333 {
2334  return mSelectedFeatureIds;
2335 }
2336 
2338 {
2339  QgsFeatureList features;
2340  QgsFeature f;
2341 
2342  if ( mSelectedFeatureIds.count() <= 8 )
2343  {
2344  // for small amount of selected features, fetch them directly
2345  // because request with FilterFids would go iterate over the whole layer
2346  Q_FOREACH ( QgsFeatureId fid, mSelectedFeatureIds )
2347  {
2348  getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
2349  features << f;
2350  }
2351  }
2352  else
2353  {
2355 
2356  while ( it.nextFeature( f ) )
2357  {
2358  features.push_back( f );
2359  }
2360  }
2361 
2362  return features;
2363 }
2364 
2366 {
2367  if ( mSelectedFeatureIds.isEmpty() )
2368  return QgsFeatureIterator();
2369 
2370  if ( geometryType() == QGis::NoGeometry )
2372 
2373  if ( mSelectedFeatureIds.count() == 1 )
2374  request.setFilterFid( *mSelectedFeatureIds.constBegin() );
2375  else
2376  request.setFilterFids( mSelectedFeatureIds );
2377 
2378  return getFeatures( request );
2379 }
2380 
2381 bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
2382 {
2383  if ( !mEditBuffer || !mDataProvider )
2384  return false;
2385 
2386  bool res = mEditBuffer->addFeatures( features );
2387 
2388  if ( makeSelected )
2389  {
2390  QgsFeatureIds ids;
2391 
2392  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
2393  ids << iter->id();
2394 
2395  setSelectedFeatures( ids );
2396  }
2397 
2398  updateExtents();
2399 
2400  return res;
2401 }
2402 
2403 
2404 bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
2405 {
2406  if ( !hasGeometryType() )
2407  return false;
2408 
2410  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
2411 
2412  if ( result != 0 )
2413  {
2414  return false;
2415  }
2416 
2417  if ( snapResults.size() < 1 )
2418  {
2419  return false;
2420  }
2421 
2423  point.setX( snap_it.value().snappedVertex.x() );
2424  point.setY( snap_it.value().snappedVertex.y() );
2425  return true;
2426 }
2427 
2428 
2429 int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snappingTolerance,
2430  QMultiMap<double, QgsSnappingResult>& snappingResults,
2431  QgsSnapper::SnappingType snap_to )
2432 {
2433  if ( !hasGeometryType() )
2434  return 1;
2435 
2436  if ( snappingTolerance <= 0 || !mDataProvider )
2437  {
2438  return 1;
2439  }
2440 
2441  QgsRectangle searchRect( startPoint.x() - snappingTolerance, startPoint.y() - snappingTolerance,
2442  startPoint.x() + snappingTolerance, startPoint.y() + snappingTolerance );
2443  double sqrSnappingTolerance = snappingTolerance * snappingTolerance;
2444 
2445  int n = 0;
2446  QgsFeature f;
2447 
2448  if ( mCache->cachedGeometriesRect().contains( searchRect ) )
2449  {
2450  QgsGeometryMap& cachedGeometries = mCache->cachedGeometries();
2451  for ( QgsGeometryMap::iterator it = cachedGeometries.begin(); it != cachedGeometries.end() ; ++it )
2452  {
2453  QgsGeometry* g = &( it.value() );
2454  if ( g->boundingBox().intersects( searchRect ) )
2455  {
2456  snapToGeometry( startPoint, it.key(), g, sqrSnappingTolerance, snappingResults, snap_to );
2457  ++n;
2458  }
2459  }
2460  }
2461  else
2462  {
2463  // snapping outside cached area
2464 
2466  .setFilterRect( searchRect )
2468  .setSubsetOfAttributes( QgsAttributeList() ) );
2469 
2470  while ( fit.nextFeature( f ) )
2471  {
2472  snapToGeometry( startPoint, f.id(), f.constGeometry(), sqrSnappingTolerance, snappingResults, snap_to );
2473  ++n;
2474  }
2475  }
2476 
2477  return n == 0 ? 2 : 0;
2478 }
2479 
2480 void QgsVectorLayer::snapToGeometry( const QgsPoint& startPoint,
2481  QgsFeatureId featureId,
2482  const QgsGeometry* geom,
2483  double sqrSnappingTolerance,
2484  QMultiMap<double, QgsSnappingResult>& snappingResults,
2485  QgsSnapper::SnappingType snap_to ) const
2486 {
2487  if ( !geom )
2488  {
2489  return;
2490  }
2491 
2492  int atVertex, beforeVertex, afterVertex;
2493  double sqrDistVertexSnap, sqrDistSegmentSnap;
2494  QgsPoint snappedPoint;
2495  QgsSnappingResult snappingResultVertex;
2496  QgsSnappingResult snappingResultSegment;
2497 
2498  if ( snap_to == QgsSnapper::SnapToVertex || snap_to == QgsSnapper::SnapToVertexAndSegment )
2499  {
2500  snappedPoint = geom->closestVertex( startPoint, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
2501  if ( sqrDistVertexSnap < sqrSnappingTolerance )
2502  {
2503  snappingResultVertex.snappedVertex = snappedPoint;
2504  snappingResultVertex.snappedVertexNr = atVertex;
2505  snappingResultVertex.beforeVertexNr = beforeVertex;
2506  if ( beforeVertex != -1 ) // make sure the vertex is valid
2507  {
2508  snappingResultVertex.beforeVertex = geom->vertexAt( beforeVertex );
2509  }
2510  snappingResultVertex.afterVertexNr = afterVertex;
2511  if ( afterVertex != -1 ) // make sure the vertex is valid
2512  {
2513  snappingResultVertex.afterVertex = geom->vertexAt( afterVertex );
2514  }
2515  snappingResultVertex.snappedAtGeometry = featureId;
2516  snappingResultVertex.layer = this;
2517  snappingResults.insert( sqrt( sqrDistVertexSnap ), snappingResultVertex );
2518  return;
2519  }
2520  }
2521  if ( snap_to == QgsSnapper::SnapToSegment || snap_to == QgsSnapper::SnapToVertexAndSegment ) // snap to segment
2522  {
2523  if ( geometryType() != QGis::Point ) // cannot snap to segment for points/multipoints
2524  {
2525  sqrDistSegmentSnap = geom->closestSegmentWithContext( startPoint, snappedPoint, afterVertex, nullptr, crs().geographicFlag() ? 1e-12 : 1e-8 );
2526 
2527  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
2528  {
2529  snappingResultSegment.snappedVertex = snappedPoint;
2530  snappingResultSegment.snappedVertexNr = -1;
2531  snappingResultSegment.beforeVertexNr = afterVertex - 1;
2532  snappingResultSegment.afterVertexNr = afterVertex;
2533  snappingResultSegment.snappedAtGeometry = featureId;
2534  snappingResultSegment.beforeVertex = geom->vertexAt( afterVertex - 1 );
2535  snappingResultSegment.afterVertex = geom->vertexAt( afterVertex );
2536  snappingResultSegment.layer = this;
2537  snappingResults.insert( sqrt( sqrDistSegmentSnap ), snappingResultSegment );
2538  }
2539  }
2540  }
2541 }
2542 
2544 {
2545  QgsVectorLayerEditUtils utils( this );
2546  return utils.insertSegmentVerticesForSnap( snapResults );
2547 }
2548 
2549 
2551 {
2552  QgsDebugMsg( "----- Computing Coordinate System" );
2553 
2554  //
2555  // Get the layers project info and set up the QgsCoordinateTransform
2556  // for this layer
2557  //
2558 
2559  if ( hasGeometryType() )
2560  {
2561  // get CRS directly from provider
2562  setCrs( mDataProvider->crs() );
2563  }
2564  else
2565  {
2567  }
2568 }
2569 
2570 
2572 {
2573  return mDisplayField;
2574 }
2575 
2576 void QgsVectorLayer::setDisplayExpression( const QString &displayExpression )
2577 {
2578  mDisplayExpression = displayExpression;
2579 }
2580 
2582 {
2583  return mDisplayExpression;
2584 }
2585 
2587 {
2588  return ( mEditBuffer && mDataProvider );
2589 }
2590 
2592 {
2593  return mReadOnly;
2594 }
2595 
2596 bool QgsVectorLayer::setReadOnly( bool readonly )
2597 {
2598  // exit if the layer is in editing mode
2599  if ( readonly && mEditBuffer )
2600  return false;
2601 
2602  mReadOnly = readonly;
2603  return true;
2604 }
2605 
2607 {
2608  emit beforeModifiedCheck();
2609  return mEditBuffer && mEditBuffer->isModified();
2610 }
2611 
2613 {
2614  if ( idx < 0 || idx >= mUpdatedFields.count() )
2615  return Hidden;
2616 
2618  return QgsLegacyHelpers::convertEditType( editorWidgetV2( idx ), editorWidgetV2Config( idx ), this, mUpdatedFields[ idx ].name() );
2620 }
2621 
2623 {
2624  if ( idx < 0 || idx >= mUpdatedFields.count() )
2625  return;
2626 
2628 
2630  const QString widgetType = QgsLegacyHelpers::convertEditType( type, cfg, this, mUpdatedFields[idx].name() );
2631 
2632  setEditorWidgetV2( idx, widgetType );
2633  setEditorWidgetV2Config( idx, cfg );
2635 }
2636 
2638 {
2639  mAnnotationForm = ui;
2640 }
2641 
2643 {
2645  return editorWidgetV2Config( idx );
2647 }
2648 
2650 {
2652  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2653  return RangeData(
2654  cfg.value( "Min" ),
2655  cfg.value( "Max" ),
2656  cfg.value( "Step" )
2657  );
2659 }
2660 
2662 {
2664  return editorWidgetV2Config( idx ).value( "DateFormat" ).toString();
2666 }
2667 
2669 {
2671  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2672  return QSize( cfg.value( "Width" ).toInt(), cfg.value( "Height" ).toInt() );
2674 }
2675 
2677 {
2678  if ( !hasGeometryType() )
2679  return;
2680 
2681  if ( r != mRendererV2 )
2682  {
2683  delete mRendererV2;
2684  mRendererV2 = r;
2685  mSymbolFeatureCounted = false;
2686  mSymbolFeatureCountMap.clear();
2687 
2688  emit rendererChanged();
2689  }
2690 }
2691 
2693 {
2694  if ( !mDataProvider )
2695  {
2696  return;
2697  }
2698  if ( !mDataProvider->transaction() )
2699  {
2700  undoStack()->beginMacro( text );
2701  mEditCommandActive = true;
2702  emit editCommandStarted( text );
2703  }
2704 }
2705 
2707 {
2708  if ( !mDataProvider )
2709  {
2710  return;
2711  }
2712  if ( !mDataProvider->transaction() )
2713  {
2714  undoStack()->endMacro();
2715  mEditCommandActive = false;
2716  if ( !mDeletedFids.isEmpty() )
2717  {
2718  emit featuresDeleted( mDeletedFids );
2719  mDeletedFids.clear();
2720  }
2721  emit editCommandEnded();
2722  }
2723 }
2724 
2726 {
2727  if ( !mDataProvider )
2728  {
2729  return;
2730  }
2731  if ( !mDataProvider->transaction() )
2732  {
2733  undoStack()->endMacro();
2734  undoStack()->undo();
2735  mEditCommandActive = false;
2736  mDeletedFids.clear();
2737  emit editCommandDestroyed();
2738  }
2739 }
2740 
2741 
2742 void QgsVectorLayer::setCheckedState( int idx, const QString& checked, const QString& unchecked )
2743 {
2746  cfg["CheckedState"] = checked;
2747  cfg["UncheckedState"] = unchecked;
2748  setEditorWidgetV2Config( idx, cfg );
2750 }
2751 
2752 int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
2753 {
2754  return fields().fieldNameIndex( fieldName );
2755 }
2756 
2758 {
2759  return mJoinBuffer && mJoinBuffer->addJoin( joinInfo );
2760 }
2761 
2763 {
2764  removeJoin( theLayerId );
2765 }
2766 
2767 bool QgsVectorLayer::removeJoin( const QString& joinLayerId )
2768 {
2769  bool res = false;
2770  if ( mJoinBuffer )
2771  {
2772  res = mJoinBuffer->removeJoin( joinLayerId );
2773  }
2774  return res;
2775 }
2776 
2778 {
2779  if ( mJoinBuffer )
2780  return mJoinBuffer->vectorJoins();
2781  else
2782  return QList< QgsVectorJoinInfo >();
2783 }
2784 
2786 {
2787  emit beforeAddingExpressionField( fld.name() );
2788  mExpressionFieldBuffer->addExpression( exp, fld );
2789  updateFields();
2790  int idx = mUpdatedFields.indexFromName( fld.name() );
2791  emit attributeAdded( idx );
2792  return idx;
2793 }
2794 
2796 {
2797  emit beforeRemovingExpressionField( index );
2798  int oi = mUpdatedFields.fieldOriginIndex( index );
2799  mExpressionFieldBuffer->removeExpression( oi );
2800  updateFields();
2801  emit attributeDeleted( index );
2802 }
2803 
2805 {
2806  int oi = mUpdatedFields.fieldOriginIndex( index );
2807  return mExpressionFieldBuffer->expressions().value( oi ).expression;
2808 }
2809 
2811 {
2812  int oi = mUpdatedFields.fieldOriginIndex( index );
2813  mExpressionFieldBuffer->updateExpression( oi, exp );
2814 }
2815 
2817 {
2818  if ( !mDataProvider )
2819  return;
2820 
2821  QgsFields oldFields = mUpdatedFields;
2822 
2823  mUpdatedFields = mDataProvider->fields();
2824 
2825  // added / removed fields
2826  if ( mEditBuffer )
2827  mEditBuffer->updateFields( mUpdatedFields );
2828 
2829  // joined fields
2830  if ( mJoinBuffer && mJoinBuffer->containsJoins() )
2831  mJoinBuffer->updateFields( mUpdatedFields );
2832 
2833  if ( mExpressionFieldBuffer )
2834  mExpressionFieldBuffer->updateFields( mUpdatedFields );
2835 
2836  if ( oldFields != mUpdatedFields )
2837  {
2838  emit updatedFields();
2839  mEditFormConfig->setFields( mUpdatedFields );
2840  }
2841 }
2842 
2843 
2845 {
2846  if ( mJoinBuffer->containsJoins() )
2847  {
2848  mJoinBuffer->createJoinCaches();
2849  }
2850 }
2851 
2852 void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
2853 {
2854  uniqueValues.clear();
2855  if ( !mDataProvider )
2856  {
2857  return;
2858  }
2859 
2860  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
2861  if ( origin == QgsFields::OriginUnknown )
2862  {
2863  return;
2864  }
2865 
2866  if ( origin == QgsFields::OriginProvider ) //a provider field
2867  {
2868  mDataProvider->uniqueValues( index, uniqueValues, limit );
2869 
2870  if ( mEditBuffer )
2871  {
2872  QSet<QString> vals;
2873  Q_FOREACH ( const QVariant& v, uniqueValues )
2874  {
2875  vals << v.toString();
2876  }
2877 
2879  while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
2880  {
2881  it.next();
2882  QVariant v = it.value().value( index );
2883  if ( v.isValid() )
2884  {
2885  QString vs = v.toString();
2886  if ( !vals.contains( vs ) )
2887  {
2888  vals << vs;
2889  uniqueValues << v;
2890  }
2891  }
2892  }
2893  }
2894 
2895  return;
2896  }
2897  else if ( origin == QgsFields::OriginJoin )
2898  {
2899  int sourceLayerIndex;
2900  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2901  Q_ASSERT( join );
2902 
2904 
2905  if ( vl )
2906  vl->dataProvider()->uniqueValues( sourceLayerIndex, uniqueValues, limit );
2907 
2908  return;
2909  }
2910  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
2911  {
2912  // the layer is editable, but in certain cases it can still be avoided going through all features
2913  if ( origin == QgsFields::OriginEdit && mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mAddedFeatures.isEmpty() && !mEditBuffer->mDeletedAttributeIds.contains( index ) && mEditBuffer->mChangedAttributeValues.isEmpty() )
2914  {
2915  mDataProvider->uniqueValues( index, uniqueValues, limit );
2916  return;
2917  }
2918 
2919  // we need to go through each feature
2920  QgsAttributeList attList;
2921  attList << index;
2922 
2924  .setFlags( QgsFeatureRequest::NoGeometry )
2925  .setSubsetOfAttributes( attList ) );
2926 
2927  QgsFeature f;
2928  QVariant currentValue;
2930  while ( fit.nextFeature( f ) )
2931  {
2932  currentValue = f.attribute( index );
2933  val.insert( currentValue.toString(), currentValue );
2934  if ( limit >= 0 && val.size() >= limit )
2935  {
2936  break;
2937  }
2938  }
2939 
2940  uniqueValues = val.values();
2941  return;
2942  }
2943 
2944  Q_ASSERT_X( false, "QgsVectorLayer::uniqueValues()", "Unknown source of the field!" );
2945 }
2946 
2948 {
2949  if ( !mDataProvider )
2950  {
2951  return QVariant();
2952  }
2953 
2954  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
2955  if ( origin == QgsFields::OriginUnknown )
2956  {
2957  return QVariant();
2958  }
2959 
2960  if ( origin == QgsFields::OriginProvider ) //a provider field
2961  {
2962  return mDataProvider->minimumValue( index );
2963  }
2964  else if ( origin == QgsFields::OriginJoin )
2965  {
2966  int sourceLayerIndex;
2967  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2968  Q_ASSERT( join );
2969 
2971  Q_ASSERT( vl );
2972 
2973  return vl->minimumValue( sourceLayerIndex );
2974  }
2975  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
2976  {
2977  // the layer is editable, but in certain cases it can still be avoided going through all features
2978  if ( origin == QgsFields::OriginEdit &&
2979  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
2980  mEditBuffer->mAddedFeatures.isEmpty() && !
2981  mEditBuffer->mDeletedAttributeIds.contains( index ) &&
2982  mEditBuffer->mChangedAttributeValues.isEmpty() )
2983  {
2984  return mDataProvider->minimumValue( index );
2985  }
2986 
2987  // we need to go through each feature
2988  QgsAttributeList attList;
2989  attList << index;
2990 
2992  .setFlags( QgsFeatureRequest::NoGeometry )
2993  .setSubsetOfAttributes( attList ) );
2994 
2995  QgsFeature f;
2997  double currentValue = 0;
2998  while ( fit.nextFeature( f ) )
2999  {
3000  currentValue = f.attribute( index ).toDouble();
3001  if ( currentValue < minimumValue )
3002  {
3003  minimumValue = currentValue;
3004  }
3005  }
3006  return QVariant( minimumValue );
3007  }
3008 
3009  Q_ASSERT_X( false, "QgsVectorLayer::minimumValue()", "Unknown source of the field!" );
3010  return QVariant();
3011 }
3012 
3014 {
3015  if ( !mDataProvider )
3016  {
3017  return QVariant();
3018  }
3019 
3020  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3021  if ( origin == QgsFields::OriginUnknown )
3022  {
3023  return QVariant();
3024  }
3025 
3026  if ( origin == QgsFields::OriginProvider ) //a provider field
3027  {
3028  return mDataProvider->maximumValue( index );
3029  }
3030  else if ( origin == QgsFields::OriginJoin )
3031  {
3032  int sourceLayerIndex;
3033  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3034  Q_ASSERT( join );
3035 
3037  Q_ASSERT( vl );
3038 
3039  return vl->maximumValue( sourceLayerIndex );
3040  }
3041  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3042  {
3043  // the layer is editable, but in certain cases it can still be avoided going through all features
3044  if ( origin == QgsFields::OriginEdit &&
3045  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3046  mEditBuffer->mAddedFeatures.isEmpty() &&
3047  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3048  mEditBuffer->mChangedAttributeValues.isEmpty() )
3049  {
3050  return mDataProvider->maximumValue( index );
3051  }
3052 
3053  // we need to go through each feature
3054  QgsAttributeList attList;
3055  attList << index;
3056 
3058  .setFlags( QgsFeatureRequest::NoGeometry )
3059  .setSubsetOfAttributes( attList ) );
3060 
3061  QgsFeature f;
3063  double currentValue = 0;
3064  while ( fit.nextFeature( f ) )
3065  {
3066  currentValue = f.attribute( index ).toDouble();
3067  if ( currentValue > maximumValue )
3068  {
3069  maximumValue = currentValue;
3070  }
3071  }
3072  return QVariant( maximumValue );
3073  }
3074 
3075  Q_ASSERT_X( false, "QgsVectorLayer::maximumValue()", "Unknown source of the field!" );
3076  return QVariant();
3077 }
3078 
3079 QList<QVariant> QgsVectorLayer::getValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly )
3080 {
3081  QList<QVariant> values;
3082 
3083  QScopedPointer<QgsExpression> expression;
3084  QgsExpressionContext context;
3085 
3086  int attrNum = fieldNameIndex( fieldOrExpression );
3087 
3088  if ( attrNum == -1 )
3089  {
3090  // try to use expression
3091  expression.reset( new QgsExpression( fieldOrExpression ) );
3095 
3096  if ( expression->hasParserError() || !expression->prepare( &context ) )
3097  {
3098  ok = false;
3099  return values;
3100  }
3101  }
3102 
3103  QgsFeature f;
3104  QStringList lst;
3105  if ( expression.isNull() )
3106  lst.append( fieldOrExpression );
3107  else
3108  lst = expression->referencedColumns();
3109 
3111  .setFlags(( expression && expression->needsGeometry() ) ?
3114  .setSubsetOfAttributes( lst, fields() );
3115 
3116  QgsFeatureIterator fit;
3117  if ( !selectedOnly )
3118  {
3119  fit = getFeatures( request );
3120  }
3121  else
3122  {
3123  fit = selectedFeaturesIterator( request );
3124  }
3125 
3126  // create list of non-null attribute values
3127  while ( fit.nextFeature( f ) )
3128  {
3129  if ( expression )
3130  {
3131  context.setFeature( f );
3132  QVariant v = expression->evaluate( &context );
3133  values << v;
3134  }
3135  else
3136  {
3137  values << f.attribute( attrNum );
3138  }
3139  }
3140  ok = true;
3141  return values;
3142 }
3143 
3144 QList<double> QgsVectorLayer::getDoubleValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly, int* nullCount )
3145 {
3146  QList<double> values;
3147 
3148  if ( nullCount )
3149  *nullCount = 0;
3150 
3151  QList<QVariant> variantValues = getValues( fieldOrExpression, ok, selectedOnly );
3152  if ( !ok )
3153  return values;
3154 
3155  bool convertOk;
3156  Q_FOREACH ( const QVariant& value, variantValues )
3157  {
3158  double val = value.toDouble( &convertOk );
3159  if ( convertOk )
3160  values << val;
3161  else if ( value.isNull() )
3162  {
3163  if ( nullCount )
3164  *nullCount += 1;
3165  }
3166  }
3167  ok = true;
3168  return values;
3169 }
3170 
3171 
3173 void QgsVectorLayer::setFeatureBlendMode( QPainter::CompositionMode featureBlendMode )
3174 {
3175  mFeatureBlendMode = featureBlendMode;
3176  emit featureBlendModeChanged( featureBlendMode );
3177 }
3178 
3180 QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
3181 {
3182  return mFeatureBlendMode;
3183 }
3184 
3186 void QgsVectorLayer::setLayerTransparency( int layerTransparency )
3187 {
3188  mLayerTransparency = layerTransparency;
3189  emit layerTransparencyChanged( layerTransparency );
3190 }
3191 
3194 {
3195  return mLayerTransparency;
3196 }
3197 
3198 
3199 
3200 void QgsVectorLayer::readSldLabeling( const QDomNode& node )
3201 {
3202  QDomElement element = node.toElement();
3203  if ( element.isNull() )
3204  return;
3205 
3206  QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
3207  if ( userStyleElem.isNull() )
3208  {
3209  QgsDebugMsg( "Info: UserStyle element not found." );
3210  return;
3211  }
3212 
3213  QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
3214  if ( featureTypeStyleElem.isNull() )
3215  {
3216  QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
3217  return;
3218  }
3219 
3220  // use last rule
3221  QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
3222  if ( ruleElem.isNull() )
3223  {
3224  QgsDebugMsg( "Info: Rule element not found." );
3225  return;
3226  }
3227 
3228  // use last text symbolizer
3229  QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3230  if ( textSymbolizerElem.isNull() )
3231  {
3232  QgsDebugMsg( "Info: TextSymbolizer element not found." );
3233  return;
3234  }
3235 
3236  // Label
3237  setCustomProperty( "labeling/enabled", false );
3238  QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3239  if ( !labelElem.isNull() )
3240  {
3241  QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3242  if ( !propertyNameElem.isNull() )
3243  {
3244  // enable labeling
3245  setCustomProperty( "labeling", "pal" );
3246  setCustomProperty( "labeling/enabled", true );
3247 
3248  // set labeling defaults
3249  setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3250  setCustomProperty( "labeling/fontItalic", false );
3251  setCustomProperty( "labeling/fontSize", 10 );
3252  setCustomProperty( "labeling/fontSizeInMapUnits", false );
3253  setCustomProperty( "labeling/fontBold", false );
3254  setCustomProperty( "labeling/fontUnderline", false );
3255  setCustomProperty( "labeling/textColorR", 0 );
3256  setCustomProperty( "labeling/textColorG", 0 );
3257  setCustomProperty( "labeling/textColorB", 0 );
3258  setCustomProperty( "labeling/textTransp", 0 );
3259  setCustomProperty( "labeling/bufferDraw", false );
3260  setCustomProperty( "labeling/bufferSize", 1 );
3261  setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3262  setCustomProperty( "labeling/bufferColorR", 255 );
3263  setCustomProperty( "labeling/bufferColorG", 255 );
3264  setCustomProperty( "labeling/bufferColorB", 255 );
3265  setCustomProperty( "labeling/bufferTransp", 0 );
3266  setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3267  setCustomProperty( "labeling/xOffset", 0 );
3268  setCustomProperty( "labeling/yOffset", 0 );
3269  setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3270  setCustomProperty( "labeling/angleOffset", 0 );
3271 
3272  // label attribute
3273  QString labelAttribute = propertyNameElem.text();
3274  setCustomProperty( "labeling/fieldName", labelAttribute );
3275  setCustomProperty( "labeling/isExpression", false );
3276 
3277  int fieldIndex = fieldNameIndex( labelAttribute );
3278  if ( fieldIndex == -1 )
3279  {
3280  // label attribute is not in columns, check if it is an expression
3281  QgsExpression exp( labelAttribute );
3282  if ( !exp.hasEvalError() )
3283  {
3284  setCustomProperty( "labeling/isExpression", true );
3285  }
3286  else
3287  {
3288  QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3289  }
3290  }
3291  }
3292  else
3293  {
3294  QgsDebugMsg( "Info: PropertyName element not found." );
3295  return;
3296  }
3297  }
3298  else
3299  {
3300  QgsDebugMsg( "Info: Label element not found." );
3301  return;
3302  }
3303 
3304  // Font
3305  QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3306  if ( !fontElem.isNull() )
3307  {
3308  QString cssName;
3309  QString elemText;
3310  QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3311  while ( !cssElem.isNull() )
3312  {
3313  cssName = cssElem.attribute( "name", "not_found" );
3314  if ( cssName != "not_found" )
3315  {
3316  elemText = cssElem.text();
3317  if ( cssName == "font-family" )
3318  {
3319  setCustomProperty( "labeling/fontFamily", elemText );
3320  }
3321  else if ( cssName == "font-style" )
3322  {
3323  setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3324  }
3325  else if ( cssName == "font-size" )
3326  {
3327  bool ok;
3328  int fontSize = elemText.toInt( &ok );
3329  if ( ok )
3330  {
3331  setCustomProperty( "labeling/fontSize", fontSize );
3332  }
3333  }
3334  else if ( cssName == "font-weight" )
3335  {
3336  setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3337  }
3338  else if ( cssName == "font-underline" )
3339  {
3340  setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3341  }
3342  }
3343 
3344  cssElem = cssElem.nextSiblingElement( "CssParameter" );
3345  }
3346  }
3347 
3348  // Fill
3349  QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3350  if ( textColor.isValid() )
3351  {
3352  setCustomProperty( "labeling/textColorR", textColor.red() );
3353  setCustomProperty( "labeling/textColorG", textColor.green() );
3354  setCustomProperty( "labeling/textColorB", textColor.blue() );
3355  setCustomProperty( "labeling/textTransp", 100 - static_cast< int >( 100 * textColor.alphaF() ) );
3356  }
3357 
3358  // Halo
3359  QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3360  if ( !haloElem.isNull() )
3361  {
3362  setCustomProperty( "labeling/bufferDraw", true );
3363  setCustomProperty( "labeling/bufferSize", 1 );
3364 
3365  QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3366  if ( !radiusElem.isNull() )
3367  {
3368  bool ok;
3369  double bufferSize = radiusElem.text().toDouble( &ok );
3370  if ( ok )
3371  {
3372  setCustomProperty( "labeling/bufferSize", bufferSize );
3373  }
3374  }
3375 
3376  QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3377  if ( bufferColor.isValid() )
3378  {
3379  setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3380  setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3381  setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3382  setCustomProperty( "labeling/bufferTransp", 100 - static_cast< int >( 100 * bufferColor.alphaF() ) );
3383  }
3384  }
3385 
3386  // LabelPlacement
3387  QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3388  if ( !labelPlacementElem.isNull() )
3389  {
3390  // PointPlacement
3391  QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3392  if ( !pointPlacementElem.isNull() )
3393  {
3394  setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3395 
3396  QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3397  if ( !displacementElem.isNull() )
3398  {
3399  QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3400  if ( !displacementXElem.isNull() )
3401  {
3402  bool ok;
3403  double xOffset = displacementXElem.text().toDouble( &ok );
3404  if ( ok )
3405  {
3406  setCustomProperty( "labeling/xOffset", xOffset );
3407  }
3408  }
3409  QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3410  if ( !displacementYElem.isNull() )
3411  {
3412  bool ok;
3413  double yOffset = displacementYElem.text().toDouble( &ok );
3414  if ( ok )
3415  {
3416  setCustomProperty( "labeling/yOffset", yOffset );
3417  }
3418  }
3419  }
3420 
3421  QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3422  if ( !rotationElem.isNull() )
3423  {
3424  bool ok;
3425  double rotation = rotationElem.text().toDouble( &ok );
3426  if ( ok )
3427  {
3428  setCustomProperty( "labeling/angleOffset", rotation );
3429  }
3430  }
3431  }
3432  }
3433 }
3434 
3436 {
3437  if ( !mDiagramLayerSettings )
3438  mDiagramLayerSettings = new QgsDiagramLayerSettings();
3439  *mDiagramLayerSettings = s;
3440 }
3441 
3443 {
3444  QString myMetadata = "<html><body>";
3445 
3446  //-------------
3447 
3448  myMetadata += "<p class=\"subheaderglossy\">";
3449  myMetadata += tr( "General" );
3450  myMetadata += "</p>\n";
3451 
3452  // data comment
3453  if ( !( dataComment().isEmpty() ) )
3454  {
3455  myMetadata += "<p class=\"glossy\">" + tr( "Layer comment" ) + "</p>\n";
3456  myMetadata += "<p>";
3457  myMetadata += dataComment();
3458  myMetadata += "</p>\n";
3459  }
3460 
3461  //storage type
3462  myMetadata += "<p class=\"glossy\">" + tr( "Storage type of this layer" ) + "</p>\n";
3463  myMetadata += "<p>";
3464  myMetadata += storageType();
3465  myMetadata += "</p>\n";
3466 
3467  if ( dataProvider() )
3468  {
3469  //provider description
3470  myMetadata += "<p class=\"glossy\">" + tr( "Description of this provider" ) + "</p>\n";
3471  myMetadata += "<p>";
3472  myMetadata += dataProvider()->description().replace( '\n', "<br>" );
3473  myMetadata += "</p>\n";
3474  }
3475 
3476  // data source
3477  myMetadata += "<p class=\"glossy\">" + tr( "Source for this layer" ) + "</p>\n";
3478  myMetadata += "<p>";
3479  myMetadata += publicSource();
3480  myMetadata += "</p>\n";
3481 
3482  //geom type
3483 
3485 
3486  if ( type < 0 || type > QGis::NoGeometry )
3487  {
3488  QgsDebugMsg( "Invalid vector type" );
3489  }
3490  else
3491  {
3492  QString typeString( QGis::vectorGeometryType( geometryType() ) );
3493 
3494  myMetadata += "<p class=\"glossy\">" + tr( "Geometry type of the features in this layer" ) + "</p>\n";
3495  myMetadata += "<p>";
3496  myMetadata += typeString;
3497  myMetadata += "</p>\n";
3498  }
3499 
3500  QgsAttributeList pkAttrList = pkAttributeList();
3501  if ( !pkAttrList.isEmpty() )
3502  {
3503  myMetadata += "<p class=\"glossy\">" + tr( "Primary key attributes" ) + "</p>\n";
3504  myMetadata += "<p>";
3505  Q_FOREACH ( int idx, pkAttrList )
3506  {
3507  myMetadata += fields().at( idx ).name() + ' ';
3508  }
3509  myMetadata += "</p>\n";
3510  }
3511 
3512 
3513  //feature count
3514  myMetadata += "<p class=\"glossy\">" + tr( "The number of features in this layer" ) + "</p>\n";
3515  myMetadata += "<p>";
3516  myMetadata += QString::number( featureCount() );
3517  myMetadata += "</p>\n";
3518  //capabilities
3519  myMetadata += "<p class=\"glossy\">" + tr( "Editing capabilities of this layer" ) + "</p>\n";
3520  myMetadata += "<p>";
3521  myMetadata += capabilitiesString();
3522  myMetadata += "</p>\n";
3523 
3524  //-------------
3525 
3526  QgsRectangle myExtent = extent();
3527  myMetadata += "<p class=\"subheaderglossy\">";
3528  myMetadata += tr( "Extents" );
3529  myMetadata += "</p>\n";
3530 
3531  //extents in layer cs TODO...maybe make a little nested table to improve layout...
3532  myMetadata += "<p class=\"glossy\">" + tr( "In layer spatial reference system units" ) + "</p>\n";
3533  myMetadata += "<p>";
3534  // Try to be a bit clever over what number format we use for the
3535  // extents. Some people don't like it using scientific notation when the
3536  // numbers get large, but for small numbers this is the more practical
3537  // option (so we can't force the format to 'f' for all values).
3538  // The scheme:
3539  // - for all numbers with more than 5 digits, force non-scientific notation
3540  // and 2 digits after the decimal point.
3541  // - for all smaller numbers let the OS decide which format to use (it will
3542  // generally use non-scientific unless the number gets much less than 1).
3543 
3544  if ( !myExtent.isEmpty() )
3545  {
3546  QString xMin, yMin, xMax, yMax;
3547  double changeoverValue = 99999; // The 'largest' 5 digit number
3548  if ( qAbs( myExtent.xMinimum() ) > changeoverValue )
3549  {
3550  xMin = QString( "%1" ).arg( myExtent.xMinimum(), 0, 'f', 2 );
3551  }
3552  else
3553  {
3554  xMin = QString( "%1" ).arg( myExtent.xMinimum() );
3555  }
3556  if ( qAbs( myExtent.yMinimum() ) > changeoverValue )
3557  {
3558  yMin = QString( "%1" ).arg( myExtent.yMinimum(), 0, 'f', 2 );
3559  }
3560  else
3561  {
3562  yMin = QString( "%1" ).arg( myExtent.yMinimum() );
3563  }
3564  if ( qAbs( myExtent.xMaximum() ) > changeoverValue )
3565  {
3566  xMax = QString( "%1" ).arg( myExtent.xMaximum(), 0, 'f', 2 );
3567  }
3568  else
3569  {
3570  xMax = QString( "%1" ).arg( myExtent.xMaximum() );
3571  }
3572  if ( qAbs( myExtent.yMaximum() ) > changeoverValue )
3573  {
3574  yMax = QString( "%1" ).arg( myExtent.yMaximum(), 0, 'f', 2 );
3575  }
3576  else
3577  {
3578  yMax = QString( "%1" ).arg( myExtent.yMaximum() );
3579  }
3580 
3581  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3582  .arg( xMin, yMin, xMax, yMax );
3583  }
3584  else
3585  {
3586  myMetadata += tr( "unknown extent" );
3587  }
3588 
3589  myMetadata += "</p>\n";
3590 
3591  //extents in project cs
3592 
3593  try
3594  {
3595 #if 0
3596  // TODO: currently disabled, will revisit later [MD]
3597  QgsRectangle myProjectedExtent = coordinateTransform->transformBoundingBox( extent() );
3598  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3599  myMetadata += "<p>";
3600  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3601  .arg( myProjectedExtent.xMinimum() )
3602  .arg( myProjectedExtent.yMinimum() )
3603  .arg( myProjectedExtent.xMaximum() )
3604  .arg( myProjectedExtent.yMaximum() );
3605  myMetadata += "</p>\n";
3606 #endif
3607 
3608  //
3609  // Display layer spatial ref system
3610  //
3611  myMetadata += "<p class=\"glossy\">" + tr( "Layer Spatial Reference System" ) + "</p>\n";
3612  myMetadata += "<p>";
3613  myMetadata += crs().toProj4().replace( '"', " \"" );
3614  myMetadata += "</p>\n";
3615 
3616  //
3617  // Display project (output) spatial ref system
3618  //
3619 #if 0
3620  // TODO: disabled for now, will revisit later [MD]
3621  //myMetadata += "<tr><td bgcolor=\"gray\">";
3622  myMetadata += "<p class=\"glossy\">" + tr( "Project (Output) Spatial Reference System" ) + "</p>\n";
3623  myMetadata += "<p>";
3624  myMetadata += coordinateTransform->destCRS().toProj4().replace( '"', " \"" );
3625  myMetadata += "</p>\n";
3626 #endif
3627  }
3628  catch ( QgsCsException &cse )
3629  {
3630  Q_UNUSED( cse );
3631  QgsDebugMsg( cse.what() );
3632 
3633  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3634  myMetadata += "<p>";
3635  myMetadata += tr( "(Invalid transformation of layer extents)" );
3636  myMetadata += "</p>\n";
3637 
3638  }
3639 
3640 #if 0
3641  //
3642  // Add the info about each field in the attribute table
3643  //
3644  myMetadata += "<p class=\"glossy\">" + tr( "Attribute field info" ) + "</p>\n";
3645  myMetadata += "<p>";
3646 
3647  // Start a nested table in this trow
3648  myMetadata += "<table width=\"100%\">";
3649  myMetadata += "<tr><th>";
3650  myMetadata += tr( "Field" );
3651  myMetadata += "</th>";
3652  myMetadata += "<th>";
3653  myMetadata += tr( "Type" );
3654  myMetadata += "</th>";
3655  myMetadata += "<th>";
3656  myMetadata += tr( "Length" );
3657  myMetadata += "</th>";
3658  myMetadata += "<th>";
3659  myMetadata += tr( "Precision" );
3660  myMetadata += "</th>";
3661  myMetadata += "<th>";
3662  myMetadata += tr( "Comment" );
3663  myMetadata += "</th>";
3664 
3665  //get info for each field by looping through them
3666  const QgsFields& myFields = pendingFields();
3667  for ( int i = 0, n = myFields.size(); i < n; ++i )
3668  {
3669  const QgsField& myField = fields[i];
3670 
3671  myMetadata += "<tr><td>";
3672  myMetadata += myField.name();
3673  myMetadata += "</td>";
3674  myMetadata += "<td>";
3675  myMetadata += myField.typeName();
3676  myMetadata += "</td>";
3677  myMetadata += "<td>";
3678  myMetadata += QString( "%1" ).arg( myField.length() );
3679  myMetadata += "</td>";
3680  myMetadata += "<td>";
3681  myMetadata += QString( "%1" ).arg( myField.precision() );
3682  myMetadata += "</td>";
3683  myMetadata += "<td>";
3684  myMetadata += QString( "%1" ).arg( myField.comment() );
3685  myMetadata += "</td></tr>";
3686  }
3687 
3688  //close field list
3689  myMetadata += "</table>"; //end of nested table
3690 #endif
3691 
3692  myMetadata += "</body></html>";
3693  return myMetadata;
3694 }
3695 
3697 {
3698  mSymbolFeatureCounted = false;
3699 }
3700 
3701 void QgsVectorLayer::onJoinedFieldsChanged()
3702 {
3703  // some of the fields of joined layers have changed -> we need to update this layer's fields too
3704  updateFields();
3705 }
3706 
3707 void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid )
3708 {
3709  if ( mEditCommandActive )
3710  mDeletedFids << fid;
3711  else
3712  emit featuresDeleted( QgsFeatureIds() << fid );
3713 
3714  emit featureDeleted( fid );
3715 }
3716 
3718 {
3719  if ( mEditFormConfig->widgetType( idx ) == "ValueRelation" )
3720  {
3721  QgsEditorWidgetConfig cfg = mEditFormConfig->widgetConfig( idx );
3722 
3723  return ValueRelationData( cfg.value( "Layer" ).toString(),
3724  cfg.value( "Key" ).toString(),
3725  cfg.value( "Value" ).toString(),
3726  cfg.value( "AllowNull" ).toBool(),
3727  cfg.value( "OrderByValue" ).toBool(),
3728  cfg.value( "AllowMulti" ).toBool(),
3729  cfg.value( "FilterExpression" ).toString()
3730  );
3731  }
3732  else
3733  {
3734  return ValueRelationData();
3735  }
3736 }
3737 
3739 {
3740  return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
3741 }
3742 
3744 {
3745  QDomElement elem = doc.createElement( "attributeEditorContainer" );
3746  elem.setAttribute( "name", mName );
3747 
3748  Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
3749  {
3750  elem.appendChild( child->toDomElement( doc ) );
3751  }
3752  return elem;
3753 }
3754 
3756 {
3757  mChildren.append( widget );
3758 }
3759 
3761 {
3762  mName = name;
3763 }
3764 
3766 {
3768 
3769  Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
3770  {
3771  if ( elem->type() == type )
3772  {
3773  results.append( elem );
3774  }
3775 
3776  if ( elem->type() == AeTypeContainer )
3777  {
3778  QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
3779  if ( cont )
3780  results += cont->findElements( type );
3781  }
3782  }
3783 
3784  return results;
3785 }
3786 
3788 {
3789  QDomElement elem = doc.createElement( "attributeEditorField" );
3790  elem.setAttribute( "name", mName );
3791  elem.setAttribute( "index", mIdx );
3792  return elem;
3793 }
3794 
3796 {
3798  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3799  if ( !myLib )
3800  {
3801  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3802  return -1;
3803  }
3804  listStyles_t* listStylesExternalMethod = reinterpret_cast< listStyles_t * >( cast_to_fptr( myLib->resolve( "listStyles" ) ) );
3805 
3806  if ( !listStylesExternalMethod )
3807  {
3808  delete myLib;
3809  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "listStyles" );
3810  return -1;
3811  }
3812 
3813  return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
3814 }
3815 
3817 {
3819  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3820  if ( !myLib )
3821  {
3822  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3823  return QObject::tr( "" );
3824  }
3825  getStyleById_t* getStyleByIdMethod = reinterpret_cast< getStyleById_t * >( cast_to_fptr( myLib->resolve( "getStyleById" ) ) );
3826 
3827  if ( !getStyleByIdMethod )
3828  {
3829  delete myLib;
3830  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "getStyleById" );
3831  return QObject::tr( "" );
3832  }
3833 
3834  return getStyleByIdMethod( mDataSource, styleId, msgError );
3835 }
3836 
3837 
3838 void QgsVectorLayer::saveStyleToDatabase( const QString& name, const QString& description,
3839  bool useAsDefault, const QString& uiFileContent, QString &msgError )
3840 {
3841 
3842  QString sldStyle, qmlStyle;
3844  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3845  if ( !myLib )
3846  {
3847  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3848  return;
3849  }
3850  saveStyle_t* saveStyleExternalMethod = reinterpret_cast< saveStyle_t * >( cast_to_fptr( myLib->resolve( "saveStyle" ) ) );
3851 
3852  if ( !saveStyleExternalMethod )
3853  {
3854  delete myLib;
3855  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "saveStyle" );
3856  return;
3857  }
3858 
3859  QDomDocument qmlDocument, sldDocument;
3860  this->exportNamedStyle( qmlDocument, msgError );
3861  if ( !msgError.isNull() )
3862  {
3863  return;
3864  }
3865  qmlStyle = qmlDocument.toString();
3866 
3867  this->exportSldStyle( sldDocument, msgError );
3868  if ( !msgError.isNull() )
3869  {
3870  return;
3871  }
3872  sldStyle = sldDocument.toString();
3873 
3874  saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
3875  description, uiFileContent, useAsDefault, msgError );
3876 }
3877 
3878 
3879 
3880 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag )
3881 {
3882  return loadNamedStyle( theURI, theResultFlag, false );
3883 }
3884 
3885 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag, bool loadFromLocalDB )
3886 {
3887  QgsDataSourceURI dsUri( theURI );
3888  if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
3889  {
3891  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3892  if ( myLib )
3893  {
3894  loadStyle_t* loadStyleExternalMethod = reinterpret_cast< loadStyle_t * >( cast_to_fptr( myLib->resolve( "loadStyle" ) ) );
3895  if ( loadStyleExternalMethod )
3896  {
3897  QString qml, errorMsg;
3898  qml = loadStyleExternalMethod( mDataSource, errorMsg );
3899  if ( !qml.isEmpty() )
3900  {
3902  theResultFlag = applyNamedStyle( qml, errorMsg );
3904  return QObject::tr( "Loaded from Provider" );
3905  }
3906  }
3907  }
3908  }
3909 
3910  return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
3911 }
3912 
3913 bool QgsVectorLayer::applyNamedStyle( const QString& namedStyle, QString& errorMsg )
3914 {
3915  QDomDocument myDocument( "qgis" );
3916  myDocument.setContent( namedStyle );
3917 
3918  return importNamedStyle( myDocument, errorMsg );
3919 }
3920 
3921 
3923 {
3924  QDomElement elem = doc.createElement( "attributeEditorRelation" );
3925  elem.setAttribute( "name", mName );
3926  elem.setAttribute( "relation", mRelation.id() );
3927  return elem;
3928 }
3929 
3931 {
3932  mRelation = relationManager->relation( mRelationId );
3933  return mRelation.isValid();
3934 }
3935 
3937 {
3938  if ( mDataProvider )
3939  {
3940  return mDataProvider->layerDependencies();
3941  }
3942  return QSet<QString>();
3943 }
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 QSet< QString > layerDependencies() const
Get the list of layer ids on which this layer depends.
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)...
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
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
virtual QString subsetString()
Returns the subset definition string (typically sql) currently in use by the layer and used by the pr...
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.
virtual bool setSubsetString(const QString &subset, bool updateFeatureCount=true)
Set the subset string used to create a subset of features in the layer.
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:197
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:99
virtual bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
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.
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.
bool contains(const Key &key) const
void createJoinCaches()
Calls cacheJoinLayer() for all vector joins.
virtual void updateExtents()
Update the extents of the layer.
void readCustomProperties(const QDomNode &layerNode, const QString &keyStartsWith="")
Read custom properties from project file.
void addExpression(const QString &exp, const QgsField &fld)
Add an expression to the buffer.
qreal alphaF() const
QString name() const
Get the display name of the layer.
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.
virtual bool addFeatures(QgsFeatureList &features)
Insert a copy of the given features into the layer (but does not commit it)
void beginEditCommand(const QString &text)
Create edit command for undo/redo operations.
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.
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
virtual bool addFeature(QgsFeature &f)
Adds a feature.
void setWindowModality(Qt::WindowModality windowModality)
field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfield.h:198
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.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:196
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
virtual QgsCoordinateReferenceSystem crs()=0
Get the QgsCoordinateReferenceSystem for this layer.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:433
QgsFields fields() const
Returns the list of fields of this layer.
float maxScale() const
Definition: qgslabel.cpp:1413
void clear()
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Returns unique values for column.
int size() const
QString toString(int indent) const
const QgsVectorJoinList & vectorJoins() const
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:446
double rendererScale() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
virtual QDomElement save(QDomDocument &doc)
store renderer info to XML element
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'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.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
void deleteCachedGeometries()
Deletes the geometries in mCachedGeometries.
int size() const
Storage and management of actions associated with Qgis layer attributes.
virtual void setEncoding(const QString &e)
Set encoding used for accessing data from layer.
bool startEditing()
Make layer editable.
const_iterator constBegin() const
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
void setRendererScale(double scale)
const T & at(int i) const
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
void removeExpressionField(int index)
Remove an expression field.
void setFeatureBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering each feature.
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
void select(QgsRectangle &rect, bool addToSelection)
Select features found within the search rectangle (in layer's coordinates)
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:407
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:102
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.
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.
void readXml(const QDomNode &layer_node)
Reads joins from project file.
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:189
virtual void rollBack()
Stop editing and discard the edits.
const QgsRectangle & cachedGeometriesRect()
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:392
QgsChangedAttributesMap mChangedAttributeValues
Changed attributes values which are not commited.
GeometryType
Definition: qgis.h:111
const QgsRectangle & extent() const
QSet< T > toSet() const
bool writeXml(QDomNode &node, QDomDocument &doc) const
Write field ui properties specific state from Dom node.
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:107
The QGis class provides global constants for use throughout the application.
Definition: qgis.h:36
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.
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:196
QString join(const QString &separator) const
WkbType
Used for symbology operations.
Definition: qgis.h:57
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
QList< QgsRelation > referencingRelations(int idx)
Get relations, where the foreign key is on this layer.
QString widgetType(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
void drawLine(const QLineF &line)
static const int EditingCapabilities
Bitmask of all provider's editing capabilities.
virtual ~QgsVectorLayer()
Destructor.
virtual QgsAttributeList pkAttributeIndexes()
Return list of indexes of fields that make up the primary key.
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 'true' 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.
void clear()
void chop(int n)
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
double toDouble(bool *ok) const
QString id() const
A (project-wide) unique id for this relation.
float minScale() const
Definition: qgslabel.cpp:1403
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.
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:685
void invertSelection()
Select not selected features and deselect selected ones.
double x() const
Get the x value of the point.
Definition: qgspoint.h:128
it has not been specified where the field comes from
Definition: qgsfield.h:195
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
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.
Returns diagram settings for a feature.
QString name() const
Return the name of this element.
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)
const QgsVectorJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
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.
bool writeXML(QDomNode &layer_node, QDomDocument &doc) const
Writes the actions out in XML format.
QgsGeometryMap & cachedGeometries()
static QString capitaliseLayerName(const QString &name)
A convenience function to (un)capitalise the layer name.
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...
bool containsJoins() const
Quick way to test if there is any join at all.
Q_DECL_DEPRECATED void setEditorWidgetV2(int attrIdx, const QString &widgetType)
Set the editor widget type for a field.
void writeXml(QDomNode &node) const
Write XML information Serialize on project save.
virtual Q_DECL_DEPRECATED QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat)
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
void setData(const QString &v)
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
QString encoding() const
Get encoding which is used for accessing data.
virtual void writeXML(QDomElement &layerElem, QDomDocument &doc, const QgsVectorLayer *layer) const =0
virtual QVariant maximumValue(int index)
Returns the maximum value of an attribute.
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.
virtual QDomElement toDomElement(QDomDocument &doc) const override
Will serialize this elements information into a QDomElement for saving it in an XML file...
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 ...
bool addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
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:92
void deselect(const QgsFeatureId featureId)
Deselect feature by its ID.
void layerDeleted()
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features.
bool writeSld(QDomNode &node, QDomDocument &doc, QString &errorMessage) const
QgsRectangle extent() override
Return the extent of the layer.
Fast access to features using their ID.
void readStyleManager(const QDomNode &layerNode)
Read style manager'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:201
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:186
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.
Edit failed due to invalid layer.
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.
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, const QString &rule="")
return a list of item text / symbol
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's attributes.
Definition: qgsfeature.cpp:110
void readXML(const QDomElement &elem, const QgsVectorLayer *layer)
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
int red() const
void setPen(const QColor &color)
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.
VertexMarkerType
Editing vertex markers.
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'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.
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:82
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 setScaleBasedVisibility(bool theVisibilityFlag)
Accessor and mutator for the scale based visilibility flag.
Definition: qgslabel.cpp:1388
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
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:417
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.
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves expressions to xml under the layer node.
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
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...
virtual long featureCount() const =0
Number of features in the layer.
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 QString dataSourceUri(bool expandAuthConfig=false) const
Get the data source specification.
QList< int > QgsAttributeList
AttributeEditorType type() const
The type of this element.
bool removeJoin(const QString &joinLayerId)
Removes a vector layer join.
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.
bool scaleBasedVisibility() const
Definition: qgslabel.cpp:1393
QgsEditorWidgetConfig widgetConfig(int fieldIdx) const
Get the configuration for the editor widget used to represent the field at the given index...
void writeCustomProperties(QDomNode &layerNode, QDomDocument &doc) const
Write custom properties to project file.
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)
virtual bool deleteFeatures(const QgsFeatureIds &fid)
Deletes a set of features from the layer (but does not commit it)
const QString displayField() const
Returns the primary display field name used in the identify results dialog.
const_iterator constEnd() const
int count() const
Return number of items.
Definition: qgsfield.cpp:363
bool setReadOnly(bool readonly=true)
Make layer read-only (editing disabled) or not.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
Change feature'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.
QString labelField(int attr) const
label field
Definition: qgslabel.cpp:499
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
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.
void updateFields(QgsFields &flds)
Adds fields with the expressions buffered in this object to a QgsFields object.
int count() const
virtual QGis::WkbType geometryType() const =0
Get feature type.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
void readXML(const QDomNode &node)
Reads the renderer configuration from an XML file.
Definition: qgslabel.cpp:745
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:679
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:383
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:65
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.
void writeXML(QDomNode &label_node, QDomDocument &document) const
Writes the contents of the renderer to a configuration file.
Definition: qgslabel.cpp:1038
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.
virtual bool commitChanges(QStringList &commitErrors)
Attempts to commit any changes to disk.
void committedAttributeValuesChanges(const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues)
QString right(int n) const
virtual bool deleteAttribute(int attr)
Delete an attribute field (but does not commit it)
const QStringList & commitErrors()
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
Definition: qgsfield.cpp:422
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:105
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.
void setY(double y)
Sets the y value of the point.
Definition: qgspoint.h:113
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 bool isReadOnly() const
Returns true if the provider is in read-only mode.
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 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:408
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.
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)
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.
void setMaxScale(float theMaxScale)
Accessor and mutator for the maximum scale member.
Definition: qgslabel.cpp:1408
Buffers information about expression fields for a vector layer.
QString getStyleById_t(const QString &uri, QString styleID, QString &errCause)
virtual QDomElement toDomElement(QDomDocument &doc) const =0
Is reimplemented in classes inheriting from this to serialize it.
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
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.
virtual QgsRectangle extent()=0
Get the extent of the layer.
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:682
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())
The attribute value should not be shown in the attribute form.
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...
void setSelectedFeatures(const QgsFeatureIds &ids)
Change selection to the new set of features.
EditResult
Result of an edit operation.
void endMacro()
void updateExpression(int index, const QString &exp)
Changes the expression at a given index.
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves mVectorJoins to xml under the layer node.
bool isEmpty() const
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.
virtual QDomElement save(QDomDocument &doc) const =0
Return labeling configuration as XML element.
virtual QVariant minimumValue(int index)
Returns the minimum value of an attribute.
bool deleteSelectedFeatures(int *deletedCount=nullptr)
Deletes the selected features.
Q_DECL_DEPRECATED RangeData range(int idx)
Access range widget config data.
virtual bool isValid()=0
Returns true if this is a valid layer.
static QgsAbstractVectorLayerLabeling * create(const QDomElement &element)
Try to create instance of an implementation based on the XML data.
float toFloat(bool *ok) const
bool readXml(const QDomNode &node)
Reads field ui properties specific state from Dom node.
Edit operation was successful.
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 updateFields(QgsFields &fields)
Updates field map with joined attributes.
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)
void readXml(const QDomNode &layer_node)
Reads expressions from project file.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &)
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:379
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
void removeExpression(int index)
Remove an expression from the buffer.
Class for storing a coordinate reference system (CRS)
void writeXML(QDomElement &layerElem, QDomDocument &doc, const QgsVectorLayer *layer) const
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:97
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:368
virtual QString description() const =0
Return description.
Q_DECL_DEPRECATED bool hasLabelsEnabled() const
Label is on.
virtual Q_DECL_DEPRECATED QDomElement writeSld(QDomDocument &doc, const QgsVectorLayer &layer) const
create the SLD UserStyle element following the SLD v1.1 specs
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
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:409
virtual void readXML(const QDomElement &elem, const QgsVectorLayer *layer)=0
This is a container for attribute editors, used to group them visually in the attribute form if it is...
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
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.
char * data()
virtual QString getStyleFromDatabase(const QString &styleId, QString &msgError)
Will return the named style corresponding to style id provided.
bool isEmpty() const
virtual bool deleteFeature(QgsFeatureId fid)
Delete a feature from the layer (but does not commit it)
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.
virtual bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant())
Changed an attribute value (but does not commit it)
double y() const
Get the y value of the point.
Definition: qgspoint.h:136
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's spatial reference system.
bool isValid() const
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
void readXml(const QDomNode &node)
Read XML information Deserialize on project load.
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage) const override
Write the symbology for the layer into the docment provided.
Edit operation resulted in an empty geometry.
virtual void addChildElement(QgsAttributeEditorElement *element)
Add a child element to this container.
iterator insert(const Key &key, const T &value)
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:258
virtual QString type() const =0
Unique type string of the labeling configuration implementation.
bool isEmpty() const
QString dataComment() const
Returns a comment for the data in the layer.
void setMinScale(float theMinScale)
Accessor and mutator for the minimum scale member.
Definition: qgslabel.cpp:1398
Custom exception class for Coordinate Reference System related exceptions.
QUndoStack * undoStack()
Return pointer to layer'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)
void clear()
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.
QgsFeatureMap mAddedFeatures
New features which are not commited.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:206
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
const QList< ExpressionField > & expressions() const
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.
void updateFields(QgsFields &fields)
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.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
int splitParts(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
void modifySelection(QgsFeatureIds selectIds, QgsFeatureIds deselectIds)
Modifies the current selection on this layer.
field is calculated from an expression
Definition: qgsfield.h:199
int selectedFeatureCount()
The number of features that are selected in this layer.
void updatedFields()
Is emitted, whenever the fields available from this layer have been changed.
QgsRelationManager * relationManager() const
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:191
QString toString() const
void updateExpressionField(int index, const QString &exp)
Changes the expression used to define an expression based (virtual) field.
const QgsVectorLayer * layer
Layer where the snap occurred.
Definition: qgssnapper.h:56
QString joinLayerId
Source layer.
void layerModified()
This signal is emitted when modifications has been done on layer.
QgsAttributeList mDeletedAttributeIds
Deleted attributes fields which are not commited.
Q_DECL_DEPRECATED void drawLabels(QgsRenderContext &rendererContext) override
Draws the layer labels using the old labeling engine.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
iterator begin()