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