Vector structure

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.

The basic vector methods

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.

Describing the vector structure

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:

Describing the vector structure

A description of these classes is the subject of the following paragraphs.

Describing the header

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

Describing the rows

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.

Exploring QgsGeometry

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.

Note

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.182.179