Install
$ agentstack add skill-impertio-studio-qgis-claude-skill-package-qgis-core-data-providers ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
qgis-core-data-providers
Quick Reference
Provider System Overview
QGIS uses a plugin-based provider architecture. Providers are registered in QgsProviderRegistry and loaded during QgsApplication.initQgis(). Each provider handles one or more data formats.
| Provider Key | Type | Formats | |-------------|------|---------| | "ogr" | Vector | Shapefile, GeoPackage, GeoJSON, FlatGeoBuf, KML, DXF, GPX | | "postgres" | Vector | PostGIS tables and views | | "spatialite" | Vector | SpatiaLite databases | | "memory" | Vector | In-memory temporary layers | | "delimitedtext" | Vector | CSV, TSV, custom-delimited text files | | "WFS" | Vector | OGC Web Feature Service | | "virtual" | Vector | SQL queries across loaded layers | | "gdal" | Raster | GeoTIFF, JPEG2000, COG, VRT, GeoPackage raster | | "wms" | Raster | WMS, WMTS, XYZ tiles | | "wcs" | Raster | OGC Web Coverage Service | | "postgresraster" | Raster | PostGIS raster tables | | "pdal" | Point Cloud | LAS, LAZ (QGIS 3.18+) | | "copc" | Point Cloud | Cloud Optimized Point Cloud (QGIS 3.26+) | | "ept" | Point Cloud | Entwine Point Tile (QGIS 3.18+) | | "mdal" | Mesh | NetCDF, GRIB, XMDF, DAT | | "vectortile" | Vector Tile | Mapbox Vector Tiles (MVT) | | "cesiumtiles" | Tiled Scene | Cesium 3D Tiles (QGIS 3.34+) |
Layer Construction Pattern
# Vector layer
vlayer = QgsVectorLayer(data_source_uri, display_name, provider_key)
# Raster layer
rlayer = QgsRasterLayer(data_source_uri, display_name, provider_key)
# Point cloud layer (QGIS 3.18+)
pclayer = QgsPointCloudLayer(data_source_uri, display_name, provider_key)
# Mesh layer
mlayer = QgsMeshLayer(data_source_uri, display_name, provider_key)
# Vector tile layer
vtlayer = QgsVectorTileLayer(data_source_uri, display_name)
ALWAYS check validity immediately after creation:
layer = QgsVectorLayer(uri, name, provider)
if not layer.isValid():
raise RuntimeError(f"Failed to load layer '{name}' from: {uri}")
Critical Warnings
NEVER skip isValid() after layer creation. A layer object is ALWAYS returned even when loading fails -- the constructor NEVER raises exceptions.
NEVER use backslashes in URIs, even on Windows. QGIS/Qt normalizes to forward slashes internally. Backslashes in URIs cause silent provider failures.
NEVER pass True to uri.uri(expandAuthConfig) when logging or displaying URIs. This exposes authentication credentials in plain text. ALWAYS use uri.uri(False).
NEVER assume a GeoPackage contains a single layer. ALWAYS use explicit |layername= in the URI or enumerate sublayers first.
ALWAYS call layer.updateExtents() after adding features to a memory layer. Without this, zoom-to-layer returns a wrong extent.
ALWAYS call layer.updateFields() after calling dataProvider().addAttributes(). Without this, the layer schema is stale.
ALWAYS use file:/// prefix (three slashes) for delimited text URIs with absolute paths.
NEVER access features or data provider methods on an invalid layer -- this causes crashes or undefined behavior.
Decision Tree: Which Format to Use
Need to store spatial data?
├── Temporary / in-memory only?
│ └── USE: memory provider
├── Exchange with non-GIS tools?
│ ├── JSON-based → USE: GeoJSON
│ └── Tabular → USE: CSV with delimitedtext provider
├── Single-layer vector file?
│ ├── Small dataset → USE: GeoPackage (single layer)
│ └── Streaming / append-heavy → USE: FlatGeoBuf
├── Multi-layer project database?
│ └── USE: GeoPackage (recommended default)
├── Enterprise / multi-user database?
│ └── USE: PostGIS with postgres provider
├── Web service?
│ ├── Vector features → USE: WFS
│ ├── Map images → USE: WMS
│ ├── Tile basemaps → USE: XYZ tiles via wms provider
│ └── Raw raster coverage → USE: WCS
├── Raster data?
│ ├── Local file → USE: GeoTIFF via gdal provider
│ ├── Cloud storage → USE: COG via /vsicurl/
│ └── Database → USE: postgresraster
├── Point cloud / LiDAR?
│ ├── Local file → USE: pdal (LAS/LAZ)
│ └── Cloud optimized → USE: copc
└── Legacy requirement?
└── Shapefile ONLY if mandated by external system
GeoPackage is the recommended default format. It supports vector, raster, and attribute tables in a single SQLite-based file with no file count limitations (unlike Shapefile's multi-file structure).
Essential Patterns
Pattern 1: Load a GeoPackage Layer
from qgis.core import QgsVectorLayer, QgsProject
# Single known layer
vlayer = QgsVectorLayer("data/project.gpkg|layername=buildings", "Buildings", "ogr")
if not vlayer.isValid():
raise RuntimeError("Layer failed to load")
QgsProject.instance().addMapLayer(vlayer)
Pattern 2: Enumerate All Sublayers
from qgis.core import QgsDataProvider, QgsVectorLayer, QgsProject
gpkg_path = "data/project.gpkg"
layer = QgsVectorLayer(gpkg_path, "probe", "ogr")
for sub in layer.dataProvider().subLayers():
name = sub.split(QgsDataProvider.SUBLAYER_SEPARATOR)[1]
uri = f"{gpkg_path}|layername={name}"
sub_layer = QgsVectorLayer(uri, name, "ogr")
if sub_layer.isValid():
QgsProject.instance().addMapLayer(sub_layer)
Pattern 3: PostGIS Connection with QgsDataSourceUri
from qgis.core import QgsDataSourceUri, QgsVectorLayer
uri = QgsDataSourceUri()
uri.setConnection("localhost", "5432", "mydb", "user", "password")
uri.setDataSource("public", "roads", "geom", "status = 'active'", "gid")
vlayer = QgsVectorLayer(uri.uri(False), "Active Roads", "postgres")
if not vlayer.isValid():
raise RuntimeError("PostGIS connection failed")
Pattern 4: Create a Memory Layer with Fields
from qgis.core import QgsVectorLayer, QgsField, QgsFeature, QgsGeometry, QgsPointXY
from qgis.PyQt.QtCore import QVariant
# URI with inline field definitions
layer = QgsVectorLayer(
"Point?crs=EPSG:4326&field=name:string(100)&field=value:double",
"Results",
"memory"
)
# OR add fields programmatically
layer = QgsVectorLayer("Point?crs=EPSG:4326", "Results", "memory")
pr = layer.dataProvider()
pr.addAttributes([
QgsField("name", QVariant.String),
QgsField("value", QVariant.Double),
])
layer.updateFields()
# Add features
feat = QgsFeature()
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(5.0, 52.0)))
feat.setAttributes(["Sample", 42.0])
pr.addFeatures([feat])
layer.updateExtents()
Pattern 5: Load WMS / XYZ Tiles
from qgis.core import QgsRasterLayer, QgsProject
# WMS
wms_uri = (
"crs=EPSG:4326"
"&format=image/png"
"&layers=my_layer"
"&styles"
"&url=https://example.com/wms"
)
wms_layer = QgsRasterLayer(wms_uri, "WMS Layer", "wms")
# XYZ tiles -- {z}/{x}/{y} MUST be URL-encoded
xyz_uri = (
"type=xyz"
"&url=https://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png"
"&zmin=0&zmax=19"
"&crs=EPSG3857"
)
xyz_layer = QgsRasterLayer(xyz_uri, "OpenStreetMap", "wms")
for lyr in [wms_layer, xyz_layer]:
if not lyr.isValid():
raise RuntimeError(f"Layer '{lyr.name()}' failed to load")
QgsProject.instance().addMapLayer(lyr)
Pattern 6: Load CSV with Coordinates
import os
from qgis.core import QgsVectorLayer
csv_path = os.path.abspath("data/stations.csv").replace("\\", "/")
uri = (
f"file:///{csv_path}"
"?delimiter=,"
"&xField=longitude"
"&yField=latitude"
"&crs=EPSG:4326"
)
vlayer = QgsVectorLayer(uri, "Stations", "delimitedtext")
Common Operations
List Available Providers
from qgis.core import QgsProviderRegistry
registry = QgsProviderRegistry.instance()
for key in registry.providerList():
print(key)
Load Raster from GeoPackage
from qgis.core import QgsRasterLayer
rlayer = QgsRasterLayer("GPKG:/data/rasters.gpkg:elevation", "Elevation", "gdal")
Load Cloud Optimized GeoTIFF (COG)
from qgis.core import QgsRasterLayer
rlayer = QgsRasterLayer("/vsicurl/https://example.com/data.tif", "Remote COG", "gdal")
Load WFS Layer
from qgis.core import QgsVectorLayer
uri = "https://example.com/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ns:layer"
vlayer = QgsVectorLayer(uri, "WFS Layer", "WFS")
Load SpatiaLite Layer
from qgis.core import QgsDataSourceUri, QgsVectorLayer
uri = QgsDataSourceUri()
uri.setDatabase("/data/regions.sqlite")
uri.setDataSource("", "regions", "geometry")
vlayer = QgsVectorLayer(uri.uri(), "Regions", "spatialite")
Virtual Layer (SQL Across Loaded Layers)
from qgis.core import QgsVectorLayer
uri = "?query=SELECT * FROM airports WHERE elevation > 500"
vlayer = QgsVectorLayer(uri, "High Airports", "virtual")
Materialize Selection as Memory Layer
from qgis.core import QgsFeatureRequest, QgsProject
memory_layer = source_layer.materialize(
QgsFeatureRequest().setFilterFids(source_layer.selectedFeatureIds())
)
QgsProject.instance().addMapLayer(memory_layer)
Reference Links
- [references/methods.md](references/methods.md) -- API signatures for QgsDataSourceUri, QgsVectorLayer, QgsRasterLayer, QgsProviderRegistry
- [references/examples.md](references/examples.md) -- URI format strings for every supported provider
- [references/anti-patterns.md](references/anti-patterns.md) -- What NOT to do when loading data
Official Sources
- https://qgis.org/pyqgis/master/core/QgsVectorLayer.html
- https://qgis.org/pyqgis/master/core/QgsRasterLayer.html
- https://qgis.org/pyqgis/master/core/QgsDataSourceUri.html
- https://qgis.org/pyqgis/master/core/QgsProviderRegistry.html
- https://docs.qgis.org/latest/en/docs/pyqgisdevelopercookbook/loadlayer.html
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/QGIS-Claude-Skill-Package
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.