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