To describe the QgsVectorLayer
class, we will first approach basic layer parameters, and then we will explore how the vector is organized. We will explore some classes that are involved in the vector structure, which represent rows and headers.
We will explore the vector class working on a real vector; we will load alaska.shp
in the myVector
variable.
This variable is an instance of the QgsVectorLayer
class. This means that all methods of the vector are documented at http://qgis.org/api/classQgsVectorLayer.html. As for rasters, this class is a specialization of the generic QgsMapLayer
class.
To get the extent of the layer, it's necessary to use the extent()
method of the QgsMapLayer
class:
print myVector.extent().toString()
Executing the preceding code will generate the following result:
-7115212.9837922714650631,1368239.6063178631011397 : 4895579.8114661639556289,7805331.2230994049459696
This shows the corner coordinates in the format xmin,ymin: xmax,ymax
.
To know how many records or features contain the vector, use the following code:
myVector.featureCount()
This will produce the result of 653L
records.
In the result, L
means that it is a Python long integer, which is an integer limited only by the available memory.
As we saw earlier, vectors can be sourced from different providers, each one with its proper capabilities and limitations. To discover the capability of myVector
, use the following method:
myVector.capabilitiesString()
This will give the following result:
u'Add Features, Delete Features, Change Attribute Values, Add Attributes, Delete Attributes, Create Spatial Index, Fast Access to Features at ID, Change Geometries, Simplify Geometries with topological validation'
A Unicode string describes all the possible actions available on the vector.
Compared to rasters, vectors are more complex. A vector involves a set of classes that are used to represent every piece of the vector, from the header to the single attribute.
We can think of a vector as a table with rows and columns, and one header that describes each column of the table. Each row has its own geometry and attributes that are archived in the columns of the row. Each vector could only contain a geometry type. For example, it can be only composed of points, lines, polygons, or collections of these geometry types.
The structure of the classes involved in a vector table is shown in the following screenshot:
A description of these classes is the subject of the following paragraphs.
The container of the header information is the QgsFields
class, which contains methods to point to every column description. A column description is abstracted by the QgsField
class.
To get the header container for myVector
, we use the following code:
header = myVector.pendingFields()
Here, header
will store a QgsFields
instance. The pendingFields()
method is named pending because it always refers to the current state of the vector. This is also the case for editing the vector, and adding or removing columns.
We can use QgsFields
methods to add or remove columns, get the column index by name with indexFromName
, or get a specific field using its index, with the following code:
field_0 = header[0]
To iterate on all column fields, use this snippet:
for column in header: <do something with the variable "column" that is a QgsField>
Each QgsField
has its methods to obtain the column name with name()
, get its type()
and typeName()
methods, and also get its precision()
method if it is numeric.
In the following code, we can explore the characteristics of the header of myVector
:
header = myVector.pendingFields() print "How many columns?", header.count() print "does the column 4 exist?", header.exists(4) print "does the column named 'value' exist?", header.indexFromName('value') print "Column 0 has name", header[0].name() for column in header: print "name", column.name() print "type", column.typeName() print "precision", column.precision()
This will produce the following output:
How many columns? 3 does the column 4 exist? False does the column named 'value' exist? -1 Column 0 has name cat name cat type Real precision 0 name NAME type String precision 0 name AREA_MI type Real precision 15
Each row of myVector
is a QgsFeature
instance. The feature contains all attribute values and a geometry. There are also as many values as QgsField
in the header.
Each feature has its own unique ID that is useful to retrieve the feature directly. For example, to retrieve the feature with ID 3
, we use the following code:
features = myVector.getFeatures( QgsFeatureRequest( 3 ) ) feature = features.next()
The preceding code could appear overcomplicated to retrieve a single feature; in the next section, we will show you the reason for this complexity by explaining the role of the QgsFeatureRequest
class in retrieving features.
With the feature, we can retrieve all the attributes and the geometry of the feature using the following code:
print feature.attributes() geom = feature.geometry() print geom
This will produce something similar to the following result:
[4.0, u'Alaska', 0.322511] <qgis._core.QgsGeometry object at 0x99f0050>
This shows an array of values we get from the attributes()
call and an instance of a QgsGeometry
result of the geometry()
method that is saved in the geom
variable.
The QgsGeometry
class is a complex and powerful class that can be used for a lot of geometry operations, and most of them are based on the capability of the underlying GEOS library.
Geometry Engine Open Source (GEOS) is an extensively used library to manage geometry entities. You can find more information about this at http://trac.osgeo.org/geos/.
It's difficult to describe the richness of this class and all the available methods; for this reason, it's best to read the API documentation. Here, we will give you only a brief introduction to some of the more useful and commonly used methods.
It's possible to have the length()
and area()
methods of the geometry. These values have sense if geometry is not a point.
print "Is this a Polygon?", geom.type() == QGis.Polygon print "it's length is", geom.length() print "it's area measure", geom.area() print "Is it multipart?", geom.isMultipart()
This will generate the following output:
Is this a Polygon? True it's length is 19143.8757902 it's area measure 8991047.15902 Is it multipart? False
The area and length unit depend on the myVector
CRS and can be obtained with the following code:
myVector.crs().mapUnits()
This returns 0
for QGis.Meters
, 1
for QGis.Feet
, or 2
for QGis.Degrees
.
Other interesting methods of the QgsGeometry
class are related with spatial operators such as intersects
, contains
, disjoint
, touches
, overlaps
, simplify
, and so on.
Useful methods can be found to export geometry as a Well-Known Text (WKT) string or to GeoJSON with exportToWkt
and exportToGeoJSON
.
There are a bunch of static methods that can be used to create geometry from a WKT or QGIS primitives such as QgsPoint
and QgsPolygon
. A static method is a method that can be called without an instance variable. For example, to create geometry from a point that is expressed as a WKT, we can use the following code:
myPoint = QgsGeometry.fromWkt('POINT( -195935.165 7663900.585 )')
Notice that the QgsGeometry
class name is used to call the fromWkt
method. This is because fromWkt
is a static method.
In the same way, it's possible to create myPoint
from QgsPoint
with the following code:
newPoint = QgsPoint( -195935.165, 7663900.585) myPoint = QgsGeometry.fromPoint( newPoint )
The two ways that we just described are equivalent and generate QgsGeometry
in the myPoint
variable.
18.117.182.179