Automating Shapefile to GeoJSON Conversion in QGIS

Automating shapefile to GeoJSON conversion in QGIS is best handled via the QgsVectorFileWriter API. For QGIS 3.16+, writeAsVectorFormatV3() safely manages coordinate reference systems, encoding, and geometry validation. This method runs headless in the Python Console, standalone scripts, or plugins, making it ideal for reproducible Vector Data Manipulation workflows.

The script loads the .shp as a QgsVectorLayer, configures export options, and writes the output. Because GeoJSON strictly requires WGS84 (EPSG:4326), PyQGIS automatically reprojects geometries during export.

import os
from pathlib import Path
from qgis.core import (
 QgsVectorLayer,
 QgsVectorFileWriter,
 QgsCoordinateTransformContext,
 QgsProject
)

def convert_shp_to_geojson(input_path: str, output_path: str) -> None:
 # Load shapefile
 layer = QgsVectorLayer(input_path, "temp_layer", "ogr")
 if not layer.isValid():
 raise RuntimeError(f"Failed to load shapefile: {input_path}")

 # Configure export options
 opts = QgsVectorFileWriter.SaveVectorOptions()
 opts.driverName = "GeoJSON"
 opts.fileEncoding = "UTF-8"
 # Use project transform context for accurate CRS reprojection
 opts.transformContext = QgsProject.instance().transformContext()

 # Write to GeoJSON
 err_code, err_msg = QgsVectorFileWriter.writeAsVectorFormatV3(
 layer, output_path, opts
 )
 if err_code != QgsVectorFileWriter.NoError:
 raise RuntimeError(f"Export error: {err_msg}")
 print(f"Success: {Path(input_path).name} -> {Path(output_path).name}")

Configuration & Environment Notes

  • QGIS Version: writeAsVectorFormatV3 requires QGIS 3.16+. For 3.10–3.14, swap to writeAsVectorFormatV2 with identical parameters.
  • Runtime Environment: Must execute inside QGIS’s bundled Python (python-qgis or the Python Console). Standalone Python lacks qgis.core unless QGIS_PREFIX_PATH and PYTHONPATH are explicitly configured.
  • CRS Enforcement: GeoJSON RFC 7946 mandates EPSG:4326. PyQGIS auto-reprojects, but always verify output coordinates if your source uses a local projected CRS.
  • Format Limits: Shapefiles truncate field names at 10 characters and cap at 2 GB. GeoJSON has no hard size limit but degrades in browser performance past ~50 MB.

Fallback Methods

If PyQGIS throws driver errors or environment conflicts, use these proven alternatives:

  1. GDAL/OGR CLI: Bypass QGIS entirely with ogr2ogr. Faster for headless servers and avoids Python overhead.
ogr2ogr -f GeoJSON -t_srs EPSG:4326 -lco RFC7946=YES -overwrite output.geojson input.shp
  1. QGIS Processing Toolbox (GUI Batch): Open the Processing Toolbox (Ctrl+Alt+T), search Convert format, right-click → Execute as Batch Process. Load multiple shapefiles, set target format to GeoJSON, and run. Best for non-programmers but lacks programmatic error handling.

Troubleshooting Common Failures

  • Driver not found: Verify GDAL is bundled with your QGIS install. On Windows, use the OSGeo4W installer and select gdal. On Linux, install python3-gdal alongside QGIS.
  • Attribute truncation/encoding errors: Shapefiles use legacy codepages. Keep opts.fileEncoding = "UTF-8" and ensure a matching .cpg file exists. If corruption persists, convert to GeoPackage first, then to GeoJSON.
  • Geometry validation failures: Invalid polygons (self-intersections, unclosed rings) cause silent feature drops. Run layer.geometry().validateGeometry() before export or chain the QGIS Fix Geometries algorithm in your pipeline.
  • Memory limits on large exports: GeoJSON loads entirely into RAM. For datasets >100 MB, split by attribute or use ogr2ogr -gt 10000 to stream features instead.

Automating shapefile to GeoJSON conversion eliminates manual overhead and standardizes data delivery for web mapping and API integrations. When integrated into broader Spatial Data Processing & Automation pipelines, PyQGIS delivers reliable, version-controlled transformations that scale from single files to enterprise datasets. Always validate output with a lightweight GeoJSON linter before deployment.