Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Qgis Core Data Providers

  • 8 installs
  • 29 repo stars
  • Updated July 8, 2026
  • openaec-foundation/qgis-claude-skill-package

Helps with ai & agent building tasks.

About

qgis-core-data-providers is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.

  • qgis-core-data-providers
  • AI & Agent Building
  • AI-coding skill

Qgis Core Data Providers by the numbers

  • 8 all-time installs (skills.sh)
  • Ranked #12,339 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/qgis-claude-skill-package --skill qgis-core-data-providers

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs8
repo stars29
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/qgis-claude-skill-package

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

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 KeyTypeFormats
"ogr"VectorShapefile, GeoPackage, GeoJSON, FlatGeoBuf, KML, DXF, GPX
"postgres"VectorPostGIS tables and views
"spatialite"VectorSpatiaLite databases
"memory"VectorIn-memory temporary layers
"delimitedtext"VectorCSV, TSV, custom-delimited text files
"WFS"VectorOGC Web Feature Service
"virtual"VectorSQL queries across loaded layers
"gdal"RasterGeoTIFF, JPEG2000, COG, VRT, GeoPackage raster
"wms"RasterWMS, WMTS, XYZ tiles
"wcs"RasterOGC Web Coverage Service
"postgresraster"RasterPostGIS raster tables
"pdal"Point CloudLAS, LAZ (QGIS 3.18+)
"copc"Point CloudCloud Optimized Point Cloud (QGIS 3.26+)
"ept"Point CloudEntwine Point Tile (QGIS 3.18+)
"mdal"MeshNetCDF, GRIB, XMDF, DAT
"vectortile"Vector TileMapbox Vector Tiles (MVT)
"cesiumtiles"Tiled SceneCesium 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 -- API signatures for QgsDataSourceUri, QgsVectorLayer, QgsRasterLayer, QgsProviderRegistry
  • references/examples.md -- URI format strings for every supported provider
  • 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/pyqgis_developer_cookbook/loadlayer.html

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.