[{"data":1,"prerenderedAt":627},["ShallowReactive",2],{"doc:\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fautomating-shapefile-to-geojson-conversion":3},{"id":4,"title":5,"body":6,"description":620,"extension":621,"meta":622,"navigation":127,"path":623,"seo":624,"stem":625,"__hash__":626},"docs\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fautomating-shapefile-to-geojson-conversion\u002Findex.md","Automating Shapefile to GeoJSON Conversion in QGIS",{"type":7,"value":8,"toc":615},"minimark",[9,13,32,43,403,408,461,465,468,481,519,543,547,603,611],[10,11,5],"h1",{"id":12},"automating-shapefile-to-geojson-conversion-in-qgis",[14,15,16,17,21,22,25,26,31],"p",{},"Automating shapefile to GeoJSON conversion in QGIS is best handled via the ",[18,19,20],"code",{},"QgsVectorFileWriter"," API. For QGIS 3.16+, ",[18,23,24],{},"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 ",[27,28,30],"a",{"href":29},"\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002F","Vector Data Manipulation"," workflows.",[14,33,34,35,38,39,42],{},"The script loads the ",[18,36,37],{},".shp"," as a ",[18,40,41],{},"QgsVectorLayer",", configures export options, and writes the output. Because GeoJSON strictly requires WGS84 (EPSG:4326), PyQGIS automatically reprojects geometries during export.",[44,45,50],"pre",{"className":46,"code":47,"language":48,"meta":49,"style":49},"language-python shiki shiki-themes github-dark","import os\nfrom pathlib import Path\nfrom qgis.core import (\n QgsVectorLayer,\n QgsVectorFileWriter,\n QgsCoordinateTransformContext,\n QgsProject\n)\n\ndef convert_shp_to_geojson(input_path: str, output_path: str) -> None:\n # Load shapefile\n layer = QgsVectorLayer(input_path, \"temp_layer\", \"ogr\")\n if not layer.isValid():\n raise RuntimeError(f\"Failed to load shapefile: {input_path}\")\n\n # Configure export options\n opts = QgsVectorFileWriter.SaveVectorOptions()\n opts.driverName = \"GeoJSON\"\n opts.fileEncoding = \"UTF-8\"\n # Use project transform context for accurate CRS reprojection\n opts.transformContext = QgsProject.instance().transformContext()\n\n # Write to GeoJSON\n err_code, err_msg = QgsVectorFileWriter.writeAsVectorFormatV3(\n layer, output_path, opts\n )\n if err_code != QgsVectorFileWriter.NoError:\n raise RuntimeError(f\"Export error: {err_msg}\")\n print(f\"Success: {Path(input_path).name} -> {Path(output_path).name}\")\n","python","",[18,51,52,65,79,92,98,104,110,116,122,129,160,167,191,203,235,240,246,257,268,279,285,296,301,307,318,324,330,344,369],{"__ignoreMap":49},[53,54,57,61],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"snl16","import",[53,62,64],{"class":63},"s95oV"," os\n",[53,66,68,71,74,76],{"class":55,"line":67},2,[53,69,70],{"class":59},"from",[53,72,73],{"class":63}," pathlib ",[53,75,60],{"class":59},[53,77,78],{"class":63}," Path\n",[53,80,82,84,87,89],{"class":55,"line":81},3,[53,83,70],{"class":59},[53,85,86],{"class":63}," qgis.core ",[53,88,60],{"class":59},[53,90,91],{"class":63}," (\n",[53,93,95],{"class":55,"line":94},4,[53,96,97],{"class":63}," QgsVectorLayer,\n",[53,99,101],{"class":55,"line":100},5,[53,102,103],{"class":63}," QgsVectorFileWriter,\n",[53,105,107],{"class":55,"line":106},6,[53,108,109],{"class":63}," QgsCoordinateTransformContext,\n",[53,111,113],{"class":55,"line":112},7,[53,114,115],{"class":63}," QgsProject\n",[53,117,119],{"class":55,"line":118},8,[53,120,121],{"class":63},")\n",[53,123,125],{"class":55,"line":124},9,[53,126,128],{"emptyLinePlaceholder":127},true,"\n",[53,130,132,135,139,142,146,149,151,154,157],{"class":55,"line":131},10,[53,133,134],{"class":59},"def",[53,136,138],{"class":137},"svObZ"," convert_shp_to_geojson",[53,140,141],{"class":63},"(input_path: ",[53,143,145],{"class":144},"sDLfK","str",[53,147,148],{"class":63},", output_path: ",[53,150,145],{"class":144},[53,152,153],{"class":63},") -> ",[53,155,156],{"class":144},"None",[53,158,159],{"class":63},":\n",[53,161,163],{"class":55,"line":162},11,[53,164,166],{"class":165},"sAwPA"," # Load shapefile\n",[53,168,170,173,176,179,183,186,189],{"class":55,"line":169},12,[53,171,172],{"class":63}," layer ",[53,174,175],{"class":59},"=",[53,177,178],{"class":63}," QgsVectorLayer(input_path, ",[53,180,182],{"class":181},"sU2Wk","\"temp_layer\"",[53,184,185],{"class":63},", ",[53,187,188],{"class":181},"\"ogr\"",[53,190,121],{"class":63},[53,192,194,197,200],{"class":55,"line":193},13,[53,195,196],{"class":59}," if",[53,198,199],{"class":59}," not",[53,201,202],{"class":63}," layer.isValid():\n",[53,204,206,209,212,215,218,221,224,227,230,233],{"class":55,"line":205},14,[53,207,208],{"class":59}," raise",[53,210,211],{"class":144}," RuntimeError",[53,213,214],{"class":63},"(",[53,216,217],{"class":59},"f",[53,219,220],{"class":181},"\"Failed to load shapefile: ",[53,222,223],{"class":144},"{",[53,225,226],{"class":63},"input_path",[53,228,229],{"class":144},"}",[53,231,232],{"class":181},"\"",[53,234,121],{"class":63},[53,236,238],{"class":55,"line":237},15,[53,239,128],{"emptyLinePlaceholder":127},[53,241,243],{"class":55,"line":242},16,[53,244,245],{"class":165}," # Configure export options\n",[53,247,249,252,254],{"class":55,"line":248},17,[53,250,251],{"class":63}," opts ",[53,253,175],{"class":59},[53,255,256],{"class":63}," QgsVectorFileWriter.SaveVectorOptions()\n",[53,258,260,263,265],{"class":55,"line":259},18,[53,261,262],{"class":63}," opts.driverName ",[53,264,175],{"class":59},[53,266,267],{"class":181}," \"GeoJSON\"\n",[53,269,271,274,276],{"class":55,"line":270},19,[53,272,273],{"class":63}," opts.fileEncoding ",[53,275,175],{"class":59},[53,277,278],{"class":181}," \"UTF-8\"\n",[53,280,282],{"class":55,"line":281},20,[53,283,284],{"class":165}," # Use project transform context for accurate CRS reprojection\n",[53,286,288,291,293],{"class":55,"line":287},21,[53,289,290],{"class":63}," opts.transformContext ",[53,292,175],{"class":59},[53,294,295],{"class":63}," QgsProject.instance().transformContext()\n",[53,297,299],{"class":55,"line":298},22,[53,300,128],{"emptyLinePlaceholder":127},[53,302,304],{"class":55,"line":303},23,[53,305,306],{"class":165}," # Write to GeoJSON\n",[53,308,310,313,315],{"class":55,"line":309},24,[53,311,312],{"class":63}," err_code, err_msg ",[53,314,175],{"class":59},[53,316,317],{"class":63}," QgsVectorFileWriter.writeAsVectorFormatV3(\n",[53,319,321],{"class":55,"line":320},25,[53,322,323],{"class":63}," layer, output_path, opts\n",[53,325,327],{"class":55,"line":326},26,[53,328,329],{"class":63}," )\n",[53,331,333,335,338,341],{"class":55,"line":332},27,[53,334,196],{"class":59},[53,336,337],{"class":63}," err_code ",[53,339,340],{"class":59},"!=",[53,342,343],{"class":63}," QgsVectorFileWriter.NoError:\n",[53,345,347,349,351,353,355,358,360,363,365,367],{"class":55,"line":346},28,[53,348,208],{"class":59},[53,350,211],{"class":144},[53,352,214],{"class":63},[53,354,217],{"class":59},[53,356,357],{"class":181},"\"Export error: ",[53,359,223],{"class":144},[53,361,362],{"class":63},"err_msg",[53,364,229],{"class":144},[53,366,232],{"class":181},[53,368,121],{"class":63},[53,370,372,375,377,379,382,384,387,389,392,394,397,399,401],{"class":55,"line":371},29,[53,373,374],{"class":144}," print",[53,376,214],{"class":63},[53,378,217],{"class":59},[53,380,381],{"class":181},"\"Success: ",[53,383,223],{"class":144},[53,385,386],{"class":63},"Path(input_path).name",[53,388,229],{"class":144},[53,390,391],{"class":181}," -> ",[53,393,223],{"class":144},[53,395,396],{"class":63},"Path(output_path).name",[53,398,229],{"class":144},[53,400,232],{"class":181},[53,402,121],{"class":63},[404,405,407],"h3",{"id":406},"configuration-environment-notes","Configuration & Environment Notes",[409,410,411,427,449,455],"ul",{},[412,413,414,418,419,422,423,426],"li",{},[415,416,417],"strong",{},"QGIS Version:"," ",[18,420,421],{},"writeAsVectorFormatV3"," requires QGIS 3.16+. For 3.10–3.14, swap to ",[18,424,425],{},"writeAsVectorFormatV2"," with identical parameters.",[412,428,429,432,433,436,437,440,441,444,445,448],{},[415,430,431],{},"Runtime Environment:"," Must execute inside QGIS’s bundled Python (",[18,434,435],{},"python-qgis"," or the Python Console). Standalone Python lacks ",[18,438,439],{},"qgis.core"," unless ",[18,442,443],{},"QGIS_PREFIX_PATH"," and ",[18,446,447],{},"PYTHONPATH"," are explicitly configured.",[412,450,451,454],{},[415,452,453],{},"CRS Enforcement:"," GeoJSON RFC 7946 mandates EPSG:4326. PyQGIS auto-reprojects, but always verify output coordinates if your source uses a local projected CRS.",[412,456,457,460],{},[415,458,459],{},"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.",[404,462,464],{"id":463},"fallback-methods","Fallback Methods",[14,466,467],{},"If PyQGIS throws driver errors or environment conflicts, use these proven alternatives:",[469,470,471],"ol",{},[412,472,473,476,477,480],{},[415,474,475],{},"GDAL\u002FOGR CLI:"," Bypass QGIS entirely with ",[18,478,479],{},"ogr2ogr",". Faster for headless servers and avoids Python overhead.",[44,482,486],{"className":483,"code":484,"language":485,"meta":49,"style":49},"language-bash shiki shiki-themes github-dark","ogr2ogr -f GeoJSON -t_srs EPSG:4326 -lco RFC7946=YES -overwrite output.geojson input.shp\n","bash",[18,487,488],{"__ignoreMap":49},[53,489,490,492,495,498,501,504,507,510,513,516],{"class":55,"line":56},[53,491,479],{"class":137},[53,493,494],{"class":144}," -f",[53,496,497],{"class":181}," GeoJSON",[53,499,500],{"class":144}," -t_srs",[53,502,503],{"class":181}," EPSG:4326",[53,505,506],{"class":144}," -lco",[53,508,509],{"class":181}," RFC7946=YES",[53,511,512],{"class":144}," -overwrite",[53,514,515],{"class":181}," output.geojson",[53,517,518],{"class":181}," input.shp\n",[469,520,521],{"start":67},[412,522,523,526,527,530,531,534,535,538,539,542],{},[415,524,525],{},"QGIS Processing Toolbox (GUI Batch):"," Open the Processing Toolbox (",[18,528,529],{},"Ctrl+Alt+T","), search ",[415,532,533],{},"Convert format",", right-click → ",[415,536,537],{},"Execute as Batch Process",". Load multiple shapefiles, set target format to ",[18,540,541],{},"GeoJSON",", and run. Best for non-programmers but lacks programmatic error handling.",[404,544,546],{"id":545},"troubleshooting-common-failures","Troubleshooting Common Failures",[409,548,549,565,579,593],{},[412,550,551,556,557,560,561,564],{},[415,552,553],{},[18,554,555],{},"Driver not found",": Verify GDAL is bundled with your QGIS install. On Windows, use the OSGeo4W installer and select ",[18,558,559],{},"gdal",". On Linux, install ",[18,562,563],{},"python3-gdal"," alongside QGIS.",[412,566,567,570,571,574,575,578],{},[415,568,569],{},"Attribute truncation\u002Fencoding errors",": Shapefiles use legacy codepages. Keep ",[18,572,573],{},"opts.fileEncoding = \"UTF-8\""," and ensure a matching ",[18,576,577],{},".cpg"," file exists. If corruption persists, convert to GeoPackage first, then to GeoJSON.",[412,580,581,584,585,588,589,592],{},[415,582,583],{},"Geometry validation failures",": Invalid polygons (self-intersections, unclosed rings) cause silent feature drops. Run ",[18,586,587],{},"layer.geometry().validateGeometry()"," before export or chain the QGIS ",[415,590,591],{},"Fix Geometries"," algorithm in your pipeline.",[412,594,595,598,599,602],{},[415,596,597],{},"Memory limits on large exports",": GeoJSON loads entirely into RAM. For datasets >100 MB, split by attribute or use ",[18,600,601],{},"ogr2ogr -gt 10000"," to stream features instead.",[14,604,605,606,610],{},"Automating shapefile to GeoJSON conversion eliminates manual overhead and standardizes data delivery for web mapping and API integrations. When integrated into broader ",[27,607,609],{"href":608},"\u002Fspatial-data-processing-automation\u002F","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.",[612,613,614],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":49,"searchDepth":67,"depth":67,"links":616},[617,618,619],{"id":406,"depth":81,"text":407},{"id":463,"depth":81,"text":464},{"id":545,"depth":81,"text":546},"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.","md",{},"\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fautomating-shapefile-to-geojson-conversion",{"title":5,"description":620},"spatial-data-processing-automation\u002Fvector-data-manipulation\u002Fautomating-shapefile-to-geojson-conversion\u002Findex","0yRryYkxRosAlojVQpB4FDpiqN8cnhlO9i7Qno_MuuI",1777824788959]