1
/***************************************************************************
2
qgsvectorlayer.h - description
5
copyright : (C) 2003 by Gary E.Sherman
6
email : sherman at mrcc.com
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
19
#ifndef QGSVECTORLAYER_H
20
#define QGSVECTORLAYER_H
25
#include <QStringList>
28
#include "qgsmaplayer.h"
29
#include "qgsfeature.h"
30
#include "qgssnapper.h"
36
class QgsAttributeAction;
37
class QgsCoordinateTransform;
39
class QgsGeometryVertexIndex;
45
class QgsVectorDataProvider;
46
class QgsVectorOverlay;
50
class QgsFeatureRendererV2;
52
typedef QList<int> QgsAttributeList;
53
typedef QSet<int> QgsFeatureIds;
54
typedef QSet<int> QgsAttributeIds;
58
* Vector layer backed by a data source provider.
60
class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
74
CheckBox, /* added in 1.4 */
77
Immutable, /*The attribute value should not be changed in the attribute form*/
78
Hidden, /*The attribute value should not be shown in the attribute form @added in 1.4 */
79
TextEdit /*multiline edit @added in 1.4*/
85
RangeData( QVariant theMin, QVariant theMax, QVariant theStep )
86
: mMin( theMin ), mMax( theMax ), mStep( theStep ) {}
94
QgsVectorLayer( QString path = 0, QString baseName = 0,
95
QString providerLib = 0, bool loadDefaultStyleFlag = true );
98
virtual ~QgsVectorLayer();
100
/** Returns the permanent storage type for this layer as a friendly name. */
101
QString storageType() const;
103
/** Capabilities for this layer in a friendly format. */
104
QString capabilitiesString() const;
106
/** Returns a comment for the data in the layer */
107
QString dataComment() const;
109
/** Set the primary display field to be used in the identify results dialog */
110
void setDisplayField( QString fldName = 0 );
112
/** Returns the primary display field name used in the identify results dialog */
113
const QString displayField() const;
115
/** Returns the data provider */
116
QgsVectorDataProvider* dataProvider();
118
/** Returns the data provider in a const-correct manner */
119
const QgsVectorDataProvider* dataProvider() const;
121
/** Sets the textencoding of the data provider */
122
void setProviderEncoding( const QString& encoding );
124
/** Setup the coordinate system tranformation for the layer */
125
void setCoordinateSystem();
127
/** Get the label object associated with this layer */
130
const QgsLabel *label() const;
132
QgsAttributeAction* actions() { return mActions; }
134
/** The number of features that are selected in this layer */
135
int selectedFeatureCount();
137
/** Select features found within the search rectangle (in layer's coordinates) */
138
void select( QgsRectangle & rect, bool lock );
140
/** Select not selected features and deselect selected ones */
141
void invertSelection();
143
/** Invert selection of features found within the search rectangle (in layer's coordinates) */
144
void invertSelectionInRectangle( QgsRectangle & rect );
146
/** Get a copy of the user-selected features */
147
QgsFeatureList selectedFeatures();
149
/** Return reference to identifiers of selected features */
150
const QgsFeatureIds& selectedFeaturesIds() const;
152
/** Change selection to the new set of features */
153
void setSelectedFeatures( const QgsFeatureIds& ids );
155
/** Returns the bounding box of the selected features. If there is no selection, QgsRectangle(0,0,0,0) is returned */
156
QgsRectangle boundingBoxOfSelected();
158
/** Copies the symbology settings from another layer. Returns true in case of success */
159
bool copySymbologySettings( const QgsMapLayer& other );
161
/** Returns true if this layer can be in the same symbology group with another layer */
162
bool hasCompatibleSymbology( const QgsMapLayer& other ) const;
164
/** Returns a pointer to the renderer */
165
const QgsRenderer* renderer() const;
167
/** Sets the renderer. If a renderer is already present, it is deleted */
168
void setRenderer( QgsRenderer * r );
170
/** Return renderer V2. Added in QGIS 1.4 */
171
QgsFeatureRendererV2* rendererV2();
172
/** Set renderer V2. Added in QGIS 1.4 */
173
void setRendererV2( QgsFeatureRendererV2* r );
174
/** Return whether using renderer V2. Added in QGIS 1.4 */
175
bool isUsingRendererV2();
176
/** set whether to use renderer V2 for drawing. Added in QGIS 1.4 */
177
void setUsingRendererV2( bool usingRendererV2 );
179
/** Draw layer with renderer V2. Added in QGIS 1.4 */
180
void drawRendererV2( QgsRenderContext& rendererContext, bool labeling );
181
/** Draw layer with renderer V2 using symbol levels. Added in QGIS 1.4 */
182
void drawRendererV2Levels( QgsRenderContext& rendererContext, bool labeling );
184
/** Returns point, line or polygon */
185
QGis::GeometryType geometryType() const;
187
/**Returns the WKBType or WKBUnknown in case of error*/
188
QGis::WkbType wkbType() const;
190
/** Return the provider type for this layer */
191
QString providerType() const;
193
/** reads vector layer specific state from project file Dom node.
194
* @note Called by QgsMapLayer::readXML().
196
virtual bool readXml( QDomNode & layer_node );
198
/** write vector layer specific state to project file Dom node.
199
* @note Called by QgsMapLayer::writeXML().
201
virtual bool writeXml( QDomNode & layer_node, QDomDocument & doc );
203
/** Read the symbology for the current layer from the Dom node supplied.
204
* @param QDomNode node that will contain the symbology definition for this layer.
205
* @param errorMessage reference to string that will be updated with any error messages
206
* @return true in case of success.
208
bool readSymbology( const QDomNode& node, QString& errorMessage );
210
/** Write the symbology for the layer into the docment provided.
211
* @param QDomNode the node that will have the style element added to it.
212
* @param QDomDocument the document that will have the QDomNode added.
213
* @param errorMessage reference to string that will be updated with any error messages
214
* @return true in case of success.
216
bool writeSymbology( QDomNode&, QDomDocument& doc, QString& errorMessage ) const;
220
* Number of features in the layer. This is necessary if features are
221
* added/deleted or the layer has been subsetted. If the data provider
222
* chooses not to support this feature, the total number of features
224
* @return long containing number of features
226
virtual long featureCount() const;
228
/** Update the feature count
229
* @return long containing the number of features in the datasource
231
virtual long updateFeatureCount() const;
234
* Set the string (typically sql) used to define a subset of the layer
235
* @param subset The subset string. This may be the where clause of a sql statement
236
* or other defintion string specific to the underlying dataprovider
238
* @return true, when setting the subset string was successful, false otherwise (added in 1.4)
240
virtual bool setSubsetString( QString subset );
243
* Get the string (typically sql) used to define a subset of the layer
244
* @return The subset string or QString::null if not implemented by the provider
246
virtual QString subsetString();
248
void select( QgsAttributeList fetchAttributes,
249
QgsRectangle rect = QgsRectangle(),
250
bool fetchGeometry = true,
251
bool useIntersect = false );
253
bool nextFeature( QgsFeature& feature );
255
/**Gets the feature at the given feature id. Considers the changed, added, deleted and permanent features
256
@return true in case of success*/
257
bool featureAtId( int featureId, QgsFeature &f, bool fetchGeometries = true, bool fetchAttributes = true );
260
@param lastFeatureInBatch If True, will also go to the effort of e.g. updating the extents.
261
@return True in case of success and False in case of error
263
bool addFeature( QgsFeature& f, bool alsoUpdateExtent = TRUE );
266
/** Insert a new vertex before the given vertex number,
267
* in the given ring, item (first number is index 0), and feature
268
* Not meaningful for Point geometries
270
bool insertVertex( double x, double y, int atFeatureId, int beforeVertex );
272
/** Moves the vertex at the given position number,
273
* ring and item (first number is index 0), and feature
274
* to the given coordinates
276
bool moveVertex( double x, double y, int atFeatureId, int atVertex );
278
/** Deletes a vertex from a feature
280
bool deleteVertex( int atFeatureId, int atVertex );
282
/** Deletes the selected features
283
* @return true in case of success and false otherwise
285
bool deleteSelectedFeatures();
287
/**Adds a ring to polygon/multipolygon features
289
0 in case of success,
290
1 problem with feature type,
293
4 ring crosses existing rings,
294
5 no feature found where ring can be inserted*/
295
int addRing( const QList<QgsPoint>& ring );
297
/**Adds a new island polygon to a multipolygon feature
299
0 in case of success,
300
1 if selected feature is not multipolygon,
301
2 if ring is not a valid geometry,
302
3 if new polygon ring not disjoint with existing rings,
303
4 if no feature was selected,
304
5 if several features are selected,
305
6 if selected geometry not found*/
306
int addIsland( const QList<QgsPoint>& ring );
308
/**Translates feature by dx, dy
309
@param featureId id of the feature to translate
310
@param dx translation of x-coordinate
311
@param dy translation of y-coordinate
312
@return 0 in case of success*/
313
int translateFeature( int featureId, double dx, double dy );
315
/**Splits features cut by the given line
316
@param splitLine line that splits the layer features
317
@param topologicalEditing true if topological editing is enabled
318
@return 0 in case of success, 4 if there is a selection but no feature split*/
319
int splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing = false );
321
/**Changes the specified geometry such that it has no intersections with other
322
polygon (or multipolygon) geometries in this vector layer
323
@param geom geometry to modify
324
@return 0 in case of success*/
325
int removePolygonIntersections( QgsGeometry* geom );
327
/**Adds topological points for every vertex of the
329
@param geom the geometry where each vertex is added to segments of other features
330
Note: geom is not going to be modified by the function
331
@return 0 in case of success*/
332
int addTopologicalPoints( QgsGeometry* geom );
334
/**Adds a vertex to segments which intersect point p but don't
335
already have a vertex there. If a feature already has a vertex at position p,
336
no additional vertex is inserted. This method is useful for topological
338
@param p position of the vertex
339
@return 0 in case of success*/
340
int addTopologicalPoints( const QgsPoint& p );
342
/**Inserts vertices to the snapped segments.
343
This is useful for topological editing if snap to segment is enabled.
344
@param snapResults results collected from the snapping operation
345
@return 0 in case of success*/
346
int insertSegmentVerticesForSnap( const QList<QgsSnappingResult>& snapResults );
349
void enableLabels( bool on );
352
bool hasLabelsEnabled( void ) const;
354
/** Returns true if the provider is in editing mode */
355
virtual bool isEditable() const;
357
/** Returns true if the provider has been modified since the last commit */
358
virtual bool isModified() const;
360
/**Snaps a point to the closest vertex if there is one within the snapping tolerance
361
@param point The point which is set to the position of a vertex if there is one within the snapping tolerance.
362
If there is no point within this tolerance, point is left unchanged.
363
@param tolerance The snapping tolerance
364
@return true if point has been snapped, false if no vertex within search tolerance*/
365
bool snapPoint( QgsPoint& point, double tolerance );
367
/**Snaps to segment or vertex within given tolerance
368
@param startPoint point to snap (in layer coordinates)
369
@param snappingTolerance distance tolerance for snapping
370
@param snappingResults snapping results. Key is the distance between startPoint and snapping target
371
@param snap_to to segment / to vertex
372
@return 0 in case of success
374
int snapWithContext( const QgsPoint& startPoint,
375
double snappingTolerance,
377
QgsSnappingResult > & snappingResults,
378
QgsSnapper::SnappingType snap_to );
381
* @return FALSE if an error occurred during drawing
383
bool draw( QgsRenderContext& rendererContext );
385
/** Draws the layer labels using coordinate transformation */
386
void drawLabels( QgsRenderContext& rendererContext );
388
/** returns field list in the to-be-committed state */
389
const QgsFieldMap &pendingFields() const;
391
/** returns list of attributes */
392
QgsAttributeList pendingAllAttributesList();
394
/** returns feature count after commit */
395
int pendingFeatureCount();
397
/** Sets whether some features are modified or not */
398
void setModified( bool modified = TRUE, bool onlyGeometryWasModified = FALSE );
400
/** Make layer editable */
403
/** change feature's geometry
404
@note added in version 1.2 */
405
bool changeGeometry( int fid, QgsGeometry* geom );
407
/** changed an attribute value (but does not commit it) */
408
bool changeAttributeValue( int fid, int field, QVariant value, bool emitSignal = true );
410
/** add an attribute field (but does not commit it)
411
returns true if the field was added
412
@note added in version 1.2 */
413
bool addAttribute( const QgsField &field );
415
/** add an attribute field (but does not commit it)
416
returns true if the field was added
418
bool addAttribute( QString name, QString type );
420
/**Sets an alias (a display name) for attributes to display in dialogs
421
@note added in version 1.2*/
422
void addAttributeAlias( int attIndex, QString aliasString );
424
/**Returns the alias of an attribute name or an empty string if there is no alias
425
@note added in version 1.2*/
426
QString attributeAlias( int attributeIndex ) const;
428
/**Convenience function that returns the attribute alias if defined or the field name else
429
@note added in version 1.2*/
430
QString attributeDisplayName( int attributeIndex ) const;
432
/** delete an attribute field (but does not commit it) */
433
bool deleteAttribute( int attr );
435
/** Insert a copy of the given features into the layer (but does not commit it) */
436
bool addFeatures( QgsFeatureList features, bool makeSelected = TRUE );
438
/** delete a feature from the layer (but does not commit it) */
439
bool deleteFeature( int fid );
442
Attempts to commit any changes to disk. Returns the result of the attempt.
443
If a commit fails, the in-memory changes are left alone.
445
This allows editing to continue if the commit failed on e.g. a
446
disallowed value in a Postgres database - the user can re-edit and try
449
The commits occur in distinct stages,
450
(add attributes, add features, change attribute values, change
451
geometries, delete features, delete attributes)
452
so if a stage fails, it's difficult to roll back cleanly.
453
Therefore any error message also includes which stage failed so
454
that the user has some chance of repairing the damage cleanly.
456
bool commitChanges();
457
const QStringList &commitErrors();
459
/** Stop editing and discard the edits */
463
EditType editType( int idx );
466
void setEditType( int idx, EditType edit );
468
/** set string representing 'true' for a checkbox (added in 1.4) */
469
void setCheckedState( int idx, QString checked, QString notChecked );
471
/** return string representing 'true' for a checkbox (added in 1.4) */
472
QPair<QString, QString> checkedState( int idx );
474
/** get edit form (added in 1.4) */
477
/** set edit form (added in 1.4) */
478
void setEditForm( QString ui );
480
/** get python function for edit form initialization (added in 1.4) */
481
QString editFormInit();
483
/** set python function for edit form initialization (added in 1.4) */
484
void setEditFormInit( QString function );
486
/**access value map*/
487
QMap<QString, QVariant> &valueMap( int idx );
490
RangeData &range( int idx );
492
/**Adds a new overlay to this class. QgsVectorLayer takes ownership of the object
493
@note this method was added in version 1.1
495
void addOverlay( QgsVectorOverlay* overlay );
497
/**Removes all overlays of a given type
498
@note this method was added in version 1.1
500
void removeOverlay( const QString& typeName );
502
/**Returns pointers to the overlays of this layer
503
@note this method was added in version 1.1
505
void vectorOverlays( QList<QgsVectorOverlay*>& overlayList );
507
/**Returns the (first) overlay of a type, e.g. diagram or label
508
@note this method was added in version 1.1
510
QgsVectorOverlay* findOverlayByType( const QString& typeName );
514
* Create edit command for undo/redo operations
515
* @param text text which is to be displayed in undo window
517
void beginEditCommand( QString text );
519
/** Finish edit command and add it to undo/redo stack */
520
void endEditCommand();
522
/** Destroy active command and reverts all changes in it */
523
void destroyEditCommand();
525
/** Execute undo operation. To be called only from QgsVectorLayerUndoCommand. */
526
void undoEditCommand( QgsUndoCommand* cmd );
528
/** Execute redo operation. To be called only from QgsVectorLayerUndoCommand. */
529
void redoEditCommand( QgsUndoCommand* cmd );
531
/** Returns the index of a field name or -1 if the field does not exist
532
@note this method was added in version 1.4
534
int fieldNameIndex( const QString& fieldName ) const;
536
/** Editing vertex markers
537
@note public from version 1.4 */
538
enum VertexMarkerType
540
SemiTransparentCircle,
542
NoMarker /* added in version 1.1 */
545
/** Draws a vertex symbol at (screen) coordinates x, y. (Useful to assist vertex editing.)
546
@note public and static from version 1.4 */
547
static void drawVertexMarker( double x, double y, QPainter& p, QgsVectorLayer::VertexMarkerType type, int vertexSize );
550
/** Select feature by its ID, optionally emit signal selectionChanged() */
551
void select( int featureId, bool emitSignal = TRUE );
553
/** Deselect feature by its ID, optionally emit signal selectionChanged() */
554
void deselect( int featureId, bool emitSignal = TRUE );
556
/** Clear selection */
557
void removeSelection( bool emitSignal = TRUE );
559
void triggerRepaint();
561
/** Update the extents for the layer. This is necessary if features are
562
* added/deleted or the layer has been subsetted.
564
virtual void updateExtents();
568
/** This signal is emited when selection was changed */
569
void selectionChanged();
571
/** This signal is emitted when modifications has been done on layer */
572
void layerModified( bool onlyGeometry );
574
void editingStarted();
575
void editingStopped();
576
void attributeAdded( int idx );
577
void attributeDeleted( int idx );
578
void featureDeleted( int fid );
581
void attributeValueChanged( int fid, int idx, const QVariant & );
583
private: // Private methods
585
/** vector layers are not copyable */
586
QgsVectorLayer( QgsVectorLayer const & rhs );
588
/** vector layers are not copyable */
589
QgsVectorLayer & operator=( QgsVectorLayer const & rhs );
591
/** bind layer to a specific data provider
592
@param provider should be "postgres", "ogr", or ??
593
@todo XXX should this return bool? Throw exceptions?
595
bool setDataProvider( QString const & provider );
597
/** Draws features. May cause projections exceptions to be generated
598
* (i.e., code that calls this function needs to catch them) */
599
void drawFeature( QgsRenderContext &renderContext,
603
/** Convenience function to transform the given point */
604
void transformPoint( double& x, double& y,
605
const QgsMapToPixel* mtp, const QgsCoordinateTransform* ct );
607
void transformPoints( std::vector<double>& x, std::vector<double>& y, std::vector<double>& z, QgsRenderContext &renderContext );
609
/** Draw the linestring as given in the WKB format. Returns a pointer
610
* to the byte after the end of the line string binary data stream (WKB).
612
unsigned char *drawLineString( unsigned char *WKBlinestring, QgsRenderContext &renderContext );
614
/** Draw the polygon as given in the WKB format. Returns a pointer to
615
* the byte after the end of the polygon binary data stream (WKB).
617
unsigned char *drawPolygon( unsigned char *WKBpolygon, QgsRenderContext &renderContext );
619
/** Goes through all features and finds a free id (e.g. to give it temporarily to a not-commited feature) */
622
/**Deletes the geometries in mCachedGeometries*/
623
void deleteCachedGeometries();
625
/**Snaps to a geometry and adds the result to the multimap if it is within the snapping result
626
@param startPoint start point of the snap
627
@param geom geometry to snap
628
@param sqrSnappingTolerance squared search tolerance of the snap
629
@param snappingResult list to which the result is appended
630
@param snap_to snap to vertex or to segment
632
void snapToGeometry( const QgsPoint& startPoint, int featureId, QgsGeometry* geom, double sqrSnappingTolerance,
633
QMultiMap<double, QgsSnappingResult>& snappingResults, QgsSnapper::SnappingType snap_to ) const;
635
/**Little helper function that gives bounding box from a list of points.
636
@return 0 in case of success*/
637
int boundingBoxFromPointList( const QList<QgsPoint>& list, double& xmin, double& ymin, double& xmax, double& ymax ) const;
639
/**Reads vertex marker type from settings*/
640
static QgsVectorLayer::VertexMarkerType currentVertexMarkerType();
642
/**Reads vertex marker size from settings*/
643
static int currentVertexMarkerSize();
645
/**Update feature with uncommited attribute updates*/
646
void updateFeatureAttributes( QgsFeature &f );
648
/**Update feature with uncommited geometry updates*/
649
void updateFeatureGeometry( QgsFeature &f );
651
/** Record changed geometry, store in active command (if any) */
652
void editGeometryChange( int featureId, QgsGeometry& geometry );
654
/** Record added feature, store in active command (if any) */
655
void editFeatureAdd( QgsFeature& feature );
657
/** Record deleted feature, store in active command (if any) */
658
void editFeatureDelete( int featureId );
660
/** Record changed attribute, store in active command (if any) */
661
void editAttributeChange( int featureId, int field, QVariant value );
664
private: // Private attributes
666
/** Update threshold for drawing features as they are read. A value of zero indicates
667
* that no features will be drawn until all have been read
669
int mUpdateThreshold;
671
/** Pointer to data provider derived from the abastract base class QgsDataProvider */
672
QgsVectorDataProvider *mDataProvider;
674
/** index of the primary label field */
675
QString mDisplayField;
677
/** Data provider key */
678
QString mProviderKey;
680
/** The user-defined actions that are accessed from the Identify Results dialog box */
681
QgsAttributeAction* mActions;
683
/** Flag indicating whether the layer is in editing mode or not */
686
/** Flag indicating whether the layer has been modified since the last commit */
689
/** cache of the committed geometries retrieved *for the current display* */
690
QgsGeometryMap mCachedGeometries;
692
/** extent for which there are cached geometries */
693
QgsRectangle mCachedGeometriesRect;
695
/** Set holding the feature IDs that are activated. Note that if a feature
696
subsequently gets deleted (i.e. by its addition to mDeletedFeatureIds),
697
it always needs to be removed from mSelectedFeatureIds as well.
699
QgsFeatureIds mSelectedFeatureIds;
701
/** Deleted feature IDs which are not commited. Note a feature can be added and then deleted
702
again before the change is committed - in that case the added feature would be removed
703
from mAddedFeatures only and *not* entered here.
705
QgsFeatureIds mDeletedFeatureIds;
707
/** New features which are not commited. Note a feature can be added and then changed,
708
therefore the details here can be overridden by mChangedAttributeValues and mChangedGeometries.
710
QgsFeatureList mAddedFeatures;
712
/** Changed attributes values which are not commited */
713
QgsChangedAttributesMap mChangedAttributeValues;
715
/** deleted attributes fields which are not commited */
716
QgsAttributeIds mDeletedAttributeIds;
718
/** added attributes fields which are not commited */
719
QgsAttributeIds mAddedAttributeIds;
721
/** Changed geometries which are not commited. */
722
QgsGeometryMap mChangedGeometries;
724
/** field map to commit */
725
QgsFieldMap mUpdatedFields;
727
/**Map that stores the aliases for attributes. Key is the attribute index and value the alias for that attribute*/
728
QMap<int, QString> mAttributeAliasMap;
730
/** max field index */
731
int mMaxUpdatedIndex;
733
/** Geometry type as defined in enum WkbType (qgis.h) */
736
QgsUndoCommand * mActiveCommand;
738
/** Renderer object which holds the information about how to display the features */
739
QgsRenderer *mRenderer;
742
QgsFeatureRendererV2 *mRendererV2;
744
/** whether to use V1 or V2 renderer */
745
bool mUsingRendererV2;
750
/** Display labels */
753
/**The current type of editing marker*/
754
QgsVectorLayer::VertexMarkerType mCurrentVertexMarkerType;
756
/** The current size of editing marker */
757
int mCurrentVertexMarkerSize;
759
/**Flag if the vertex markers should be drawn only for selection (true) or for all features (false)*/
760
bool mVertexMarkerOnlyForSelection;
762
/**List of overlays. Vector overlays will be rendered on top of all maplayers*/
763
QList<QgsVectorOverlay*> mOverlays;
765
QStringList mCommitErrors;
767
QMap< QString, EditType > mEditTypes;
768
QMap< QString, QMap<QString, QVariant> > mValueMaps;
769
QMap< QString, RangeData > mRanges;
770
QMap< QString, QPair<QString, QString> > mCheckedStates;
772
QString mEditForm, mEditFormInit;
775
QgsRectangle mFetchRect;
776
QgsAttributeList mFetchAttributes;
779
QSet<int> mFetchConsidered;
780
QgsGeometryMap::iterator mFetchChangedGeomIt;
781
QgsFeatureList::iterator mFetchAddedFeaturesIt;