Vector Layers

Vector Layers

1. Loading Layers

1.1 读取

from qgis.core import QgsVectorLayer
QgsVectorLayer(data_source, layer_name, provider_name)
  • Parameters:

    • data_source: file path

    • layer_name: layer name; can set '' to use the file name

    • provider_name:

  • File type:

    • Shapefile: provider_name 设为 'ogr'

    • CSV and WKT (well known text) files: provider_name 设为 'delimitedtext'

    • geopackage

    • Other types:

      • dxf files

      • PostGIS database

      • GPX files

      • SpatiaLite database

      • MySQL WKB-based geometries

      • WFS connection

  • Load shapefile file

layer = QgsVectorLayer(path, "Airports", "ogr")
if not layer.isValid():
    print("Layer failed to load!")
else:
    QgsProject.instance().addMapLayer(layer)

# add and display a vector layer in current window
layer = iface.addVectorLayer(path, "Airports", "ogr")
  • Load CSV and WKT file
# CSV file
uri = "file:///{0}?delimiter={1}&xField={2}&yField={3}&crs={4}".format(
	"c:/data.csv", ",", "longitude", "latitude", "EPSG:4326")
layer = QgsVectorLayer(uri, "layer_name", "delimitedtext")

# WKT (well known text)
uri = "file:///file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
layer = QgsVectorLayer(uri, "layer_name", "delimitedtext")
  • uri 参数:

    • url 必须为 file:/// 开头

    • delimiter: 分隔符,默认为 ,

    • xFieldyField: x 坐标和 y 坐标的行名

    • wktField: WKT 字段

    • crs: CRS

    • useHeader ('yes', 'no'): 默认为 yes

1.2 删除

QgsProject.instance().removeMapLayer(layer.id())
iface.removeMapLayer(layer.id())

2. Using Vector Layers

field (字段,列)

layer 的每一列为 field,qgis._core.QgsField 类型

  • field.name()

  • field.typeName()

layer.fields(): 返回每一个 field (每一列)的迭代器

  • 每一个元素为 field
for field in layer.fields():
    print(field.name(), field.typeName())

feature(特征,行)

layer 的每一行为 feature,qgis._core.QgsFeature 类型

  • feature.id()

  • feature.geometry()

  • feature.attributes(): 返回为 list 类型

  • feature['name']: access attributes

获取 feature

  • layer.getFeatures(): 返回 every feature with its geometry and attributes(每一行)的迭代器(qgis._core.QgsFeatureIterator 类型)

  • 通过 selection 方法选择,再通过 layer.selectedFeatures() 方法返回 feature 的列表(list 类型)

  • 通过 request 方法选择,再通过 layer.getFeatures(request) 方法返回 feature 的迭代器

  • selection 方法

# select all the feature
layer.selectAll()

# select using an expression
layer.selectByExpression('"Class"=\'B52\' and "Heading" > 10', QgsVectorLayer.SetSelection)

# select by features' id
layer.select(selected_fid)
# selected_fid: list of selected features id

# iterate over selected features
selection = layer.selectedFeatures()
for feature in selection:
    # do whatever you need with the feature
    pass

selection 的一些其他方法

# removeSelection()
layer.removeSelection()

# change the selection color 
iface.mapCanvas().setSelectionColor( QColor("red") )
  • request 方法
# area of interest
aoi = QgsRectangle(450290,400520, 450750,400780)

request = QgsFeatureRequest().setFilterRect(aoi)
# or 
request = QgsFeatureRequest().setFilterRect(aoi) \
                             .setFlags(QgsFeatureRequest.ExactIntersect)

# limit the number of requested feature
request.setLimit(2)

for feature in layer.getFeatures(request):
    # do whatever you need with the feature
    pass

2.1 Retrieving information about attributes

2.2 Iterating over Vector Layer

2.3 Selecting features

2.4 Modifying Vector Layers

Most vector data providers support editing of layer data. Sometimes they support just a subset of possible editing actions.

Use the capabilities() function to find out what set of functionality is supported.

By using any of the following methods for vector layer editing, the changes are directly committed to the underlying data store

caps = layer.dataProvider().capabilities()
# Check if a particular capability is supported:
if caps & QgsVectorDataProvider.DeleteFeatures:
    print('The layer supports DeleteFeatures')

# print layer’s capabilities textual description
caps_string = layer.dataProvider().capabilitiesString()
print(caps_string)

If working inside QGIS, it is necessary to force a redraw of the map canvas in order to see the changes of the geometry, the style or the attributes:

# If caching is enabled, a simple canvas refresh might not be sufficient
# to trigger a redraw and you must clear the cached image for the layer
if iface.mapCanvas().isCachingEnabled():
    layer.triggerRepaint()
else:
    iface.mapCanvas().refresh()

2.4.1 Add, Delete, and Modify

  • Add feature

    • add a feature [0, 'hello', POINT (123, 456)]
