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