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 
2050 {
2051  if ( attIndex < 0 || attIndex >= pendingFields().count() )
2052  return;
2053 
2054  QString name = pendingFields()[ attIndex ].name();
2055  if ( mAttributeAliasMap.contains( name ) )
2056  {
2057  mAttributeAliasMap.remove( name );
2058  emit layerModified();
2059  }
2060 }
2061 
2062 void QgsVectorLayer::addAttributeAlias( int attIndex, QString aliasString )
2063 {
2064  if ( attIndex < 0 || attIndex >= pendingFields().count() )
2065  return;
2066 
2067  QString name = pendingFields()[ attIndex ].name();
2068 
2069  mAttributeAliasMap.insert( name, aliasString );
2070  emit layerModified(); // TODO[MD]: should have a different signal?
2071 }
2072 
2074 {
2075  mAttributeEditorElements.append( data );
2076 }
2077 
2078 const QString QgsVectorLayer::editorWidgetV2( int fieldIdx ) const
2079 {
2080  return mEditorWidgetV2Types.value( mUpdatedFields[fieldIdx].name(), "TextEdit" );
2081 }
2082 
2083 const QString QgsVectorLayer::editorWidgetV2( const QString& fieldName ) const
2084 {
2085  return mEditorWidgetV2Types.value( fieldName, "TextEdit" );
2086 }
2087 
2089 {
2090  return mEditorWidgetV2Configs.value( mUpdatedFields[fieldIdx].name() );
2091 }
2092 
2093 const QgsEditorWidgetConfig QgsVectorLayer::editorWidgetV2Config( const QString& fieldName ) const
2094 {
2095  return mEditorWidgetV2Configs.value( fieldName );
2096 }
2097 
2098 QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
2099 {
2100  if ( attributeIndex < 0 || attributeIndex >= pendingFields().count() )
2101  return "";
2102 
2103  QString name = pendingFields()[ attributeIndex ].name();
2104 
2105  return mAttributeAliasMap.value( name, "" );
2106 }
2107 
2108 QString QgsVectorLayer::attributeDisplayName( int attributeIndex ) const
2109 {
2110  QString displayName = attributeAlias( attributeIndex );
2111  if ( displayName.isEmpty() )
2112  {
2113  const QgsFields& fields = pendingFields();
2114  if ( attributeIndex >= 0 && attributeIndex < fields.count() )
2115  {
2116  displayName = fields[attributeIndex].name();
2117  }
2118  }
2119  return displayName;
2120 }
2121 
2123 {
2124  if ( !mEditBuffer || !mDataProvider )
2125  return false;
2126 
2127  return mEditBuffer->deleteAttribute( index );
2128 }
2129 
2130 bool QgsVectorLayer::deleteAttributes( QList<int> attrs )
2131 {
2132  bool deleted = false;
2133 
2134  // Remove multiple occurences of same attribute
2135  attrs = attrs.toSet().toList();
2136 
2137  qSort( attrs.begin(), attrs.end(), qGreater<int>() );
2138 
2139  foreach ( int attr, attrs )
2140  {
2141  if ( deleteAttribute( attr ) )
2142  {
2143  deleted = true;
2144  }
2145  }
2146 
2147  return deleted;
2148 }
2149 
2151 {
2152  if ( !mEditBuffer )
2153  return false;
2154 
2155  bool res = mEditBuffer->deleteFeature( fid );
2156  if ( res )
2157  mSelectedFeatureIds.remove( fid ); // remove it from selection
2158 
2159  updateExtents();
2160 
2161  return res;
2162 }
2163 
2165 {
2166  return mUpdatedFields;
2167 }
2168 
2170 {
2172 }
2173 
2175 {
2176  QgsAttributeList pkAttributesList;
2177 
2178  QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
2179  for ( int i = 0; i < mUpdatedFields.count(); ++i )
2180  {
2182  providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
2183  pkAttributesList << i;
2184  }
2185 
2186  return pkAttributesList;
2187 }
2188 
2190 {
2191  return mDataProvider->featureCount() +
2193 }
2194 
2196 {
2197  mCommitErrors.clear();
2198 
2199  if ( !mDataProvider )
2200  {
2201  mCommitErrors << tr( "ERROR: no provider" );
2202  return false;
2203  }
2204 
2205  if ( !mEditBuffer )
2206  {
2207  mCommitErrors << tr( "ERROR: layer not editable" );
2208  return false;
2209  }
2210 
2211  emit beforeCommitChanges();
2212 
2213  bool success = mEditBuffer->commitChanges( mCommitErrors );
2214 
2215  if ( success )
2216  {
2217  delete mEditBuffer;
2218  mEditBuffer = 0;
2219  undoStack()->clear();
2220  emit editingStopped();
2221  }
2222  else
2223  {
2224  QgsMessageLog::logMessage( tr( "Commit errors:\n %1" ).arg( mCommitErrors.join( "\n " ) ) );
2225  }
2226 
2227  if ( mCache )
2228  {
2230  }
2231 
2232  updateFields();
2234 
2235  emit repaintRequested();
2236 
2237  return success;
2238 }
2239 
2240 const QStringList &QgsVectorLayer::commitErrors()
2241 {
2242  return mCommitErrors;
2243 }
2244 
2245 bool QgsVectorLayer::rollBack( bool deleteBuffer )
2246 {
2247  if ( !mEditBuffer )
2248  {
2249  return false;
2250  }
2251 
2252  emit beforeRollBack();
2253 
2254  mEditBuffer->rollBack();
2255 
2256  if ( isModified() )
2257  {
2258  // new undo stack roll back method
2259  // old method of calling every undo could cause many canvas refreshes
2260  undoStack()->setIndex( 0 );
2261  }
2262 
2263  updateFields();
2264 
2265  if ( deleteBuffer )
2266  {
2267  delete mEditBuffer;
2268  mEditBuffer = 0;
2269  undoStack()->clear();
2270  }
2271  emit editingStopped();
2272 
2273  if ( mCache )
2274  {
2276  }
2277 
2278  emit repaintRequested();
2279  return true;
2280 }
2281 
2283 {
2284  QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - ids;
2285 
2286  mSelectedFeatureIds = ids;
2287 
2288  emit selectionChanged( ids, deselectedFeatures, true );
2289 }
2290 
2292 {
2293  return mSelectedFeatureIds.size();
2294 }
2295 
2297 {
2298  return mSelectedFeatureIds;
2299 }
2300 
2301 
2303 {
2304  QgsFeatureList features;
2305 
2306  QgsFeatureRequest req;
2307  if ( geometryType() == QGis::NoGeometry )
2309 
2310  foreach ( QgsFeatureId fid, mSelectedFeatureIds )
2311  {
2312  features.push_back( QgsFeature() );
2313  getFeatures( req.setFilterFid( fid ) ).nextFeature( features.back() );
2314  }
2315 
2316  return features;
2317 }
2318 
2319 bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
2320 {
2321  if ( !mEditBuffer || !mDataProvider )
2322  return false;
2323 
2324  bool res = mEditBuffer->addFeatures( features );
2325 
2326  if ( makeSelected )
2327  {
2328  QgsFeatureIds ids;
2329 
2330  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
2331  ids << iter->id();
2332 
2333  setSelectedFeatures( ids );
2334  }
2335 
2336  updateExtents();
2337 
2338  return res;
2339 }
2340 
2341 
2342 bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
2343 {
2344  if ( !hasGeometryType() )
2345  return false;
2346 
2347  QMultiMap<double, QgsSnappingResult> snapResults;
2348  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
2349 
2350  if ( result != 0 )
2351  {
2352  return false;
2353  }
2354 
2355  if ( snapResults.size() < 1 )
2356  {
2357  return false;
2358  }
2359 
2360  QMultiMap<double, QgsSnappingResult>::const_iterator snap_it = snapResults.constBegin();
2361  point.setX( snap_it.value().snappedVertex.x() );
2362  point.setY( snap_it.value().snappedVertex.y() );
2363  return true;
2364 }
2365 
2366 
2367 int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snappingTolerance,
2368  QMultiMap<double, QgsSnappingResult>& snappingResults,
2369  QgsSnapper::SnappingType snap_to )
2370 {
2371  if ( !hasGeometryType() )
2372  return 1;
2373 
2374  if ( snappingTolerance <= 0 || !mDataProvider )
2375  {
2376  return 1;
2377  }
2378 
2379  QList<QgsFeature> featureList;
2380  QgsRectangle searchRect( startPoint.x() - snappingTolerance, startPoint.y() - snappingTolerance,
2381  startPoint.x() + snappingTolerance, startPoint.y() + snappingTolerance );
2382  double sqrSnappingTolerance = snappingTolerance * snappingTolerance;
2383 
2384  int n = 0;
2385  QgsFeature f;
2386 
2387  if ( mCache->cachedGeometriesRect().contains( searchRect ) )
2388  {
2389  QgsGeometryMap& cachedGeometries = mCache->cachedGeometries();
2390  for ( QgsGeometryMap::iterator it = cachedGeometries.begin(); it != cachedGeometries.end() ; ++it )
2391  {
2392  QgsGeometry* g = &( it.value() );
2393  if ( g->boundingBox().intersects( searchRect ) )
2394  {
2395  snapToGeometry( startPoint, it.key(), g, sqrSnappingTolerance, snappingResults, snap_to );
2396  ++n;
2397  }
2398  }
2399  }
2400  else
2401  {
2402  // snapping outside cached area
2403 
2405  .setFilterRect( searchRect )
2407  .setSubsetOfAttributes( QgsAttributeList() ) );
2408 
2409  while ( fit.nextFeature( f ) )
2410  {
2411  snapToGeometry( startPoint, f.id(), f.geometry(), sqrSnappingTolerance, snappingResults, snap_to );
2412  ++n;
2413  }
2414  }
2415 
2416  return n == 0 ? 2 : 0;
2417 }
2418 
2420  QgsFeatureId featureId,
2421  QgsGeometry* geom,
2422  double sqrSnappingTolerance,
2423  QMultiMap<double, QgsSnappingResult>& snappingResults,
2424  QgsSnapper::SnappingType snap_to ) const
2425 {
2426  if ( !geom )
2427  {
2428  return;
2429  }
2430 
2431  int atVertex, beforeVertex, afterVertex;
2432  double sqrDistVertexSnap, sqrDistSegmentSnap;
2433  QgsPoint snappedPoint;
2434  QgsSnappingResult snappingResultVertex;
2435  QgsSnappingResult snappingResultSegment;
2436 
2437  if ( snap_to == QgsSnapper::SnapToVertex || snap_to == QgsSnapper::SnapToVertexAndSegment )
2438  {
2439  snappedPoint = geom->closestVertex( startPoint, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
2440  if ( sqrDistVertexSnap < sqrSnappingTolerance )
2441  {
2442  snappingResultVertex.snappedVertex = snappedPoint;
2443  snappingResultVertex.snappedVertexNr = atVertex;
2444  snappingResultVertex.beforeVertexNr = beforeVertex;
2445  if ( beforeVertex != -1 ) // make sure the vertex is valid
2446  {
2447  snappingResultVertex.beforeVertex = geom->vertexAt( beforeVertex );
2448  }
2449  snappingResultVertex.afterVertexNr = afterVertex;
2450  if ( afterVertex != -1 ) // make sure the vertex is valid
2451  {
2452  snappingResultVertex.afterVertex = geom->vertexAt( afterVertex );
2453  }
2454  snappingResultVertex.snappedAtGeometry = featureId;
2455  snappingResultVertex.layer = this;
2456  snappingResults.insert( sqrt( sqrDistVertexSnap ), snappingResultVertex );
2457  return;
2458  }
2459  }
2460  if ( snap_to == QgsSnapper::SnapToSegment || snap_to == QgsSnapper::SnapToVertexAndSegment ) // snap to segment
2461  {
2462  if ( geometryType() != QGis::Point ) // cannot snap to segment for points/multipoints
2463  {
2464  sqrDistSegmentSnap = geom->closestSegmentWithContext( startPoint, snappedPoint, afterVertex, NULL, crs().geographicFlag() ? 1e-12 : 1e-8 );
2465 
2466  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
2467  {
2468  snappingResultSegment.snappedVertex = snappedPoint;
2469  snappingResultSegment.snappedVertexNr = -1;
2470  snappingResultSegment.beforeVertexNr = afterVertex - 1;
2471  snappingResultSegment.afterVertexNr = afterVertex;
2472  snappingResultSegment.snappedAtGeometry = featureId;
2473  snappingResultSegment.beforeVertex = geom->vertexAt( afterVertex - 1 );
2474  snappingResultSegment.afterVertex = geom->vertexAt( afterVertex );
2475  snappingResultSegment.layer = this;
2476  snappingResults.insert( sqrt( sqrDistSegmentSnap ), snappingResultSegment );
2477  }
2478  }
2479  }
2480 }
2481 
2482 int QgsVectorLayer::insertSegmentVerticesForSnap( const QList<QgsSnappingResult>& snapResults )
2483 {
2484  QgsVectorLayerEditUtils utils( this );
2485  return utils.insertSegmentVerticesForSnap( snapResults );
2486 }
2487 
2488 
2490 {
2491  QgsDebugMsg( "----- Computing Coordinate System" );
2492 
2493  //
2494  // Get the layers project info and set up the QgsCoordinateTransform
2495  // for this layer
2496  //
2497 
2498  if ( hasGeometryType() )
2499  {
2500  // get CRS directly from provider
2501  setCrs( mDataProvider->crs() );
2502  }
2503  else
2504  {
2506  }
2507 }
2508 
2509 
2510 const QString QgsVectorLayer::displayField() const
2511 {
2512  return mDisplayField;
2513 }
2514 
2515 void QgsVectorLayer::setDisplayExpression( const QString &displayExpression )
2516 {
2518 }
2519 
2521 {
2522  return mDisplayExpression;
2523 }
2524 
2526 {
2527  return ( mEditBuffer && mDataProvider );
2528 }
2529 
2531 {
2532  return mReadOnly;
2533 }
2534 
2535 bool QgsVectorLayer::setReadOnly( bool readonly )
2536 {
2537  // exit if the layer is in editing mode
2538  if ( readonly && mEditBuffer )
2539  return false;
2540 
2541  mReadOnly = readonly;
2542  return true;
2543 }
2544 
2546 {
2547  emit beforeModifiedCheck();
2548  return mEditBuffer && mEditBuffer->isModified();
2549 }
2550 
2552 {
2556 }
2557 
2559 {
2561 
2563  const QString widgetType = QgsLegacyHelpers::convertEditType( type, cfg, this, mUpdatedFields[idx].name() );
2565 
2566  setEditorWidgetV2( idx, widgetType );
2567  setEditorWidgetV2Config( idx, cfg );
2568 }
2569 
2571 {
2572  return mEditorLayout;
2573 }
2574 
2576 {
2578 }
2579 
2580 void QgsVectorLayer::setEditorWidgetV2( int attrIdx, const QString& widgetType )
2581 {
2582  mEditorWidgetV2Types[ mUpdatedFields[ attrIdx ].name()] = widgetType;
2583 }
2584 
2586 {
2587  mEditorWidgetV2Configs[ mUpdatedFields[ attrIdx ].name()] = config;
2588 }
2589 
2591 {
2592  return mEditForm;
2593 }
2594 
2596 {
2597  if ( ui.isEmpty() || ui.isNull() )
2598  {
2600  }
2601  else
2602  {
2604  }
2605  mEditForm = ui;
2606 }
2607 
2608 void QgsVectorLayer::setAnnotationForm( const QString& ui )
2609 {
2610  mAnnotationForm = ui;
2611 }
2612 
2614 {
2615  return mEditFormInit;
2616 }
2617 
2618 void QgsVectorLayer::setEditFormInit( QString function )
2619 {
2620  mEditFormInit = function;
2621 }
2622 
2623 QMap< QString, QVariant > QgsVectorLayer::valueMap( int idx )
2624 {
2625  return editorWidgetV2Config( idx );
2626 }
2627 
2629 {
2630  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2631  return RangeData(
2632  cfg.value( "Min" ),
2633  cfg.value( "Max" ),
2634  cfg.value( "Step" )
2635  );
2636 }
2637 
2638 QString QgsVectorLayer::dateFormat( int idx )
2639 {
2640  return editorWidgetV2Config( idx ).value( "DateFormat" ).toString();
2641 }
2642 
2644 {
2645  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2646  return QSize( cfg.value( "Width" ).toInt(), cfg.value( "Height" ).toInt() );
2647 }
2648 
2650 {
2651  const QgsFields &fields = pendingFields();
2652  if ( idx >= 0 && idx < fields.count() )
2653  {
2656  return false;
2657  return mFieldEditables.value( fields[idx].name(), true );
2658  }
2659  else
2660  return true;
2661 }
2662 
2664 {
2665  const QgsFields &fields = pendingFields();
2666  if ( idx >= 0 && idx < fields.count() )
2667  return mLabelOnTop.value( fields[idx].name(), false );
2668  else
2669  return false;
2670 }
2671 
2672 void QgsVectorLayer::setFieldEditable( int idx, bool editable )
2673 {
2674  const QgsFields &fields = pendingFields();
2675  if ( idx >= 0 && idx < fields.count() )
2676  mFieldEditables[ fields[idx].name()] = editable;
2677 }
2678 
2679 void QgsVectorLayer::setLabelOnTop( int idx, bool onTop )
2680 {
2681  const QgsFields &fields = pendingFields();
2682  if ( idx >= 0 && idx < fields.count() )
2683  mLabelOnTop[ fields[idx].name()] = onTop;
2684 }
2685 
2687 {
2688  return mRendererV2;
2689 }
2690 
2692 {
2693  if ( !hasGeometryType() )
2694  return;
2695 
2696  if ( r != mRendererV2 )
2697  {
2698  delete mRendererV2;
2699  mRendererV2 = r;
2700  mSymbolFeatureCounted = false;
2701  mSymbolFeatureCountMap.clear();
2702 
2703  emit rendererChanged();
2704  }
2705 }
2706 
2707 
2708 
2710 {
2711  undoStack()->beginMacro( text );
2712  emit editCommandStarted( text );
2713 }
2714 
2716 {
2717  undoStack()->endMacro();
2718  emit editCommandEnded();
2719 }
2720 
2722 {
2723  undoStack()->endMacro();
2724  undoStack()->undo();
2725  emit editCommandDestroyed();
2726 }
2727 
2728 
2729 void QgsVectorLayer::setCheckedState( int idx, QString checked, QString unchecked )
2730 {
2732  cfg["CheckedState"] = checked;
2733  cfg["UncheckedState"] = unchecked;
2734  setEditorWidgetV2Config( idx, cfg );
2735 }
2736 
2737 int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
2738 {
2739  return pendingFields().fieldNameIndex( fieldName );
2740 }
2741 
2743 {
2744  mJoinBuffer->addJoin( joinInfo );
2745  updateFields();
2746 }
2747 
2748 void QgsVectorLayer::checkJoinLayerRemove( QString theLayerId )
2749 {
2750  removeJoin( theLayerId );
2751 }
2752 
2753 void QgsVectorLayer::removeJoin( const QString& joinLayerId )
2754 {
2755  mJoinBuffer->removeJoin( joinLayerId );
2756  updateFields();
2757 }
2758 
2759 const QList< QgsVectorJoinInfo >& QgsVectorLayer::vectorJoins() const
2760 {
2761  return mJoinBuffer->vectorJoins();
2762 }
2763 
2764 void QgsVectorLayer::addExpressionField( const QString& exp, const QgsField& fld )
2765 {
2767  updateFields();
2768  int idx = mUpdatedFields.indexFromName( fld.name() );
2769  emit( attributeAdded( idx ) );
2770 }
2771 
2773 {
2774  int oi = mUpdatedFields.fieldOriginIndex( index );
2776  updateFields();
2777  emit( attributeDeleted( index ) );
2778 }
2779 
2781 {
2782  if ( !mDataProvider )
2783  return;
2784 
2786 
2787  // added / removed fields
2788  if ( mEditBuffer )
2790 
2791  // joined fields
2794 
2795  if ( mExpressionFieldBuffer )
2797 
2798  emit updatedFields();
2799 }
2800 
2801 
2803 {
2804  if ( mJoinBuffer->containsJoins() )
2805  {
2807  }
2808 }
2809 
2810 void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
2811 {
2812  uniqueValues.clear();
2813  if ( !mDataProvider )
2814  {
2815  return;
2816  }
2817 
2819 
2820  if ( origin == QgsFields::OriginProvider ) //a provider field
2821  {
2822  mDataProvider->uniqueValues( index, uniqueValues, limit );
2823 
2824  if ( mEditBuffer )
2825  {
2826  QSet<QString> vals;
2827  Q_FOREACH( const QVariant& v, uniqueValues )
2828  vals << v.toString();
2829 
2830  QMapIterator< QgsFeatureId, QgsAttributeMap > it ( mEditBuffer->changedAttributeValues() );
2831  while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
2832  {
2833  it.next();
2834  QVariant v = it.value().value( index );
2835  if ( v.isValid() )
2836  {
2837  QString vs = v.toString();
2838  if ( !vals.contains( vs ) )
2839  {
2840  vals << vs;
2841  uniqueValues << v;
2842  }
2843  }
2844  }
2845  }
2846 
2847  return;
2848  }
2849  else if ( origin == QgsFields::OriginJoin )
2850  {
2851  int sourceLayerIndex;
2852  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2853  Q_ASSERT( join );
2854 
2856  Q_ASSERT( vl );
2857 
2858  return vl->dataProvider()->uniqueValues( sourceLayerIndex, uniqueValues, limit );
2859  }
2860  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
2861  {
2862  // the layer is editable, but in certain cases it can still be avoided going through all features
2863  if ( origin == QgsFields::OriginEdit && mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mAddedFeatures.isEmpty() && !mEditBuffer->mDeletedAttributeIds.contains( index ) && mEditBuffer->mChangedAttributeValues.isEmpty() )
2864  {
2865  return mDataProvider->uniqueValues( index, uniqueValues, limit );
2866  }
2867 
2868  // we need to go through each feature
2869  QgsAttributeList attList;
2870  attList << index;
2871 
2873  .setFlags( QgsFeatureRequest::NoGeometry )
2874  .setSubsetOfAttributes( attList ) );
2875 
2876  QgsFeature f;
2877  QVariant currentValue;
2878  QHash<QString, QVariant> val;
2879  while ( fit.nextFeature( f ) )
2880  {
2881  currentValue = f.attribute( index );
2882  val.insert( currentValue.toString(), currentValue );
2883  if ( limit >= 0 && val.size() >= limit )
2884  {
2885  break;
2886  }
2887  }
2888 
2889  uniqueValues = val.values();
2890  return;
2891  }
2892 
2893  Q_ASSERT_X( false, "QgsVectorLayer::uniqueValues()", "Unknown source of the field!" );
2894 }
2895 
2897 {
2898  if ( !mDataProvider )
2899  {
2900  return QVariant();
2901  }
2902 
2904 
2905  if ( origin == QgsFields::OriginProvider ) //a provider field
2906  {
2907  return mDataProvider->minimumValue( index );
2908  }
2909  else if ( origin == QgsFields::OriginJoin )
2910  {
2911  int sourceLayerIndex;
2912  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2913  Q_ASSERT( join );
2914 
2916  Q_ASSERT( vl );
2917 
2918  return vl->minimumValue( sourceLayerIndex );
2919  }
2920  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
2921  {
2922  // the layer is editable, but in certain cases it can still be avoided going through all features
2923  if ( origin == QgsFields::OriginEdit &&
2924  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
2925  mEditBuffer->mAddedFeatures.isEmpty() && !
2926  mEditBuffer->mDeletedAttributeIds.contains( index ) &&
2928  {
2929  return mDataProvider->minimumValue( index );
2930  }
2931 
2932  // we need to go through each feature
2933  QgsAttributeList attList;
2934  attList << index;
2935 
2937  .setFlags( QgsFeatureRequest::NoGeometry )
2938  .setSubsetOfAttributes( attList ) );
2939 
2940  QgsFeature f;
2942  double currentValue = 0;
2943  while ( fit.nextFeature( f ) )
2944  {
2945  currentValue = f.attribute( index ).toDouble();
2946  if ( currentValue < minimumValue )
2947  {
2948  minimumValue = currentValue;
2949  }
2950  }
2951  return QVariant( minimumValue );
2952  }
2953 
2954  Q_ASSERT_X( false, "QgsVectorLayer::minimumValue()", "Unknown source of the field!" );
2955  return QVariant();
2956 }
2957 
2959 {
2960  if ( !mDataProvider )
2961  {
2962  return QVariant();
2963  }
2964 
2966 
2967  if ( origin == QgsFields::OriginProvider ) //a provider field
2968  {
2969  return mDataProvider->maximumValue( index );
2970  }
2971  else if ( origin == QgsFields::OriginJoin )
2972  {
2973  int sourceLayerIndex;
2974  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2975  Q_ASSERT( join );
2976 
2978  Q_ASSERT( vl );
2979 
2980  return vl->maximumValue( sourceLayerIndex );
2981  }
2982  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
2983  {
2984  // the layer is editable, but in certain cases it can still be avoided going through all features
2985  if ( origin == QgsFields::OriginEdit &&
2986  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
2987  mEditBuffer->mAddedFeatures.isEmpty() &&
2988  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
2990  {
2991  return mDataProvider->maximumValue( index );
2992  }
2993 
2994  // we need to go through each feature
2995  QgsAttributeList attList;
2996  attList << index;
2997 
2999  .setFlags( QgsFeatureRequest::NoGeometry )
3000  .setSubsetOfAttributes( attList ) );
3001 
3002  QgsFeature f;
3004  double currentValue = 0;
3005  while ( fit.nextFeature( f ) )
3006  {
3007  currentValue = f.attribute( index ).toDouble();
3008  if ( currentValue > maximumValue )
3009  {
3010  maximumValue = currentValue;
3011  }
3012  }
3013  return QVariant( maximumValue );
3014  }
3015 
3016  Q_ASSERT_X( false, "QgsVectorLayer::maximumValue()", "Unknown source of the field!" );
3017  return QVariant();
3018 }
3019 
3021 void QgsVectorLayer::setFeatureBlendMode( const QPainter::CompositionMode &featureBlendMode )
3022 {
3024  emit featureBlendModeChanged( featureBlendMode );
3025 }
3026 
3028 QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
3029 {
3030  return mFeatureBlendMode;
3031 }
3032 
3034 void QgsVectorLayer::setLayerTransparency( int layerTransparency )
3035 {
3037  emit layerTransparencyChanged( layerTransparency );
3038 }
3039 
3042 {
3043  return mLayerTransparency;
3044 }
3045 
3046 
3047 
3048 void QgsVectorLayer::readSldLabeling( const QDomNode& node )
3049 {
3050  QDomElement element = node.toElement();
3051  if ( element.isNull() )
3052  return;
3053 
3054  QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
3055  if ( userStyleElem.isNull() )
3056  {
3057  QgsDebugMsg( "Info: UserStyle element not found." );
3058  return;
3059  }
3060 
3061  QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
3062  if ( featureTypeStyleElem.isNull() )
3063  {
3064  QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
3065  return;
3066  }
3067 
3068  // use last rule
3069  QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
3070  if ( ruleElem.isNull() )
3071  {
3072  QgsDebugMsg( "Info: Rule element not found." );
3073  return;
3074  }
3075 
3076  // use last text symbolizer
3077  QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3078  if ( textSymbolizerElem.isNull() )
3079  {
3080  QgsDebugMsg( "Info: TextSymbolizer element not found." );
3081  return;
3082  }
3083 
3084  // Label
3085  setCustomProperty( "labeling/enabled", false );
3086  QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3087  if ( !labelElem.isNull() )
3088  {
3089  QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3090  if ( !propertyNameElem.isNull() )
3091  {
3092  // enable labeling
3093  setCustomProperty( "labeling", "pal" );
3094  setCustomProperty( "labeling/enabled", true );
3095 
3096  // set labeling defaults
3097  setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3098  setCustomProperty( "labeling/fontItalic", false );
3099  setCustomProperty( "labeling/fontSize", 10 );
3100  setCustomProperty( "labeling/fontSizeInMapUnits", false );
3101  setCustomProperty( "labeling/fontBold", false );
3102  setCustomProperty( "labeling/fontUnderline", false );
3103  setCustomProperty( "labeling/textColorR", 0 );
3104  setCustomProperty( "labeling/textColorG", 0 );
3105  setCustomProperty( "labeling/textColorB", 0 );
3106  setCustomProperty( "labeling/textTransp", 0 );
3107  setCustomProperty( "labeling/bufferDraw", false );
3108  setCustomProperty( "labeling/bufferSize", 1 );
3109  setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3110  setCustomProperty( "labeling/bufferColorR", 255 );
3111  setCustomProperty( "labeling/bufferColorG", 255 );
3112  setCustomProperty( "labeling/bufferColorB", 255 );
3113  setCustomProperty( "labeling/bufferTransp", 0 );
3114  setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3115  setCustomProperty( "labeling/xOffset", 0 );
3116  setCustomProperty( "labeling/yOffset", 0 );
3117  setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3118  setCustomProperty( "labeling/angleOffset", 0 );
3119 
3120  // label attribute
3121  QString labelAttribute = propertyNameElem.text();
3122  setCustomProperty( "labeling/fieldName", labelAttribute );
3123  setCustomProperty( "labeling/isExpression", false );
3124 
3125  int fieldIndex = fieldNameIndex( labelAttribute );
3126  if ( fieldIndex == -1 )
3127  {
3128  // label attribute is not in columns, check if it is an expression
3129  QgsExpression exp( labelAttribute );
3130  if ( !exp.hasEvalError() )
3131  {
3132  setCustomProperty( "labeling/isExpression", true );
3133  }
3134  else
3135  {
3136  QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3137  }
3138  }
3139  }
3140  else
3141  {
3142  QgsDebugMsg( "Info: PropertyName element not found." );
3143  return;
3144  }
3145  }
3146  else
3147  {
3148  QgsDebugMsg( "Info: Label element not found." );
3149  return;
3150  }
3151 
3152  // Font
3153  QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3154  if ( !fontElem.isNull() )
3155  {
3156  QString cssName;
3157  QString elemText;
3158  QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3159  while ( !cssElem.isNull() )
3160  {
3161  cssName = cssElem.attribute( "name", "not_found" );
3162  if ( cssName != "not_found" )
3163  {
3164  elemText = cssElem.text();
3165  if ( cssName == "font-family" )
3166  {
3167  setCustomProperty( "labeling/fontFamily", elemText );
3168  }
3169  else if ( cssName == "font-style" )
3170  {
3171  setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3172  }
3173  else if ( cssName == "font-size" )
3174  {
3175  bool ok;
3176  int fontSize = elemText.toInt( &ok );
3177  if ( ok )
3178  {
3179  setCustomProperty( "labeling/fontSize", fontSize );
3180  }
3181  }
3182  else if ( cssName == "font-weight" )
3183  {
3184  setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3185  }
3186  else if ( cssName == "font-underline" )
3187  {
3188  setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3189  }
3190  }
3191 
3192  cssElem = cssElem.nextSiblingElement( "CssParameter" );
3193  }
3194  }
3195 
3196  // Fill
3197  QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3198  if ( textColor.isValid() )
3199  {
3200  setCustomProperty( "labeling/textColorR", textColor.red() );
3201  setCustomProperty( "labeling/textColorG", textColor.green() );
3202  setCustomProperty( "labeling/textColorB", textColor.blue() );
3203  setCustomProperty( "labeling/textTransp", 100 - ( int )( 100 * textColor.alphaF() ) );
3204  }
3205 
3206  // Halo
3207  QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3208  if ( !haloElem.isNull() )
3209  {
3210  setCustomProperty( "labeling/bufferDraw", true );
3211  setCustomProperty( "labeling/bufferSize", 1 );
3212 
3213  QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3214  if ( !radiusElem.isNull() )
3215  {
3216  bool ok;
3217  double bufferSize = radiusElem.text().toDouble( &ok );
3218  if ( ok )
3219  {
3220  setCustomProperty( "labeling/bufferSize", bufferSize );
3221  }
3222  }
3223 
3224  QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3225  if ( bufferColor.isValid() )
3226  {
3227  setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3228  setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3229  setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3230  setCustomProperty( "labeling/bufferTransp", 100 - ( int )( 100 * bufferColor.alphaF() ) );
3231  }
3232  }
3233 
3234  // LabelPlacement
3235  QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3236  if ( !labelPlacementElem.isNull() )
3237  {
3238  // PointPlacement
3239  QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3240  if ( !pointPlacementElem.isNull() )
3241  {
3242  setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3243 
3244  QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3245  if ( !displacementElem.isNull() )
3246  {
3247  QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3248  if ( !displacementXElem.isNull() )
3249  {
3250  bool ok;
3251  double xOffset = displacementXElem.text().toDouble( &ok );
3252  if ( ok )
3253  {
3254  setCustomProperty( "labeling/xOffset", xOffset );
3255  }
3256  }
3257  QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3258  if ( !displacementYElem.isNull() )
3259  {
3260  bool ok;
3261  double yOffset = displacementYElem.text().toDouble( &ok );
3262  if ( ok )
3263  {
3264  setCustomProperty( "labeling/yOffset", yOffset );
3265  }
3266  }
3267  }
3268 
3269  QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3270  if ( !rotationElem.isNull() )
3271  {
3272  bool ok;
3273  double rotation = rotationElem.text().toDouble( &ok );
3274  if ( ok )
3275  {
3276  setCustomProperty( "labeling/angleOffset", rotation );
3277  }
3278  }
3279  }
3280  }
3281 }
3282 
3284 {
3285  if ( !mDiagramLayerSettings )
3287  *mDiagramLayerSettings = s;
3288 }
3289 
3291 {
3292  QString myMetadata = "<html><body>";
3293 
3294  //-------------
3295 
3296  myMetadata += "<p class=\"subheaderglossy\">";
3297  myMetadata += tr( "General" );
3298  myMetadata += "</p>\n";
3299 
3300  // data comment
3301  if ( !( dataComment().isEmpty() ) )
3302  {
3303  myMetadata += "<p class=\"glossy\">" + tr( "Layer comment" ) + "</p>\n";
3304  myMetadata += "<p>";
3305  myMetadata += dataComment();
3306  myMetadata += "</p>\n";
3307  }
3308 
3309  //storage type
3310  myMetadata += "<p class=\"glossy\">" + tr( "Storage type of this layer" ) + "</p>\n";
3311  myMetadata += "<p>";
3312  myMetadata += storageType();
3313  myMetadata += "</p>\n";
3314 
3315  if ( dataProvider() )
3316  {
3317  //provider description
3318  myMetadata += "<p class=\"glossy\">" + tr( "Description of this provider" ) + "</p>\n";
3319  myMetadata += "<p>";
3320  myMetadata += dataProvider()->description().replace( "\n", "<br>" );
3321  myMetadata += "</p>\n";
3322  }
3323 
3324  // data source
3325  myMetadata += "<p class=\"glossy\">" + tr( "Source for this layer" ) + "</p>\n";
3326  myMetadata += "<p>";
3327  myMetadata += publicSource();
3328  myMetadata += "</p>\n";
3329 
3330  //geom type
3331 
3333 
3334  if ( type < 0 || type > QGis::NoGeometry )
3335  {
3336  QgsDebugMsg( "Invalid vector type" );
3337  }
3338  else
3339  {
3340  QString typeString( QGis::vectorGeometryType( geometryType() ) );
3341 
3342  myMetadata += "<p class=\"glossy\">" + tr( "Geometry type of the features in this layer" ) + "</p>\n";
3343  myMetadata += "<p>";
3344  myMetadata += typeString;
3345  myMetadata += "</p>\n";
3346  }
3347 
3349  if ( !pkAttrList.isEmpty() )
3350  {
3351  myMetadata += "<p class=\"glossy\">" + tr( "Primary key attributes" ) + "</p>\n";
3352  myMetadata += "<p>";
3353  foreach ( int idx, pkAttrList )
3354  {
3355  myMetadata += pendingFields()[ idx ].name() + " ";
3356  }
3357  myMetadata += "</p>\n";
3358  }
3359 
3360 
3361  //feature count
3362  myMetadata += "<p class=\"glossy\">" + tr( "The number of features in this layer" ) + "</p>\n";
3363  myMetadata += "<p>";
3364  myMetadata += QString::number( featureCount() );
3365  myMetadata += "</p>\n";
3366  //capabilities
3367  myMetadata += "<p class=\"glossy\">" + tr( "Editing capabilities of this layer" ) + "</p>\n";
3368  myMetadata += "<p>";
3369  myMetadata += capabilitiesString();
3370  myMetadata += "</p>\n";
3371 
3372  //-------------
3373 
3374  QgsRectangle myExtent = extent();
3375  myMetadata += "<p class=\"subheaderglossy\">";
3376  myMetadata += tr( "Extents" );
3377  myMetadata += "</p>\n";
3378 
3379  //extents in layer cs TODO...maybe make a little nested table to improve layout...
3380  myMetadata += "<p class=\"glossy\">" + tr( "In layer spatial reference system units" ) + "</p>\n";
3381  myMetadata += "<p>";
3382  // Try to be a bit clever over what number format we use for the
3383  // extents. Some people don't like it using scientific notation when the
3384  // numbers get large, but for small numbers this is the more practical
3385  // option (so we can't force the format to 'f' for all values).
3386  // The scheme:
3387  // - for all numbers with more than 5 digits, force non-scientific notation
3388  // and 2 digits after the decimal point.
3389  // - for all smaller numbers let the OS decide which format to use (it will
3390  // generally use non-scientific unless the number gets much less than 1).
3391 
3392  if ( !myExtent.isEmpty() )
3393  {
3394  QString xMin, yMin, xMax, yMax;
3395  double changeoverValue = 99999; // The 'largest' 5 digit number
3396  if ( qAbs( myExtent.xMinimum() ) > changeoverValue )
3397  {
3398  xMin = QString( "%1" ).arg( myExtent.xMinimum(), 0, 'f', 2 );
3399  }
3400  else
3401  {
3402  xMin = QString( "%1" ).arg( myExtent.xMinimum() );
3403  }
3404  if ( qAbs( myExtent.yMinimum() ) > changeoverValue )
3405  {
3406  yMin = QString( "%1" ).arg( myExtent.yMinimum(), 0, 'f', 2 );
3407  }
3408  else
3409  {
3410  yMin = QString( "%1" ).arg( myExtent.yMinimum() );
3411  }
3412  if ( qAbs( myExtent.xMaximum() ) > changeoverValue )
3413  {
3414  xMax = QString( "%1" ).arg( myExtent.xMaximum(), 0, 'f', 2 );
3415  }
3416  else
3417  {
3418  xMax = QString( "%1" ).arg( myExtent.xMaximum() );
3419  }
3420  if ( qAbs( myExtent.yMaximum() ) > changeoverValue )
3421  {
3422  yMax = QString( "%1" ).arg( myExtent.yMaximum(), 0, 'f', 2 );
3423  }
3424  else
3425  {
3426  yMax = QString( "%1" ).arg( myExtent.yMaximum() );
3427  }
3428 
3429  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3430  .arg( xMin ).arg( yMin ).arg( xMax ).arg( yMax );
3431  }
3432  else
3433  {
3434  myMetadata += tr( "unknown extent" );
3435  }
3436 
3437  myMetadata += "</p>\n";
3438 
3439  //extents in project cs
3440 
3441  try
3442  {
3443 #if 0
3444  // TODO: currently disabled, will revisit later [MD]
3445  QgsRectangle myProjectedExtent = coordinateTransform->transformBoundingBox( extent() );
3446  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3447  myMetadata += "<p>";
3448  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3449  .arg( myProjectedExtent.xMinimum() )
3450  .arg( myProjectedExtent.yMinimum() )
3451  .arg( myProjectedExtent.xMaximum() )
3452  .arg( myProjectedExtent.yMaximum() );
3453  myMetadata += "</p>\n";
3454 #endif
3455 
3456  //
3457  // Display layer spatial ref system
3458  //
3459  myMetadata += "<p class=\"glossy\">" + tr( "Layer Spatial Reference System" ) + "</p>\n";
3460  myMetadata += "<p>";
3461  myMetadata += crs().toProj4().replace( QRegExp( "\"" ), " \"" );
3462  myMetadata += "</p>\n";
3463 
3464  //
3465  // Display project (output) spatial ref system
3466  //
3467 #if 0
3468  // TODO: disabled for now, will revisit later [MD]
3469  //myMetadata += "<tr><td bgcolor=\"gray\">";
3470  myMetadata += "<p class=\"glossy\">" + tr( "Project (Output) Spatial Reference System" ) + "</p>\n";
3471  myMetadata += "<p>";
3472  myMetadata += coordinateTransform->destCRS().toProj4().replace( QRegExp( "\"" ), " \"" );
3473  myMetadata += "</p>\n";
3474 #endif
3475  }
3476  catch ( QgsCsException &cse )
3477  {
3478  Q_UNUSED( cse );
3479  QgsDebugMsg( cse.what() );
3480 
3481  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3482  myMetadata += "<p>";
3483  myMetadata += tr( "(Invalid transformation of layer extents)" );
3484  myMetadata += "</p>\n";
3485 
3486  }
3487 
3488 #if 0
3489  //
3490  // Add the info about each field in the attribute table
3491  //
3492  myMetadata += "<p class=\"glossy\">" + tr( "Attribute field info" ) + "</p>\n";
3493  myMetadata += "<p>";
3494 
3495  // Start a nested table in this trow
3496  myMetadata += "<table width=\"100%\">";
3497  myMetadata += "<tr><th>";
3498  myMetadata += tr( "Field" );
3499  myMetadata += "</th>";
3500  myMetadata += "<th>";
3501  myMetadata += tr( "Type" );
3502  myMetadata += "</th>";
3503  myMetadata += "<th>";
3504  myMetadata += tr( "Length" );
3505  myMetadata += "</th>";
3506  myMetadata += "<th>";
3507  myMetadata += tr( "Precision" );
3508  myMetadata += "</th>";
3509  myMetadata += "<th>";
3510  myMetadata += tr( "Comment" );
3511  myMetadata += "</th>";
3512 
3513  //get info for each field by looping through them
3514  const QgsFields& myFields = pendingFields();
3515  for ( int i = 0, n = myFields.size(); i < n; ++i )
3516  {
3517  const QgsField& myField = fields[i];
3518 
3519  myMetadata += "<tr><td>";
3520  myMetadata += myField.name();
3521  myMetadata += "</td>";
3522  myMetadata += "<td>";
3523  myMetadata += myField.typeName();
3524  myMetadata += "</td>";
3525  myMetadata += "<td>";
3526  myMetadata += QString( "%1" ).arg( myField.length() );
3527  myMetadata += "</td>";
3528  myMetadata += "<td>";
3529  myMetadata += QString( "%1" ).arg( myField.precision() );
3530  myMetadata += "</td>";
3531  myMetadata += "<td>";
3532  myMetadata += QString( "%1" ).arg( myField.comment() );
3533  myMetadata += "</td></tr>";
3534  }
3535 
3536  //close field list
3537  myMetadata += "</table>"; //end of nested table
3538 #endif
3539 
3540  myMetadata += "</body></html>";
3541  return myMetadata;
3542 }
3543 
3545 {
3546  mSymbolFeatureCounted = false;
3547 }
3548 
3550 {
3552  {
3554  {
3555  QgsAttributeEditorContainer* cont = dynamic_cast< QgsAttributeEditorContainer* >( elem );
3556  QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
3557  Q_FOREACH( QgsAttributeEditorElement* relElem, relations )
3558  {
3559  QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
3560  rel->init( QgsProject::instance()->relationManager() );
3561  }
3562  }
3563  }
3564 }
3565 
3567 {
3568  if ( editorWidgetV2( idx ) == "ValueRelation" )
3569  {
3571 
3572  return ValueRelationData( cfg.value( "Layer" ).toString(),
3573  cfg.value( "Key" ).toString(),
3574  cfg.value( "Value" ).toString(),
3575  cfg.value( "AllowNull" ).toBool(),
3576  cfg.value( "OrderByValue" ).toBool(),
3577  cfg.value( "AllowMulti" ).toBool(),
3578  cfg.value( "FilterExpression" ).toString()
3579  );
3580  }
3581  else
3582  {
3583  return ValueRelationData();
3584  }
3585 }
3586 
3587 QList<QgsRelation> QgsVectorLayer::referencingRelations( int idx )
3588 {
3589  return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
3590 }
3591 
3592 QList<QgsAttributeEditorElement*> &QgsVectorLayer::attributeEditorElements()
3593 {
3594  return mAttributeEditorElements;
3595 }
3596 
3598 {
3599  mAttributeEditorElements.clear();
3600 }
3601 
3602 QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
3603 {
3604  QDomElement elem = doc.createElement( "attributeEditorContainer" );
3605  elem.setAttribute( "name", mName );
3606 
3607  Q_FOREACH( QgsAttributeEditorElement* child, mChildren )
3608  {
3609  elem.appendChild( child->toDomElement( doc ) );
3610  }
3611  return elem;
3612 }
3613 
3615 {
3616  mChildren.append( widget );
3617 }
3618 
3620 {
3621  QList<QgsAttributeEditorElement*> results;
3622 
3623  Q_FOREACH( QgsAttributeEditorElement* elem, mChildren )
3624  {
3625  if ( elem->type() == type )
3626  {
3627  results.append( elem );
3628  }
3629 
3630  if ( elem->type() == AeTypeContainer )
3631  {
3632  QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
3633  results += cont->findElements( type );
3634  }
3635  }
3636 
3637  return results;
3638 }
3639 
3640 QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const
3641 {
3642  QDomElement elem = doc.createElement( "attributeEditorField" );
3643  elem.setAttribute( "name", mName );
3644  elem.setAttribute( "index", mIdx );
3645  return elem;
3646 }
3647 
3648 int QgsVectorLayer::listStylesInDatabase( QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError )
3649 {
3651  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3652  if ( !myLib )
3653  {
3654  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3655  return -1;
3656  }
3657  listStyles_t* listStylesExternalMethod = ( listStyles_t * ) cast_to_fptr( myLib->resolve( "listStyles" ) );
3658 
3659  if ( !listStylesExternalMethod )
3660  {
3661  delete myLib;
3662  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "listStyles" );
3663  return -1;
3664  }
3665 
3666  return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
3667 }
3668 
3669 QString QgsVectorLayer::getStyleFromDatabase( QString styleId, QString &msgError )
3670 {
3672  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3673  if ( !myLib )
3674  {
3675  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3676  return QObject::tr( "" );
3677  }
3678  getStyleById_t* getStyleByIdMethod = ( getStyleById_t * ) cast_to_fptr( myLib->resolve( "getStyleById" ) );
3679 
3680  if ( !getStyleByIdMethod )
3681  {
3682  delete myLib;
3683  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "getStyleById" );
3684  return QObject::tr( "" );
3685  }
3686 
3687  return getStyleByIdMethod( mDataSource, styleId, msgError );
3688 }
3689 
3690 
3691 void QgsVectorLayer::saveStyleToDatabase( QString name, QString description,
3692  bool useAsDefault, QString uiFileContent, QString &msgError )
3693 {
3694 
3695  QString sldStyle, qmlStyle;
3697  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3698  if ( !myLib )
3699  {
3700  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3701  return;
3702  }
3703  saveStyle_t* saveStyleExternalMethod = ( saveStyle_t * ) cast_to_fptr( myLib->resolve( "saveStyle" ) );
3704 
3705  if ( !saveStyleExternalMethod )
3706  {
3707  delete myLib;
3708  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "saveStyle" );
3709  return;
3710  }
3711 
3712  QDomDocument qmlDocument, sldDocument;
3713  this->exportNamedStyle( qmlDocument, msgError );
3714  if ( !msgError.isNull() )
3715  {
3716  return;
3717  }
3718  qmlStyle = qmlDocument.toString();
3719 
3720  this->exportSldStyle( sldDocument, msgError );
3721  if ( !msgError.isNull() )
3722  {
3723  return;
3724  }
3725  sldStyle = sldDocument.toString();
3726 
3727  saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
3728  description, uiFileContent, useAsDefault, msgError );
3729 }
3730 
3731 
3732 
3733 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag )
3734 {
3735  return loadNamedStyle( theURI, theResultFlag, false );
3736 }
3737 
3738 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag, bool loadFromLocalDB )
3739 {
3740  QgsDataSourceURI dsUri( theURI );
3741  if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
3742  {
3744  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3745  if ( myLib )
3746  {
3747  loadStyle_t* loadStyleExternalMethod = ( loadStyle_t * ) cast_to_fptr( myLib->resolve( "loadStyle" ) );
3748  if ( loadStyleExternalMethod )
3749  {
3750  QString qml, errorMsg;
3751  qml = loadStyleExternalMethod( mDataSource, errorMsg );
3752  if ( !qml.isEmpty() )
3753  {
3754  theResultFlag = this->applyNamedStyle( qml, errorMsg );
3755  return QObject::tr( "Loaded from Provider" );
3756  }
3757  }
3758  }
3759  }
3760 
3761  return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
3762 }
3763 
3764 bool QgsVectorLayer::applyNamedStyle( QString namedStyle, QString errorMsg )
3765 {
3766  QDomDocument myDocument( "qgis" );
3767  myDocument.setContent( namedStyle );
3768 
3769  QDomElement myRoot = myDocument.firstChildElement( "qgis" );
3770 
3771  if ( myRoot.isNull() )
3772  {
3773  errorMsg = tr( "Error: qgis element could not be found" );
3774  return false;
3775  }
3776  toggleScaleBasedVisibility( myRoot.attribute( "hasScaleBasedVisibilityFlag" ).toInt() == 1 );
3777  setMinimumScale( myRoot.attribute( "minimumScale" ).toFloat() );
3778  setMaximumScale( myRoot.attribute( "maximumScale" ).toFloat() );
3779 
3780 #if 0
3781  //read transparency level
3782  QDomNode transparencyNode = myRoot.namedItem( "transparencyLevelInt" );
3783  if ( ! transparencyNode.isNull() )
3784  {
3785  // set transparency level only if it's in project
3786  // (otherwise it sets the layer transparent)
3787  QDomElement myElement = transparencyNode.toElement();
3788  setTransparency( myElement.text().toInt() );
3789  }
3790 #endif
3791 
3792  return readSymbology( myRoot, errorMsg );
3793 }
3794 
3795 
3796 QDomElement QgsAttributeEditorRelation::toDomElement( QDomDocument& doc ) const
3797 {
3798  QDomElement elem = doc.createElement( "attributeEditorRelation" );
3799  elem.setAttribute( "name", mName );
3800  elem.setAttribute( "relation", mRelation.id() );
3801  return elem;
3802 }
3803 
3805 {
3806  mRelation = relationManager->relation( mRelationId );
3807  return mRelation.isValid();
3808 }
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.
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
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 remAttributeAlias(int attIndex)
Removes an alias (a display name) for attributes to display in dialogs.
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
void triggerRepaint()
Will advice the map canvas (and any other interested party) that this layer requires to be repainted...
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.