if caps & QgsVectorDataProvider.AddFeatures:
    # Step 1: create a QgsFeature instance
    feat = QgsFeature(layer.fields())
    # Step 2: Set feature's attributes
    #   Way I:
    feat.setAttributes([0, 'hello'])
    #   Way II: set a single attribute by key or by index:
    feat.setAttribute('name', 'hello')
    feat.setAttribute(0, 'hello')
    # Step 3: Set feature's geometry
    feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(123, 456)))
    # Step 4: add feature to a layer
    (res, outFeats) = layer.dataProvider().addFeatures([feat])
  • Delete feature
if caps & QgsVectorDataProvider.DeleteFeatures:
    res = layer.dataProvider().deleteFeatures([5, 10])
    # [5, 10] feature IDs
  • Modify feature
fid = 100   # ID of the feature we will modify

if caps & QgsVectorDataProvider.ChangeAttributeValues:
    attrs = { 0 : "hello", 1 : 123 }
    layer.dataProvider().changeAttributeValues({ fid : attrs })

if caps & QgsVectorDataProvider.ChangeGeometries:
    geom = QgsGeometry.fromPointXY(QgsPointXY(111,222))
    layer.dataProvider().changeGeometryValues({ fid : geom })

4.4.2 Modifying Vector Layers with an Editing Buffer

When editing vectors within QGIS application,

  • you have to first start editing mode for a particular layer, then do some modifications and finally commit (or rollback) the changes.

  • All the changes you make are not written until you commit them — they stay in layer’s in-memory editing buffer.

  • it is just another method for vector layer editing that complements the direct usage of data provider (i.e., .dataProvider())

For these methods to work, the layer must be in editing mode.

  • To start the editing mode, use the `startEditing() method.

  • To stop editing, use the commitChanges() or rollBack() methods.

    • commitChanges() will commit all your changes to the data source,

    • rollBack() will discard them and will not modify the data source at all.

To find out whether a layer is in editing mode, use the isEditable() method.

from qgis.PyQt.QtCore import QVariant

# Feature 1
feat_1 = QgsFeature(layer.fields())
feat_1.setId(fid)
# add features
layer.addFeatures([feat_1, ..])
# delete features by feature's ID
layer.deleteFeature(fid)
# set new geometry (QgsGeometry instance) for a feature
layer.changeGeometry(fid, geometry)
# update an attribute
layer.changeAttributeValue(fid, fieldIndex, value)
# add new field
layer.addAttribute(QgsField("feature_name", QVariant.String))
# remove a field
layer.deleteAttribute(fieldIndex)

4.4.3 Adding and Removing Fields

  • and and remove fields (attributes)
from qgis.PyQt.QtCore import QVariant

if caps & QgsVectorDataProvider.AddAttributes:
    res = layer.dataProvider().addAttributes(
        [QgsField("feat_name_1", QVariant.String),
         QgsField("feat_name_2", QVariant.Int)])

if caps & QgsVectorDataProvider.DeleteAttributes:
    res = layer.dataProvider().deleteAttributes([0])
    # field index

# need to update the layer's fields in the data provider after adding or removing fields
layer.updateFields()

# count of layer fields
count = layer.fields().count()

2.5 Using Spatial Index

2.6 The QgsVectorLayerUtils class

2.7 Creating Vector Layers

2.8 Appearance (Symbology) of Vector Layers

renderer = layer.renderer()
print('Type:'', renderer.type())
print(QgsApplication.rendererRegistry().renderersList())
# Out: ['nullSymbol', 'singleSymbol', 'categorizedSymbol', 
#       'graduatedSymbol', 'RuleRenderer', 'pointDisplacement', 
#       'pointCluster', 'mergedFeatureRenderer', 'invertedPolygonRenderer', 
#       'heatmapRenderer', '25dRenderer', 'embeddedSymbol']

# obtain a dump of a renderer contents in text form
renderer.dump()
  • single symbol: QgsSingleSymbolRenderer

  • categorized symbol: QgsCategorizedSymbolRenderer

  • graduated symbol: QgsGraduatedSymbolRenderer

2.8.1 Single Symbol Renderer

symbol = QgsMarkerSymbol.createSimple({'name': 'square', 'color': 'red'})
layer.renderer().setSymbol(symbol)
# show the change
layer.triggerRepaint()
  • QgsMarkerSymbol(), QgsLineSymbol, and QgsFillSymbol: Symbols for point, line, and polygon layers

  • 'name' indicates the shape of the marker, and can be any of the following:

    • 'circle', 'square', 'cross', 'rectangle', 'diamond', 'pentagon', 'triangle', 'equilateral_triangle', 'star', 'regular_star', 'arrow', 'filled_arrowhead', 'x'
# To get the full list of properties for the first symbol layer of a symbol instance
print(layer.renderer().symbol().symbolLayers()[0].properties())
  • alter properties
# alter a single property,
# but not all properties are accessible from methods,
layer.renderer().symbol().symbolLayer(0).setSize(3)

# can also replace the symbol completely:
props = layer.renderer().symbol().symbolLayer(0).properties()
props['color'] = 'yellow'
props['name'] = 'square'
layer.renderer().setSymbol(QgsMarkerSymbol.createSimple(props))
# show the changes
layer.triggerRepaint()

2.8.2 Categorized Symbol Renderer

2.8.3. Graduated Symbol Renderer

posted @ 2023-04-10 20:56  veager  阅读(82)  评论(0)    收藏  举报