QGIS API Documentation  2.14.11-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  if ( mRendererV2 )
1927  {
1928  QDomElement rendererElement = mRendererV2->save( doc );
1929  node.appendChild( rendererElement );
1930  }
1931 
1932  if ( mLabeling )
1933  {
1934  QDomElement labelingElement = mLabeling->save( doc );
1935  node.appendChild( labelingElement );
1936  }
1937 
1938  // use scale dependent visibility flag
1939  if ( mLabel )
1940  {
1941  mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
1942  mapLayerNode.setAttribute( "minLabelScale", QString::number( mLabel->minScale() ) );
1943  mapLayerNode.setAttribute( "maxLabelScale", QString::number( mLabel->maxScale() ) );
1944  }
1945 
1946  // save the simplification drawing settings
1947  mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) );
1948  mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) );
1949  mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 );
1950  mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) );
1951 
1952  //save customproperties (for labeling ng)
1953  writeCustomProperties( node, doc );
1954 
1955  // add the blend mode field
1956  QDomElement blendModeElem = doc.createElement( "blendMode" );
1958  blendModeElem.appendChild( blendModeText );
1959  node.appendChild( blendModeElem );
1960 
1961  // add the feature blend mode field
1962  QDomElement featureBlendModeElem = doc.createElement( "featureBlendMode" );
1964  featureBlendModeElem.appendChild( featureBlendModeText );
1965  node.appendChild( featureBlendModeElem );
1966 
1967  // add the layer transparency
1968  QDomElement layerTransparencyElem = doc.createElement( "layerTransparency" );
1969  QDomText layerTransparencyText = doc.createTextNode( QString::number( layerTransparency() ) );
1970  layerTransparencyElem.appendChild( layerTransparencyText );
1971  node.appendChild( layerTransparencyElem );
1972 
1973  // add the display field
1974  QDomElement dField = doc.createElement( "displayfield" );
1975  QDomText dFieldText = doc.createTextNode( displayField() );
1976  dField.appendChild( dFieldText );
1977  node.appendChild( dField );
1978 
1979  // add label node
1980  QDomElement labelElem = doc.createElement( "label" );
1981  QDomText labelText = doc.createTextNode( "" );
1982 
1984  if ( hasLabelsEnabled() )
1985  {
1986  labelText.setData( "1" );
1987  }
1988  else
1989  {
1990  labelText.setData( "0" );
1991  }
1993  labelElem.appendChild( labelText );
1994 
1995  node.appendChild( labelElem );
1996 
1997  // Now we get to do all that all over again for QgsLabel
1998 
1999  if ( mLabel )
2000  {
2001  QString fieldname = mLabel->labelField( QgsLabel::Text );
2002  if ( fieldname != "" )
2003  {
2004  dField = doc.createElement( "labelfield" );
2005  dFieldText = doc.createTextNode( fieldname );
2006  dField.appendChild( dFieldText );
2007  node.appendChild( dField );
2008  }
2009 
2010  mLabel->writeXML( node, doc );
2011  }
2012 
2013  if ( mDiagramRenderer )
2014  {
2015  mDiagramRenderer->writeXML( mapLayerNode, doc, this );
2016  if ( mDiagramLayerSettings )
2017  mDiagramLayerSettings->writeXML( mapLayerNode, doc, this );
2018  }
2019  }
2020 
2021  // FIXME
2022  // edittypes are written to the layerNode
2023  // by slot QgsEditorWidgetRegistry::writeMapLayer()
2024  // triggered by signal QgsProject::writeMapLayer()
2025  // still other editing settings are written here,
2026  // although they are not part of symbology either
2027 
2028  QDomElement afField = doc.createElement( "annotationform" );
2029  QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
2030  afField.appendChild( afText );
2031  node.appendChild( afField );
2032 
2033  //attribute aliases
2034  if ( !mAttributeAliasMap.isEmpty() )
2035  {
2036  QDomElement aliasElem = doc.createElement( "aliases" );
2037  QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
2038  for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
2039  {
2040  int idx = fieldNameIndex( a_it.key() );
2041  if ( idx < 0 )
2042  continue;
2043 
2044  QDomElement aliasEntryElem = doc.createElement( "alias" );
2045  aliasEntryElem.setAttribute( "field", a_it.key() );
2046  aliasEntryElem.setAttribute( "index", idx );
2047  aliasEntryElem.setAttribute( "name", a_it.value() );
2048  aliasElem.appendChild( aliasEntryElem );
2049  }
2050  node.appendChild( aliasElem );
2051  }
2052 
2053  //exclude attributes WMS
2054  QDomElement excludeWMSElem = doc.createElement( "excludeAttributesWMS" );
2055  QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
2056  for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
2057  {
2058  QDomElement attrElem = doc.createElement( "attribute" );
2059  QDomText attrText = doc.createTextNode( *attWMSIt );
2060  attrElem.appendChild( attrText );
2061  excludeWMSElem.appendChild( attrElem );
2062  }
2063  node.appendChild( excludeWMSElem );
2064 
2065  //exclude attributes WFS
2066  QDomElement excludeWFSElem = doc.createElement( "excludeAttributesWFS" );
2067  QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
2068  for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
2069  {
2070  QDomElement attrElem = doc.createElement( "attribute" );
2071  QDomText attrText = doc.createTextNode( *attWFSIt );
2072  attrElem.appendChild( attrText );
2073  excludeWFSElem.appendChild( attrElem );
2074  }
2075  node.appendChild( excludeWFSElem );
2076 
2077  // add attribute actions
2078  mActions->writeXML( node, doc );
2079 
2080  mEditFormConfig->writeXml( node );
2081 
2082  mConditionalStyles->writeXml( node, doc );
2083 
2084  return true;
2085 }
2086 
2087 bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
2088 {
2089  // get the Name element
2090  QDomElement nameElem = node.firstChildElement( "Name" );
2091  if ( nameElem.isNull() )
2092  {
2093  errorMessage = "Warning: Name element not found within NamedLayer while it's required.";
2094  }
2095 
2096  if ( hasGeometryType() )
2097  {
2098  QgsFeatureRendererV2* r = QgsFeatureRendererV2::loadSld( node, geometryType(), errorMessage );
2099  if ( !r )
2100  return false;
2101 
2102  setRendererV2( r );
2103 
2104  // labeling
2105  readSldLabeling( node );
2106  }
2107  return true;
2108 }
2109 
2110 bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2111 {
2112  return writeSld( node, doc, errorMessage, QgsStringMap() );
2113 }
2114 
2115 bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage, const QgsStringMap& props ) const
2116 {
2117  Q_UNUSED( errorMessage );
2118 
2119  // store the Name element
2120  QDomElement nameNode = doc.createElement( "se:Name" );
2121  nameNode.appendChild( doc.createTextNode( name() ) );
2122  node.appendChild( nameNode );
2123 
2124  QgsStringMap localProps = QgsStringMap( props );
2125  if ( hasScaleBasedVisibility() )
2126  {
2128  }
2129 
2130  if ( hasGeometryType() )
2131  {
2132  node.appendChild( mRendererV2->writeSld( doc, name(), localProps ) );
2133  }
2134  return true;
2135 }
2136 
2137 
2139 {
2140  if ( !mEditBuffer || !mDataProvider )
2141  {
2142  return false;
2143  }
2144 
2145  updateExtents();
2146 
2147  bool result = mEditBuffer->changeGeometry( fid, geom );
2148 
2149  if ( result )
2150  updateExtents();
2151  return result;
2152 }
2153 
2154 
2155 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant& value, bool emitSignal )
2156 {
2157  Q_UNUSED( emitSignal );
2158  return changeAttributeValue( fid, field, value );
2159 }
2160 
2161 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
2162 {
2163  if ( !mEditBuffer || !mDataProvider )
2164  return false;
2165 
2166  return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
2167 }
2168 
2170 {
2171  if ( !mEditBuffer || !mDataProvider )
2172  return false;
2173 
2174  return mEditBuffer->addAttribute( field );
2175 }
2176 
2178 {
2179  if ( attIndex < 0 || attIndex >= fields().count() )
2180  return;
2181 
2182  QString name = fields().at( attIndex ).name();
2183  if ( mAttributeAliasMap.contains( name ) )
2184  {
2185  mAttributeAliasMap.remove( name );
2186  emit layerModified();
2187  }
2188 }
2189 
2190 void QgsVectorLayer::addAttributeAlias( int attIndex, const QString& aliasString )
2191 {
2192  if ( attIndex < 0 || attIndex >= fields().count() )
2193  return;
2194 
2195  QString name = fields().at( attIndex ).name();
2196 
2197  mAttributeAliasMap.insert( name, aliasString );
2198  emit layerModified(); // TODO[MD]: should have a different signal?
2199 }
2200 
2201 QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
2202 {
2203  if ( attributeIndex < 0 || attributeIndex >= fields().count() )
2204  return "";
2205 
2206  QString name = fields().at( attributeIndex ).name();
2207 
2208  return mAttributeAliasMap.value( name, "" );
2209 }
2210 
2212 {
2213  QString displayName = attributeAlias( attributeIndex );
2214  if ( displayName.isEmpty() )
2215  {
2216  if ( attributeIndex >= 0 && attributeIndex < mUpdatedFields.count() )
2217  {
2218  displayName = mUpdatedFields[attributeIndex].name();
2219  }
2220  }
2221  return displayName;
2222 }
2223 
2225 {
2226  if ( index < 0 || index >= fields().count() )
2227  return false;
2228 
2229  if ( mUpdatedFields.fieldOrigin( index ) == QgsFields::OriginExpression )
2230  {
2231  removeExpressionField( index );
2232  return true;
2233  }
2234 
2235  if ( !mEditBuffer || !mDataProvider )
2236  return false;
2237 
2238  return mEditBuffer->deleteAttribute( index );
2239 }
2240 
2242 {
2243  bool deleted = false;
2244 
2245  // Remove multiple occurrences of same attribute
2246  attrs = attrs.toSet().toList();
2247 
2248  qSort( attrs.begin(), attrs.end(), qGreater<int>() );
2249 
2250  Q_FOREACH ( int attr, attrs )
2251  {
2252  if ( deleteAttribute( attr ) )
2253  {
2254  deleted = true;
2255  }
2256  }
2257 
2258  return deleted;
2259 }
2260 
2262 {
2263  if ( !mEditBuffer )
2264  return false;
2265 
2266  bool res = mEditBuffer->deleteFeature( fid );
2267  if ( res )
2268  {
2269  mSelectedFeatureIds.remove( fid ); // remove it from selection
2270  updateExtents();
2271  }
2272 
2273  return res;
2274 }
2275 
2277 {
2278  if ( !mEditBuffer )
2279  return false;
2280 
2281  bool res = mEditBuffer->deleteFeatures( fids );
2282 
2283  if ( res )
2284  {
2285  mSelectedFeatureIds.subtract( fids ); // remove it from selection
2286  updateExtents();
2287  }
2288 
2289  return res;
2290 }
2291 
2293 {
2294  QgsAttributeList pkAttributesList;
2295 
2296  QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
2297  for ( int i = 0; i < mUpdatedFields.count(); ++i )
2298  {
2299  if ( mUpdatedFields.fieldOrigin( i ) == QgsFields::OriginProvider &&
2300  providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
2301  pkAttributesList << i;
2302  }
2303 
2304  return pkAttributesList;
2305 }
2306 
2308 {
2309  return mDataProvider->featureCount() +
2310  ( mEditBuffer ? mEditBuffer->mAddedFeatures.size() - mEditBuffer->mDeletedFeatureIds.size() : 0 );
2311 }
2312 
2314 {
2315  mCommitErrors.clear();
2316 
2317  if ( !mDataProvider )
2318  {
2319  mCommitErrors << tr( "ERROR: no provider" );
2320  return false;
2321  }
2322 
2323  if ( !mEditBuffer )
2324  {
2325  mCommitErrors << tr( "ERROR: layer not editable" );
2326  return false;
2327  }
2328 
2329  emit beforeCommitChanges();
2330 
2331  bool success = mEditBuffer->commitChanges( mCommitErrors );
2332 
2333  if ( success )
2334  {
2335  delete mEditBuffer;
2336  mEditBuffer = nullptr;
2337  undoStack()->clear();
2338  emit editingStopped();
2339  }
2340  else
2341  {
2342  QgsMessageLog::logMessage( tr( "Commit errors:\n %1" ).arg( mCommitErrors.join( "\n " ) ) );
2343  }
2344 
2345  if ( mCache )
2346  {
2347  mCache->deleteCachedGeometries();
2348  }
2349 
2350  updateFields();
2351  mDataProvider->updateExtents();
2352 
2353  mDataProvider->leaveUpdateMode();
2354 
2355  emit repaintRequested();
2356 
2357  return success;
2358 }
2359 
2361 {
2362  return mCommitErrors;
2363 }
2364 
2365 bool QgsVectorLayer::rollBack( bool deleteBuffer )
2366 {
2367  if ( !mEditBuffer )
2368  {
2369  return false;
2370  }
2371 
2372  bool rollbackExtent = !mEditBuffer->mDeletedFeatureIds.isEmpty() ||
2373  !mEditBuffer->mAddedFeatures.isEmpty() ||
2374  !mEditBuffer->mChangedGeometries.isEmpty();
2375 
2376  emit beforeRollBack();
2377 
2378  mEditBuffer->rollBack();
2379 
2380  if ( isModified() )
2381  {
2382  // new undo stack roll back method
2383  // old method of calling every undo could cause many canvas refreshes
2384  undoStack()->setIndex( 0 );
2385  }
2386 
2387  updateFields();
2388 
2389  if ( deleteBuffer )
2390  {
2391  delete mEditBuffer;
2392  mEditBuffer = nullptr;
2393  undoStack()->clear();
2394  }
2395  emit editingStopped();
2396 
2397  if ( mCache )
2398  {
2399  mCache->deleteCachedGeometries();
2400  }
2401 
2402  if ( rollbackExtent )
2403  updateExtents();
2404 
2405  mDataProvider->leaveUpdateMode();
2406 
2407  emit repaintRequested();
2408  return true;
2409 }
2410 
2412 {
2413  QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - ids;
2414 
2415  mSelectedFeatureIds = ids;
2416 
2417  emit selectionChanged( ids, deselectedFeatures, true );
2418 }
2419 
2421 {
2422  return mSelectedFeatureIds.size();
2423 }
2424 
2426 {
2427  return mSelectedFeatureIds;
2428 }
2429 
2431 {
2432  QgsFeatureList features;
2433  QgsFeature f;
2434 
2435  if ( mSelectedFeatureIds.count() <= 8 )
2436  {
2437  // for small amount of selected features, fetch them directly
2438  // because request with FilterFids would go iterate over the whole layer
2439  Q_FOREACH ( QgsFeatureId fid, mSelectedFeatureIds )
2440  {
2441  getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
2442  features << f;
2443  }
2444  }
2445  else
2446  {
2448 
2449  while ( it.nextFeature( f ) )
2450  {
2451  features.push_back( f );
2452  }
2453  }
2454 
2455  return features;
2456 }
2457 
2459 {
2460  if ( mSelectedFeatureIds.isEmpty() )
2461  return QgsFeatureIterator();
2462 
2463  if ( geometryType() == QGis::NoGeometry )
2465 
2466  if ( mSelectedFeatureIds.count() == 1 )
2467  request.setFilterFid( *mSelectedFeatureIds.constBegin() );
2468  else
2469  request.setFilterFids( mSelectedFeatureIds );
2470 
2471  return getFeatures( request );
2472 }
2473 
2474 bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
2475 {
2476  if ( !mEditBuffer || !mDataProvider )
2477  return false;
2478 
2479  bool res = mEditBuffer->addFeatures( features );
2480 
2481  if ( makeSelected )
2482  {
2483  QgsFeatureIds ids;
2484 
2485  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
2486  ids << iter->id();
2487 
2488  setSelectedFeatures( ids );
2489  }
2490 
2491  updateExtents();
2492 
2493  return res;
2494 }
2495 
2496 
2497 bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
2498 {
2499  if ( !hasGeometryType() )
2500  return false;
2501 
2503  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
2504 
2505  if ( result != 0 )
2506  {
2507  return false;
2508  }
2509 
2510  if ( snapResults.size() < 1 )
2511  {
2512  return false;
2513  }
2514 
2516  point.setX( snap_it.value().snappedVertex.x() );
2517  point.setY( snap_it.value().snappedVertex.y() );
2518  return true;
2519 }
2520 
2521 
2522 int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snappingTolerance,
2523  QMultiMap<double, QgsSnappingResult>& snappingResults,
2524  QgsSnapper::SnappingType snap_to )
2525 {
2526  if ( !hasGeometryType() )
2527  return 1;
2528 
2529  if ( snappingTolerance <= 0 || !mDataProvider )
2530  {
2531  return 1;
2532  }
2533 
2534  QgsRectangle searchRect( startPoint.x() - snappingTolerance, startPoint.y() - snappingTolerance,
2535  startPoint.x() + snappingTolerance, startPoint.y() + snappingTolerance );
2536  double sqrSnappingTolerance = snappingTolerance * snappingTolerance;
2537 
2538  int n = 0;
2539  QgsFeature f;
2540 
2541  if ( mCache->cachedGeometriesRect().contains( searchRect ) )
2542  {
2543  QgsGeometryMap& cachedGeometries = mCache->cachedGeometries();
2544  for ( QgsGeometryMap::iterator it = cachedGeometries.begin(); it != cachedGeometries.end() ; ++it )
2545  {
2546  QgsGeometry* g = &( it.value() );
2547  if ( g->boundingBox().intersects( searchRect ) )
2548  {
2549  snapToGeometry( startPoint, it.key(), g, sqrSnappingTolerance, snappingResults, snap_to );
2550  ++n;
2551  }
2552  }
2553  }
2554  else
2555  {
2556  // snapping outside cached area
2557 
2559  .setFilterRect( searchRect )
2561  .setSubsetOfAttributes( QgsAttributeList() ) );
2562 
2563  while ( fit.nextFeature( f ) )
2564  {
2565  snapToGeometry( startPoint, f.id(), f.constGeometry(), sqrSnappingTolerance, snappingResults, snap_to );
2566  ++n;
2567  }
2568  }
2569 
2570  return n == 0 ? 2 : 0;
2571 }
2572 
2573 void QgsVectorLayer::snapToGeometry( const QgsPoint& startPoint,
2574  QgsFeatureId featureId,
2575  const QgsGeometry* geom,
2576  double sqrSnappingTolerance,
2577  QMultiMap<double, QgsSnappingResult>& snappingResults,
2578  QgsSnapper::SnappingType snap_to ) const
2579 {
2580  if ( !geom )
2581  {
2582  return;
2583  }
2584 
2585  int atVertex, beforeVertex, afterVertex;
2586  double sqrDistVertexSnap, sqrDistSegmentSnap;
2587  QgsPoint snappedPoint;
2588  QgsSnappingResult snappingResultVertex;
2589  QgsSnappingResult snappingResultSegment;
2590 
2591  if ( snap_to == QgsSnapper::SnapToVertex || snap_to == QgsSnapper::SnapToVertexAndSegment )
2592  {
2593  snappedPoint = geom->closestVertex( startPoint, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
2594  if ( sqrDistVertexSnap < sqrSnappingTolerance )
2595  {
2596  snappingResultVertex.snappedVertex = snappedPoint;
2597  snappingResultVertex.snappedVertexNr = atVertex;
2598  snappingResultVertex.beforeVertexNr = beforeVertex;
2599  if ( beforeVertex != -1 ) // make sure the vertex is valid
2600  {
2601  snappingResultVertex.beforeVertex = geom->vertexAt( beforeVertex );
2602  }
2603  snappingResultVertex.afterVertexNr = afterVertex;
2604  if ( afterVertex != -1 ) // make sure the vertex is valid
2605  {
2606  snappingResultVertex.afterVertex = geom->vertexAt( afterVertex );
2607  }
2608  snappingResultVertex.snappedAtGeometry = featureId;
2609  snappingResultVertex.layer = this;
2610  snappingResults.insert( sqrt( sqrDistVertexSnap ), snappingResultVertex );
2611  return;
2612  }
2613  }
2614  if ( snap_to == QgsSnapper::SnapToSegment || snap_to == QgsSnapper::SnapToVertexAndSegment ) // snap to segment
2615  {
2616  if ( geometryType() != QGis::Point ) // cannot snap to segment for points/multipoints
2617  {
2618  sqrDistSegmentSnap = geom->closestSegmentWithContext( startPoint, snappedPoint, afterVertex, nullptr, crs().geographicFlag() ? 1e-12 : 1e-8 );
2619 
2620  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
2621  {
2622  snappingResultSegment.snappedVertex = snappedPoint;
2623  snappingResultSegment.snappedVertexNr = -1;
2624  snappingResultSegment.beforeVertexNr = afterVertex - 1;
2625  snappingResultSegment.afterVertexNr = afterVertex;
2626  snappingResultSegment.snappedAtGeometry = featureId;
2627  snappingResultSegment.beforeVertex = geom->vertexAt( afterVertex - 1 );
2628  snappingResultSegment.afterVertex = geom->vertexAt( afterVertex );
2629  snappingResultSegment.layer = this;
2630  snappingResults.insert( sqrt( sqrDistSegmentSnap ), snappingResultSegment );
2631  }
2632  }
2633  }
2634 }
2635 
2637 {
2638  QgsVectorLayerEditUtils utils( this );
2639  return utils.insertSegmentVerticesForSnap( snapResults );
2640 }
2641 
2642 
2644 {
2645  QgsDebugMsg( "----- Computing Coordinate System" );
2646 
2647  //
2648  // Get the layers project info and set up the QgsCoordinateTransform
2649  // for this layer
2650  //
2651 
2652  if ( hasGeometryType() )
2653  {
2654  // get CRS directly from provider
2655  setCrs( mDataProvider->crs() );
2656  }
2657  else
2658  {
2660  }
2661 }
2662 
2663 
2665 {
2666  return mDisplayField;
2667 }
2668 
2670 {
2671  mDisplayExpression = displayExpression;
2672 }
2673 
2675 {
2676  return mDisplayExpression;
2677 }
2678 
2680 {
2681  return ( mEditBuffer && mDataProvider );
2682 }
2683 
2685 {
2686  return mReadOnly;
2687 }
2688 
2689 bool QgsVectorLayer::setReadOnly( bool readonly )
2690 {
2691  // exit if the layer is in editing mode
2692  if ( readonly && mEditBuffer )
2693  return false;
2694 
2695  mReadOnly = readonly;
2696  return true;
2697 }
2698 
2700 {
2701  emit beforeModifiedCheck();
2702  return mEditBuffer && mEditBuffer->isModified();
2703 }
2704 
2706 {
2707  if ( idx < 0 || idx >= mUpdatedFields.count() )
2708  return Hidden;
2709 
2711  return QgsLegacyHelpers::convertEditType( editorWidgetV2( idx ), editorWidgetV2Config( idx ), this, mUpdatedFields[ idx ].name() );
2713 }
2714 
2716 {
2717  if ( idx < 0 || idx >= mUpdatedFields.count() )
2718  return;
2719 
2721 
2723  const QString widgetType = QgsLegacyHelpers::convertEditType( type, cfg, this, mUpdatedFields[idx].name() );
2724 
2725  setEditorWidgetV2( idx, widgetType );
2726  setEditorWidgetV2Config( idx, cfg );
2728 }
2729 
2731 {
2732  mAnnotationForm = ui;
2733 }
2734 
2736 {
2738  return editorWidgetV2Config( idx );
2740 }
2741 
2743 {
2745  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2746  return RangeData(
2747  cfg.value( "Min" ),
2748  cfg.value( "Max" ),
2749  cfg.value( "Step" )
2750  );
2752 }
2753 
2755 {
2757  return editorWidgetV2Config( idx ).value( "DateFormat" ).toString();
2759 }
2760 
2762 {
2764  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2765  return QSize( cfg.value( "Width" ).toInt(), cfg.value( "Height" ).toInt() );
2767 }
2768 
2770 {
2771  if ( !hasGeometryType() )
2772  return;
2773 
2774  if ( r != mRendererV2 )
2775  {
2776  delete mRendererV2;
2777  mRendererV2 = r;
2778  mSymbolFeatureCounted = false;
2779  mSymbolFeatureCountMap.clear();
2780 
2781  emit rendererChanged();
2782  }
2783 }
2784 
2786 {
2787  if ( !mDataProvider )
2788  {
2789  return;
2790  }
2791  if ( !mDataProvider->transaction() )
2792  {
2793  undoStack()->beginMacro( text );
2794  mEditCommandActive = true;
2795  emit editCommandStarted( text );
2796  }
2797 }
2798 
2800 {
2801  if ( !mDataProvider )
2802  {
2803  return;
2804  }
2805  if ( !mDataProvider->transaction() )
2806  {
2807  undoStack()->endMacro();
2808  mEditCommandActive = false;
2809  if ( !mDeletedFids.isEmpty() )
2810  {
2811  emit featuresDeleted( mDeletedFids );
2812  mDeletedFids.clear();
2813  }
2814  emit editCommandEnded();
2815  }
2816 }
2817 
2819 {
2820  if ( !mDataProvider )
2821  {
2822  return;
2823  }
2824  if ( !mDataProvider->transaction() )
2825  {
2826  undoStack()->endMacro();
2827  undoStack()->undo();
2828  mEditCommandActive = false;
2829  mDeletedFids.clear();
2830  emit editCommandDestroyed();
2831  }
2832 }
2833 
2834 
2835 void QgsVectorLayer::setCheckedState( int idx, const QString& checked, const QString& unchecked )
2836 {
2839  cfg["CheckedState"] = checked;
2840  cfg["UncheckedState"] = unchecked;
2841  setEditorWidgetV2Config( idx, cfg );
2843 }
2844 
2845 int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
2846 {
2847  return fields().fieldNameIndex( fieldName );
2848 }
2849 
2851 {
2852  return mJoinBuffer && mJoinBuffer->addJoin( joinInfo );
2853 }
2854 
2856 {
2857  removeJoin( theLayerId );
2858 }
2859 
2860 bool QgsVectorLayer::removeJoin( const QString& joinLayerId )
2861 {
2862  bool res = false;
2863  if ( mJoinBuffer )
2864  {
2865  res = mJoinBuffer->removeJoin( joinLayerId );
2866  }
2867  return res;
2868 }
2869 
2871 {
2872  if ( mJoinBuffer )
2873  return mJoinBuffer->vectorJoins();
2874  else
2875  return QList< QgsVectorJoinInfo >();
2876 }
2877 
2879 {
2880  emit beforeAddingExpressionField( fld.name() );
2881  mExpressionFieldBuffer->addExpression( exp, fld );
2882  updateFields();
2883  int idx = mUpdatedFields.indexFromName( fld.name() );
2884  emit attributeAdded( idx );
2885  return idx;
2886 }
2887 
2889 {
2890  emit beforeRemovingExpressionField( index );
2891  int oi = mUpdatedFields.fieldOriginIndex( index );
2892  mExpressionFieldBuffer->removeExpression( oi );
2893  updateFields();
2894  emit attributeDeleted( index );
2895 }
2896 
2898 {
2899  int oi = mUpdatedFields.fieldOriginIndex( index );
2900  return mExpressionFieldBuffer->expressions().value( oi ).expression;
2901 }
2902 
2904 {
2905  int oi = mUpdatedFields.fieldOriginIndex( index );
2906  mExpressionFieldBuffer->updateExpression( oi, exp );
2907 }
2908 
2910 {
2911  if ( !mDataProvider )
2912  return;
2913 
2914  QgsFields oldFields = mUpdatedFields;
2915 
2916  mUpdatedFields = mDataProvider->fields();
2917 
2918  // added / removed fields
2919  if ( mEditBuffer )
2920  mEditBuffer->updateFields( mUpdatedFields );
2921 
2922  // joined fields
2923  if ( mJoinBuffer && mJoinBuffer->containsJoins() )
2924  mJoinBuffer->updateFields( mUpdatedFields );
2925 
2926  if ( mExpressionFieldBuffer )
2927  mExpressionFieldBuffer->updateFields( mUpdatedFields );
2928 
2929  if ( oldFields != mUpdatedFields )
2930  {
2931  emit updatedFields();
2932  mEditFormConfig->setFields( mUpdatedFields );
2933  }
2934 }
2935 
2936 
2938 {
2939  if ( mJoinBuffer->containsJoins() )
2940  {
2941  mJoinBuffer->createJoinCaches();
2942  }
2943 }
2944 
2946 {
2947  uniqueValues.clear();
2948  if ( !mDataProvider )
2949  {
2950  return;
2951  }
2952 
2953  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
2954  switch ( origin )
2955  {
2957  return;
2958 
2959  case QgsFields::OriginProvider: //a provider field
2960  {
2961  mDataProvider->uniqueValues( index, uniqueValues, limit );
2962 
2963  if ( mEditBuffer )
2964  {
2965  QSet<QString> vals;
2966  Q_FOREACH ( const QVariant& v, uniqueValues )
2967  {
2968  vals << v.toString();
2969  }
2970 
2971  QgsFeatureMap added = mEditBuffer->addedFeatures();
2973  while ( addedIt.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
2974  {
2975  addedIt.next();
2976  QVariant v = addedIt.value().attribute( index );
2977  if ( v.isValid() )
2978  {
2979  QString vs = v.toString();
2980  if ( !vals.contains( vs ) )
2981  {
2982  vals << vs;
2983  uniqueValues << v;
2984  }
2985  }
2986  }
2987 
2989  while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
2990  {
2991  it.next();
2992  QVariant v = it.value().value( index );
2993  if ( v.isValid() )
2994  {
2995  QString vs = v.toString();
2996  if ( !vals.contains( vs ) )
2997  {
2998  vals << vs;
2999  uniqueValues << v;
3000  }
3001  }
3002  }
3003  }
3004 
3005  return;
3006  }
3007 
3008  case QgsFields::OriginEdit:
3009  // the layer is editable, but in certain cases it can still be avoided going through all features
3010  if ( mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3011  mEditBuffer->mAddedFeatures.isEmpty() &&
3012  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3013  mEditBuffer->mChangedAttributeValues.isEmpty() )
3014  {
3015  mDataProvider->uniqueValues( index, uniqueValues, limit );
3016  return;
3017  }
3018  FALLTHROUGH;
3019  //we need to go through each feature
3020  case QgsFields::OriginJoin:
3022  {
3023  QgsAttributeList attList;
3024  attList << index;
3025 
3027  .setFlags( QgsFeatureRequest::NoGeometry )
3028  .setSubsetOfAttributes( attList ) );
3029 
3030  QgsFeature f;
3031  QVariant currentValue;
3033  while ( fit.nextFeature( f ) )
3034  {
3035  currentValue = f.attribute( index );
3036  val.insert( currentValue.toString(), currentValue );
3037  if ( limit >= 0 && val.size() >= limit )
3038  {
3039  break;
3040  }
3041  }
3042 
3043  uniqueValues = val.values();
3044  return;
3045  }
3046  }
3047 
3048  Q_ASSERT_X( false, "QgsVectorLayer::uniqueValues()", "Unknown source of the field!" );
3049 }
3050 
3052 {
3053  if ( !mDataProvider )
3054  {
3055  return QVariant();
3056  }
3057 
3058  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3059 
3060  switch ( origin )
3061  {
3063  return QVariant();
3064 
3065  case QgsFields::OriginProvider: //a provider field
3066  {
3067  QVariant min = mDataProvider->minimumValue( index );
3068  if ( mEditBuffer )
3069  {
3070  QgsFeatureMap added = mEditBuffer->addedFeatures();
3072  while ( addedIt.hasNext() )
3073  {
3074  addedIt.next();
3075  QVariant v = addedIt.value().attribute( index );
3076  if ( v.isValid() && qgsVariantLessThan( v, min ) )
3077  {
3078  min = v;
3079  }
3080  }
3081 
3083  while ( it.hasNext() )
3084  {
3085  it.next();
3086  QVariant v = it.value().value( index );
3087  if ( v.isValid() && qgsVariantLessThan( v, min ) )
3088  {
3089  min = v;
3090  }
3091  }
3092  }
3093  return min;
3094  }
3095 
3096  case QgsFields::OriginEdit:
3097  {
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->minimumValue( index );
3105  }
3106  }
3107  FALLTHROUGH;
3108  // no choice but to go through all features
3110  case QgsFields::OriginJoin:
3111  {
3112  // we need to go through each feature
3113  QgsAttributeList attList;
3114  attList << index;
3115 
3117  .setFlags( QgsFeatureRequest::NoGeometry )
3118  .setSubsetOfAttributes( attList ) );
3119 
3120  QgsFeature f;
3122  double currentValue = 0;
3123  while ( fit.nextFeature( f ) )
3124  {
3125  currentValue = f.attribute( index ).toDouble();
3126  if ( currentValue < minimumValue )
3127  {
3128  minimumValue = currentValue;
3129  }
3130  }
3131  return QVariant( minimumValue );
3132  }
3133  }
3134 
3135  Q_ASSERT_X( false, "QgsVectorLayer::minimumValue()", "Unknown source of the field!" );
3136  return QVariant();
3137 }
3138 
3140 {
3141  if ( !mDataProvider )
3142  {
3143  return QVariant();
3144  }
3145 
3146  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3147  switch ( origin )
3148  {
3150  return QVariant();
3151 
3152  case QgsFields::OriginProvider: //a provider field
3153  {
3154  QVariant min = mDataProvider->maximumValue( index );
3155  if ( mEditBuffer )
3156  {
3157  QgsFeatureMap added = mEditBuffer->addedFeatures();
3159  while ( addedIt.hasNext() )
3160  {
3161  addedIt.next();
3162  QVariant v = addedIt.value().attribute( index );
3163  if ( v.isValid() && qgsVariantGreaterThan( v, min ) )
3164  {
3165  min = v;
3166  }
3167  }
3168 
3170  while ( it.hasNext() )
3171  {
3172  it.next();
3173  QVariant v = it.value().value( index );
3174  if ( v.isValid() && qgsVariantGreaterThan( v, min ) )
3175  {
3176  min = v;
3177  }
3178  }
3179  }
3180  return min;
3181  }
3182 
3183  case QgsFields::OriginEdit:
3184  // the layer is editable, but in certain cases it can still be avoided going through all features
3185  if ( mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3186  mEditBuffer->mAddedFeatures.isEmpty() &&
3187  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3188  mEditBuffer->mChangedAttributeValues.isEmpty() )
3189  {
3190  return mDataProvider->maximumValue( index );
3191  }
3192 
3193  FALLTHROUGH;
3194  //no choice but to go through each feature
3195  case QgsFields::OriginJoin:
3197  {
3198  QgsAttributeList attList;
3199  attList << index;
3200 
3202  .setFlags( QgsFeatureRequest::NoGeometry )
3203  .setSubsetOfAttributes( attList ) );
3204 
3205  QgsFeature f;
3207  double currentValue = 0;
3208  while ( fit.nextFeature( f ) )
3209  {
3210  currentValue = f.attribute( index ).toDouble();
3211  if ( currentValue > maximumValue )
3212  {
3213  maximumValue = currentValue;
3214  }
3215  }
3216  return QVariant( maximumValue );
3217  }
3218  }
3219 
3220  Q_ASSERT_X( false, "QgsVectorLayer::maximumValue()", "Unknown source of the field!" );
3221  return QVariant();
3222 }
3223 
3224 QList<QVariant> QgsVectorLayer::getValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly )
3225 {
3226  QList<QVariant> values;
3227 
3228  QScopedPointer<QgsExpression> expression;
3229  QgsExpressionContext context;
3230 
3231  int attrNum = fieldNameIndex( fieldOrExpression );
3232 
3233  if ( attrNum == -1 )
3234  {
3235  // try to use expression
3236  expression.reset( new QgsExpression( fieldOrExpression ) );
3240 
3241  if ( expression->hasParserError() || !expression->prepare( &context ) )
3242  {
3243  ok = false;
3244  return values;
3245  }
3246  }
3247 
3248  QgsFeature f;
3249  QStringList lst;
3250  if ( expression.isNull() )
3251  lst.append( fieldOrExpression );
3252  else
3253  lst = expression->referencedColumns();
3254 
3256  .setFlags(( expression && expression->needsGeometry() ) ?
3259  .setSubsetOfAttributes( lst, fields() );
3260 
3261  QgsFeatureIterator fit;
3262  if ( !selectedOnly )
3263  {
3264  fit = getFeatures( request );
3265  }
3266  else
3267  {
3268  fit = selectedFeaturesIterator( request );
3269  }
3270 
3271  // create list of non-null attribute values
3272  while ( fit.nextFeature( f ) )
3273  {
3274  if ( expression )
3275  {
3276  context.setFeature( f );
3277  QVariant v = expression->evaluate( &context );
3278  values << v;
3279  }
3280  else
3281  {
3282  values << f.attribute( attrNum );
3283  }
3284  }
3285  ok = true;
3286  return values;
3287 }
3288 
3289 QList<double> QgsVectorLayer::getDoubleValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly, int* nullCount )
3290 {
3291  QList<double> values;
3292 
3293  if ( nullCount )
3294  *nullCount = 0;
3295 
3296  QList<QVariant> variantValues = getValues( fieldOrExpression, ok, selectedOnly );
3297  if ( !ok )
3298  return values;
3299 
3300  bool convertOk;
3301  Q_FOREACH ( const QVariant& value, variantValues )
3302  {
3303  double val = value.toDouble( &convertOk );
3304  if ( convertOk )
3305  values << val;
3306  else if ( value.isNull() )
3307  {
3308  if ( nullCount )
3309  *nullCount += 1;
3310  }
3311  }
3312  ok = true;
3313  return values;
3314 }
3315 
3316 
3319 {
3320  mFeatureBlendMode = featureBlendMode;
3321  emit featureBlendModeChanged( featureBlendMode );
3322 }
3323 
3325 QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
3326 {
3327  return mFeatureBlendMode;
3328 }
3329 
3332 {
3333  mLayerTransparency = layerTransparency;
3334  emit layerTransparencyChanged( layerTransparency );
3335 }
3336 
3339 {
3340  return mLayerTransparency;
3341 }
3342 
3343 
3344 
3345 void QgsVectorLayer::readSldLabeling( const QDomNode& node )
3346 {
3347  QDomElement element = node.toElement();
3348  if ( element.isNull() )
3349  return;
3350 
3351  QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
3352  if ( userStyleElem.isNull() )
3353  {
3354  QgsDebugMsg( "Info: UserStyle element not found." );
3355  return;
3356  }
3357 
3358  QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
3359  if ( featureTypeStyleElem.isNull() )
3360  {
3361  QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
3362  return;
3363  }
3364 
3365  // use last rule
3366  QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
3367  if ( ruleElem.isNull() )
3368  {
3369  QgsDebugMsg( "Info: Rule element not found." );
3370  return;
3371  }
3372 
3373  // use last text symbolizer
3374  QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3375  if ( textSymbolizerElem.isNull() )
3376  {
3377  QgsDebugMsg( "Info: TextSymbolizer element not found." );
3378  return;
3379  }
3380 
3381  // Label
3382  setCustomProperty( "labeling/enabled", false );
3383  QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3384  if ( !labelElem.isNull() )
3385  {
3386  QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3387  if ( !propertyNameElem.isNull() )
3388  {
3389  // enable labeling
3390  setCustomProperty( "labeling", "pal" );
3391  setCustomProperty( "labeling/enabled", true );
3392 
3393  // set labeling defaults
3394  setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3395  setCustomProperty( "labeling/fontItalic", false );
3396  setCustomProperty( "labeling/fontSize", 10 );
3397  setCustomProperty( "labeling/fontSizeInMapUnits", false );
3398  setCustomProperty( "labeling/fontBold", false );
3399  setCustomProperty( "labeling/fontUnderline", false );
3400  setCustomProperty( "labeling/textColorR", 0 );
3401  setCustomProperty( "labeling/textColorG", 0 );
3402  setCustomProperty( "labeling/textColorB", 0 );
3403  setCustomProperty( "labeling/textTransp", 0 );
3404  setCustomProperty( "labeling/bufferDraw", false );
3405  setCustomProperty( "labeling/bufferSize", 1 );
3406  setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3407  setCustomProperty( "labeling/bufferColorR", 255 );
3408  setCustomProperty( "labeling/bufferColorG", 255 );
3409  setCustomProperty( "labeling/bufferColorB", 255 );
3410  setCustomProperty( "labeling/bufferTransp", 0 );
3411  setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3412  setCustomProperty( "labeling/xOffset", 0 );
3413  setCustomProperty( "labeling/yOffset", 0 );
3414  setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3415  setCustomProperty( "labeling/angleOffset", 0 );
3416 
3417  // label attribute
3418  QString labelAttribute = propertyNameElem.text();
3419  setCustomProperty( "labeling/fieldName", labelAttribute );
3420  setCustomProperty( "labeling/isExpression", false );
3421 
3422  int fieldIndex = fieldNameIndex( labelAttribute );
3423  if ( fieldIndex == -1 )
3424  {
3425  // label attribute is not in columns, check if it is an expression
3426  QgsExpression exp( labelAttribute );
3427  if ( !exp.hasEvalError() )
3428  {
3429  setCustomProperty( "labeling/isExpression", true );
3430  }
3431  else
3432  {
3433  QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3434  }
3435  }
3436  }
3437  else
3438  {
3439  QgsDebugMsg( "Info: PropertyName element not found." );
3440  return;
3441  }
3442  }
3443  else
3444  {
3445  QgsDebugMsg( "Info: Label element not found." );
3446  return;
3447  }
3448 
3449  // Font
3450  QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3451  if ( !fontElem.isNull() )
3452  {
3453  QString cssName;
3454  QString elemText;
3455  QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3456  while ( !cssElem.isNull() )
3457  {
3458  cssName = cssElem.attribute( "name", "not_found" );
3459  if ( cssName != "not_found" )
3460  {
3461  elemText = cssElem.text();
3462  if ( cssName == "font-family" )
3463  {
3464  setCustomProperty( "labeling/fontFamily", elemText );
3465  }
3466  else if ( cssName == "font-style" )
3467  {
3468  setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3469  }
3470  else if ( cssName == "font-size" )
3471  {
3472  bool ok;
3473  int fontSize = elemText.toInt( &ok );
3474  if ( ok )
3475  {
3476  setCustomProperty( "labeling/fontSize", fontSize );
3477  }
3478  }
3479  else if ( cssName == "font-weight" )
3480  {
3481  setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3482  }
3483  else if ( cssName == "font-underline" )
3484  {
3485  setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3486  }
3487  }
3488 
3489  cssElem = cssElem.nextSiblingElement( "CssParameter" );
3490  }
3491  }
3492 
3493  // Fill
3494  QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3495  if ( textColor.isValid() )
3496  {
3497  setCustomProperty( "labeling/textColorR", textColor.red() );
3498  setCustomProperty( "labeling/textColorG", textColor.green() );
3499  setCustomProperty( "labeling/textColorB", textColor.blue() );
3500  setCustomProperty( "labeling/textTransp", 100 - static_cast< int >( 100 * textColor.alphaF() ) );
3501  }
3502 
3503  // Halo
3504  QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3505  if ( !haloElem.isNull() )
3506  {
3507  setCustomProperty( "labeling/bufferDraw", true );
3508  setCustomProperty( "labeling/bufferSize", 1 );
3509 
3510  QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3511  if ( !radiusElem.isNull() )
3512  {
3513  bool ok;
3514  double bufferSize = radiusElem.text().toDouble( &ok );
3515  if ( ok )
3516  {
3517  setCustomProperty( "labeling/bufferSize", bufferSize );
3518  }
3519  }
3520 
3521  QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3522  if ( bufferColor.isValid() )
3523  {
3524  setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3525  setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3526  setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3527  setCustomProperty( "labeling/bufferTransp", 100 - static_cast< int >( 100 * bufferColor.alphaF() ) );
3528  }
3529  }
3530 
3531  // LabelPlacement
3532  QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3533  if ( !labelPlacementElem.isNull() )
3534  {
3535  // PointPlacement
3536  QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3537  if ( !pointPlacementElem.isNull() )
3538  {
3539  setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3540 
3541  QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3542  if ( !displacementElem.isNull() )
3543  {
3544  QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3545  if ( !displacementXElem.isNull() )
3546  {
3547  bool ok;
3548  double xOffset = displacementXElem.text().toDouble( &ok );
3549  if ( ok )
3550  {
3551  setCustomProperty( "labeling/xOffset", xOffset );
3552  }
3553  }
3554  QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3555  if ( !displacementYElem.isNull() )
3556  {
3557  bool ok;
3558  double yOffset = displacementYElem.text().toDouble( &ok );
3559  if ( ok )
3560  {
3561  setCustomProperty( "labeling/yOffset", yOffset );
3562  }
3563  }
3564  }
3565 
3566  QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3567  if ( !rotationElem.isNull() )
3568  {
3569  bool ok;
3570  double rotation = rotationElem.text().toDouble( &ok );
3571  if ( ok )
3572  {
3573  setCustomProperty( "labeling/angleOffset", rotation );
3574  }
3575  }
3576  }
3577  }
3578 }
3579 
3581 {
3582  if ( !mDiagramLayerSettings )
3583  mDiagramLayerSettings = new QgsDiagramLayerSettings();
3584  *mDiagramLayerSettings = s;
3585 }
3586 
3588 {
3589  QString myMetadata = "<html><body>";
3590 
3591  //-------------
3592 
3593  myMetadata += "<p class=\"subheaderglossy\">";
3594  myMetadata += tr( "General" );
3595  myMetadata += "</p>\n";
3596 
3597  // data comment
3598  if ( !( dataComment().isEmpty() ) )
3599  {
3600  myMetadata += "<p class=\"glossy\">" + tr( "Layer comment" ) + "</p>\n";
3601  myMetadata += "<p>";
3602  myMetadata += dataComment();
3603  myMetadata += "</p>\n";
3604  }
3605 
3606  //storage type
3607  myMetadata += "<p class=\"glossy\">" + tr( "Storage type of this layer" ) + "</p>\n";
3608  myMetadata += "<p>";
3609  myMetadata += storageType();
3610  myMetadata += "</p>\n";
3611 
3612  if ( dataProvider() )
3613  {
3614  //provider description
3615  myMetadata += "<p class=\"glossy\">" + tr( "Description of this provider" ) + "</p>\n";
3616  myMetadata += "<p>";
3617  myMetadata += dataProvider()->description().replace( '\n', "<br>" );
3618  myMetadata += "</p>\n";
3619  }
3620 
3621  // data source
3622  myMetadata += "<p class=\"glossy\">" + tr( "Source for this layer" ) + "</p>\n";
3623  myMetadata += "<p>";
3624  myMetadata += publicSource();
3625  myMetadata += "</p>\n";
3626 
3627  //geom type
3628 
3630 
3631  if ( type < 0 || type > QGis::NoGeometry )
3632  {
3633  QgsDebugMsg( "Invalid vector type" );
3634  }
3635  else
3636  {
3637  QString typeString( QGis::vectorGeometryType( geometryType() ) );
3638 
3639  myMetadata += "<p class=\"glossy\">" + tr( "Geometry type of the features in this layer" ) + "</p>\n";
3640  myMetadata += "<p>";
3641  myMetadata += typeString;
3642  myMetadata += "</p>\n";
3643  }
3644 
3645  QgsAttributeList pkAttrList = pkAttributeList();
3646  if ( !pkAttrList.isEmpty() )
3647  {
3648  myMetadata += "<p class=\"glossy\">" + tr( "Primary key attributes" ) + "</p>\n";
3649  myMetadata += "<p>";
3650  Q_FOREACH ( int idx, pkAttrList )
3651  {
3652  myMetadata += fields().at( idx ).name() + ' ';
3653  }
3654  myMetadata += "</p>\n";
3655  }
3656 
3657 
3658  //feature count
3659  myMetadata += "<p class=\"glossy\">" + tr( "The number of features in this layer" ) + "</p>\n";
3660  myMetadata += "<p>";
3661  myMetadata += QString::number( featureCount() );
3662  myMetadata += "</p>\n";
3663  //capabilities
3664  myMetadata += "<p class=\"glossy\">" + tr( "Capabilities of this layer" ) + "</p>\n";
3665  myMetadata += "<p>";
3666  myMetadata += capabilitiesString();
3667  myMetadata += "</p>\n";
3668 
3669  //-------------
3670 
3671  QgsRectangle myExtent = extent();
3672  myMetadata += "<p class=\"subheaderglossy\">";
3673  myMetadata += tr( "Extents" );
3674  myMetadata += "</p>\n";
3675 
3676  //extents in layer cs TODO...maybe make a little nested table to improve layout...
3677  myMetadata += "<p class=\"glossy\">" + tr( "In layer spatial reference system units" ) + "</p>\n";
3678  myMetadata += "<p>";
3679  // Try to be a bit clever over what number format we use for the
3680  // extents. Some people don't like it using scientific notation when the
3681  // numbers get large, but for small numbers this is the more practical
3682  // option (so we can't force the format to 'f' for all values).
3683  // The scheme:
3684  // - for all numbers with more than 5 digits, force non-scientific notation
3685  // and 2 digits after the decimal point.
3686  // - for all smaller numbers let the OS decide which format to use (it will
3687  // generally use non-scientific unless the number gets much less than 1).
3688 
3689  if ( !myExtent.isEmpty() )
3690  {
3691  QString xMin, yMin, xMax, yMax;
3692  double changeoverValue = 99999; // The 'largest' 5 digit number
3693  if ( qAbs( myExtent.xMinimum() ) > changeoverValue )
3694  {
3695  xMin = QString( "%1" ).arg( myExtent.xMinimum(), 0, 'f', 2 );
3696  }
3697  else
3698  {
3699  xMin = QString( "%1" ).arg( myExtent.xMinimum() );
3700  }
3701  if ( qAbs( myExtent.yMinimum() ) > changeoverValue )
3702  {
3703  yMin = QString( "%1" ).arg( myExtent.yMinimum(), 0, 'f', 2 );
3704  }
3705  else
3706  {
3707  yMin = QString( "%1" ).arg( myExtent.yMinimum() );
3708  }
3709  if ( qAbs( myExtent.xMaximum() ) > changeoverValue )
3710  {
3711  xMax = QString( "%1" ).arg( myExtent.xMaximum(), 0, 'f', 2 );
3712  }
3713  else
3714  {
3715  xMax = QString( "%1" ).arg( myExtent.xMaximum() );
3716  }
3717  if ( qAbs( myExtent.yMaximum() ) > changeoverValue )
3718  {
3719  yMax = QString( "%1" ).arg( myExtent.yMaximum(), 0, 'f', 2 );
3720  }
3721  else
3722  {
3723  yMax = QString( "%1" ).arg( myExtent.yMaximum() );
3724  }
3725 
3726  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3727  .arg( xMin, yMin, xMax, yMax );
3728  }
3729  else
3730  {
3731  myMetadata += tr( "unknown extent" );
3732  }
3733 
3734  myMetadata += "</p>\n";
3735 
3736  //extents in project cs
3737 
3738  try
3739  {
3740 #if 0
3741  // TODO: currently disabled, will revisit later [MD]
3742  QgsRectangle myProjectedExtent = coordinateTransform->transformBoundingBox( extent() );
3743  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3744  myMetadata += "<p>";
3745  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3746  .arg( myProjectedExtent.xMinimum() )
3747  .arg( myProjectedExtent.yMinimum() )
3748  .arg( myProjectedExtent.xMaximum() )
3749  .arg( myProjectedExtent.yMaximum() );
3750  myMetadata += "</p>\n";
3751 #endif
3752 
3753  //
3754  // Display layer spatial ref system
3755  //
3756  myMetadata += "<p class=\"glossy\">" + tr( "Layer Spatial Reference System" ) + "</p>\n";
3757  myMetadata += "<p>";
3758  myMetadata += crs().toProj4().replace( '"', " \"" );
3759  myMetadata += "</p>\n";
3760 
3761  //
3762  // Display project (output) spatial ref system
3763  //
3764 #if 0
3765  // TODO: disabled for now, will revisit later [MD]
3766  //myMetadata += "<tr><td bgcolor=\"gray\">";
3767  myMetadata += "<p class=\"glossy\">" + tr( "Project (Output) Spatial Reference System" ) + "</p>\n";
3768  myMetadata += "<p>";
3769  myMetadata += coordinateTransform->destCRS().toProj4().replace( '"', " \"" );
3770  myMetadata += "</p>\n";
3771 #endif
3772  }
3773  catch ( QgsCsException &cse )
3774  {
3775  Q_UNUSED( cse );
3776  QgsDebugMsg( cse.what() );
3777 
3778  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3779  myMetadata += "<p>";
3780  myMetadata += tr( "(Invalid transformation of layer extents)" );
3781  myMetadata += "</p>\n";
3782 
3783  }
3784 
3785 #if 0
3786  //
3787  // Add the info about each field in the attribute table
3788  //
3789  myMetadata += "<p class=\"glossy\">" + tr( "Attribute field info" ) + "</p>\n";
3790  myMetadata += "<p>";
3791 
3792  // Start a nested table in this trow
3793  myMetadata += "<table width=\"100%\">";
3794  myMetadata += "<tr><th>";
3795  myMetadata += tr( "Field" );
3796  myMetadata += "</th>";
3797  myMetadata += "<th>";
3798  myMetadata += tr( "Type" );
3799  myMetadata += "</th>";
3800  myMetadata += "<th>";
3801  myMetadata += tr( "Length" );
3802  myMetadata += "</th>";
3803  myMetadata += "<th>";
3804  myMetadata += tr( "Precision" );
3805  myMetadata += "</th>";
3806  myMetadata += "<th>";
3807  myMetadata += tr( "Comment" );
3808  myMetadata += "</th>";
3809 
3810  //get info for each field by looping through them
3811  const QgsFields& myFields = pendingFields();
3812  for ( int i = 0, n = myFields.size(); i < n; ++i )
3813  {
3814  const QgsField& myField = fields[i];
3815 
3816  myMetadata += "<tr><td>";
3817  myMetadata += myField.name();
3818  myMetadata += "</td>";
3819  myMetadata += "<td>";
3820  myMetadata += myField.typeName();
3821  myMetadata += "</td>";
3822  myMetadata += "<td>";
3823  myMetadata += QString( "%1" ).arg( myField.length() );
3824  myMetadata += "</td>";
3825  myMetadata += "<td>";
3826  myMetadata += QString( "%1" ).arg( myField.precision() );
3827  myMetadata += "</td>";
3828  myMetadata += "<td>";
3829  myMetadata += QString( "%1" ).arg( myField.comment() );
3830  myMetadata += "</td></tr>";
3831  }
3832 
3833  //close field list
3834  myMetadata += "</table>"; //end of nested table
3835 #endif
3836 
3837  myMetadata += "</body></html>";
3838  return myMetadata;
3839 }
3840 
3842 {
3843  mSymbolFeatureCounted = false;
3844 }
3845 
3846 void QgsVectorLayer::onJoinedFieldsChanged()
3847 {
3848  // some of the fields of joined layers have changed -> we need to update this layer's fields too
3849  updateFields();
3850 }
3851 
3852 void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid )
3853 {
3854  if ( mEditCommandActive )
3855  mDeletedFids << fid;
3856  else
3857  emit featuresDeleted( QgsFeatureIds() << fid );
3858 
3859  emit featureDeleted( fid );
3860 }
3861 
3863 {
3864  if ( mEditFormConfig->widgetType( idx ) == "ValueRelation" )
3865  {
3866  QgsEditorWidgetConfig cfg = mEditFormConfig->widgetConfig( idx );
3867 
3868  return ValueRelationData( cfg.value( "Layer" ).toString(),
3869  cfg.value( "Key" ).toString(),
3870  cfg.value( "Value" ).toString(),
3871  cfg.value( "AllowNull" ).toBool(),
3872  cfg.value( "OrderByValue" ).toBool(),
3873  cfg.value( "AllowMulti" ).toBool(),
3874  cfg.value( "FilterExpression" ).toString()
3875  );
3876  }
3877  else
3878  {
3879  return ValueRelationData();
3880  }
3881 }
3882 
3884 {
3885  return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
3886 }
3887 
3889 {
3890  QDomElement elem = doc.createElement( "attributeEditorContainer" );
3891  elem.setAttribute( "name", mName );
3892 
3893  Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
3894  {
3895  elem.appendChild( child->toDomElement( doc ) );
3896  }
3897  return elem;
3898 }
3899 
3901 {
3902  mChildren.append( widget );
3903 }
3904 
3906 {
3907  mName = name;
3908 }
3909 
3911 {
3913 
3914  Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
3915  {
3916  if ( elem->type() == type )
3917  {
3918  results.append( elem );
3919  }
3920 
3921  if ( elem->type() == AeTypeContainer )
3922  {
3923  QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
3924  if ( cont )
3925  results += cont->findElements( type );
3926  }
3927  }
3928 
3929  return results;
3930 }
3931 
3933 {
3934  QDomElement elem = doc.createElement( "attributeEditorField" );
3935  elem.setAttribute( "name", mName );
3936  elem.setAttribute( "index", mIdx );
3937  return elem;
3938 }
3939 
3941 {
3943  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3944  if ( !myLib )
3945  {
3946  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3947  return -1;
3948  }
3949  listStyles_t* listStylesExternalMethod = reinterpret_cast< listStyles_t * >( cast_to_fptr( myLib->resolve( "listStyles" ) ) );
3950 
3951  if ( !listStylesExternalMethod )
3952  {
3953  delete myLib;
3954  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "listStyles" );
3955  return -1;
3956  }
3957 
3958  return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
3959 }
3960 
3962 {
3964  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3965  if ( !myLib )
3966  {
3967  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3968  return QObject::tr( "" );
3969  }
3970  getStyleById_t* getStyleByIdMethod = reinterpret_cast< getStyleById_t * >( cast_to_fptr( myLib->resolve( "getStyleById" ) ) );
3971 
3972  if ( !getStyleByIdMethod )
3973  {
3974  delete myLib;
3975  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "getStyleById" );
3976  return QObject::tr( "" );
3977  }
3978 
3979  return getStyleByIdMethod( mDataSource, styleId, msgError );
3980 }
3981 
3982 
3983 void QgsVectorLayer::saveStyleToDatabase( const QString& name, const QString& description,
3984  bool useAsDefault, const QString& uiFileContent, QString &msgError )
3985 {
3986 
3987  QString sldStyle, qmlStyle;
3989  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3990  if ( !myLib )
3991  {
3992  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3993  return;
3994  }
3995  saveStyle_t* saveStyleExternalMethod = reinterpret_cast< saveStyle_t * >( cast_to_fptr( myLib->resolve( "saveStyle" ) ) );
3996 
3997  if ( !saveStyleExternalMethod )
3998  {
3999  delete myLib;
4000  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "saveStyle" );
4001  return;
4002  }
4003 
4004  QDomDocument qmlDocument, sldDocument;
4005  this->exportNamedStyle( qmlDocument, msgError );
4006  if ( !msgError.isNull() )
4007  {
4008  return;
4009  }
4010  qmlStyle = qmlDocument.toString();
4011 
4012  this->exportSldStyle( sldDocument, msgError );
4013  if ( !msgError.isNull() )
4014  {
4015  return;
4016  }
4017  sldStyle = sldDocument.toString();
4018 
4019  saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
4020  description, uiFileContent, useAsDefault, msgError );
4021 }
4022 
4023 
4024 
4025 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag )
4026 {
4027  return loadNamedStyle( theURI, theResultFlag, false );
4028 }
4029 
4030 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag, bool loadFromLocalDB )
4031 {
4032  QgsDataSourceURI dsUri( theURI );
4033  if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
4034  {
4036  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
4037  if ( myLib )
4038  {
4039  loadStyle_t* loadStyleExternalMethod = reinterpret_cast< loadStyle_t * >( cast_to_fptr( myLib->resolve( "loadStyle" ) ) );
4040  if ( loadStyleExternalMethod )
4041  {
4042  QString qml, errorMsg;
4043  qml = loadStyleExternalMethod( mDataSource, errorMsg );
4044  if ( !qml.isEmpty() )
4045  {
4047  theResultFlag = applyNamedStyle( qml, errorMsg );
4049  return QObject::tr( "Loaded from Provider" );
4050  }
4051  }
4052  }
4053  }
4054 
4055  return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
4056 }
4057 
4058 bool QgsVectorLayer::applyNamedStyle( const QString& namedStyle, QString& errorMsg )
4059 {
4060  QDomDocument myDocument( "qgis" );
4061  myDocument.setContent( namedStyle );
4062 
4063  return importNamedStyle( myDocument, errorMsg );
4064 }
4065 
4066 
4068 {
4069  QDomElement elem = doc.createElement( "attributeEditorRelation" );
4070  elem.setAttribute( "name", mName );
4071  elem.setAttribute( "relation", mRelation.id() );
4072  return elem;
4073 }
4074 
4076 {
4077  mRelation = relationManager->relation( mRelationId );
4078  return mRelation.isValid();
4079 }
4080 
4082 {
4083  if ( mDataProvider )
4084  {
4085  return mDataProvider->layerDependencies();
4086  }
4087  return QSet<QString>();
4088 }
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 labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
bool draw(QgsRenderContext &rendererContext) override
Draws the layer.
virtual QString subsetString()
Get the string (typically sql) used to define a subset of the layer.
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves mVectorJoins to xml under the layer node.
virtual Q_DECL_DEPRECATED bool applyNamedStyle(const QString &namedStyle, QString &errorMsg)
Will load a named style from a provided QML string.
Class for parsing and evaluation of expressions (formerly called "search strings").
void updateFields()
Assembles mUpdatedFields considering provider fields, joined fields and added fields.
Q_DECL_DEPRECATED int removePolygonIntersections(QgsGeometry *geom, const QgsFeatureIds &ignoreFeatures=QgsFeatureIds())
Changes the specified geometry such that it has no intersections with other polygon (or multipolygon)...
void clear()
QString encoding() const
Get encoding which is used for accessing data.
Wrapper for iterator of features from vector data provider or vector layer.
void featuresDeleted(const QgsFeatureIds &fids)
Emitted when features have been deleted.
void selectAll()
Select all the features.
QDomNodeList elementsByTagName(const QString &tagname) const
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
bool isValid() const
Returns the validity of this relation.
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
double rendererScale() const
bool writeXml(QDomNode &node, QDomDocument &doc) const
Write field ui properties specific state from Dom node.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
QString comment() const
Returns the field comment.
Definition: qgsfield.cpp:109
bool init(QgsRelationManager *relManager)
Initializes the relation from the id.
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
iterator insert(const Key &key, const T &value)
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
bool containsJoins() const
Quick way to test if there is any join at all.
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
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
QgsFeatureList selectedFeatures()
Get a copy of the user-selected features.
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.
int size() const
Return number of items.
Definition: qgsfield.cpp:370
This is an abstract base class for any elements of a drag and drop form.
FieldOrigin fieldOrigin(int fieldIdx) const
Get field&#39;s origin (value from an enumeration)
Definition: qgsfield.cpp:411
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
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
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 the maximum value for an attribute column or an invalid variant in case of error...
QgsMapLayerLegend * legend() const
Can be null.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
Renders the diagrams for all features with the same settings.
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
QString labelField(int attr) const
label field
Definition: qgslabel.cpp:499
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.
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
void clear()
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Calculates a list of unique values contained within an attribute in the layer.
int size() const
QString toString(int indent) 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...
void invertSelectionInRectangle(QgsRectangle &rect)
Invert selection of features found within the search rectangle (in layer&#39;s coordinates) ...
QLibrary * providerLibrary(const QString &providerKey) const
bool commitChanges()
Attempts to commit any changes to disk.
void setRendererV2(QgsFeatureRendererV2 *r)
Set renderer which will be invoked to represent this layer.
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
void setRendererScale(double scale)
const T & at(int i) const
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
const QgsCoordinateReferenceSystem & crs() const
Returns layer&#39;s spatial reference system.
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 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.
QString toProj4() const
Returns a Proj4 string representation of this CRS.
bool writeXML(QDomNode &layer_node, QDomDocument &doc) const
Writes the actions out in XML format.
Q_DECL_DEPRECATED QString dateFormat(int idx)
Access date format.
virtual QList< QgsAttributeEditorElement * > findElements(AttributeEditorType type) const
Traverses the element tree to find any element of the specified type.
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.
QString evalErrorString() const
Returns evaluation error.
QDomElement nextSiblingElement(const QString &tagName) const
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...
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
static void mergeScaleDependencies(int mScaleMinDenom, int mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
QSet< T > toSet() const
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:104
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.
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.
QgsRelationManager * relationManager() const
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.
const QList< QgsVectorJoinInfo > vectorJoins() const
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.
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
Definition: qgis.cpp:335
void clear()
void chop(int n)
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
double toDouble(bool *ok) const
void committedAttributesDeleted(const QString &layerId, const QgsAttributeList &deletedAttributes)
Signals emitted after committing changes.
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
virtual QSet< QString > layerDependencies() const
Get the list of layer ids on which this layer depends.
QVariant minimumValue(int index)
Returns the minimum value for an attribute column or an 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.
QgsMapLayer::LayerType type() const
Get the type of the layer.
virtual Q_DECL_DEPRECATED bool willRenderFeature(QgsFeature &feat)
Returns whether the renderer will render a feature or not.
int count() const
Return number of items.
Definition: qgsfield.cpp:365
const QList< ExpressionField > & expressions() const
QString tr(const char *sourceText, const char *disambiguation, int n)
void featureDeleted(QgsFeatureId fid)
Emitted when a feature has been deleted.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:392
long featureCount() const
Returns feature count including changes which have not yet been committed If you need only the count ...
void editCommandEnded()
Signal emitted, when an edit command successfully ended.
AttributeEditorType type() const
The type of this element.
QString mLayerName
Name of the layer - used for display.
Definition: qgsmaplayer.h:686
bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
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...
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
void invertSelection()
Select not selected features and deselect selected ones.
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
Definition: qgis.cpp:267
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.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
int size() const
double y() const
Get the y value of the point.
Definition: qgspoint.h:136
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
Needs to be called when a new render cycle is started.
bool isNull() const
virtual void updateExtents()
Update the extents for the layer.
Returns diagram settings for a feature.
QString what() const
Definition: qgsexception.h:36
void writeCustomProperties(QDomNode &layerNode, QDomDocument &doc) const
Write custom properties to project file.
void removeSelection()
Clear selection.
Manages joined fields for a vector layer.
void reset(T *other)
QgsFields fields() const
Returns the list of fields of this layer.
QgsConditionalLayerStyles * conditionalStyles() const
Return the conditional styles that are set for this layer.
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.
int fieldOriginIndex(int fieldIdx) const
Get field&#39;s origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:419
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
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
virtual QDomElement toDomElement(QDomDocument &doc) const override
Will serialize this containers information into a QDomElement for saving it in an XML file...
Q_DECL_DEPRECATED void setEditorWidgetV2(int attrIdx, const QString &widgetType)
Set the editor widget type for a field.
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
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
float maximumScale() const
Returns the maximum scale denominator at which the layer is visible.
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)
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)
float maximumScale() const
Gets the maximum scale at which the layer should be simplified.
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.
void append(const T &value)
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.
void setIndex(int idx)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
void deselect(const QgsFeatureId featureId)
Deselect feature by its ID.
void layerDeleted()
TODO QGIS3: remove in favor of QObject::destroyed.
#define FALLTHROUGH
Definition: qgis.h:439
void writeXml(QDomNode &node) const
Write XML information Serialize on project save.
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
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:27
bool writeSld(QDomNode &node, QDomDocument &doc, QString &errorMessage) const
Writes the symbology of the layer into the document provided in SLD 1.1 format.
QgsDataProvider * provider(const QString &providerKey, const QString &dataSource)
Create an instance of the provider.
bool hasAttribute(const QString &name) const
bool isEmpty() const
test if rectangle is empty.
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:94
const QgsRectangle & extent() const
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.
Represents the result of a snapping operation.
Definition: qgssnapper.h:36
QString database() const
Returns the database.
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)
void beforeModifiedCheck() const
Is emitted, when layer is checked for modifications.
QStringList capturedTexts() const
void drawEllipse(const QRectF &rectangle)
QString dataComment() const
Returns a comment for the data in the layer.
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 bool isReadOnly() const
Returns true if the provider is in read-only mode.
int snapWithContext(const QgsPoint &startPoint, double snappingTolerance, QMultiMap< double, QgsSnappingResult > &snappingResults, QgsSnapper::SnappingType snap_to)
Snaps to segment or vertex within given tolerance.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:207
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
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Get the data source specification.
const_iterator constEnd() const
bool deleteAttribute(int attr)
Delete an attribute field (but does not commit it)
void editingStopped()
Is emitted, when edited changes successfully have been written to the data provider.
void beforeEditingStarted()
Is emitted, before editing on this layer is started.
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
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)...
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)
virtual QSet< QString > layerDependencies() const
Get the list of layer ids on which this layer depends.
const QString displayField() const
Returns the primary display field name used in the identify results dialog.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves expressions to xml under the layer node.
QList< int > QgsAttributeList
float threshold() const
Gets the simplification threshold of the vector layer managed.
bool removeJoin(const QString &joinLayerId)
Removes a vector layer join.
void destroyEditCommand()
Destroy active command and reverts all changes in it.
bool isEmpty() const
Returns true if the geometry is empty (ie, contains no underlying geometry accessible via geometry)...
void setBrush(const QBrush &brush)
void setDisplayField(const QString &fldName="")
Set the primary display field to be used in the identify results dialog.
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example...
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_iterator constEnd() const
int layerTransparency() const
Returns the current transparency for the vector layer.
bool setReadOnly(bool readonly=true)
Make layer read-only (editing disabled) or not.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
Change feature&#39;s geometry.
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
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
const QgsVectorJoinList & vectorJoins() const
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
const QgsAbstractVectorLayerLabeling * labeling() const
Access to labeling configuration.
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.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
Fast access to features using their ID.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
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 scaleBasedVisibility() const
Definition: qgslabel.cpp:1393
const T & value() const
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.
void raiseError(const QString &msg)
Signals an error related to this vector layer.
void editingStarted()
Is emitted, when editing on this layer has started.
QgsAttributeList pkAttributeList() const
Returns list of attributes making up the primary key.
QString capabilitiesString() const
Capabilities for this layer in a friendly format.
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.
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.
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features.
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()
QDomText createTextNode(const QString &value)
int green() const
void invalidateSymbolCountedFlag()
iterator end()
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
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
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
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
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
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:202
virtual void reload() override
Synchronises with changes in the datasource.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
bool contains(const T &value) const
bool countSymbolFeatures(bool showProgress=true)
Count features for symbols.
A class to render labels.
Definition: qgslabel.h:51
static QgsMapLayerLegend * defaultVectorLegend(QgsVectorLayer *vl)
Create new legend implementation for vector layer.
A registry / canonical manager of data providers.
void setProviderEncoding(const QString &encoding)
Sets the textencoding of the data provider.
QgsExpressionContext & expressionContext()
Gets the expression context.
virtual QString loadNamedStyle(const QString &theURI, bool &theResultFlag, bool loadFromLocalDb)
Load a named style from file/local db/datasource db.
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:76
Implementation of threaded rendering for vector layers.
void writeStyleManager(QDomNode &layerNode, QDomDocument &doc) const
Write style manager&#39;s configuration (if exists).
const_iterator constBegin() const
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:187
bool contains(const T &value) const
bool isNull() const
QgsFeatureIterator selectedFeaturesIterator(QgsFeatureRequest request=QgsFeatureRequest())
Get an iterator of the selected features.
QString capabilitiesString() const
Returns the above in friendly format.
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
const QgsFeatureMap & addedFeatures()
New features which are not commited.
bool useRenderingOptimization() const
Returns true if the rendering optimization (geometry simplification) can be executed.
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 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.
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 & replace(int position, int n, QChar after)
void renderLabel(QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=nullptr)
render label
Definition: qgslabel.cpp:72
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.
int blue() const
const T & at(int i) const
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.
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.
int indexFromName(const QString &name) const
Look up field&#39;s index from name. Returns -1 on error.
Definition: qgsfield.cpp:424
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
void setMaxScale(float theMaxScale)
Accessor and mutator for the maximum scale member.
Definition: qgslabel.cpp:1408
QString name() const
Get the display name of the layer.
Buffers information about expression fields for a vector layer.
QString getStyleById_t(const QString &uri, QString styleID, QString &errCause)
QgsEditorWidgetConfig widgetConfig(int fieldIdx) const
Get the configuration for the editor widget used to represent the field at the given index...
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.
QgsVectorLayer(const QString &path=QString::null, const QString &baseName=QString::null, const QString &providerLib=QString::null, bool loadDefaultStyleFlag=true)
Constructor - creates a vector layer.
bool simplifyDrawingCanbeApplied(const QgsRenderContext &renderContext, QgsVectorSimplifyMethod::SimplifyHint simplifyHint) const
Returns whether the VectorLayer can apply the specified simplification hint.
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())
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
QgsVectorLayer::EditResult deleteVertexV2(QgsFeatureId featureId, int vertex)
Deletes a vertex from a feature.
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.
bool isEmpty() const
This class manages a set of relations between layers.
static QgsFeatureRendererV2 * load(QDomElement &symbologyElem)
create a renderer from XML element
virtual Q_DECL_DEPRECATED QDomElement writeSld(QDomDocument &doc, const QgsVectorLayer &layer) const
create the SLD UserStyle element following the SLD v1.1 specs
virtual void reloadData()
Reloads the data from the source.
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 forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported...
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
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
void removeExpression(int index)
Remove an expression from the buffer.
virtual QString dataComment() const
Return a short comment for the data that this provider is providing access to (e.g.
Class for storing a coordinate reference system (CRS)
float maxScale() const
Definition: qgslabel.cpp:1413
friend class QgsVectorLayerEditBuffer
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
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.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
virtual QString description() const =0
Return description.
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:99
QList< T > values() const
QList< T > mid(int pos, int length) const
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...
void writeCustomSymbology(QDomElement &element, QDomDocument &doc, QString &errorMessage) const
Signal emitted whenever the symbology (QML-file) for this layer is being written. ...
virtual bool setSubsetString(const QString &subset)
Set the string (typically sql) used to define a subset of the layer.
char * data()
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:192
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
Read the symbology of the layer according to the information contained in the UserStyle element of a ...
Basic implementation of the labeling interface.
void undo()
QString readPath(QString filename) const
Turn filename read from the project file to an absolute path.
qint64 QgsFeatureId
Definition: qgsfeature.h:31
QgsFields pendingFields() const
Returns the list of fields of this layer.
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)
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.
bool isValid() const
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:197
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)
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
void addRequiredFields(QgsAttributeList &fields) const
add vector of required fields to existing list of fields
Definition: qgslabel.cpp:459
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.
Edit failed due to invalid layer.
void setMinScale(float theMinScale)
Accessor and mutator for the minimum scale member.
Definition: qgslabel.cpp:1398
float minimumScale() const
Returns the minimum scale denominator at which the layer is visible.
Custom exception class for Coordinate Reference System related exceptions.
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QUndoStack * undoStack()
Return pointer to layer&#39;s undo stack.
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
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.
double ANALYSIS_EXPORT min(double x, double y)
Returns the minimum of two doubles or the first argument if both are equal.
float minScale() const
Definition: qgslabel.cpp:1403
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.
QString providerType() const
Return the provider type for this layer.
const_iterator constEnd() const
void normalize()
Normalize the rectangle so it has non-negative width/height.
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.
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.
Q_DECL_DEPRECATED bool hasLabelsEnabled() const
Label is on.
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
QString widgetType(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
bool intersects(const QgsRectangle &rect) const
returns true when rectangle intersects with other rectangle
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.
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
int addRing(const QList< QgsPoint > &ring, QgsFeatureId *featureId=nullptr)
Adds a ring to polygon/multipolygon features.
void committedGeometriesChanges(const QString &layerId, const QgsGeometryMap &changedGeometries)
A vector of attributes.
Definition: qgsfeature.h:115
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QgsFeatureIds allFeatureIds()
Get all feature Ids.
static QgsFeatureRendererV2 * readOldRenderer(const QDomNode &layerNode, QGis::GeometryType geomType)
Read old renderer definition from XML and create matching new renderer.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
void updateFields(QgsFields &fields)
virtual QgsRectangle extent()
Return the extent of the layer.
bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:271
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.
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 ...
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
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.
Q_DECL_DEPRECATED void drawLabels(QgsRenderContext &rendererContext) override
Draws the layer labels using the old labeling engine.
QString attributeDisplayName(int attributeIndex) const
Convenience function that returns the attribute alias if defined or the field name else...
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 writeXML(QDomElement &layerElem, QDomDocument &doc, const QgsVectorLayer *layer) const
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 fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
double x() const
Get the x value of the point.
Definition: qgspoint.h:128
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
void writeXML(QDomNode &label_node, QDomDocument &document) const
Writes the contents of the renderer to a configuration file.
Definition: qgslabel.cpp:1038
bool hasNext() const
virtual bool leaveUpdateMode()
Leave update mode.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
bool diagramsEnabled() const
Returns whether the layer contains diagrams which are enabled and should be drawn.
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:212
bool isValid() const
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
QDomNode at(int index) const
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)
int listStyles_t(const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause)
QByteArray toUtf8() const