QGIS API Documentation  2.4.0-Chugiak
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
38 #include "qgsattributeaction.h"
39 
40 #include "qgis.h" //for globals
41 #include "qgsapplication.h"
42 #include "qgsclipper.h"
44 #include "qgscoordinatetransform.h"
45 #include "qgsdatasourceuri.h"
46 #include "qgsfeature.h"
47 #include "qgsfeaturerequest.h"
48 #include "qgsfield.h"
49 #include "qgsgeometrycache.h"
50 #include "qgsgeometry.h"
51 #include "qgslabel.h"
52 #include "qgslegacyhelpers.h"
53 #include "qgslogger.h"
54 #include "qgsmaplayerregistry.h"
55 #include "qgsmaptopixel.h"
56 #include "qgsmessagelog.h"
57 #include "qgsogcutils.h"
58 #include "qgspoint.h"
59 #include "qgsproject.h"
60 #include "qgsproviderregistry.h"
61 #include "qgsrectangle.h"
62 #include "qgsrelationmanager.h"
63 #include "qgsrendercontext.h"
64 #include "qgsvectordataprovider.h"
69 #include "qgsvectorlayerrenderer.h"
71 
72 #include "qgsrendererv2.h"
73 #include "qgssymbolv2.h"
74 #include "qgssymbollayerv2.h"
76 #include "qgsdiagramrendererv2.h"
77 #include "qgsstylev2.h"
79 #include "qgspallabeling.h"
80 #include "qgssimplifymethod.h"
81 
82 #include "diagram/qgsdiagram.h"
83 
84 #ifdef TESTPROVIDERLIB
85 #include <dlfcn.h>
86 #endif
87 
88 typedef bool saveStyle_t(
89  const QString& uri,
90  const QString& qmlStyle,
91  const QString& sldStyle,
92  const QString& styleName,
93  const QString& styleDescription,
94  const QString& uiFileContent,
95  bool useAsDefault,
96  QString& errCause
97 );
98 
99 typedef QString loadStyle_t(
100  const QString& uri,
101  QString& errCause
102 );
103 
104 typedef int listStyles_t(
105  const QString& uri,
106  QStringList &ids,
107  QStringList &names,
108  QStringList &descriptions,
109  QString& errCause
110 );
111 
112 typedef QString getStyleById_t(
113  const QString& uri,
114  QString styleID,
115  QString& errCause
116 );
117 
118 QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
119  QString baseName,
120  QString providerKey,
121  bool loadDefaultStyleFlag )
122  : QgsMapLayer( VectorLayer, baseName, vectorLayerPath )
123  , mDataProvider( NULL )
124  , mProviderKey( providerKey )
125  , mReadOnly( false )
126  , mRendererV2( NULL )
127  , mLabel( 0 )
128  , mLabelOn( false )
129  , mLabelFontNotFoundNotified( false )
130  , mFeatureBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal feature blending
131  , mLayerTransparency( 0 )
132  , mVertexMarkerOnlyForSelection( false )
133  , mEditorLayout( GeneratedLayout )
134  , mFeatureFormSuppress( SuppressDefault )
135  , mCache( new QgsGeometryCache() )
136  , mEditBuffer( 0 )
137  , mJoinBuffer( 0 )
138  , mDiagramRenderer( 0 )
139  , mDiagramLayerSettings( 0 )
140  , mValidExtent( false )
141  , mLazyExtent( true )
142  , mSymbolFeatureCounted( false )
143 
144 {
145  mActions = new QgsAttributeAction( this );
146 
147  // if we're given a provider type, try to create and bind one to this layer
148  if ( ! mProviderKey.isEmpty() )
149  {
151  }
152  if ( mValid )
153  {
154  // Always set crs
156 
157  // check if there is a default style / propertysheet defined
158  // for this layer and if so apply it
159  bool defaultLoadedFlag = false;
160  if ( loadDefaultStyleFlag )
161  {
162  loadDefaultStyle( defaultLoadedFlag );
163  }
164 
165  // if the default style failed to load or was disabled use some very basic defaults
166  if ( !defaultLoadedFlag && hasGeometryType() )
167  {
168  // add single symbol renderer
170  }
171 
172  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
173  }
174 
175  connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( selectionChanged() ) );
176 
177  connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( repaintRequested() ) );
178 
179  connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
180 
181  // Default simplify drawing settings
182  QSettings settings;
183  mSimplifyMethod.setSimplifyHints(( QgsVectorSimplifyMethod::SimplifyHints ) settings.value( "/qgis/simplifyDrawingHints", ( int ) mSimplifyMethod.simplifyHints() ).toInt() );
184  mSimplifyMethod.setThreshold( settings.value( "/qgis/simplifyDrawingTol", mSimplifyMethod.threshold() ).toFloat() );
185  mSimplifyMethod.setForceLocalOptimization( settings.value( "/qgis/simplifyLocal", mSimplifyMethod.forceLocalOptimization() ).toBool() );
186  mSimplifyMethod.setMaximumScale( settings.value( "/qgis/simplifyMaxScale", mSimplifyMethod.maximumScale() ).toFloat() );
187 
188 } // QgsVectorLayer ctor
189 
190 
191 
193 {
194  QgsDebugMsg( "entered." );
195 
196  emit layerDeleted();
197 
198  mValid = false;
199 
200  delete mDataProvider;
201  delete mEditBuffer;
202  delete mJoinBuffer;
203  delete mCache;
204  delete mLabel;
205  delete mDiagramLayerSettings;
206 
207  delete mActions;
208 
209  delete mRendererV2;
210 }
211 
213 {
214  if ( mDataProvider )
215  {
216  return mDataProvider->storageType();
217  }
218  return 0;
219 }
220 
221 
223 {
224  if ( mDataProvider )
225  {
227  }
228  return 0;
229 }
230 
232 {
233  if ( mDataProvider )
234  {
235  return mDataProvider->dataComment();
236  }
237  return QString();
238 }
239 
240 
242 {
243  return mProviderKey;
244 }
245 
249 void QgsVectorLayer::setDisplayField( QString fldName )
250 {
251  if ( !hasGeometryType() )
252  return;
253 
254  // If fldName is provided, use it as the display field, otherwise
255  // determine the field index for the feature column of the identify
256  // dialog. We look for fields containing "name" first and second for
257  // fields containing "id". If neither are found, the first field
258  // is used as the node.
259  QString idxName = "";
260  QString idxId = "";
261 
262  if ( !fldName.isEmpty() )
263  {
264  mDisplayField = fldName;
265  }
266  else
267  {
268  const QgsFields &fields = pendingFields();
269  int fieldsSize = fields.size();
270 
271  for ( int idx = 0; idx < fields.count(); ++idx )
272  {
273  QString fldName = fields[idx].name();
274  QgsDebugMsg( "Checking field " + fldName + " of " + QString::number( fieldsSize ) + " total" );
275 
276  // Check the fields and keep the first one that matches.
277  // We assume that the user has organized the data with the
278  // more "interesting" field names first. As such, name should
279  // be selected before oldname, othername, etc.
280  if ( fldName.indexOf( "name", 0, Qt::CaseInsensitive ) > -1 )
281  {
282  if ( idxName.isEmpty() )
283  {
284  idxName = fldName;
285  }
286  }
287  if ( fldName.indexOf( "descrip", 0, Qt::CaseInsensitive ) > -1 )
288  {
289  if ( idxName.isEmpty() )
290  {
291  idxName = fldName;
292  }
293  }
294  if ( fldName.indexOf( "id", 0, Qt::CaseInsensitive ) > -1 )
295  {
296  if ( idxId.isEmpty() )
297  {
298  idxId = fldName;
299  }
300  }
301  }
302 
303  //if there were no fields in the dbf just return - otherwise qgis segfaults!
304  if ( fieldsSize == 0 )
305  return;
306 
307  if ( idxName.length() > 0 )
308  {
309  mDisplayField = idxName;
310  }
311  else
312  {
313  if ( idxId.length() > 0 )
314  {
315  mDisplayField = idxId;
316  }
317  else
318  {
319  mDisplayField = fields[0].name();
320  }
321  }
322 
323  }
324 }
325 
326 // NOTE this is a temporary method added by Tim to prevent label clipping
327 // which was occurring when labeller was called in the main draw loop
328 // This method will probably be removed again in the near future!
330 {
331  if ( !hasGeometryType() )
332  return;
333 
334  QgsDebugMsg( "Starting draw of labels: " + id() );
335 
336  if ( mRendererV2 && mLabelOn && mLabel &&
338  ( mLabel->minScale() <= rendererContext.rendererScale() &&
339  rendererContext.rendererScale() <= mLabel->maxScale() ) ) )
340  {
341  QgsAttributeList attributes;
342  foreach ( QString attrName, mRendererV2->usedAttributes() )
343  {
344  int attrNum = fieldNameIndex( attrName );
345  attributes.append( attrNum );
346  }
347  // make sure the renderer is ready for classification ("symbolForFeature")
348  mRendererV2->startRender( rendererContext, pendingFields() );
349 
350  // Add fields required for labels
351  mLabel->addRequiredFields( attributes );
352 
353  QgsDebugMsg( "Selecting features based on view extent" );
354 
355  int featureCount = 0;
356 
357  try
358  {
359  // select the records in the extent. The provider sets a spatial filter
360  // and sets up the selection set for retrieval
362  .setFilterRect( rendererContext.extent() )
363  .setSubsetOfAttributes( attributes ) );
364 
365  QgsFeature fet;
366  while ( fit.nextFeature( fet ) )
367  {
368  if ( mRendererV2->willRenderFeature( fet ) )
369  {
370  bool sel = mSelectedFeatureIds.contains( fet.id() );
371  mLabel->renderLabel( rendererContext, fet, sel, 0 );
372  }
373  featureCount++;
374  }
375  }
376  catch ( QgsCsException &e )
377  {
378  Q_UNUSED( e );
379  QgsDebugMsg( "Error projecting label locations" );
380  }
381 
382  if ( mRendererV2 )
383  {
384  mRendererV2->stopRender( rendererContext );
385  }
386 
387  QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
388  }
389 }
390 
392 {
393  if ( mDataProvider )
394  {
396  }
397 }
398 
400 {
401  return new QgsVectorLayerRenderer( this, rendererContext );
402 }
403 
404 bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
405 {
406  QgsVectorLayerRenderer renderer( this, rendererContext );
407  return renderer.render();
408 }
409 
410 void QgsVectorLayer::drawVertexMarker( double x, double y, QPainter& p, QgsVectorLayer::VertexMarkerType type, int m )
411 {
413  {
414  p.setPen( QColor( 50, 100, 120, 200 ) );
415  p.setBrush( QColor( 200, 200, 210, 120 ) );
416  p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
417  }
418  else if ( type == QgsVectorLayer::Cross )
419  {
420  p.setPen( QColor( 255, 0, 0 ) );
421  p.drawLine( x - m, y + m, x + m, y - m );
422  p.drawLine( x - m, y - m, x + m, y + m );
423  }
424 }
425 
427 {
428  mSelectedFeatureIds.insert( fid );
429 
430  emit selectionChanged( QgsFeatureIds() << fid, QgsFeatureIds(), false );
431 }
432 
433 void QgsVectorLayer::select( const QgsFeatureIds& featureIds )
434 {
435  mSelectedFeatureIds.unite( featureIds );
436 
437  emit selectionChanged( featureIds, QgsFeatureIds(), false );
438 }
439 
441 {
442  mSelectedFeatureIds.remove( fid );
443 
444  emit selectionChanged( QgsFeatureIds(), QgsFeatureIds() << fid, false );
445 }
446 
447 void QgsVectorLayer::deselect( const QgsFeatureIds& featureIds )
448 {
449  mSelectedFeatureIds.subtract( featureIds );
450 
451  emit selectionChanged( QgsFeatureIds(), featureIds, false );
452 }
453 
454 void QgsVectorLayer::select( QgsRectangle & rect, bool addToSelection )
455 {
456  // normalize the rectangle
457  rect.normalize();
458 
459  //select all the elements
461  .setFilterRect( rect )
463  .setSubsetOfAttributes( QgsAttributeList() ) );
464 
465  QgsFeatureIds ids;
466 
467  QgsFeature f;
468  while ( fit.nextFeature( f ) )
469  {
470  ids << f.id();
471  }
472 
473  if ( !addToSelection )
474  {
476  }
477  else
478  {
479  select( ids );
480  }
481 }
482 
484 {
485  QgsFeatureIds intersectingIds = selectIds & deselectIds;
486  if ( intersectingIds.count() > 0 )
487  {
488  QgsDebugMsg( "Trying to select and deselect the same item at the same time. Unsure what to do. Selecting dubious items." );
489  }
490 
491  mSelectedFeatureIds -= deselectIds;
492  mSelectedFeatureIds += selectIds;
493 
494  emit selectionChanged( selectIds, deselectIds - intersectingIds, false );
495 }
496 
498 {
500  ids.subtract( mSelectedFeatureIds );
501  setSelectedFeatures( ids );
502 }
503 
505 {
507 }
508 
510 {
512  .setFlags( QgsFeatureRequest::NoGeometry )
513  .setSubsetOfAttributes( QgsAttributeList() ) );
514 
515  QgsFeatureIds ids;
516 
517  QgsFeature fet;
518  while ( fit.nextFeature( fet ) )
519  {
520  ids << fet.id();
521  }
522 
523  return ids;
524 }
525 
527 {
528  // normalize the rectangle
529  rect.normalize();
530 
532  .setFilterRect( rect )
534  .setSubsetOfAttributes( QgsAttributeList() ) );
535 
536  QgsFeatureIds selectIds;
537  QgsFeatureIds deselectIds;
538 
539  QgsFeature fet;
540  while ( fit.nextFeature( fet ) )
541  {
542  if ( mSelectedFeatureIds.contains( fet.id() ) )
543  {
544  deselectIds << fet.id();
545  }
546  else
547  {
548  selectIds << fet.id();
549  }
550  }
551 
552  modifySelection( selectIds, deselectIds );
553 }
554 
556 {
557  if ( mSelectedFeatureIds.size() == 0 )
558  return;
559 
561 }
562 
564 {
565  emit repaintRequested();
566 }
567 
569 {
570  return mDataProvider;
571 }
572 
574 {
575  return mDataProvider;
576 }
577 
578 void QgsVectorLayer::setProviderEncoding( const QString& encoding )
579 {
580  if ( mDataProvider && mDataProvider->encoding() != encoding )
581  {
582  mDataProvider->setEncoding( encoding );
583  updateFields();
584  }
585 }
586 
588 {
589  delete mDiagramRenderer;
590  mDiagramRenderer = r;
591 }
592 
594 {
595  if ( mDataProvider )
596  {
598  switch ( type )
599  {
600  case QGis::WKBPoint:
601  case QGis::WKBPoint25D:
602  return QGis::Point;
603 
604  case QGis::WKBLineString:
606  return QGis::Line;
607 
608  case QGis::WKBPolygon:
609  case QGis::WKBPolygon25D:
610  return QGis::Polygon;
611 
612  case QGis::WKBMultiPoint:
614  return QGis::Point;
615 
618  return QGis::Line;
619 
622  return QGis::Polygon;
623 
624  case QGis::WKBNoGeometry:
625  return QGis::NoGeometry;
626  }
627  QgsDebugMsg( QString( "Data Provider Geometry type is not recognised, is %1" ).arg( type ) );
628  }
629  else
630  {
631  QgsDebugMsg( "pointer to mDataProvider is null" );
632  }
633 
634  // We shouldn't get here, and if we have, other things are likely to
635  // go wrong. Code that uses the type() return value should be
636  // rewritten to cope with a value of QGis::Unknown. To make this
637  // need known, the following message is printed every time we get
638  // here.
639  QgsDebugMsg( "WARNING: This code should never be reached. Problems may occur..." );
640 
641  return QGis::UnknownGeometry;
642 }
643 
645 {
647  return ( t != QGis::NoGeometry && t != QGis::UnknownGeometry );
648 }
649 
651 {
652  return ( QGis::WkbType )( mWkbType );
653 }
654 
656 {
657  if ( mSelectedFeatureIds.size() == 0 ) //no selected features
658  {
659  return QgsRectangle( 0, 0, 0, 0 );
660  }
661 
662  QgsRectangle r, retval;
663  retval.setMinimal();
664 
665  QgsFeature fet;
667  {
668  foreach ( QgsFeatureId fid, mSelectedFeatureIds )
669  {
671  .setFilterFid( fid )
672  .setSubsetOfAttributes( QgsAttributeList() ) )
673  .nextFeature( fet ) &&
674  fet.geometry() )
675  {
676  r = fet.geometry()->boundingBox();
677  retval.combineExtentWith( &r );
678  }
679  }
680  }
681  else
682  {
684  .setSubsetOfAttributes( QgsAttributeList() ) );
685 
686  while ( fit.nextFeature( fet ) )
687  {
688  if ( mSelectedFeatureIds.contains( fet.id() ) )
689  {
690  if ( fet.geometry() )
691  {
692  r = fet.geometry()->boundingBox();
693  retval.combineExtentWith( &r );
694  }
695  }
696  }
697  }
698 
699  if ( retval.width() == 0.0 || retval.height() == 0.0 )
700  {
701  // If all of the features are at the one point, buffer the
702  // rectangle a bit. If they are all at zero, do something a bit
703  // more crude.
704 
705  if ( retval.xMinimum() == 0.0 && retval.xMaximum() == 0.0 &&
706  retval.yMinimum() == 0.0 && retval.yMaximum() == 0.0 )
707  {
708  retval.set( -1.0, -1.0, 1.0, 1.0 );
709  }
710  }
711 
712  return retval;
713 }
714 
716 {
717  if ( !mDataProvider )
718  {
719  QgsDebugMsg( "invoked with null mDataProvider" );
720  return 0;
721  }
722 
723  return mDataProvider->featureCount();
724 }
725 
727 {
728  if ( !mSymbolFeatureCounted ) return -1;
729  return mSymbolFeatureCountMap.value( symbol );
730 }
731 
732 bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
733 {
734  if ( mSymbolFeatureCounted ) return true;
735  mSymbolFeatureCountMap.clear();
736 
737  if ( !mDataProvider )
738  {
739  QgsDebugMsg( "invoked with null mDataProvider" );
740  return false;
741  }
742  if ( !mRendererV2 )
743  {
744  QgsDebugMsg( "invoked with null mRendererV2" );
745  return false;
746  }
747 
749  QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
750 
751  for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
752  {
753  mSymbolFeatureCountMap.insert( symbolIt->second, 0 );
754  }
755 
756  long nFeatures = pendingFeatureCount();
757  QProgressDialog progressDialog( tr( "Updating feature count for layer %1" ).arg( name() ), tr( "Abort" ), 0, nFeatures );
758  progressDialog.setWindowModality( Qt::WindowModal );
759  int featuresCounted = 0;
760 
762 
763  // Renderer (rule based) may depend on context scale, with scale is ignored if 0
764  QgsRenderContext renderContext;
765  renderContext.setRendererScale( 0 );
766  mRendererV2->startRender( renderContext, pendingFields() );
767 
768  QgsFeature f;
769  while ( fit.nextFeature( f ) )
770  {
771  QgsSymbolV2List featureSymbolList = mRendererV2->symbolsForFeature( f );
772  for ( QgsSymbolV2List::iterator symbolIt = featureSymbolList.begin(); symbolIt != featureSymbolList.end(); ++symbolIt )
773  {
774  mSymbolFeatureCountMap[*symbolIt] += 1;
775  }
776  ++featuresCounted;
777 
778  if ( showProgress )
779  {
780  if ( featuresCounted % 50 == 0 )
781  {
782  if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
783  {
784  progressDialog.setMaximum( 0 );
785  }
786  progressDialog.setValue( featuresCounted );
787  if ( progressDialog.wasCanceled() )
788  {
789  mSymbolFeatureCountMap.clear();
790  mRendererV2->stopRender( renderContext );
791  return false;
792  }
793  }
794  }
795  }
796  mRendererV2->stopRender( renderContext );
797  progressDialog.setValue( nFeatures );
798  mSymbolFeatureCounted = true;
799  return true;
800 }
801 
803 {
804  mValidExtent = false;
805 }
806 
808 {
810  mValidExtent = true;
811 }
812 
814 {
815  QgsRectangle rect;
816  rect.setMinimal();
817 
818  if ( !hasGeometryType() )
819  return rect;
820 
822  {
823  // get the extent
825 
826  // show the extent
827  QString s = mbr.toString();
828 
829  QgsDebugMsg( "Extent of layer: " + s );
830  // store the extent
831  setExtent( mbr );
832 
833  mLazyExtent = false;
834  }
835 
836  if ( mValidExtent )
837  return QgsMapLayer::extent();
838 
839  if ( !mDataProvider )
840  {
841  QgsDebugMsg( "invoked with null mDataProvider" );
842  }
843 
844  if ( mEditBuffer && mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mChangedGeometries.isEmpty() )
845  {
847 
848  // get the extent of the layer from the provider
849  // but only when there are some features already
850  if ( mDataProvider->featureCount() != 0 )
851  {
853  rect.combineExtentWith( &r );
854  }
855 
856  for ( QgsFeatureMap::iterator it = mEditBuffer->mAddedFeatures.begin(); it != mEditBuffer->mAddedFeatures.end(); ++it )
857  {
858  if ( it->geometry() )
859  {
860  QgsRectangle r = it->geometry()->boundingBox();
861  rect.combineExtentWith( &r );
862  }
863  }
864  }
865  else
866  {
868  .setSubsetOfAttributes( QgsAttributeList() ) );
869 
870  QgsFeature fet;
871  while ( fit.nextFeature( fet ) )
872  {
873  if ( fet.geometry() && fet.geometry()->type() != QGis::UnknownGeometry )
874  {
875  QgsRectangle bb = fet.geometry()->boundingBox();
876  rect.combineExtentWith( &bb );
877  }
878  }
879  }
880 
881  if ( rect.xMinimum() > rect.xMaximum() && rect.yMinimum() > rect.yMaximum() )
882  {
883  // special case when there are no features in provider nor any added
884  rect = QgsRectangle(); // use rectangle with zero coordinates
885  }
886 
887  setExtent( rect );
888 
889  // Send this (hopefully) up the chain to the map canvas
890  emit recalculateExtents();
891 
892  return rect;
893 }
894 
896 {
897  if ( ! mDataProvider )
898  {
899  QgsDebugMsg( "invoked with null mDataProvider" );
900  return 0;
901  }
902  return mDataProvider->subsetString();
903 }
904 
905 bool QgsVectorLayer::setSubsetString( QString subset )
906 {
907  if ( ! mDataProvider )
908  {
909  QgsDebugMsg( "invoked with null mDataProvider" );
910  return false;
911  }
912 
913  bool res = mDataProvider->setSubsetString( subset );
914 
915  // get the updated data source string from the provider
917  updateExtents();
918 
919  if ( res )
920  emit repaintRequested();
921 
922  return res;
923 }
924 
926 {
927  if ( mDataProvider && !mEditBuffer && ( hasGeometryType() && geometryType() != QGis::Point ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && renderContext.useRenderingOptimization() )
928  {
929  double maximumSimplificationScale = mSimplifyMethod.maximumScale();
930 
931  // check maximum scale at which generalisation should be carried out
932  if ( maximumSimplificationScale > 1 && renderContext.rendererScale() <= maximumSimplificationScale )
933  return false;
934 
935  return true;
936  }
937  return false;
938 }
939 
941 {
942  if ( !mDataProvider )
943  return QgsFeatureIterator();
944 
945  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( new QgsVectorLayerFeatureSource( this ), true, request ) );
946 }
947 
948 
949 bool QgsVectorLayer::addFeature( QgsFeature& f, bool alsoUpdateExtent )
950 {
951  Q_UNUSED( alsoUpdateExtent ); // TODO[MD]
952  if ( !mEditBuffer || !mDataProvider )
953  return false;
954 
955  bool success = mEditBuffer->addFeature( f );
956 
957  if ( success )
958  updateExtents();
959 
960  return success;
961 }
962 
964 {
965  QgsFeatureRequest req;
966  req.setFilterFid( f.id() );
967  if ( !f.geometry() )
969  if ( f.attributes().isEmpty() )
971 
972  QgsFeature current;
973  if ( !getFeatures( req ).nextFeature( current ) )
974  {
975  QgsDebugMsg( QString( "feature %1 could not be retrieved" ).arg( f.id() ) );
976  return false;
977  }
978 
979  if ( f.geometry() && current.geometry() && f.geometry() != current.geometry() && !f.geometry()->isGeosEqual( *current.geometry() ) )
980  {
981  if ( !changeGeometry( f.id(), f.geometry() ) )
982  {
983  QgsDebugMsg( QString( "geometry of feature %1 could not be changed." ).arg( f.id() ) );
984  return false;
985  }
986  }
987 
988  const QgsAttributes &fa = f.attributes();
989  const QgsAttributes &ca = current.attributes();
990 
991  for ( int attr = 0; attr < fa.count(); ++attr )
992  {
993  if ( fa[attr] != ca[attr] )
994  {
995  if ( !changeAttributeValue( f.id(), attr, fa[attr], ca[attr] ) )
996  {
997  QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( f.id() ) );
998  return false;
999  }
1000  }
1001  }
1002 
1003  return true;
1004 }
1005 
1006 
1007 bool QgsVectorLayer::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
1008 {
1009  if ( !mEditBuffer || !mDataProvider )
1010  return false;
1011 
1012  QgsVectorLayerEditUtils utils( this );
1013  return utils.insertVertex( x, y, atFeatureId, beforeVertex );
1014 }
1015 
1016 
1017 bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
1018 {
1019  if ( !mEditBuffer || !mDataProvider )
1020  return false;
1021 
1022  QgsVectorLayerEditUtils utils( this );
1023  return utils.moveVertex( x, y, atFeatureId, atVertex );
1024 }
1025 
1026 
1027 bool QgsVectorLayer::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
1028 {
1029  if ( !mEditBuffer || !mDataProvider )
1030  return false;
1031 
1032  QgsVectorLayerEditUtils utils( this );
1033  return utils.deleteVertex( atFeatureId, atVertex );
1034 }
1035 
1036 
1038 {
1040  {
1041  return false;
1042  }
1043 
1044  if ( !isEditable() )
1045  {
1046  return false;
1047  }
1048 
1049  if ( mSelectedFeatureIds.size() == 0 )
1050  return true;
1051 
1052  while ( mSelectedFeatureIds.size() > 0 )
1053  {
1054  QgsFeatureId fid = *mSelectedFeatureIds.begin();
1055  deleteFeature( fid ); // removes from selection
1056  }
1057 
1058  triggerRepaint();
1059  updateExtents();
1060 
1061  return true;
1062 }
1063 
1064 int QgsVectorLayer::addRing( const QList<QgsPoint>& ring )
1065 {
1066  if ( !mEditBuffer || !mDataProvider )
1067  return 6;
1068 
1069  QgsVectorLayerEditUtils utils( this );
1070  return utils.addRing( ring );
1071 }
1072 
1073 int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
1074 {
1075  if ( !mEditBuffer || !mDataProvider )
1076  return 7;
1077 
1078  //number of selected features must be 1
1079 
1080  if ( mSelectedFeatureIds.size() < 1 )
1081  {
1082  QgsDebugMsg( "Number of selected features <1" );
1083  return 4;
1084  }
1085  else if ( mSelectedFeatureIds.size() > 1 )
1086  {
1087  QgsDebugMsg( "Number of selected features >1" );
1088  return 5;
1089  }
1090 
1091  QgsVectorLayerEditUtils utils( this );
1092  return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
1093 }
1094 
1095 
1096 int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy )
1097 {
1098  if ( !mEditBuffer || !mDataProvider )
1099  return -1;
1100 
1101  QgsVectorLayerEditUtils utils( this );
1102  return utils.translateFeature( featureId, dx, dy );
1103 }
1104 
1105 int QgsVectorLayer::splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1106 {
1107  if ( !mEditBuffer || !mDataProvider )
1108  return -1;
1109 
1110  QgsVectorLayerEditUtils utils( this );
1111  return utils.splitParts( splitLine, topologicalEditing );
1112 }
1113 
1114 int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1115 {
1116  if ( !mEditBuffer || !mDataProvider )
1117  return -1;
1118 
1119  QgsVectorLayerEditUtils utils( this );
1120  return utils.splitFeatures( splitLine, topologicalEditing );
1121 }
1122 
1124 {
1125  if ( !hasGeometryType() )
1126  return 1;
1127 
1128  int returnValue = 0;
1129 
1130  //first test if geom really has type polygon or multipolygon
1131  if ( geom->type() != QGis::Polygon )
1132  {
1133  return 1;
1134  }
1135 
1136  //get bounding box of geom
1137  QgsRectangle geomBBox = geom->boundingBox();
1138 
1139  //get list of features that intersect this bounding box
1141  .setFilterRect( geomBBox )
1143  .setSubsetOfAttributes( QgsAttributeList() ) );
1144 
1145  QgsFeature f;
1146  while ( fit.nextFeature( f ) )
1147  {
1148  if ( ignoreFeatures.contains( f.id() ) )
1149  {
1150  continue;
1151  }
1152 
1153  //call geometry->makeDifference for each feature
1154  QgsGeometry *currentGeom = f.geometry();
1155  if ( currentGeom )
1156  {
1157  if ( geom->makeDifference( currentGeom ) != 0 )
1158  {
1159  returnValue = 2;
1160  }
1161  }
1162  }
1163 
1164  return returnValue;
1165 }
1166 
1168 {
1169  if ( !mEditBuffer || !mDataProvider )
1170  return -1;
1171 
1172  QgsVectorLayerEditUtils utils( this );
1173  return utils.addTopologicalPoints( geom );
1174 }
1175 
1177 {
1178  if ( !mEditBuffer || !mDataProvider )
1179  return -1;
1180 
1181  QgsVectorLayerEditUtils utils( this );
1182  return utils.addTopologicalPoints( p );
1183 }
1184 
1186 {
1187  return mLabel;
1188 }
1189 
1191 {
1192  return mLabel;
1193 }
1194 
1196 {
1197  mLabelOn = on;
1198 }
1199 
1201 {
1202  return mLabelOn;
1203 }
1204 
1206 {
1207  if ( !mDataProvider )
1208  {
1209  return false;
1210  }
1211 
1212  // allow editing if provider supports any of the capabilities
1214  {
1215  return false;
1216  }
1217 
1218  if ( mReadOnly )
1219  {
1220  return false;
1221  }
1222 
1223  if ( mEditBuffer )
1224  {
1225  // editing already underway
1226  return false;
1227  }
1228 
1229  mEditBuffer = new QgsVectorLayerEditBuffer( this );
1230  // forward signals
1231  connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( invalidateSymbolCountedFlag() ) );
1232  connect( mEditBuffer, SIGNAL( layerModified() ), this, SIGNAL( layerModified() ) ); // TODO[MD]: necessary?
1233  //connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( triggerRepaint() ) ); // TODO[MD]: works well?
1234  connect( mEditBuffer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SIGNAL( featureAdded( QgsFeatureId ) ) );
1235  connect( mEditBuffer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SIGNAL( featureDeleted( QgsFeatureId ) ) );
1236  connect( mEditBuffer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
1237  connect( mEditBuffer, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ), this, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ) );
1238  connect( mEditBuffer, SIGNAL( attributeAdded( int ) ), this, SIGNAL( attributeAdded( int ) ) );
1239  connect( mEditBuffer, SIGNAL( attributeDeleted( int ) ), this, SIGNAL( attributeDeleted( int ) ) );
1240  connect( mEditBuffer, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ), this, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ) );
1241  connect( mEditBuffer, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ), this, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ) );
1242 
1243  updateFields();
1244 
1245  emit editingStarted();
1246 
1247  return true;
1248 }
1249 
1250 bool QgsVectorLayer::readXml( const QDomNode& layer_node )
1251 {
1252  QgsDebugMsg( QString( "Datasource in QgsVectorLayer::readXml: " ) + mDataSource.toLocal8Bit().data() );
1253 
1254  //process provider key
1255  QDomNode pkeyNode = layer_node.namedItem( "provider" );
1256 
1257  if ( pkeyNode.isNull() )
1258  {
1259  mProviderKey = "";
1260  }
1261  else
1262  {
1263  QDomElement pkeyElt = pkeyNode.toElement();
1264  mProviderKey = pkeyElt.text();
1265  }
1266 
1267  // determine type of vector layer
1268  if ( ! mProviderKey.isNull() )
1269  {
1270  // if the provider string isn't empty, then we successfully
1271  // got the stored provider
1272  }
1273  else if ( mDataSource.contains( "dbname=" ) )
1274  {
1275  mProviderKey = "postgres";
1276  }
1277  else
1278  {
1279  mProviderKey = "ogr";
1280  }
1281 
1282  if ( ! setDataProvider( mProviderKey ) )
1283  {
1284  return false;
1285  }
1286 
1287  QDomElement pkeyElem = pkeyNode.toElement();
1288  if ( !pkeyElem.isNull() )
1289  {
1290  QString encodingString = pkeyElem.attribute( "encoding" );
1291  if ( !encodingString.isEmpty() )
1292  {
1293  mDataProvider->setEncoding( encodingString );
1294  }
1295  }
1296 
1297  //load vector joins
1298  if ( !mJoinBuffer )
1299  {
1301  }
1302  mJoinBuffer->readXml( layer_node );
1303 
1304  updateFields();
1305  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1306 
1307  QDomNode prevExpNode = layer_node.namedItem( "previewExpression" );
1308 
1309  if ( prevExpNode.isNull() )
1310  {
1311  mDisplayExpression = "";
1312  }
1313  else
1314  {
1315  QDomElement prevExpElem = prevExpNode.toElement();
1316  mDisplayExpression = prevExpElem.text();
1317  }
1318 
1319  QString errorMsg;
1320  if ( !readSymbology( layer_node, errorMsg ) )
1321  {
1322  return false;
1323  }
1324 
1325  return mValid; // should be true if read successfully
1326 
1327 } // void QgsVectorLayer::readXml
1328 
1329 
1330 bool QgsVectorLayer::setDataProvider( QString const & provider )
1331 {
1332  // XXX should I check for and possibly delete any pre-existing providers?
1333  // XXX How often will that scenario occur?
1334 
1335  mProviderKey = provider; // XXX is this necessary? Usually already set
1336  // XXX when execution gets here.
1337 
1338  //XXX - This was a dynamic cast but that kills the Windows
1339  // version big-time with an abnormal termination error
1340  mDataProvider =
1342 
1343  if ( mDataProvider )
1344  {
1345  QgsDebugMsg( "Instantiated the data provider plugin" );
1346 
1348  if ( mValid )
1349  {
1350  // TODO: Check if the provider has the capability to send fullExtentCalculated
1351  connect( mDataProvider, SIGNAL( fullExtentCalculated() ), this, SLOT( updateExtents() ) );
1352 
1353  // get and store the feature type
1355 
1357 
1358  updateFields();
1359 
1360  // look at the fields in the layer and set the primary
1361  // display field using some real fuzzy logic
1362  setDisplayField();
1363 
1364  if ( mProviderKey == "postgres" )
1365  {
1366  QgsDebugMsg( "Beautifying layer name " + name() );
1367 
1368  // adjust the display name for postgres layers
1369  QRegExp reg( "\"[^\"]+\"\\.\"([^\"]+)\"( \\([^)]+\\))?" );
1370  if ( reg.indexIn( name() ) >= 0 )
1371  {
1372  QStringList stuff = reg.capturedTexts();
1373  QString lName = stuff[1];
1374 
1375  const QMap<QString, QgsMapLayer*> &layers = QgsMapLayerRegistry::instance()->mapLayers();
1376 
1377  QMap<QString, QgsMapLayer*>::const_iterator it;
1378  for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
1379  ;
1380 
1381  if ( it != layers.constEnd() && stuff.size() > 2 )
1382  {
1383  lName += "." + stuff[2].mid( 2, stuff[2].length() - 3 );
1384  }
1385 
1386  if ( !lName.isEmpty() )
1387  setLayerName( lName );
1388  }
1389 
1390  QgsDebugMsg( "Beautified layer name " + name() );
1391 
1392  // deal with unnecessary schema qualification to make v.in.ogr happy
1394  }
1395  else if ( mProviderKey == "osm" )
1396  {
1397  // make sure that the "observer" has been removed from URI to avoid crashes
1399  }
1400  else if ( provider == "ogr" )
1401  {
1402  // make sure that the /vsigzip or /vsizip is added to uri, if applicable
1404  if ( mDataSource.right( 10 ) == "|layerid=0" )
1405  mDataSource.chop( 10 );
1406  }
1407 
1408  // label
1409  mLabel = new QgsLabel( mDataProvider->fields() );
1410  mLabelOn = false;
1411  }
1412  else
1413  {
1414  QgsDebugMsg( "Invalid provider plugin " + QString( mDataSource.toUtf8() ) );
1415  return false;
1416  }
1417  }
1418  else
1419  {
1420  QgsDebugMsg( " unable to get data provider" );
1421  return false;
1422  }
1423 
1424  return true;
1425 
1426 } // QgsVectorLayer:: setDataProvider
1427 
1428 
1429 
1430 
1431 /* virtual */
1432 bool QgsVectorLayer::writeXml( QDomNode & layer_node,
1433  QDomDocument & document )
1434 {
1435  // first get the layer element so that we can append the type attribute
1436 
1437  QDomElement mapLayerNode = layer_node.toElement();
1438 
1439  if ( mapLayerNode.isNull() || ( "maplayer" != mapLayerNode.nodeName() ) )
1440  {
1441  QgsDebugMsg( "can't find <maplayer>" );
1442  return false;
1443  }
1444 
1445  mapLayerNode.setAttribute( "type", "vector" );
1446 
1447  // set the geometry type
1448  mapLayerNode.setAttribute( "geometry", QGis::vectorGeometryType( geometryType() ) );
1449 
1450  // add provider node
1451  if ( mDataProvider )
1452  {
1453  QDomElement provider = document.createElement( "provider" );
1454  provider.setAttribute( "encoding", mDataProvider->encoding() );
1455  QDomText providerText = document.createTextNode( providerType() );
1456  provider.appendChild( providerText );
1457  layer_node.appendChild( provider );
1458  }
1459 
1460  // save preview expression
1461  QDomElement prevExpElem = document.createElement( "previewExpression" );
1462  QDomText prevExpText = document.createTextNode( mDisplayExpression );
1463  prevExpElem.appendChild( prevExpText );
1464  layer_node.appendChild( prevExpElem );
1465 
1466  //save joins
1467  mJoinBuffer->writeXml( layer_node, document );
1468 
1469  // renderer specific settings
1470  QString errorMsg;
1471  return writeSymbology( layer_node, document, errorMsg );
1472 } // bool QgsVectorLayer::writeXml
1473 
1474 bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
1475 {
1476  Q_UNUSED( errorMessage );
1477  if ( hasGeometryType() )
1478  {
1479  // try renderer v2 first
1480  QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
1481  if ( !rendererElement.isNull() )
1482  {
1483  QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
1484  if ( !r )
1485  return false;
1486 
1487  setRendererV2( r );
1488  }
1489  else
1490  {
1492  if ( !r )
1494 
1495  setRendererV2( r );
1496  }
1497 
1498  // get and set the display field if it exists.
1499  QDomNode displayFieldNode = node.namedItem( "displayfield" );
1500  if ( !displayFieldNode.isNull() )
1501  {
1502  QDomElement e = displayFieldNode.toElement();
1503  setDisplayField( e.text() );
1504  }
1505 
1506  // get and set the blend mode if it exists
1507  QDomNode blendModeNode = node.namedItem( "blendMode" );
1508  if ( !blendModeNode.isNull() )
1509  {
1510  QDomElement e = blendModeNode.toElement();
1512  }
1513 
1514  // get and set the feature blend mode if it exists
1515  QDomNode featureBlendModeNode = node.namedItem( "featureBlendMode" );
1516  if ( !featureBlendModeNode.isNull() )
1517  {
1518  QDomElement e = featureBlendModeNode.toElement();
1520  }
1521 
1522  // get and set the layer transparency if it exists
1523  QDomNode layerTransparencyNode = node.namedItem( "layerTransparency" );
1524  if ( !layerTransparencyNode.isNull() )
1525  {
1526  QDomElement e = layerTransparencyNode.toElement();
1527  setLayerTransparency( e.text().toInt() );
1528  }
1529 
1530  // use scale dependent visibility flag
1531  QDomElement e = node.toElement();
1532  if ( mLabel )
1533  {
1534  mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
1535  mLabel->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
1536  mLabel->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
1537  }
1538 
1539  // get the simplification drawing settings
1540  mSimplifyMethod.setSimplifyHints(( QgsVectorSimplifyMethod::SimplifyHints ) e.attribute( "simplifyDrawingHints", "1" ).toInt() );
1541  mSimplifyMethod.setThreshold( e.attribute( "simplifyDrawingTol", "1" ).toFloat() );
1542  mSimplifyMethod.setForceLocalOptimization( e.attribute( "simplifyLocal", "1" ).toInt() );
1543  mSimplifyMethod.setMaximumScale( e.attribute( "simplifyMaxScale", "1" ).toFloat() );
1544 
1545  //also restore custom properties (for labeling-ng)
1546  readCustomProperties( node, "labeling" );
1547 
1548  // Test if labeling is on or off
1549  QDomNode labelnode = node.namedItem( "label" );
1550  QDomElement element = labelnode.toElement();
1551  int hasLabelsEnabled = element.text().toInt();
1552  if ( hasLabelsEnabled < 1 )
1553  {
1554  enableLabels( false );
1555  }
1556  else
1557  {
1558  enableLabels( true );
1559  }
1560 
1561  QDomNode labelattributesnode = node.namedItem( "labelattributes" );
1562 
1563  if ( !labelattributesnode.isNull() && mLabel )
1564  {
1565  QgsDebugMsg( "calling readXML" );
1566  mLabel->readXML( labelattributesnode );
1567  }
1568 
1569  //diagram renderer and diagram layer settings
1570  delete mDiagramRenderer; mDiagramRenderer = 0;
1571  QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
1572  if ( !singleCatDiagramElem.isNull() )
1573  {
1575  mDiagramRenderer->readXML( singleCatDiagramElem, this );
1576  }
1577  QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
1578  if ( !linearDiagramElem.isNull() )
1579  {
1581  mDiagramRenderer->readXML( linearDiagramElem, this );
1582  }
1583 
1584  if ( mDiagramRenderer )
1585  {
1586  QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
1587  if ( !diagramSettingsElem.isNull() )
1588  {
1590  mDiagramLayerSettings->readXML( diagramSettingsElem, this );
1591  }
1592  }
1593  }
1594 
1595  // process the attribute actions
1596  mActions->readXML( node );
1597 
1598 
1599  QDomNode editFormNode = node.namedItem( "editform" );
1600  if ( !editFormNode.isNull() )
1601  {
1602  QDomElement e = editFormNode.toElement();
1603  mEditForm = QgsProject::instance()->readPath( e.text() );
1604  }
1605 
1606  QDomNode editFormInitNode = node.namedItem( "editforminit" );
1607  if ( !editFormInitNode.isNull() )
1608  {
1609  mEditFormInit = editFormInitNode.toElement().text();
1610  }
1611 
1612  QDomNode fFSuppNode = node.namedItem( "featformsuppress" );
1613  if ( fFSuppNode.isNull() )
1614  {
1616  }
1617  else
1618  {
1619  QDomElement e = fFSuppNode.toElement();
1621  }
1622 
1623  QDomNode annotationFormNode = node.namedItem( "annotationform" );
1624  if ( !annotationFormNode.isNull() )
1625  {
1626  QDomElement e = annotationFormNode.toElement();
1628  }
1629 
1630  mAttributeAliasMap.clear();
1631  QDomNode aliasesNode = node.namedItem( "aliases" );
1632  if ( !aliasesNode.isNull() )
1633  {
1634  QDomElement aliasElem;
1635  QString name;
1636 
1637  QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( "alias" );
1638  for ( int i = 0; i < aliasNodeList.size(); ++i )
1639  {
1640  aliasElem = aliasNodeList.at( i ).toElement();
1641 
1642  QString field;
1643  if ( aliasElem.hasAttribute( "field" ) )
1644  {
1645  field = aliasElem.attribute( "field" );
1646  }
1647  else
1648  {
1649  int index = aliasElem.attribute( "index" ).toInt();
1650 
1651  if ( index >= 0 && index < pendingFields().count() )
1652  field = pendingFields()[ index ].name();
1653  }
1654 
1655  mAttributeAliasMap.insert( field, aliasElem.attribute( "name" ) );
1656  }
1657  }
1658 
1659  // tab display
1660  QDomNode editorLayoutNode = node.namedItem( "editorlayout" );
1661  if ( editorLayoutNode.isNull() )
1662  {
1664  }
1665  else
1666  {
1667  if ( editorLayoutNode.toElement().text() == "uifilelayout" )
1668  {
1670  }
1671  else if ( editorLayoutNode.toElement().text() == "tablayout" )
1672  {
1674  }
1675  else
1676  {
1678  }
1679  }
1680 
1681  //Attributes excluded from WMS and WFS
1682  mExcludeAttributesWMS.clear();
1683  QDomNode excludeWMSNode = node.namedItem( "excludeAttributesWMS" );
1684  if ( !excludeWMSNode.isNull() )
1685  {
1686  QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( "attribute" );
1687  for ( int i = 0; i < attributeNodeList.size(); ++i )
1688  {
1689  mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
1690  }
1691  }
1692 
1693  mExcludeAttributesWFS.clear();
1694  QDomNode excludeWFSNode = node.namedItem( "excludeAttributesWFS" );
1695  if ( !excludeWFSNode.isNull() )
1696  {
1697  QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( "attribute" );
1698  for ( int i = 0; i < attributeNodeList.size(); ++i )
1699  {
1700  mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
1701  }
1702  }
1703 
1704  // tabs and groups display info
1705  mAttributeEditorElements.clear();
1706  QDomNode attributeEditorFormNode = node.namedItem( "attributeEditorForm" );
1707  QDomNodeList attributeEditorFormNodeList = attributeEditorFormNode.toElement().childNodes();
1708 
1709  for ( int i = 0; i < attributeEditorFormNodeList.size(); i++ )
1710  {
1711  QDomElement elem = attributeEditorFormNodeList.at( i ).toElement();
1712 
1713  QgsAttributeEditorElement *attributeEditorWidget = attributeEditorElementFromDomElement( elem, this );
1714  mAttributeEditorElements.append( attributeEditorWidget );
1715  }
1716 
1717  return true;
1718 }
1719 
1721 {
1722  QgsAttributeEditorElement* newElement = NULL;
1723 
1724  if ( elem.tagName() == "attributeEditorContainer" )
1725  {
1726  QgsAttributeEditorContainer* container = new QgsAttributeEditorContainer( elem.attribute( "name" ), parent );
1727 
1728  QDomNodeList childNodeList = elem.childNodes();
1729 
1730  for ( int i = 0; i < childNodeList.size(); i++ )
1731  {
1732  QDomElement childElem = childNodeList.at( i ).toElement();
1733  QgsAttributeEditorElement* myElem = attributeEditorElementFromDomElement( childElem, container );
1734  if ( myElem )
1735  container->addChildElement( myElem );
1736  }
1737 
1738  newElement = container;
1739  }
1740  else if ( elem.tagName() == "attributeEditorField" )
1741  {
1742  QString name = elem.attribute( "name" );
1743  int idx = *( dataProvider()->fieldNameMap() ).find( name );
1744  newElement = new QgsAttributeEditorField( name, idx, parent );
1745  }
1746  else if ( elem.tagName() == "attributeEditorRelation" )
1747  {
1748  // At this time, the relations are not loaded
1749  // So we only grab the id and delegate the rest to onRelationsLoaded()
1750  QString name = elem.attribute( "name" );
1751  newElement = new QgsAttributeEditorRelation( name, elem.attribute( "relation", "[None]" ), parent );
1752  }
1753  return newElement;
1754 }
1755 
1756 bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
1757 {
1758  Q_UNUSED( errorMessage );
1759  QDomElement mapLayerNode = node.toElement();
1760 
1761  if ( hasGeometryType() )
1762  {
1763  QDomElement rendererElement = mRendererV2->save( doc );
1764  node.appendChild( rendererElement );
1765 
1766  // use scale dependent visibility flag
1767  if ( mLabel )
1768  {
1769  mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
1770  mapLayerNode.setAttribute( "minLabelScale", QString::number( mLabel->minScale() ) );
1771  mapLayerNode.setAttribute( "maxLabelScale", QString::number( mLabel->maxScale() ) );
1772  }
1773 
1774  // save the simplification drawing settings
1775  mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) );
1776  mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) );
1777  mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 );
1778  mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) );
1779 
1780  //save customproperties (for labeling ng)
1781  writeCustomProperties( node, doc );
1782 
1783  // add the blend mode field
1784  QDomElement blendModeElem = doc.createElement( "blendMode" );
1785  QDomText blendModeText = doc.createTextNode( QString::number( QgsMapRenderer::getBlendModeEnum( blendMode() ) ) );
1786  blendModeElem.appendChild( blendModeText );
1787  node.appendChild( blendModeElem );
1788 
1789  // add the feature blend mode field
1790  QDomElement featureBlendModeElem = doc.createElement( "featureBlendMode" );
1791  QDomText featureBlendModeText = doc.createTextNode( QString::number( QgsMapRenderer::getBlendModeEnum( featureBlendMode() ) ) );
1792  featureBlendModeElem.appendChild( featureBlendModeText );
1793  node.appendChild( featureBlendModeElem );
1794 
1795  // add the layer transparency
1796  QDomElement layerTransparencyElem = doc.createElement( "layerTransparency" );
1797  QDomText layerTransparencyText = doc.createTextNode( QString::number( layerTransparency() ) );
1798  layerTransparencyElem.appendChild( layerTransparencyText );
1799  node.appendChild( layerTransparencyElem );
1800 
1801  // add the display field
1802  QDomElement dField = doc.createElement( "displayfield" );
1803  QDomText dFieldText = doc.createTextNode( displayField() );
1804  dField.appendChild( dFieldText );
1805  node.appendChild( dField );
1806 
1807  // add label node
1808  QDomElement labelElem = doc.createElement( "label" );
1809  QDomText labelText = doc.createTextNode( "" );
1810 
1811  if ( hasLabelsEnabled() )
1812  {
1813  labelText.setData( "1" );
1814  }
1815  else
1816  {
1817  labelText.setData( "0" );
1818  }
1819  labelElem.appendChild( labelText );
1820 
1821  node.appendChild( labelElem );
1822 
1823  // Now we get to do all that all over again for QgsLabel
1824 
1825  if ( mLabel )
1826  {
1827  QString fieldname = mLabel->labelField( QgsLabel::Text );
1828  if ( fieldname != "" )
1829  {
1830  dField = doc.createElement( "labelfield" );
1831  dFieldText = doc.createTextNode( fieldname );
1832  dField.appendChild( dFieldText );
1833  node.appendChild( dField );
1834  }
1835 
1836  mLabel->writeXML( node, doc );
1837  }
1838 
1839  if ( mDiagramRenderer )
1840  {
1841  mDiagramRenderer->writeXML( mapLayerNode, doc, this );
1842  if ( mDiagramLayerSettings )
1843  mDiagramLayerSettings->writeXML( mapLayerNode, doc, this );
1844  }
1845  }
1846 
1847  //edit types
1848  QDomElement editTypesElement = doc.createElement( "edittypes" );
1849 
1850  Q_FOREACH( QgsField field, pendingFields().toList() )
1851  {
1852  QDomElement editTypeElement = doc.createElement( "edittype" );
1853  editTypeElement.setAttribute( "name", field.name() );
1854  editTypeElement.setAttribute( "editable", mFieldEditables[field.name()] ? 1 : 0 );
1855  editTypeElement.setAttribute( "labelontop", mLabelOnTop[field.name()] ? 1 : 0 );
1856 
1857 
1858  editTypesElement.appendChild( editTypeElement );
1859  }
1860 
1861  node.appendChild( editTypesElement );
1862 
1863  QDomElement efField = doc.createElement( "editform" );
1864  QDomText efText = doc.createTextNode( QgsProject::instance()->writePath( mEditForm ) );
1865  efField.appendChild( efText );
1866  node.appendChild( efField );
1867 
1868  QDomElement efiField = doc.createElement( "editforminit" );
1869  QDomText efiText = doc.createTextNode( mEditFormInit );
1870  efiField.appendChild( efiText );
1871  node.appendChild( efiField );
1872 
1873  QDomElement fFSuppElem = doc.createElement( "featformsuppress" );
1874  QDomText fFSuppText = doc.createTextNode( QString::number( featureFormSuppress() ) );
1875  fFSuppElem.appendChild( fFSuppText );
1876  node.appendChild( fFSuppElem );
1877 
1878  QDomElement afField = doc.createElement( "annotationform" );
1879  QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
1880  afField.appendChild( afText );
1881  node.appendChild( afField );
1882 
1883  // tab display
1884  QDomElement editorLayoutElem = doc.createElement( "editorlayout" );
1885  switch ( mEditorLayout )
1886  {
1887  case UiFileLayout:
1888  editorLayoutElem.appendChild( doc.createTextNode( "uifilelayout" ) );
1889  break;
1890 
1891  case TabLayout:
1892  editorLayoutElem.appendChild( doc.createTextNode( "tablayout" ) );
1893  break;
1894 
1895  case GeneratedLayout:
1896  default:
1897  editorLayoutElem.appendChild( doc.createTextNode( "generatedlayout" ) );
1898  break;
1899  }
1900 
1901  node.appendChild( editorLayoutElem );
1902 
1903  //attribute aliases
1904  if ( mAttributeAliasMap.size() > 0 )
1905  {
1906  QDomElement aliasElem = doc.createElement( "aliases" );
1907  QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
1908  for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
1909  {
1910  int idx = fieldNameIndex( a_it.key() );
1911  if ( idx < 0 )
1912  continue;
1913 
1914  QDomElement aliasEntryElem = doc.createElement( "alias" );
1915  aliasEntryElem.setAttribute( "field", a_it.key() );
1916  aliasEntryElem.setAttribute( "index", idx );
1917  aliasEntryElem.setAttribute( "name", a_it.value() );
1918  aliasElem.appendChild( aliasEntryElem );
1919  }
1920  node.appendChild( aliasElem );
1921  }
1922 
1923  //exclude attributes WMS
1924  QDomElement excludeWMSElem = doc.createElement( "excludeAttributesWMS" );
1925  QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
1926  for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
1927  {
1928  QDomElement attrElem = doc.createElement( "attribute" );
1929  QDomText attrText = doc.createTextNode( *attWMSIt );
1930  attrElem.appendChild( attrText );
1931  excludeWMSElem.appendChild( attrElem );
1932  }
1933  node.appendChild( excludeWMSElem );
1934 
1935  //exclude attributes WFS
1936  QDomElement excludeWFSElem = doc.createElement( "excludeAttributesWFS" );
1937  QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
1938  for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
1939  {
1940  QDomElement attrElem = doc.createElement( "attribute" );
1941  QDomText attrText = doc.createTextNode( *attWFSIt );
1942  attrElem.appendChild( attrText );
1943  excludeWFSElem.appendChild( attrElem );
1944  }
1945  node.appendChild( excludeWFSElem );
1946 
1947  // tabs and groups of edit form
1948  if ( mAttributeEditorElements.size() > 0 )
1949  {
1950  QDomElement tabsElem = doc.createElement( "attributeEditorForm" );
1951 
1952  for ( QList< QgsAttributeEditorElement* >::const_iterator it = mAttributeEditorElements.begin(); it != mAttributeEditorElements.end(); ++it )
1953  {
1954  QDomElement attributeEditorWidgetElem = ( *it )->toDomElement( doc );
1955  tabsElem.appendChild( attributeEditorWidgetElem );
1956  }
1957 
1958  node.appendChild( tabsElem );
1959  }
1960 
1961  // add attribute actions
1962  mActions->writeXML( node, doc );
1963 
1964  return true;
1965 }
1966 
1967 bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
1968 {
1969  // get the Name element
1970  QDomElement nameElem = node.firstChildElement( "Name" );
1971  if ( nameElem.isNull() )
1972  {
1973  errorMessage = "Warning: Name element not found within NamedLayer while it's required.";
1974  }
1975 
1976  if ( hasGeometryType() )
1977  {
1978  QgsFeatureRendererV2* r = QgsFeatureRendererV2::loadSld( node, geometryType(), errorMessage );
1979  if ( !r )
1980  return false;
1981 
1982  setRendererV2( r );
1983 
1984  // labeling
1985  readSldLabeling( node );
1986  }
1987  return true;
1988 }
1989 
1990 
1991 bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
1992 {
1993  Q_UNUSED( errorMessage );
1994 
1995  // store the Name element
1996  QDomElement nameNode = doc.createElement( "se:Name" );
1997  nameNode.appendChild( doc.createTextNode( name() ) );
1998  node.appendChild( nameNode );
1999 
2000  if ( hasGeometryType() )
2001  {
2002  node.appendChild( mRendererV2->writeSld( doc, *this ) );
2003  }
2004  return true;
2005 }
2006 
2007 
2009 {
2010  if ( !mEditBuffer || !mDataProvider )
2011  {
2012  return false;
2013  }
2014 
2015  updateExtents();
2016 
2017  return mEditBuffer->changeGeometry( fid, geom );
2018 }
2019 
2020 
2021 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, QVariant value, bool emitSignal )
2022 {
2023  Q_UNUSED( emitSignal );
2024  return changeAttributeValue( fid, field, value );
2025 }
2026 
2027 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
2028 {
2029  if ( !mEditBuffer || !mDataProvider )
2030  return false;
2031 
2032  return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
2033 }
2034 
2036 {
2037  if ( !mEditBuffer || !mDataProvider )
2038  return false;
2039 
2040  return mEditBuffer->addAttribute( field );
2041 }
2042 
2043 void QgsVectorLayer::addAttributeAlias( int attIndex, QString aliasString )
2044 {
2045  if ( attIndex < 0 || attIndex >= pendingFields().count() )
2046  return;
2047 
2048  QString name = pendingFields()[ attIndex ].name();
2049 
2050  mAttributeAliasMap.insert( name, aliasString );
2051  emit layerModified(); // TODO[MD]: should have a different signal?
2052 }
2053 
2055 {
2056  mAttributeEditorElements.append( data );
2057 }
2058 
2059 const QString QgsVectorLayer::editorWidgetV2( int fieldIdx ) const
2060 {
2061  return mEditorWidgetV2Types.value( mUpdatedFields[fieldIdx].name(), "TextEdit" );
2062 }
2063 
2064 const QString QgsVectorLayer::editorWidgetV2( const QString& fieldName ) const
2065 {
2066  return mEditorWidgetV2Types.value( fieldName, "TextEdit" );
2067 }
2068 
2070 {
2071  return mEditorWidgetV2Configs.value( mUpdatedFields[fieldIdx].name() );
2072 }
2073 
2074 const QgsEditorWidgetConfig QgsVectorLayer::editorWidgetV2Config( const QString& fieldName ) const
2075 {
2076  return mEditorWidgetV2Configs.value( fieldName );
2077 }
2078 
2079 QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
2080 {
2081  if ( attributeIndex < 0 || attributeIndex >= pendingFields().count() )
2082  return "";
2083 
2084  QString name = pendingFields()[ attributeIndex ].name();
2085 
2086  return mAttributeAliasMap.value( name, "" );
2087 }
2088 
2089 QString QgsVectorLayer::attributeDisplayName( int attributeIndex ) const
2090 {
2091  QString displayName = attributeAlias( attributeIndex );
2092  if ( displayName.isEmpty() )
2093  {
2094  const QgsFields& fields = pendingFields();
2095  if ( attributeIndex >= 0 && attributeIndex < fields.count() )
2096  {
2097  displayName = fields[attributeIndex].name();
2098  }
2099  }
2100  return displayName;
2101 }
2102 
2104 {
2105  if ( !mEditBuffer || !mDataProvider )
2106  return false;
2107 
2108  return mEditBuffer->deleteAttribute( index );
2109 }
2110 
2111 bool QgsVectorLayer::deleteAttributes( QList<int> attrs )
2112 {
2113  bool deleted = false;
2114 
2115  // Remove multiple occurences of same attribute
2116  attrs = attrs.toSet().toList();
2117 
2118  qSort( attrs.begin(), attrs.end(), qGreater<int>() );
2119 
2120  foreach ( int attr, attrs )
2121  {
2122  if ( deleteAttribute( attr ) )
2123  {
2124  deleted = true;
2125  }
2126  }
2127 
2128  return deleted;
2129 }
2130 
2132 {
2133  if ( !mEditBuffer )
2134  return false;
2135 
2136  bool res = mEditBuffer->deleteFeature( fid );
2137  if ( res )
2138  mSelectedFeatureIds.remove( fid ); // remove it from selection
2139 
2140  updateExtents();
2141 
2142  return res;
2143 }
2144 
2146 {
2147  return mUpdatedFields;
2148 }
2149 
2151 {
2153 }
2154 
2156 {
2157  QgsAttributeList pkAttributesList;
2158 
2159  QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
2160  for ( int i = 0; i < mUpdatedFields.count(); ++i )
2161  {
2163  providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
2164  pkAttributesList << i;
2165  }
2166 
2167  return pkAttributesList;
2168 }
2169 
2171 {
2172  return mDataProvider->featureCount() +
2174 }
2175 
2177 {
2178  mCommitErrors.clear();
2179 
2180  if ( !mDataProvider )
2181  {
2182  mCommitErrors << tr( "ERROR: no provider" );
2183  return false;
2184  }
2185 
2186  if ( !mEditBuffer )
2187  {
2188  mCommitErrors << tr( "ERROR: layer not editable" );
2189  return false;
2190  }
2191 
2192  emit beforeCommitChanges();
2193 
2194  bool success = mEditBuffer->commitChanges( mCommitErrors );
2195 
2196  if ( success )
2197  {
2198  delete mEditBuffer;
2199  mEditBuffer = 0;
2200  undoStack()->clear();
2201  emit editingStopped();
2202  }
2203  else
2204  {
2205  QgsMessageLog::logMessage( tr( "Commit errors:\n %1" ).arg( mCommitErrors.join( "\n " ) ) );
2206  }
2207 
2208  if ( mCache )
2209  {
2211  }
2212 
2213  updateFields();
2215 
2216  emit repaintRequested();
2217 
2218  return success;
2219 }
2220 
2221 const QStringList &QgsVectorLayer::commitErrors()
2222 {
2223  return mCommitErrors;
2224 }
2225 
2226 bool QgsVectorLayer::rollBack( bool deleteBuffer )
2227 {
2228  if ( !mEditBuffer )
2229  {
2230  return false;
2231  }
2232 
2233  emit beforeRollBack();
2234 
2235  mEditBuffer->rollBack();
2236 
2237  if ( isModified() )
2238  {
2239  // new undo stack roll back method
2240  // old method of calling every undo could cause many canvas refreshes
2241  undoStack()->setIndex( 0 );
2242  }
2243 
2244  updateFields();
2245 
2246  if ( deleteBuffer )
2247  {
2248  delete mEditBuffer;
2249  mEditBuffer = 0;
2250  undoStack()->clear();
2251  }
2252  emit editingStopped();
2253 
2254  if ( mCache )
2255  {
2257  }
2258 
2259  emit repaintRequested();
2260  return true;
2261 }
2262 
2264 {
2265  QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - ids;
2266 
2267  mSelectedFeatureIds = ids;
2268 
2269  emit selectionChanged( ids, deselectedFeatures, true );
2270 }
2271 
2273 {
2274  return mSelectedFeatureIds.size();
2275 }
2276 
2278 {
2279  return mSelectedFeatureIds;
2280 }
2281 
2282 
2284 {
2285  QgsFeatureList features;
2286 
2287  QgsFeatureRequest req;
2288  if ( geometryType() == QGis::NoGeometry )
2290 
2291  foreach ( QgsFeatureId fid, mSelectedFeatureIds )
2292  {
2293  features.push_back( QgsFeature() );
2294  getFeatures( req.setFilterFid( fid ) ).nextFeature( features.back() );
2295  }
2296 
2297  return features;
2298 }
2299 
2300 bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
2301 {
2302  if ( !mEditBuffer || !mDataProvider )
2303  return false;
2304 
2305  bool res = mEditBuffer->addFeatures( features );
2306 
2307  if ( makeSelected )
2308  {
2309  QgsFeatureIds ids;
2310 
2311  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
2312  ids << iter->id();
2313 
2314  setSelectedFeatures( ids );
2315  }
2316 
2317  updateExtents();
2318 
2319  return res;
2320 }
2321 
2322 
2323 bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
2324 {
2325  if ( !hasGeometryType() )
2326  return false;
2327 
2328  QMultiMap<double, QgsSnappingResult> snapResults;
2329  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
2330 
2331  if ( result != 0 )
2332  {
2333  return false;
2334  }
2335 
2336  if ( snapResults.size() < 1 )
2337  {
2338  return false;
2339  }
2340 
2341  QMultiMap<double, QgsSnappingResult>::const_iterator snap_it = snapResults.constBegin();
2342  point.setX( snap_it.value().snappedVertex.x() );
2343  point.setY( snap_it.value().snappedVertex.y() );
2344  return true;
2345 }
2346 
2347 
2348 int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snappingTolerance,
2349  QMultiMap<double, QgsSnappingResult>& snappingResults,
2350  QgsSnapper::SnappingType snap_to )
2351 {
2352  if ( !hasGeometryType() )
2353  return 1;
2354 
2355  if ( snappingTolerance <= 0 || !mDataProvider )
2356  {
2357  return 1;
2358  }
2359 
2360  QList<QgsFeature> featureList;
2361  QgsRectangle searchRect( startPoint.x() - snappingTolerance, startPoint.y() - snappingTolerance,
2362  startPoint.x() + snappingTolerance, startPoint.y() + snappingTolerance );
2363  double sqrSnappingTolerance = snappingTolerance * snappingTolerance;
2364 
2365  int n = 0;
2366  QgsFeature f;
2367 
2368  if ( mCache->cachedGeometriesRect().contains( searchRect ) )
2369  {
2370  QgsGeometryMap& cachedGeometries = mCache->cachedGeometries();
2371  for ( QgsGeometryMap::iterator it = cachedGeometries.begin(); it != cachedGeometries.end() ; ++it )
2372  {
2373  QgsGeometry* g = &( it.value() );
2374  if ( g->boundingBox().intersects( searchRect ) )
2375  {
2376  snapToGeometry( startPoint, it.key(), g, sqrSnappingTolerance, snappingResults, snap_to );
2377  ++n;
2378  }
2379  }
2380  }
2381  else
2382  {
2383  // snapping outside cached area
2384 
2386  .setFilterRect( searchRect )
2388  .setSubsetOfAttributes( QgsAttributeList() ) );
2389 
2390  while ( fit.nextFeature( f ) )
2391  {
2392  snapToGeometry( startPoint, f.id(), f.geometry(), sqrSnappingTolerance, snappingResults, snap_to );
2393  ++n;
2394  }
2395  }
2396 
2397  return n == 0 ? 2 : 0;
2398 }
2399 
2401  QgsFeatureId featureId,
2402  QgsGeometry* geom,
2403  double sqrSnappingTolerance,
2404  QMultiMap<double, QgsSnappingResult>& snappingResults,
2405  QgsSnapper::SnappingType snap_to ) const
2406 {
2407  if ( !geom )
2408  {
2409  return;
2410  }
2411 
2412  int atVertex, beforeVertex, afterVertex;
2413  double sqrDistVertexSnap, sqrDistSegmentSnap;
2414  QgsPoint snappedPoint;
2415  QgsSnappingResult snappingResultVertex;
2416  QgsSnappingResult snappingResultSegment;
2417 
2418  if ( snap_to == QgsSnapper::SnapToVertex || snap_to == QgsSnapper::SnapToVertexAndSegment )
2419  {
2420  snappedPoint = geom->closestVertex( startPoint, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
2421  if ( sqrDistVertexSnap < sqrSnappingTolerance )
2422  {
2423  snappingResultVertex.snappedVertex = snappedPoint;
2424  snappingResultVertex.snappedVertexNr = atVertex;
2425  snappingResultVertex.beforeVertexNr = beforeVertex;
2426  if ( beforeVertex != -1 ) // make sure the vertex is valid
2427  {
2428  snappingResultVertex.beforeVertex = geom->vertexAt( beforeVertex );
2429  }
2430  snappingResultVertex.afterVertexNr = afterVertex;
2431  if ( afterVertex != -1 ) // make sure the vertex is valid
2432  {
2433  snappingResultVertex.afterVertex = geom->vertexAt( afterVertex );
2434  }
2435  snappingResultVertex.snappedAtGeometry = featureId;
2436  snappingResultVertex.layer = this;
2437  snappingResults.insert( sqrt( sqrDistVertexSnap ), snappingResultVertex );
2438  return;
2439  }
2440  }
2441  if ( snap_to == QgsSnapper::SnapToSegment || snap_to == QgsSnapper::SnapToVertexAndSegment ) // snap to segment
2442  {
2443  if ( geometryType() != QGis::Point ) // cannot snap to segment for points/multipoints
2444  {
2445  sqrDistSegmentSnap = geom->closestSegmentWithContext( startPoint, snappedPoint, afterVertex, NULL, crs().geographicFlag() ? 1e-12 : 1e-8 );
2446 
2447  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
2448  {
2449  snappingResultSegment.snappedVertex = snappedPoint;
2450  snappingResultSegment.snappedVertexNr = -1;
2451  snappingResultSegment.beforeVertexNr = afterVertex - 1;
2452  snappingResultSegment.afterVertexNr = afterVertex;
2453  snappingResultSegment.snappedAtGeometry = featureId;
2454  snappingResultSegment.beforeVertex = geom->vertexAt( afterVertex - 1 );
2455  snappingResultSegment.afterVertex = geom->vertexAt( afterVertex );
2456  snappingResultSegment.layer = this;
2457  snappingResults.insert( sqrt( sqrDistSegmentSnap ), snappingResultSegment );
2458  }
2459  }
2460  }
2461 }
2462 
2463 int QgsVectorLayer::insertSegmentVerticesForSnap( const QList<QgsSnappingResult>& snapResults )
2464 {
2465  QgsVectorLayerEditUtils utils( this );
2466  return utils.insertSegmentVerticesForSnap( snapResults );
2467 }
2468 
2469 
2471 {
2472  QgsDebugMsg( "----- Computing Coordinate System" );
2473 
2474  //
2475  // Get the layers project info and set up the QgsCoordinateTransform
2476  // for this layer
2477  //
2478 
2479  if ( hasGeometryType() )
2480  {
2481  // get CRS directly from provider
2482  setCrs( mDataProvider->crs() );
2483  }
2484  else
2485  {
2487  }
2488 }
2489 
2490 
2491 const QString QgsVectorLayer::displayField() const
2492 {
2493  return mDisplayField;
2494 }
2495 
2496 void QgsVectorLayer::setDisplayExpression( const QString &displayExpression )
2497 {
2499 }
2500 
2502 {
2503  return mDisplayExpression;
2504 }
2505 
2507 {
2508  return ( mEditBuffer && mDataProvider );
2509 }
2510 
2512 {
2513  return mReadOnly;
2514 }
2515 
2516 bool QgsVectorLayer::setReadOnly( bool readonly )
2517 {
2518  // exit if the layer is in editing mode
2519  if ( readonly && mEditBuffer )
2520  return false;
2521 
2522  mReadOnly = readonly;
2523  return true;
2524 }
2525 
2527 {
2528  emit beforeModifiedCheck();
2529  return mEditBuffer && mEditBuffer->isModified();
2530 }
2531 
2533 {
2537 }
2538 
2540 {
2542 
2544  const QString widgetType = QgsLegacyHelpers::convertEditType( type, cfg, this, mUpdatedFields[idx].name() );
2546 
2547  setEditorWidgetV2( idx, widgetType );
2548  setEditorWidgetV2Config( idx, cfg );
2549 }
2550 
2552 {
2553  return mEditorLayout;
2554 }
2555 
2557 {
2559 }
2560 
2561 void QgsVectorLayer::setEditorWidgetV2( int attrIdx, const QString& widgetType )
2562 {
2563  mEditorWidgetV2Types[ mUpdatedFields[ attrIdx ].name()] = widgetType;
2564 }
2565 
2567 {
2568  mEditorWidgetV2Configs[ mUpdatedFields[ attrIdx ].name()] = config;
2569 }
2570 
2572 {
2573  return mEditForm;
2574 }
2575 
2577 {
2578  mEditForm = ui;
2579 }
2580 
2581 void QgsVectorLayer::setAnnotationForm( const QString& ui )
2582 {
2583  mAnnotationForm = ui;
2584 }
2585 
2587 {
2588  return mEditFormInit;
2589 }
2590 
2591 void QgsVectorLayer::setEditFormInit( QString function )
2592 {
2593  mEditFormInit = function;
2594 }
2595 
2596 QMap< QString, QVariant > QgsVectorLayer::valueMap( int idx )
2597 {
2598  return editorWidgetV2Config( idx );
2599 }
2600 
2602 {
2603  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2604  return RangeData(
2605  cfg.value( "Min" ),
2606  cfg.value( "Max" ),
2607  cfg.value( "Step" )
2608  );
2609 }
2610 
2611 QString QgsVectorLayer::dateFormat( int idx )
2612 {
2613  return editorWidgetV2Config( idx ).value( "DateFormat" ).toString();
2614 }
2615 
2617 {
2618  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2619  return QSize( cfg.value( "Width" ).toInt(), cfg.value( "Height" ).toInt() );
2620 }
2621 
2623 {
2624  const QgsFields &fields = pendingFields();
2625  if ( idx >= 0 && idx < fields.count() )
2626  {
2628  return false;
2629  return mFieldEditables.value( fields[idx].name(), true );
2630  }
2631  else
2632  return true;
2633 }
2634 
2636 {
2637  const QgsFields &fields = pendingFields();
2638  if ( idx >= 0 && idx < fields.count() )
2639  return mLabelOnTop.value( fields[idx].name(), false );
2640  else
2641  return false;
2642 }
2643 
2644 void QgsVectorLayer::setFieldEditable( int idx, bool editable )
2645 {
2646  const QgsFields &fields = pendingFields();
2647  if ( idx >= 0 && idx < fields.count() )
2648  mFieldEditables[ fields[idx].name()] = editable;
2649 }
2650 
2651 void QgsVectorLayer::setLabelOnTop( int idx, bool onTop )
2652 {
2653  const QgsFields &fields = pendingFields();
2654  if ( idx >= 0 && idx < fields.count() )
2655  mLabelOnTop[ fields[idx].name()] = onTop;
2656 }
2657 
2659 {
2660  return mRendererV2;
2661 }
2662 
2664 {
2665  if ( !hasGeometryType() )
2666  return;
2667 
2668  if ( r != mRendererV2 )
2669  {
2670  delete mRendererV2;
2671  mRendererV2 = r;
2672  mSymbolFeatureCounted = false;
2673  mSymbolFeatureCountMap.clear();
2674 
2675  emit rendererChanged();
2676  }
2677 }
2678 
2679 
2680 
2682 {
2683  undoStack()->beginMacro( text );
2684  emit editCommandStarted( text );
2685 }
2686 
2688 {
2689  undoStack()->endMacro();
2690  emit editCommandEnded();
2691 }
2692 
2694 {
2695  undoStack()->endMacro();
2696  undoStack()->undo();
2697  emit editCommandDestroyed();
2698 }
2699 
2700 
2701 void QgsVectorLayer::setCheckedState( int idx, QString checked, QString unchecked )
2702 {
2704  cfg["CheckedState"] = checked;
2705  cfg["UncheckedState"] = unchecked;
2706  setEditorWidgetV2Config( idx, cfg );
2707 }
2708 
2709 int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
2710 {
2711  return pendingFields().fieldNameIndex( fieldName );
2712 }
2713 
2715 {
2716  mJoinBuffer->addJoin( joinInfo );
2717  updateFields();
2718 }
2719 
2720 void QgsVectorLayer::checkJoinLayerRemove( QString theLayerId )
2721 {
2722  removeJoin( theLayerId );
2723 }
2724 
2725 void QgsVectorLayer::removeJoin( const QString& joinLayerId )
2726 {
2727  mJoinBuffer->removeJoin( joinLayerId );
2728  updateFields();
2729 }
2730 
2731 const QList< QgsVectorJoinInfo >& QgsVectorLayer::vectorJoins() const
2732 {
2733  return mJoinBuffer->vectorJoins();
2734 }
2735 
2737 {
2738  if ( !mDataProvider )
2739  return;
2740 
2742 
2743  // added / removed fields
2744  if ( mEditBuffer )
2746 
2747  // joined fields
2750 
2751  emit updatedFields();
2752 }
2753 
2754 
2756 {
2757  if ( mJoinBuffer->containsJoins() )
2758  {
2760  }
2761 }
2762 
2763 void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
2764 {
2765  uniqueValues.clear();
2766  if ( !mDataProvider )
2767  {
2768  return;
2769  }
2770 
2772 
2773  if ( origin == QgsFields::OriginProvider ) //a provider field
2774  {
2775  return mDataProvider->uniqueValues( index, uniqueValues, limit );
2776  }
2777  else if ( origin == QgsFields::OriginJoin )
2778  {
2779  int sourceLayerIndex;
2780  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2781  Q_ASSERT( join );
2782 
2784  Q_ASSERT( vl );
2785 
2786  return vl->dataProvider()->uniqueValues( sourceLayerIndex, uniqueValues, limit );
2787  }
2788  else if ( origin == QgsFields::OriginEdit )
2789  {
2790  // the layer is editable, but in certain cases it can still be avoided going through all features
2791  if ( mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mAddedFeatures.isEmpty() && !mEditBuffer->mDeletedAttributeIds.contains( index ) && mEditBuffer->mChangedAttributeValues.isEmpty() )
2792  {
2793  return mDataProvider->uniqueValues( index, uniqueValues, limit );
2794  }
2795 
2796  // we need to go through each feature
2797  QgsAttributeList attList;
2798  attList << index;
2799 
2801  .setFlags( QgsFeatureRequest::NoGeometry )
2802  .setSubsetOfAttributes( attList ) );
2803 
2804  QgsFeature f;
2805  QVariant currentValue;
2806  QHash<QString, QVariant> val;
2807  while ( fit.nextFeature( f ) )
2808  {
2809  currentValue = f.attribute( index );
2810  val.insert( currentValue.toString(), currentValue );
2811  if ( limit >= 0 && val.size() >= limit )
2812  {
2813  break;
2814  }
2815  }
2816 
2817  uniqueValues = val.values();
2818  return;
2819  }
2820 
2821  Q_ASSERT_X( false, "QgsVectorLayer::uniqueValues()", "Unknown source of the field!" );
2822 }
2823 
2825 {
2826  if ( !mDataProvider )
2827  {
2828  return QVariant();
2829  }
2830 
2832 
2833  if ( origin == QgsFields::OriginProvider ) //a provider field
2834  {
2835  return mDataProvider->minimumValue( index );
2836  }
2837  else if ( origin == QgsFields::OriginJoin )
2838  {
2839  int sourceLayerIndex;
2840  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2841  Q_ASSERT( join );
2842 
2844  Q_ASSERT( vl );
2845 
2846  return vl->minimumValue( sourceLayerIndex );
2847  }
2848  else if ( origin == QgsFields::OriginEdit )
2849  {
2850  // the layer is editable, but in certain cases it can still be avoided going through all features
2851  if ( mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mAddedFeatures.isEmpty() && !mEditBuffer->mDeletedAttributeIds.contains( index ) && mEditBuffer->mChangedAttributeValues.isEmpty() )
2852  {
2853  return mDataProvider->minimumValue( index );
2854  }
2855 
2856  // we need to go through each feature
2857  QgsAttributeList attList;
2858  attList << index;
2859 
2861  .setFlags( QgsFeatureRequest::NoGeometry )
2862  .setSubsetOfAttributes( attList ) );
2863 
2864  QgsFeature f;
2866  double currentValue = 0;
2867  while ( fit.nextFeature( f ) )
2868  {
2869  currentValue = f.attribute( index ).toDouble();
2870  if ( currentValue < minimumValue )
2871  {
2872  minimumValue = currentValue;
2873  }
2874  }
2875  return QVariant( minimumValue );
2876  }
2877 
2878  Q_ASSERT_X( false, "QgsVectorLayer::minimumValue()", "Unknown source of the field!" );
2879  return QVariant();
2880 }
2881 
2883 {
2884  if ( !mDataProvider )
2885  {
2886  return QVariant();
2887  }
2888 
2890 
2891  if ( origin == QgsFields::OriginProvider ) //a provider field
2892  {
2893  return mDataProvider->maximumValue( index );
2894  }
2895  else if ( origin == QgsFields::OriginJoin )
2896  {
2897  int sourceLayerIndex;
2898  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2899  Q_ASSERT( join );
2900 
2902  Q_ASSERT( vl );
2903 
2904  return vl->maximumValue( sourceLayerIndex );
2905  }
2906  else if ( origin == QgsFields::OriginEdit )
2907  {
2908  // the layer is editable, but in certain cases it can still be avoided going through all features
2909  if ( mEditBuffer->mDeletedFeatureIds.isEmpty() &&
2910  mEditBuffer->mAddedFeatures.isEmpty() &&
2911  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
2913  {
2914  return mDataProvider->maximumValue( index );
2915  }
2916 
2917  // we need to go through each feature
2918  QgsAttributeList attList;
2919  attList << index;
2920 
2922  .setFlags( QgsFeatureRequest::NoGeometry )
2923  .setSubsetOfAttributes( attList ) );
2924 
2925  QgsFeature f;
2927  double currentValue = 0;
2928  while ( fit.nextFeature( f ) )
2929  {
2930  currentValue = f.attribute( index ).toDouble();
2931  if ( currentValue > maximumValue )
2932  {
2933  maximumValue = currentValue;
2934  }
2935  }
2936  return QVariant( maximumValue );
2937  }
2938 
2939  Q_ASSERT_X( false, "QgsVectorLayer::maximumValue()", "Unknown source of the field!" );
2940  return QVariant();
2941 }
2942 
2944 void QgsVectorLayer::setFeatureBlendMode( const QPainter::CompositionMode &featureBlendMode )
2945 {
2947  emit featureBlendModeChanged( featureBlendMode );
2948 }
2949 
2951 QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
2952 {
2953  return mFeatureBlendMode;
2954 }
2955 
2957 void QgsVectorLayer::setLayerTransparency( int layerTransparency )
2958 {
2960  emit layerTransparencyChanged( layerTransparency );
2961 }
2962 
2965 {
2966  return mLayerTransparency;
2967 }
2968 
2969 
2970 
2971 void QgsVectorLayer::readSldLabeling( const QDomNode& node )
2972 {
2973  QDomElement element = node.toElement();
2974  if ( element.isNull() )
2975  return;
2976 
2977  QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
2978  if ( userStyleElem.isNull() )
2979  {
2980  QgsDebugMsg( "Info: UserStyle element not found." );
2981  return;
2982  }
2983 
2984  QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
2985  if ( featureTypeStyleElem.isNull() )
2986  {
2987  QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
2988  return;
2989  }
2990 
2991  // use last rule
2992  QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
2993  if ( ruleElem.isNull() )
2994  {
2995  QgsDebugMsg( "Info: Rule element not found." );
2996  return;
2997  }
2998 
2999  // use last text symbolizer
3000  QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3001  if ( textSymbolizerElem.isNull() )
3002  {
3003  QgsDebugMsg( "Info: TextSymbolizer element not found." );
3004  return;
3005  }
3006 
3007  // Label
3008  setCustomProperty( "labeling/enabled", false );
3009  QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3010  if ( !labelElem.isNull() )
3011  {
3012  QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3013  if ( !propertyNameElem.isNull() )
3014  {
3015  // enable labeling
3016  setCustomProperty( "labeling", "pal" );
3017  setCustomProperty( "labeling/enabled", true );
3018 
3019  // set labeling defaults
3020  setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3021  setCustomProperty( "labeling/fontItalic", false );
3022  setCustomProperty( "labeling/fontSize", 10 );
3023  setCustomProperty( "labeling/fontSizeInMapUnits", false );
3024  setCustomProperty( "labeling/fontBold", false );
3025  setCustomProperty( "labeling/fontUnderline", false );
3026  setCustomProperty( "labeling/textColorR", 0 );
3027  setCustomProperty( "labeling/textColorG", 0 );
3028  setCustomProperty( "labeling/textColorB", 0 );
3029  setCustomProperty( "labeling/textTransp", 0 );
3030  setCustomProperty( "labeling/bufferDraw", false );
3031  setCustomProperty( "labeling/bufferSize", 1 );
3032  setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3033  setCustomProperty( "labeling/bufferColorR", 255 );
3034  setCustomProperty( "labeling/bufferColorG", 255 );
3035  setCustomProperty( "labeling/bufferColorB", 255 );
3036  setCustomProperty( "labeling/bufferTransp", 0 );
3037  setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3038  setCustomProperty( "labeling/xOffset", 0 );
3039  setCustomProperty( "labeling/yOffset", 0 );
3040  setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3041  setCustomProperty( "labeling/angleOffset", 0 );
3042 
3043  // label attribute
3044  QString labelAttribute = propertyNameElem.text();
3045  setCustomProperty( "labeling/fieldName", labelAttribute );
3046  setCustomProperty( "labeling/isExpression", false );
3047 
3048  int fieldIndex = fieldNameIndex( labelAttribute );
3049  if ( fieldIndex == -1 )
3050  {
3051  // label attribute is not in columns, check if it is an expression
3052  QgsExpression exp( labelAttribute );
3053  if ( !exp.hasEvalError() )
3054  {
3055  setCustomProperty( "labeling/isExpression", true );
3056  }
3057  else
3058  {
3059  QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3060  }
3061  }
3062  }
3063  else
3064  {
3065  QgsDebugMsg( "Info: PropertyName element not found." );
3066  return;
3067  }
3068  }
3069  else
3070  {
3071  QgsDebugMsg( "Info: Label element not found." );
3072  return;
3073  }
3074 
3075  // Font
3076  QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3077  if ( !fontElem.isNull() )
3078  {
3079  QString cssName;
3080  QString elemText;
3081  QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3082  while ( !cssElem.isNull() )
3083  {
3084  cssName = cssElem.attribute( "name", "not_found" );
3085  if ( cssName != "not_found" )
3086  {
3087  elemText = cssElem.text();
3088  if ( cssName == "font-family" )
3089  {
3090  setCustomProperty( "labeling/fontFamily", elemText );
3091  }
3092  else if ( cssName == "font-style" )
3093  {
3094  setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3095  }
3096  else if ( cssName == "font-size" )
3097  {
3098  bool ok;
3099  int fontSize = elemText.toInt( &ok );
3100  if ( ok )
3101  {
3102  setCustomProperty( "labeling/fontSize", fontSize );
3103  }
3104  }
3105  else if ( cssName == "font-weight" )
3106  {
3107  setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3108  }
3109  else if ( cssName == "font-underline" )
3110  {
3111  setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3112  }
3113  }
3114 
3115  cssElem = cssElem.nextSiblingElement( "CssParameter" );
3116  }
3117  }
3118 
3119  // Fill
3120  QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3121  if ( textColor.isValid() )
3122  {
3123  setCustomProperty( "labeling/textColorR", textColor.red() );
3124  setCustomProperty( "labeling/textColorG", textColor.green() );
3125  setCustomProperty( "labeling/textColorB", textColor.blue() );
3126  setCustomProperty( "labeling/textTransp", 100 - ( int )( 100 * textColor.alphaF() ) );
3127  }
3128 
3129  // Halo
3130  QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3131  if ( !haloElem.isNull() )
3132  {
3133  setCustomProperty( "labeling/bufferDraw", true );
3134  setCustomProperty( "labeling/bufferSize", 1 );
3135 
3136  QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3137  if ( !radiusElem.isNull() )
3138  {
3139  bool ok;
3140  double bufferSize = radiusElem.text().toDouble( &ok );
3141  if ( ok )
3142  {
3143  setCustomProperty( "labeling/bufferSize", bufferSize );
3144  }
3145  }
3146 
3147  QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3148  if ( bufferColor.isValid() )
3149  {
3150  setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3151  setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3152  setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3153  setCustomProperty( "labeling/bufferTransp", 100 - ( int )( 100 * bufferColor.alphaF() ) );
3154  }
3155  }
3156 
3157  // LabelPlacement
3158  QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3159  if ( !labelPlacementElem.isNull() )
3160  {
3161  // PointPlacement
3162  QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3163  if ( !pointPlacementElem.isNull() )
3164  {
3165  setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3166 
3167  QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3168  if ( !displacementElem.isNull() )
3169  {
3170  QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3171  if ( !displacementXElem.isNull() )
3172  {
3173  bool ok;
3174  double xOffset = displacementXElem.text().toDouble( &ok );
3175  if ( ok )
3176  {
3177  setCustomProperty( "labeling/xOffset", xOffset );
3178  }
3179  }
3180  QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3181  if ( !displacementYElem.isNull() )
3182  {
3183  bool ok;
3184  double yOffset = displacementYElem.text().toDouble( &ok );
3185  if ( ok )
3186  {
3187  setCustomProperty( "labeling/yOffset", yOffset );
3188  }
3189  }
3190  }
3191 
3192  QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3193  if ( !rotationElem.isNull() )
3194  {
3195  bool ok;
3196  double rotation = rotationElem.text().toDouble( &ok );
3197  if ( ok )
3198  {
3199  setCustomProperty( "labeling/angleOffset", rotation );
3200  }
3201  }
3202  }
3203  }
3204 }
3205 
3207 {
3208  if ( !mDiagramLayerSettings )
3210  *mDiagramLayerSettings = s;
3211 }
3212 
3214 {
3215  QString myMetadata = "<html><body>";
3216 
3217  //-------------
3218 
3219  myMetadata += "<p class=\"subheaderglossy\">";
3220  myMetadata += tr( "General" );
3221  myMetadata += "</p>\n";
3222 
3223  // data comment
3224  if ( !( dataComment().isEmpty() ) )
3225  {
3226  myMetadata += "<p class=\"glossy\">" + tr( "Layer comment" ) + "</p>\n";
3227  myMetadata += "<p>";
3228  myMetadata += dataComment();
3229  myMetadata += "</p>\n";
3230  }
3231 
3232  //storage type
3233  myMetadata += "<p class=\"glossy\">" + tr( "Storage type of this layer" ) + "</p>\n";
3234  myMetadata += "<p>";
3235  myMetadata += storageType();
3236  myMetadata += "</p>\n";
3237 
3238  if ( dataProvider() )
3239  {
3240  //provider description
3241  myMetadata += "<p class=\"glossy\">" + tr( "Description of this provider" ) + "</p>\n";
3242  myMetadata += "<p>";
3243  myMetadata += dataProvider()->description().replace( "\n", "<br>" );
3244  myMetadata += "</p>\n";
3245  }
3246 
3247  // data source
3248  myMetadata += "<p class=\"glossy\">" + tr( "Source for this layer" ) + "</p>\n";
3249  myMetadata += "<p>";
3250  myMetadata += publicSource();
3251  myMetadata += "</p>\n";
3252 
3253  //geom type
3254 
3256 
3257  if ( type < 0 || type > QGis::NoGeometry )
3258  {
3259  QgsDebugMsg( "Invalid vector type" );
3260  }
3261  else
3262  {
3263  QString typeString( QGis::vectorGeometryType( geometryType() ) );
3264 
3265  myMetadata += "<p class=\"glossy\">" + tr( "Geometry type of the features in this layer" ) + "</p>\n";
3266  myMetadata += "<p>";
3267  myMetadata += typeString;
3268  myMetadata += "</p>\n";
3269  }
3270 
3272  if ( !pkAttrList.isEmpty() )
3273  {
3274  myMetadata += "<p class=\"glossy\">" + tr( "Primary key attributes" ) + "</p>\n";
3275  myMetadata += "<p>";
3276  foreach ( int idx, pkAttrList )
3277  {
3278  myMetadata += pendingFields()[ idx ].name() + " ";
3279  }
3280  myMetadata += "</p>\n";
3281  }
3282 
3283 
3284  //feature count
3285  myMetadata += "<p class=\"glossy\">" + tr( "The number of features in this layer" ) + "</p>\n";
3286  myMetadata += "<p>";
3287  myMetadata += QString::number( featureCount() );
3288  myMetadata += "</p>\n";
3289  //capabilities
3290  myMetadata += "<p class=\"glossy\">" + tr( "Editing capabilities of this layer" ) + "</p>\n";
3291  myMetadata += "<p>";
3292  myMetadata += capabilitiesString();
3293  myMetadata += "</p>\n";
3294 
3295  //-------------
3296 
3297  QgsRectangle myExtent = extent();
3298  myMetadata += "<p class=\"subheaderglossy\">";
3299  myMetadata += tr( "Extents" );
3300  myMetadata += "</p>\n";
3301 
3302  //extents in layer cs TODO...maybe make a little nested table to improve layout...
3303  myMetadata += "<p class=\"glossy\">" + tr( "In layer spatial reference system units" ) + "</p>\n";
3304  myMetadata += "<p>";
3305  // Try to be a bit clever over what number format we use for the
3306  // extents. Some people don't like it using scientific notation when the
3307  // numbers get large, but for small numbers this is the more practical
3308  // option (so we can't force the format to 'f' for all values).
3309  // The scheme:
3310  // - for all numbers with more than 5 digits, force non-scientific notation
3311  // and 2 digits after the decimal point.
3312  // - for all smaller numbers let the OS decide which format to use (it will
3313  // generally use non-scientific unless the number gets much less than 1).
3314 
3315  if ( !myExtent.isEmpty() )
3316  {
3317  QString xMin, yMin, xMax, yMax;
3318  double changeoverValue = 99999; // The 'largest' 5 digit number
3319  if ( qAbs( myExtent.xMinimum() ) > changeoverValue )
3320  {
3321  xMin = QString( "%1" ).arg( myExtent.xMinimum(), 0, 'f', 2 );
3322  }
3323  else
3324  {
3325  xMin = QString( "%1" ).arg( myExtent.xMinimum() );
3326  }
3327  if ( qAbs( myExtent.yMinimum() ) > changeoverValue )
3328  {
3329  yMin = QString( "%1" ).arg( myExtent.yMinimum(), 0, 'f', 2 );
3330  }
3331  else
3332  {
3333  yMin = QString( "%1" ).arg( myExtent.yMinimum() );
3334  }
3335  if ( qAbs( myExtent.xMaximum() ) > changeoverValue )
3336  {
3337  xMax = QString( "%1" ).arg( myExtent.xMaximum(), 0, 'f', 2 );
3338  }
3339  else
3340  {
3341  xMax = QString( "%1" ).arg( myExtent.xMaximum() );
3342  }
3343  if ( qAbs( myExtent.yMaximum() ) > changeoverValue )
3344  {
3345  yMax = QString( "%1" ).arg( myExtent.yMaximum(), 0, 'f', 2 );
3346  }
3347  else
3348  {
3349  yMax = QString( "%1" ).arg( myExtent.yMaximum() );
3350  }
3351 
3352  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3353  .arg( xMin ).arg( yMin ).arg( xMax ).arg( yMax );
3354  }
3355  else
3356  {
3357  myMetadata += tr( "unknown extent" );
3358  }
3359 
3360  myMetadata += "</p>\n";
3361 
3362  //extents in project cs
3363 
3364  try
3365  {
3366 #if 0
3367  // TODO: currently disabled, will revisit later [MD]
3368  QgsRectangle myProjectedExtent = coordinateTransform->transformBoundingBox( extent() );
3369  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3370  myMetadata += "<p>";
3371  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3372  .arg( myProjectedExtent.xMinimum() )
3373  .arg( myProjectedExtent.yMinimum() )
3374  .arg( myProjectedExtent.xMaximum() )
3375  .arg( myProjectedExtent.yMaximum() );
3376  myMetadata += "</p>\n";
3377 #endif
3378 
3379  //
3380  // Display layer spatial ref system
3381  //
3382  myMetadata += "<p class=\"glossy\">" + tr( "Layer Spatial Reference System" ) + "</p>\n";
3383  myMetadata += "<p>";
3384  myMetadata += crs().toProj4().replace( QRegExp( "\"" ), " \"" );
3385  myMetadata += "</p>\n";
3386 
3387  //
3388  // Display project (output) spatial ref system
3389  //
3390 #if 0
3391  // TODO: disabled for now, will revisit later [MD]
3392  //myMetadata += "<tr><td bgcolor=\"gray\">";
3393  myMetadata += "<p class=\"glossy\">" + tr( "Project (Output) Spatial Reference System" ) + "</p>\n";
3394  myMetadata += "<p>";
3395  myMetadata += coordinateTransform->destCRS().toProj4().replace( QRegExp( "\"" ), " \"" );
3396  myMetadata += "</p>\n";
3397 #endif
3398  }
3399  catch ( QgsCsException &cse )
3400  {
3401  Q_UNUSED( cse );
3402  QgsDebugMsg( cse.what() );
3403 
3404  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3405  myMetadata += "<p>";
3406  myMetadata += tr( "(Invalid transformation of layer extents)" );
3407  myMetadata += "</p>\n";
3408 
3409  }
3410 
3411 #if 0
3412  //
3413  // Add the info about each field in the attribute table
3414  //
3415  myMetadata += "<p class=\"glossy\">" + tr( "Attribute field info" ) + "</p>\n";
3416  myMetadata += "<p>";
3417 
3418  // Start a nested table in this trow
3419  myMetadata += "<table width=\"100%\">";
3420  myMetadata += "<tr><th>";
3421  myMetadata += tr( "Field" );
3422  myMetadata += "</th>";
3423  myMetadata += "<th>";
3424  myMetadata += tr( "Type" );
3425  myMetadata += "</th>";
3426  myMetadata += "<th>";
3427  myMetadata += tr( "Length" );
3428  myMetadata += "</th>";
3429  myMetadata += "<th>";
3430  myMetadata += tr( "Precision" );
3431  myMetadata += "</th>";
3432  myMetadata += "<th>";
3433  myMetadata += tr( "Comment" );
3434  myMetadata += "</th>";
3435 
3436  //get info for each field by looping through them
3437  const QgsFields& myFields = pendingFields();
3438  for ( int i = 0, n = myFields.size(); i < n; ++i )
3439  {
3440  const QgsField& myField = fields[i];
3441 
3442  myMetadata += "<tr><td>";
3443  myMetadata += myField.name();
3444  myMetadata += "</td>";
3445  myMetadata += "<td>";
3446  myMetadata += myField.typeName();
3447  myMetadata += "</td>";
3448  myMetadata += "<td>";
3449  myMetadata += QString( "%1" ).arg( myField.length() );
3450  myMetadata += "</td>";
3451  myMetadata += "<td>";
3452  myMetadata += QString( "%1" ).arg( myField.precision() );
3453  myMetadata += "</td>";
3454  myMetadata += "<td>";
3455  myMetadata += QString( "%1" ).arg( myField.comment() );
3456  myMetadata += "</td></tr>";
3457  }
3458 
3459  //close field list
3460  myMetadata += "</table>"; //end of nested table
3461 #endif
3462 
3463  myMetadata += "</body></html>";
3464  return myMetadata;
3465 }
3466 
3468 {
3469  mSymbolFeatureCounted = false;
3470 }
3471 
3473 {
3475  {
3477  {
3478  QgsAttributeEditorContainer* cont = dynamic_cast< QgsAttributeEditorContainer* >( elem );
3479  QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
3480  Q_FOREACH( QgsAttributeEditorElement* relElem, relations )
3481  {
3482  QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
3483  rel->init( QgsProject::instance()->relationManager() );
3484  }
3485  }
3486  }
3487 }
3488 
3490 {
3491  if ( editorWidgetV2( idx ) == "ValueRelation" )
3492  {
3494 
3495  return ValueRelationData( cfg.value( "Layer" ).toString(),
3496  cfg.value( "Key" ).toString(),
3497  cfg.value( "Value" ).toString(),
3498  cfg.value( "AllowNull" ).toBool(),
3499  cfg.value( "OrderByValue" ).toBool(),
3500  cfg.value( "AllowMulti" ).toBool(),
3501  cfg.value( "FilterExpression" ).toString()
3502  );
3503  }
3504  else
3505  {
3506  return ValueRelationData();
3507  }
3508 }
3509 
3510 QList<QgsRelation> QgsVectorLayer::referencingRelations( int idx )
3511 {
3512  return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
3513 }
3514 
3515 QList<QgsAttributeEditorElement*> &QgsVectorLayer::attributeEditorElements()
3516 {
3517  return mAttributeEditorElements;
3518 }
3519 
3521 {
3522  mAttributeEditorElements.clear();
3523 }
3524 
3525 QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
3526 {
3527  QDomElement elem = doc.createElement( "attributeEditorContainer" );
3528  elem.setAttribute( "name", mName );
3529 
3530  Q_FOREACH( QgsAttributeEditorElement* child, mChildren )
3531  {
3532  elem.appendChild( child->toDomElement( doc ) );
3533  }
3534  return elem;
3535 }
3536 
3538 {
3539  mChildren.append( widget );
3540 }
3541 
3543 {
3544  QList<QgsAttributeEditorElement*> results;
3545 
3546  Q_FOREACH( QgsAttributeEditorElement* elem, mChildren )
3547  {
3548  if ( elem->type() == type )
3549  {
3550  results.append( elem );
3551  }
3552 
3553  if ( elem->type() == AeTypeContainer )
3554  {
3555  QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
3556  results += cont->findElements( type );
3557  }
3558  }
3559 
3560  return results;
3561 }
3562 
3563 QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const
3564 {
3565  QDomElement elem = doc.createElement( "attributeEditorField" );
3566  elem.setAttribute( "name", mName );
3567  elem.setAttribute( "index", mIdx );
3568  return elem;
3569 }
3570 
3571 int QgsVectorLayer::listStylesInDatabase( QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError )
3572 {
3574  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3575  if ( !myLib )
3576  {
3577  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3578  return -1;
3579  }
3580  listStyles_t* listStylesExternalMethod = ( listStyles_t * ) cast_to_fptr( myLib->resolve( "listStyles" ) );
3581 
3582  if ( !listStylesExternalMethod )
3583  {
3584  delete myLib;
3585  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "listStyles" );
3586  return -1;
3587  }
3588 
3589  return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
3590 }
3591 
3592 QString QgsVectorLayer::getStyleFromDatabase( QString styleId, QString &msgError )
3593 {
3595  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3596  if ( !myLib )
3597  {
3598  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3599  return QObject::tr( "" );
3600  }
3601  getStyleById_t* getStyleByIdMethod = ( getStyleById_t * ) cast_to_fptr( myLib->resolve( "getStyleById" ) );
3602 
3603  if ( !getStyleByIdMethod )
3604  {
3605  delete myLib;
3606  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "getStyleById" );
3607  return QObject::tr( "" );
3608  }
3609 
3610  return getStyleByIdMethod( mDataSource, styleId, msgError );
3611 }
3612 
3613 
3614 void QgsVectorLayer::saveStyleToDatabase( QString name, QString description,
3615  bool useAsDefault, QString uiFileContent, QString &msgError )
3616 {
3617 
3618  QString sldStyle, qmlStyle;
3620  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3621  if ( !myLib )
3622  {
3623  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3624  return;
3625  }
3626  saveStyle_t* saveStyleExternalMethod = ( saveStyle_t * ) cast_to_fptr( myLib->resolve( "saveStyle" ) );
3627 
3628  if ( !saveStyleExternalMethod )
3629  {
3630  delete myLib;
3631  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "saveStyle" );
3632  return;
3633  }
3634 
3635  QDomDocument qmlDocument, sldDocument;
3636  this->exportNamedStyle( qmlDocument, msgError );
3637  if ( !msgError.isNull() )
3638  {
3639  return;
3640  }
3641  qmlStyle = qmlDocument.toString();
3642 
3643  this->exportSldStyle( sldDocument, msgError );
3644  if ( !msgError.isNull() )
3645  {
3646  return;
3647  }
3648  sldStyle = sldDocument.toString();
3649 
3650  saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
3651  description, uiFileContent, useAsDefault, msgError );
3652 }
3653 
3654 
3655 
3656 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag )
3657 {
3658  return loadNamedStyle( theURI, theResultFlag, false );
3659 }
3660 
3661 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag, bool loadFromLocalDB )
3662 {
3663  QgsDataSourceURI dsUri( theURI );
3664  if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
3665  {
3667  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3668  if ( myLib )
3669  {
3670  loadStyle_t* loadStyleExternalMethod = ( loadStyle_t * ) cast_to_fptr( myLib->resolve( "loadStyle" ) );
3671  if ( loadStyleExternalMethod )
3672  {
3673  QString qml, errorMsg;
3674  qml = loadStyleExternalMethod( mDataSource, errorMsg );
3675  if ( !qml.isEmpty() )
3676  {
3677  theResultFlag = this->applyNamedStyle( qml, errorMsg );
3678  return QObject::tr( "Loaded from Provider" );
3679  }
3680  }
3681  }
3682  }
3683 
3684  return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
3685 }
3686 
3687 bool QgsVectorLayer::applyNamedStyle( QString namedStyle, QString errorMsg )
3688 {
3689  QDomDocument myDocument( "qgis" );
3690  myDocument.setContent( namedStyle );
3691 
3692  QDomElement myRoot = myDocument.firstChildElement( "qgis" );
3693 
3694  if ( myRoot.isNull() )
3695  {
3696  errorMsg = tr( "Error: qgis element could not be found" );
3697  return false;
3698  }
3699  toggleScaleBasedVisibility( myRoot.attribute( "hasScaleBasedVisibilityFlag" ).toInt() == 1 );
3700  setMinimumScale( myRoot.attribute( "minimumScale" ).toFloat() );
3701  setMaximumScale( myRoot.attribute( "maximumScale" ).toFloat() );
3702 
3703 #if 0
3704  //read transparency level
3705  QDomNode transparencyNode = myRoot.namedItem( "transparencyLevelInt" );
3706  if ( ! transparencyNode.isNull() )
3707  {
3708  // set transparency level only if it's in project
3709  // (otherwise it sets the layer transparent)
3710  QDomElement myElement = transparencyNode.toElement();
3711  setTransparency( myElement.text().toInt() );
3712  }
3713 #endif
3714 
3715  return readSymbology( myRoot, errorMsg );
3716 }
3717 
3718 
3719 QDomElement QgsAttributeEditorRelation::toDomElement( QDomDocument& doc ) const
3720 {
3721  QDomElement elem = doc.createElement( "attributeEditorRelation" );
3722  elem.setAttribute( "name", mName );
3723  elem.setAttribute( "relation", mRelation.id() );
3724  return elem;
3725 }
3726 
3728 {
3729  mRelation = relationManager->relation( mRelationId );
3730  return mRelation.isValid();
3731 }
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:100
bool deleteVertex(QgsFeatureId atFeatureId, int atVertex)
Deletes a vertex from a feature.
virtual QString subsetString()
Get the string (typically sql) used to define a subset of the layer.
virtual QDomElement toDomElement(QDomDocument &doc) const
const QgsEditorWidgetConfig editorWidgetV2Config(int fieldIdx) const
Get the configuration for the editor widget used to represent the field at the given index...
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:89
void updateFields()
Assembles mUpdatedFields considering provider fields, joined fields and added fields.
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:58
EditorLayout mEditorLayout
Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated)
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
const QList< QgsVectorJoinInfo > & vectorJoins() const
int mWkbType
Geometry type as defined in enum WkbType (qgis.h)
Wrapper for iterator of features from vector data provider or vector layer.
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:323
bool isValid() const
Returns the validity of this relation.
void selectAll()
Select all the features.
QString database() const
bool intersects(const QgsRectangle &rect) const
returns true when rectangle intersects with other rectangle
QgsFeatureRendererV2 * rendererV2()
Return renderer V2.
#define RENDERER_TAG_NAME
Definition: qgsrendererv2.h:43
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 fieldEditable(int idx)
is edit widget editable
virtual QString getStyleFromDatabase(QString styleId, QString &msgError)
Will return the named style corresponding to style id provided.
virtual bool willRenderFeature(QgsFeature &feat)
return whether the renderer will render a feature or not.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:47
QSet< QString > mExcludeAttributesWFS
Attributes which are not published in WFS.
QgsVectorLayer::FeatureFormSuppress mFeatureFormSuppress
Type of feature form suppression after feature creation.
bool init(QgsRelationManager *relManager)
Initializes the relation from the id.
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
bool isEmpty() const
test if rectangle is empty.
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfield.h:169
float threshold() const
Gets the simplification threshold of the vector layer managed.
void clearAttributeEditorWidgets()
Clears all the tabs for the attribute editor form.
QgsFeatureList selectedFeatures()
Get a copy of the user-selected features.
QgsVectorDataProvider * mDataProvider
Pointer to data provider derived from the abastract base class QgsDataProvider.
QgsMapLayer::LayerType type() const
Get the type of the layer.
Definition: qgsmaplayer.cpp:86
bool addAttribute(const QgsField &field)
add an attribute field (but does not commit it) returns true if the field was added ...
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
int makeDifference(QgsGeometry *other)
Changes this geometry such that it does not intersect the other geometry.
EditorLayout editorLayout()
get the active layout for the attribute editor for this layer (added in 1.9)
GeometryType
Definition: qgis.h:155
virtual void saveStyleToDatabase(QString name, QString description, bool useAsDefault, QString uiFileContent, QString &msgError)
Save named and sld style of the layer to the style table in the db.
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.
QList< QgsSymbolV2 * > QgsSymbolV2List
Definition: qgsrendererv2.h:37
void removeJoin(const QString &joinLayerId)
Removes a vector layer join.
QString publicSource() const
void beforeRollBack()
Is emitted, before changes are rolled back.
bool addFeatures(QgsFeatureList &features)
Insert a copy of the given features into the layer (but does not commit it)
EditorLayout
The different types to layout the attribute editor.
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 setEditFormInit(QString function)
set python function for edit form initialization (added in 1.4)
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
QVariant maximumValue(int index)
Returns maximum value for an attribute column or invalid variant in case of error.
Renders the diagrams for all features with the same settings.
QString capabilitiesString() const
Returns the above in friendly format.
QMap< QString, QgsEditorWidgetConfig > mEditorWidgetV2Configs
Q_DECL_DEPRECATED int removePolygonIntersections(QgsGeometry *geom, QgsFeatureIds ignoreFeatures=QgsFeatureIds())
Changes the specified geometry such that it has no intersections with other polygon (or multipolygon)...
bool addFeature(QgsFeature &f)
Adds a feature.
static QgsProviderRegistry * instance(QString pluginPath=QString::null)
means of accessing canonical single instance
field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfield.h:170
void layerTransparencyChanged(int layerTransparency)
Signal emitted when setLayerTransparency() is called.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:194
bool deleteFeature(QgsFeatureId fid)
delete a feature from the layer (but does not commit it)
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
virtual QgsCoordinateReferenceSystem crs()=0
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:325
float maxScale() const
Definition: qgslabel.cpp:1397
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Returns unique values for column.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:330
void drawLabels(QgsRenderContext &rendererContext)
Draws the layer labels using coordinate transformation.
void beginEditCommand(QString text)
Create edit command for undo/redo operations.
QList< QgsAttributeEditorElement * > mAttributeEditorElements
Stores a list of attribute editor elements (Each holding a tree structure for a tab in the attribute ...
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name - case insensitive TODO: sort out case sensitive (indexFromName()) vs...
Definition: qgsfield.cpp:175
double rendererScale() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
virtual QDomElement save(QDomDocument &doc)
store renderer info to XML element
friend class QgsVectorLayerFeatureSource
void setForceLocalOptimization(bool localOptimization)
Sets where the simplification executes, after fetch the geometries from provider, or when supported...
QgsFeatureRendererV2 * mRendererV2
Renderer object which holds the information about how to display the features.
void invertSelectionInRectangle(QgsRectangle &rect)
Invert selection of features found within the search rectangle (in layer's coordinates) ...
bool commitChanges()
Attempts to commit any changes to disk.
void setRendererV2(QgsFeatureRendererV2 *r)
Set renderer V2.
void deleteCachedGeometries()
Deletes the geometries in mCachedGeometries.
Storage and management of actions associated with Qgis layer attributes.
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:112
virtual void setEncoding(const QString &e)
Set encoding used for accessing data from layer.
bool startEditing()
Make layer editable.
void setSimplifyHints(SimplifyHints simplifyHints)
Sets the simplification hints of the vector layer managed.
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
void setRendererScale(double scale)
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
VertexMarkerType
Editing vertex markers.
double closestSegmentWithContext(const QgsPoint &point, QgsPoint &minDistPoint, int &afterVertex, double *leftOf=0, double epsilon=DEFAULT_SEGMENT_EPSILON)
Searches for the closest segment of geometry to the given point.
void select(QgsRectangle &rect, bool addToSelection)
Select features found within the search rectangle (in layer's coordinates)
QgsVectorLayer::FeatureFormSuppress featureFormSuppress() const
Type of feature form pop-up suppression after feature creation (overrides app setting) ...
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:439
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:78
void renderLabel(QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0)
render label
Definition: qgslabel.cpp:72
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
return a list of item text / symbol
Q_DECL_DEPRECATED QString dateFormat(int idx)
Access date format.
SimplifyHint
Simplification flags for fast rendering of features.
bool deleteAttributes(QList< int > attrs)
Deletes a list of attribute fields (but does not commit it)
void addAttributeAlias(int attIndex, QString aliasString)
Sets an alias (a display name) for attributes to display in dialogs.
static const char * vectorGeometryType(GeometryType type)
description strings for geometry types
Definition: qgis.h:165
QString mDisplayExpression
the preview expression used to generate a human readable preview string for features ...
QGis::GeometryType type()
Returns type of the vector.
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
Q_DECL_DEPRECATED QMap< QString, QVariant > valueMap(int idx)
Access value map.
void readXml(const QDomNode &layer_node)
Reads joins from project file.
virtual void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Return unique values of an attribute.
virtual bool writeXml(QDomNode &layer_node, QDomDocument &doc)
write vector layer specific state to project file Dom node.
Container of fields for a vector layer.
Definition: qgsfield.h:161
void rollBack()
Stop editing and discard the edits.
const QgsRectangle & cachedGeometriesRect()
void setDiagramRenderer(QgsDiagramRendererV2 *r)
Sets diagram rendering object (takes ownership)
void setLayerTransparency(int layerTransparency)
Write transparency for layer.
ValueRelationData valueRelation(int idx)
Access value relation widget data.
bool readSld(const QDomNode &node, QString &errorMessage)
QgsChangedAttributesMap mChangedAttributeValues
Changed attributes values which are not commited.
WkbType
Used for symbology operations.
Definition: qgis.h:53
QMap< QString, bool > mFieldEditables
const QgsRectangle & extent() const
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
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:168
int addPart(const QList< QgsPoint > &ring, QgsFeatureId featureId)
Adds a new part polygon to a multipart feature.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
QList< QgsRelation > referencingRelations(int idx)
Get relations, where the foreign key is on this layer.
static const int EditingCapabilities
bitmask of all provider's editing capabilities
virtual ~QgsVectorLayer()
Destructor.
virtual QgsAttributeList pkAttributeIndexes()
Return list of indexes of fields that make up the primary key.
const QString displayExpression()
Get the preview expression, used to create a human readable preview string.
bool deleteVertex(QgsFeatureId atFeatureId, int atVertex)
Deletes a vertex from a feature.
void beforeCommitChanges()
Is emitted, before changes are commited to the data provider.
QStringList mCommitErrors
QgsPoint closestVertex(const QgsPoint &point, int &atVertex, int &beforeVertex, int &afterVertex, double &sqrDist)
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
QgsPoint vertexAt(int atVertex)
Returns coordinates of a vertex.
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
float minScale() const
Definition: qgslabel.cpp:1387
QVariant minimumValue(int index)
Returns minimum value for an attribute column or invalid variant in case of error.
bool insertVertex(double x, double y, QgsFeatureId atFeatureId, int beforeVertex)
Insert a new vertex before the given vertex number, in the given ring, item (first number is index 0)...
void featureDeleted(QgsFeatureId fid)
QString readPath(QString filename) const
turn filename read from the project file to an absolute path
void editCommandEnded()
Signal emitted, when an edit command successfully ended.
void setBlendMode(const QPainter::CompositionMode &blendMode)
Write blend mode for layer.
bool setDataProvider(QString const &provider)
bind layer to a specific data provider
void setMaximumScale(float theMaxScale)
Accessor and mutator for the maximum scale denominator member.
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
void invertSelection()
Select not selected features and deselect selected ones.
double x() const
Definition: qgspoint.h:110
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
virtual void updateExtents()
Update the extents for the layer.
Returns diagram settings for a feature.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
void removeSelection()
Clear selection.
Manages joined fields for a vector layer.
const QgsVectorJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
QString editForm()
get edit form (added in 1.4)
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints.
virtual void stopRender(QgsRenderContext &context)=0
void setEditorLayout(EditorLayout editorLayout)
set the active layout for the attribute editor for this layer (added in 1.9)
bool writeXML(QDomNode &layer_node, QDomDocument &doc) const
Writes the actions out in XML format.
QgsGeometryMap & cachedGeometries()
double ANALYSIS_EXPORT max(double x, double y)
returns the maximum of two doubles or the first argument if both are equal
bool containsJoins() const
Quick way to test if there is any join at all.
const QString & name() const
Get the display name of the layer.
void checkJoinLayerRemove(QString theLayerId)
Check if there is a join with a layer that will be removed.
QString mAnnotationForm
QgsRectangle extent()
Return the extent of the layer as a QRect.
virtual int listStylesInDatabase(QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError)
Lists all the style in db split into related to the layer and not related to.
SnappingType
Snap to vertex, to segment or both.
Definition: qgssnapper.h:66
QString encoding() const
Get encoding which is used for accessing data.
virtual void writeXML(QDomElement &layerElem, QDomDocument &doc, const QgsVectorLayer *layer) const =0
virtual QVariant maximumValue(int index)
Returns the maximum value of an attribute.
virtual QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext)
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.
QList< QgsAttributeEditorElement * > mChildren
void geometryChanged(QgsFeatureId fid, QgsGeometry &geom)
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
QPainter::CompositionMode blendMode() const
Read blend mode for layer.
bool simplifyDrawingCanbeApplied(const QgsRenderContext &renderContext, QgsVectorSimplifyMethod::SimplifyHint simplifyHint) const
Returns whether the VectorLayer can apply the specified simplification hint.
virtual void reload()
Synchronises with changes in the datasource.
void deselect(const QgsFeatureId featureId)
Deselect feature by its ID.
void layerDeleted()
QPainter::CompositionMode featureBlendMode() const
Read blend mode for layer.
bool writeSld(QDomNode &node, QDomDocument &doc, QString &errorMessage) const
bool rollBack(bool deleteBuffer=true)
Stop editing and discard the edits.
QgsGeometryCache * mCache
cache for some vector layer data - currently only geometries for faster editing
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:199
virtual bool setSubsetString(QString subset, bool updateFeatureCount=true)
Set the subset string used to create a subset of features in the layer.
QgsDataProvider * provider(const QString &providerKey, const QString &dataSource)
Create an instance of the provider.
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:184
QString attributeDisplayName(int attributeIndex) const
Convenience function that returns the attribute alias if defined or the field name else...
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
QString capabilitiesString() const
Capabilities for this layer in a friendly format.
QgsRelation relation(const QString &id) const
virtual QString dataComment() const
Return a short comment for the data that this provider is providing access to (e.g.
Represents the result of a snapping operation.
Definition: qgssnapper.h:36
void readXML(const QDomElement &elem, const QgsVectorLayer *layer)
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Q_DECL_DEPRECATED EditType editType(int idx)
Get edit type.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
int snapWithContext(const QgsPoint &startPoint, double snappingTolerance, QMultiMap< double, QgsSnappingResult > &snappingResults, QgsSnapper::SnappingType snap_to)
Snaps to segment or vertex within given tolerance.
const QString & id() const
The id.
const QString editorWidgetV2(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
virtual void setExtent(const QgsRectangle &rect)
Set the extent.
int addTopologicalPoints(QgsGeometry *geom)
Adds topological points for every vertex of the geometry.
void setScaleBasedVisibility(bool theVisibilityFlag)
Accessor and mutator for the scale based visilibility flag.
Definition: qgslabel.cpp:1372
void committedFeaturesAdded(const QString &layerId, const QgsFeatureList &addedFeatures)
virtual QDomElement toDomElement(QDomDocument &doc) const
int addPart(const QList< QgsPoint > &ring)
Adds a new part polygon to a multipart feature.
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.h:217
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.
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)...
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
virtual long featureCount() const =0
Number of features in the layer.
QgsVectorLayer(QString path=QString::null, QString baseName=QString::null, QString providerLib=QString::null, bool loadDefaultStyleFlag=true)
Constructor - creates a vector layer.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
int pendingFeatureCount()
returns feature count after commit
QList< int > QgsAttributeList
void readSldLabeling(const QDomNode &node)
Add joined attributes to a feature.
AttributeEditorType type() const
void destroyEditCommand()
Destroy active command and reverts all changes in it.
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, QVariant value, bool emitSignal)
Changes an attribute value (but does not commit it)
const QgsAttributes & attributes() const
Definition: qgsfeature.h:142
bool scaleBasedVisibility() const
Definition: qgslabel.cpp:1377
void writeCustomProperties(QDomNode &layerNode, QDomDocument &doc) const
Write custom properties to project file.
const QString displayField() const
Returns the primary display field name used in the identify results dialog.
int count() const
Return number of items.
Definition: qgsfield.h:195
bool setReadOnly(bool readonly=true)
Make layer read-only (editing disabled) or not.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
change feature's geometry
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
QString labelField(int attr) const
label field
Definition: qgslabel.cpp:499
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
int afterVertexNr
The index of the vertex after snappedVertex or -1 if no such vertex.
Definition: qgssnapper.h:52
QgsVectorSimplifyMethod mSimplifyMethod
Simplification object which holds the information about how to simplify the features for fast renderi...
QgsDiagramLayerSettings * mDiagramLayerSettings
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:31
void featureAdded(QgsFeatureId fid)
static QgsFeatureRendererV2 * defaultRenderer(QGis::GeometryType geomType)
return a new renderer - used by default in vector layers
void setFeatureBlendMode(const QPainter::CompositionMode &blendMode)
Write blend mode for features.
QMap< QgsSymbolV2 *, long > mSymbolFeatureCountMap
void rendererChanged()
Signal emitted when renderer is changed.
virtual QGis::WkbType geometryType() const =0
Get feature type.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
fast access to features using their ID
void readXML(const QDomNode &node)
Reads the renderer configuration from an XML file.
Definition: qgslabel.cpp:729
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:488
bool useRenderingOptimization() const
Returns true if the rendering optimization (geometry simplification) can be executed.
virtual bool readXml(const QDomNode &layer_node)
reads vector layer specific state from project file Dom node.
QMap< QString, int > fieldNameMap() const
Return a map where the key is the name of the field and the value is its index.
const QList< QgsVectorJoinInfo > & vectorJoins() const
void editingStarted()
Is emitted, when editing on this layer has started.
static void drawVertexMarker(double x, double y, QPainter &p, QgsVectorLayer::VertexMarkerType type, int vertexSize)
Draws a vertex symbol at (screen) coordinates x, y.
bool addFeatures(QgsFeatureList features, bool makeSelected=true)
Insert a copy of the given features into the layer (but does not commit it)
A class to represent a point geometry.
Definition: qgspoint.h:63
QList< QgsRelation > referencingRelations(QgsVectorLayer *layer=0, int fieldIdx=-2) const
void writeXML(QDomNode &label_node, QDomDocument &document) const
Writes the contents of the renderer to a configuration file.
Definition: qgslabel.cpp:1022
void removeJoin(const QString &joinLayerId)
Removes a vector layer join.
void endEditCommand()
Finish edit command and add it to undo/redo stack.
bool commitChanges(QStringList &commitErrors)
Attempts to commit any changes to disk.
int addRing(const QList< QgsPoint > &ring)
Adds a ring to polygon/multipolygon features.
QMap< QString, QString > mAttributeAliasMap
Map that stores the aliases for attributes.
bool deleteAttribute(int attr)
delete an attribute field (but does not commit it)
const QStringList & commitErrors()
bool labelOnTop(int idx)
label widget on top
void invalidateSymbolCountedFlag()
bool readSymbology(const QDomNode &node, QString &errorMessage)
Read the symbology for the current layer from the Dom node supplied.
QgsPoint beforeVertex
The layer coordinates of the vertex before snappedVertex.
Definition: qgssnapper.h:44
bool forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported...
QgsVectorLayerEditBuffer * mEditBuffer
stores information about uncommitted changes to layer
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
virtual QDomElement toDomElement(QDomDocument &doc) const
int addTopologicalPoints(QgsGeometry *geom)
Adds topological points for every vertex of the geometry.
void editCommandDestroyed()
Signal emitted, whan an edit command is destroyed.
void setX(double x)
Definition: qgspoint.h:87
bool isGeosEqual(QgsGeometry &)
compare geometries using GEOS
void setMaximumScale(float maximumScale)
Sets the maximum scale at which the layer should be simplified.
void setY(double y)
Definition: qgspoint.h:95
void setEditorWidgetV2Config(int attrIdx, const QgsEditorWidgetConfig &config)
Set the editor widget config for a field.
bool countSymbolFeatures(bool showProgress=true)
Count features for symbols.
A class to render labels.
Definition: qgslabel.h:51
A registry / canonical manager of data providers.
void setProviderEncoding(const QString &encoding)
Sets the textencoding of the data provider.
virtual bool isReadOnly() const
Returns true if the provider is in read-only mode.
virtual QString loadNamedStyle(const QString &theURI, bool &theResultFlag, bool loadFromLocalDb)
Load a named style from file/local db/datasource db.
QgsAttributeEditorElement * attributeEditorElementFromDomElement(QDomElement &elem, QObject *parent)
convert a saved attribute editor element into a AttributeEditor structure as it's used internally...
Implementation of threaded rendering for vector layers.
int layerTransparency() const
Read transparency for layer.
static Q_DECL_DEPRECATED const QString convertEditType(QgsVectorLayer::EditType editType, QgsEditorWidgetConfig &cfg, QgsVectorLayer *vl, const QString &name, const QDomElement editTypeElement=QDomElement())
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode Added in 1.9.
QLibrary * providerLibrary(const QString &providerKey) const
int snappedVertexNr
The vertex index of snappedVertex or -1 if no such vertex number (e.g.
Definition: qgssnapper.h:42
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:440
bool snapPoint(QgsPoint &point, double tolerance)
Snaps a point to the closest vertex if there is one within the snapping tolerance.
void setEditorWidgetV2(int attrIdx, const QString &widgetType)
Set the editor widget type for a field.
void addRequiredFields(QgsAttributeList &fields) const
add vector of required fields to existing list of fields
Definition: qgslabel.cpp:459
Q_DECL_DEPRECATED void setEditType(int idx, EditType edit)
Get edit type.
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)...
QString providerType() const
Return the provider type for this layer.
void featureBlendModeChanged(const QPainter::CompositionMode &blendMode)
Signal emitted when setFeatureBlendMode() is called.
QgsRectangle boundingBox()
Returns the bounding box of this feature.
QgsDiagramRendererV2 * mDiagramRenderer
QString what() const
Definition: qgsexception.h:35
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer.
virtual long featureCount() const
Number of features in the layer.
Q_DECL_DEPRECATED QSize widgetSize(int idx)
Access widget size for photo and webview widget.
Contains information about the context of a rendering operation.
void setMaxScale(float theMaxScale)
Accessor and mutator for the maximum scale member.
Definition: qgslabel.cpp:1392
int addRing(const QList< QgsPoint > &ring)
Adds a ring to polygon/multipolygon features.
QString mDisplayField
index of the primary label field
QString getStyleById_t(const QString &uri, QString styleID, QString &errCause)
virtual QDomElement toDomElement(QDomDocument &doc) const =0
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
QSet< QString > mExcludeAttributesWMS
Attributes which are not published in WMS.
void editCommandStarted(const QString &text)
Signal emitted when a new edit command has been started.
QString loadStyle_t(const QString &uri, QString &errCause)
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:230
QgsAttributeList pendingAllAttributesList()
returns list of attributes
virtual QgsRectangle extent()=0
Get the extent of the layer.
void setAnnotationForm(const QString &ui)
set annotation form for layer (added in 1.5)
QMap< QString, QString > mEditorWidgetV2Types
void setExtent(const QgsRectangle &rect)
Set the extent.
QString mDataSource
data source description string, varies by layer type
Definition: qgsmaplayer.h:491
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...
bool mLabelOn
Display labels.
QgsVectorLayerJoinBuffer * mJoinBuffer
bool draw(QgsRenderContext &rendererContext)
Draws the layer.
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:100
void setSelectedFeatures(const QgsFeatureIds &ids)
Change selection to the new set of features.
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat)
return list of symbols used for rendering the feature.
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves mVectorJoins to xml under the layer node.
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.h:215
This class manages a set of relations between layers.
static QgsFeatureRendererV2 * load(QDomElement &symbologyElem)
create a renderer from XML element
const QString & typeName() const
Gets the field type.
Definition: qgsfield.cpp:68
virtual bool setSubsetString(QString subset)
Set the string (typically sql) used to define a subset of the layer.
virtual void reloadData()
Reloads the data from the source.
void beforeModifiedCheck() const
Is emitted, when layer is checked for modifications.
virtual QVariant minimumValue(int index)
Returns the minimum value of an attribute.
void setEditForm(QString ui)
set edit form (added in 1.4)
Q_DECL_DEPRECATED RangeData range(int idx)
Access range widget config data.
virtual bool isValid()=0
Returns true if this is a valid layer.
void snapToGeometry(const QgsPoint &startPoint, QgsFeatureId featureId, QgsGeometry *geom, double sqrSnappingTolerance, QMultiMap< double, QgsSnappingResult > &snappingResults, QgsSnapper::SnappingType snap_to) const
Snaps to a geometry and adds the result to the multimap if it is within the snapping result...
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 attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &)
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:362
QgsPoint snappedVertex
The coordinates of the snapping result.
Definition: qgssnapper.h:39
Q_DECL_DEPRECATED void setCheckedState(int idx, QString checked, QString notChecked)
Set string representing 'true' for a checkbox (added in 1.4)
Class for storing a coordinate reference system (CRS)
void writeXML(QDomElement &layerElem, QDomDocument &doc, const QgsVectorLayer *layer) const
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:73
friend class QgsVectorLayerEditBuffer
QgsLabel * label()
Get the label object associated with this layer.
int size() const
Return number of items.
Definition: qgsfield.h:197
virtual QString description() const =0
return description
bool hasLabelsEnabled() const
Label is on.
QList< QgsAttributeEditorElement * > & attributeEditorElements()
Returns a list of tabs holding groups and fields.
virtual QDomElement writeSld(QDomDocument &doc, const QgsVectorLayer &layer) const
create the SLD UserStyle element following the SLD v1.1 specs
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
virtual void readXML(const QDomElement &elem, const QgsVectorLayer *layer)=0
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.
QMap< QString, bool > mLabelOnTop
const QString & comment() const
Returns the field comment.
Definition: qgsfield.cpp:83
void setFieldEditable(int idx, bool editable)
set edit widget editable
bool deleteFeature(QgsFeatureId fid)
delete a feature from the layer (but does not commit it)
QMap< QString, QVariant > QgsEditorWidgetConfig
Holds a set of configuration parameters for a editor widget wrapper.
qint64 QgsFeatureId
Definition: qgsfeature.h:30
static QColor colorFromOgcFill(const QDomElement &fillElement)
Parse XML with OGC fill into QColor.
bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant())
changed an attribute value (but does not commit it)
double y() const
Definition: qgspoint.h:118
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.
Definition: qgsmaplayer.cpp:98
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
int mLayerTransparency
Layer transparency.
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
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 ...
void(*)() cast_to_fptr(void *p)
Definition: qgis.h:301
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode Added in 1.9.
QgsLabel * mLabel
Label.
QString dataComment() const
Returns a comment for the data in the layer.
void setMinScale(float theMinScale)
Accessor and mutator for the minimum scale member.
Definition: qgslabel.cpp:1382
Custom exception class for Coordinate Reference System related exceptions.
QUndoStack * undoStack()
Return pointer to layer's undo stack.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
void setLabelOnTop(int idx, bool onTop)
label widget on top
QgsVectorDataProvider * dataProvider()
Returns the data provider.
virtual void addChildElement(QgsAttributeEditorElement *widget)
int splitParts(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
void normalize()
Normalize the rectangle so it has non-negative width/height.
QString editFormInit()
get python function for edit form initialization (added in 1.4)
float maximumScale() const
Gets the maximum scale at which the layer should be simplified.
bool nextFeature(QgsFeature &f)
FeatureFormSuppress
Types of feature form suppression after feature creation.
void setCoordinateSystem()
Setup the coordinate system tranformation 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.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QgsFields mUpdatedFields
field map to commit
QgsFeatureMap mAddedFeatures
New features which are not commited.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:204
QgsFeatureIds allFeatureIds()
Get all feature Ids.
QgsAttributeList pendingPkAttributesList()
returns list of attribute making up the primary key
virtual bool isEditable() const
Returns true if the provider is in editing mode.
QPainter::CompositionMode mFeatureBlendMode
Blend mode for features.
QString metadata()
Obtain Metadata for this layer.
static QgsFeatureRendererV2 * readOldRenderer(const QDomNode &layerNode, QGis::GeometryType geomType)
Read old renderer definition from XML and create matching new renderer.
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage) const
Write the symbology for the layer into the docment provided.
void updateFields(QgsFields &fields)
virtual QgsRectangle extent()
Return the extent of the layer.
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
bool addAttribute(const QgsField &field)
add an attribute field (but does not commit it) returns true if the field was added ...
bool isModified() const
Returns true if the provider has been modified since the last commit.
bool deleteSelectedFeatures()
Deletes the selected features.
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
Definition: qgsrendererv2.h:41
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.
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.
QgsFeatureRequest & setFlags(Flags flags)
Set flags that affect how features will be fetched.
QgsRelationManager * relationManager() const
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:189
bool mReadOnly
Flag indicating whether the layer is in read-only mode (editing disabled) or not. ...
QgsFeatureIds mSelectedFeatureIds
Set holding the feature IDs that are activated.
const QgsVectorLayer * layer
Layer where the snap occured.
Definition: qgssnapper.h:56
QString joinLayerId
Source layer.
void layerModified()
This signal is emitted when modifications has been done on layer.
QgsAttributeList mDeletedAttributeIds
deleted attributes fields which are not commited.
QString evalErrorString() const
Returns evaluation error.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:187
virtual bool applyNamedStyle(QString namedStyle, QString errorMsg)
bool readXML(const QDomNode &layer_node)
Reads the actions in in XML format.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
change feature's geometry
int beforeVertexNr
The index of the vertex before snappedVertex or -1 if no such vertex.
Definition: qgssnapper.h:47
void createJoinCaches()
Caches joined attributes if required (and not already done)
virtual void exportSldStyle(QDomDocument &doc, QString &errorMsg)
Export the properties of this layer as SLD style in a QDomDocument.
virtual QString dataSourceUri() const
Get the data source specification.
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
void setDisplayField(QString fldName="")
Set the primary display field to be used in the identify results dialog.
const CORE_EXPORT QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
Definition: qgis.cpp:71
QString mProviderKey
Data provider key.
void addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.
virtual QList< QgsAttributeEditorElement * > findElements(AttributeEditorType type) const
void toggleScaleBasedVisibility(bool theVisibilityFlag)
Accessor and mutator for the scale based visilibility flag.
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:209
QString toProj4() const
Get the Proj Proj4 string representation of this srs.
void enableLabels(bool on)
Set labels on.
void setMinimumScale(float theMinScale)
Accessor and mutator for the minimum scale denominator member.
void setThreshold(float threshold)
Sets the simplification threshold of the vector layer managed.
void addAttributeEditorWidget(QgsAttributeEditorElement *data)
Adds a tab (for the attribute editor form) holding groups and fields.
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)
QgsAttributeAction * mActions
The user-defined actions that are accessed from the Identify Results dialog box.
virtual bool render()
Do the rendering (based on data stored in the class)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
#define tr(sourceText)
int listStyles_t(const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause)
void addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.