Beaucoup d'utilisateurs de QGIS se lancent dans les traitements en Python en s'appuyant sur le tutoriel de http://www.qgis.org/pyqgis-cookbook/index.html , le seul qui existe mais qui est complexe à souhait avec des while provider.nextFeature(feat) et autres joyeusetés qui sont tout sauf du bon traitement en Python comme l'a souligné maintes fois Sean Gillies (surtout l'itération avec le next, source de multiples erreurs) alors que ça peut être rendu si simple avec des boucles...
Prenons par exemple, "iterating over a Vector Layer " qui peut être résumé en quelques lignes de code:
La première chose est de sélectionner tous les éléments (géométrie et attributs d'une couche). Une simple fonction suffit (sans feat = QgsFeature(), allAttrs = provider.attributeIndexes(), provider.select(allAttrs))
def select_tout(couche):
couche.select([])
couche.setSelectedFeatures([obj.id() for obj in couche])
ensuite on active la couche choisie (ou un fichier shapefile, ou...) et on utilise la fonction
macouche = qgis.utils.iface.activeLayer()
select_tout(macouche)
et tout se retrouve dans la variable macouche, les géométries et les attributs et on peut utiliser les boucles for, les compréhensions de liste, etc.
for elem in macouche.selectedFeatures():
geom= elem.geometry()
attrs = elem.attributeMap()
(traitements)
et c'est fini mais si l'on veut absolument un itérateur, faisons-le de manière pythonesque....
for i, elem in enumerate(macouche.selectedFeatures()):
geom= elem.geometry()
wkt = geom.exportToWkt()
print "élément: ", i, "géométrie: ", wkt
élément: 0 géométrie: LINESTRING(110923.171250 113663.674220, 117364.375933 120736.374336, 117364.375933 120736.374336)
élément: 1 géométrie: LINESTRING(112501.896619 119157.645479, 118248.464701 116189.640235)
élément: 2 géométrie: LINESTRING(118753.656671 118399.858513, 115659.352293 115494.999389)
Pour les attributs c'est la même chose:
for elem in macouche.selectedFeatures():
attrs = elem.attributeMap()
for (k,atr) in attrs.iteritems():
print "%d: %s" % (k, atr.toString())
0, -100, test
1, -200, test2
etc.
plus de provider.select(allAttrs), de feat.attributeMap(), etc., mais du bon traitement en Python .
Si l'on veut les métadonnées:
macouche.name()
PyQt4.QtCore.QString(u'testligne')
macouche.geometryType()
1
un simple dir(macouche) donne tout ce qu'il est possible de faire avec macouche
>>> dir(macouche)
['CheckBox', 'Classification', 'Cross', 'EditRange', 'EditType', 'Enumeration', 'FileName', 'Hidden', 'Immutable', 'LayerType', 'LineEdit', 'NoMarker', 'PluginLayer', 'RangeData', 'RasterLayer', 'SemiTransparentCircle', 'SliderRange', 'TextEdit', 'UniqueValues', 'UniqueValuesEditable', 'ValueMap', 'VectorLayer', 'VertexMarkerType', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__iter__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'actions', 'addAttribute', 'addAttributeAlias', 'addFeature', 'addFeatures', 'addIsland', 'addJoin', 'addOverlay', 'addRing', 'addTopologicalPoints', 'annotationForm', 'attributeAdded', 'attributeAlias', 'attributeDeleted', 'attributeDisplayName', 'attributeValueChanged', 'beginEditCommand', 'blockSignals', 'boundingBoxOfSelected', 'cacheImage', 'capabilitiesString', 'capitaliseLayerName', 'changeAttributeValue', 'changeGeometry', 'checkJoinLayerRemove', 'childEvent', 'children', 'commitChanges', 'commitErrors', 'committedAttributeValuesChanges', 'committedAttributesAdded', 'committedAttributesDeleted', 'committedFeaturesAdded', 'committedFeaturesRemoved', 'committedGeometriesChanges', 'connect', 'connectNotify', 'copySymbologySettings', 'createJoinCaches', 'crs', 'customEvent', 'customProperty', 'dataComment', 'dataProvider', 'deleteAttribute', 'deleteFeature', 'deleteLater', 'deleteSelectedFeatures', 'deleteVertex', 'deselect', 'destroyEditCommand', 'destroyed', 'disconnect', 'disconnectNotify', 'displayField', 'draw', 'drawLabels', 'drawRendererV2', 'drawRendererV2Levels', 'drawVertexMarker', 'dumpObjectInfo', 'dumpObjectTree', 'dynamicPropertyNames', 'editForm', 'editFormInit', 'editType', 'editingStarted', 'editingStopped', 'emit', 'enableLabels', 'endEditCommand', 'event', 'eventFilter', 'extent', 'featureAtId', 'featureCount', 'featureDeleted', 'fieldNameIndex', 'findChild', 'findChildren', 'findOverlayByType', 'geometryType', 'getLayerID', 'getTransparency', 'hasCompatibleSymbology', 'hasGeometryType', 'hasLabelsEnabled', 'hasScaleBasedVisibility', 'id', 'inherits', 'insertSegmentVerticesForSnap', 'insertVertex', 'installEventFilter', 'invalidTransformInput', 'invertSelection', 'invertSelectionInRectangle', 'isEditable', 'isModified', 'isReadOnly', 'isUsingRendererV2', 'isValid', 'isWidgetType', 'killTimer', 'label', 'lastError', 'lastErrorTitle', 'layerCrsChanged', 'layerDeleted', 'layerModified', 'layerNameChanged', 'loadDefaultStyle', 'loadNamedStyle', 'loadNamedStyleFromDb', 'maximumScale', 'maximumValue', 'metaObject', 'minimumScale', 'minimumValue', 'moveToThread', 'moveVertex', 'name', 'next', 'nextFeature', 'objectName', 'parent', 'pendingAllAttributesList', 'pendingFeatureCount', 'pendingFields', 'property', 'providerType', 'publicSource', 'pyqtConfigure', 'range', 'readSymbology', 'readXML', 'readXml', 'recalculateExtents', 'receivers', 'reload', 'removeCustomProperty', 'removeEventFilter', 'removeJoin', 'removeOverlay', 'removePolygonIntersections', 'removeSelection', 'renderer', 'rendererV2', 'repaintRequested', 'rollBack', 'saveDefaultStyle', 'saveNamedStyle', 'select', 'selectedFeatureCount', 'selectedFeatures', 'selectedFeaturesIds', 'selectionChanged', 'sender', 'senderSignalIndex', 'setAnnotationForm', 'setCacheImage', 'setCheckedState', 'setCoordinateSystem', 'setCrs', 'setCustomProperty', 'setDisplayField', 'setEditForm', 'setEditFormInit', 'setEditType', 'setLayerName', 'setLayerOrder', 'setMaximumScale', 'setMinimumScale', 'setModified', 'setObjectName', 'setParent', 'setProgress', 'setProperty', 'setProviderEncoding', 'setReadOnly', 'setRenderer', 'setRendererV2', 'setSelectedFeatures', 'setStatus', 'setSubLayerVisibility', 'setSubsetString', 'setTransparency', 'setUsingRendererV2', 'setValid', 'signalsBlocked', 'snapPoint', 'snapWithContext', 'source', 'splitFeatures', 'srs', 'startEditing', 'startTimer', 'staticMetaObject', 'storageType', 'subLayers', 'subsetString', 'thread', 'timerEvent', 'toggleScaleBasedVisibility', 'tr', 'trUtf8', 'translateFeature', 'triggerRepaint', 'type', 'undoStack', 'uniqueValues', 'updateExtents', 'updateFeatureCount', 'updateFieldMap', 'valueMap', 'vectorJoins', 'vectorOverlays', 'wkbType', 'writeSymbology', 'writeXML', 'writeXml']
exemple,passer de QGIS à Shapely pour trouver les intersections de lignes, pas possible avec PyQgis:
from shapely.wkb import loads
lignes = []
for elem in macouche.selectedFeatures():
geom= elem.geometry()
wkb = geom.asWkb()
lignes.append(loads(wkb))
print lignes
LINESTRING (110923.1712503755552461 113663.6742198988795280, 117364.3759331023175037 120736.3743357229977846, 117364.3759331023175037 120736.3743357229977846)
LINESTRING (112501.8966194807144348 119157.6454794853925705, 118248.4647013077046722 116189.6402345467358828)
LINESTRING (118753.6566714597429382 118399.8585130013525486, 115659.3522931780025829 115494.9993889210745692)
intersection avec Shapely
intersection = lignes[0].intersection(lignes[1])
print intersection
POINT (114831.0474645419890294 117954.6784518682106864)
print intersection.x
114831.047465
print intersection.y
117954.678452
etc.
Simplifions nous la vie, que diable
Liens sociaux