[{"data":1,"prerenderedAt":1677},["ShallowReactive",2],{"doc:\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fclip-vector-layer-pyqgis":3},{"id":4,"title":5,"body":6,"description":1670,"extension":1671,"meta":1672,"navigation":145,"path":1673,"seo":1674,"stem":1675,"__hash__":1676},"docs\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fclip-vector-layer-pyqgis\u002Findex.md","Clip a Vector Layer in PyQGIS",{"type":7,"value":8,"toc":1656},"minimark",[9,13,28,31,36,69,89,93,104,304,326,337,390,399,403,413,416,615,631,638,642,651,710,727,734,782,796,800,803,873,890,960,978,986,990,993,1236,1245,1249,1259,1417,1429,1433,1443,1497,1513,1517,1572,1576,1584,1588,1597,1609,1615,1631,1635,1652],[10,11,5],"h1",{"id":12},"clip-a-vector-layer-in-pyqgis",[14,15,16,17,22,23,27],"p",{},"Clipping trims an input vector layer to the boundary of an overlay (mask) polygon, keeping only the parts of features that fall inside that boundary. It is one of the most common operations in ",[18,19,21],"a",{"href":20},"\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002F","Vector Data Manipulation",": extracting roads inside a city limit, parcels within a study area, or rivers inside a watershed. In PyQGIS the cleanest way to do this is the ",[24,25,26],"code",{},"native:clip"," Processing algorithm, which is geometry-type aware and runs identically in the Python Console, a standalone script, or a plugin.",[14,29,30],{},"Unlike a selection or a spatial filter, a clip physically cuts geometries at the mask boundary. A road that crosses the edge of your study area is split, and only the inside segment is written to the output. Attribute values are preserved on the surviving parts. This page walks through a correct, runnable clip workflow, the CRS pitfalls that silently produce empty results, output options, and how a clip differs from intersection and difference.",[32,33,35],"h2",{"id":34},"prerequisites","Prerequisites",[37,38,39,43,55,66],"ul",{},[40,41,42],"li",{},"QGIS 3.34 LTR (bundled Python 3.12) with the Processing framework available.",[40,44,45,46,50,51,54],{},"An ",[47,48,49],"strong",{},"input layer"," to be trimmed (points, lines, or polygons) and an ",[47,52,53],{},"overlay layer"," containing one or more mask polygons.",[40,56,57,58,61,62,65],{},"Familiarity with the QGIS Python Console (",[24,59,60],{},"Plugins > Python Console",", or ",[24,63,64],{},"Ctrl+Alt+P",").",[40,67,68],{},"For file output, write permission to the target directory.",[14,70,71,72,75,76,79,80,83,84,88],{},"In the Python Console, ",[24,73,74],{},"processing"," and ",[24,77,78],{},"iface"," are already imported. In a standalone script you must initialize ",[24,81,82],{},"QgsApplication"," and Processing first — see ",[18,85,87],{"href":86},"\u002Fspatial-data-processing-automation\u002Fbatch-processing-with-pyqgis\u002Frun-processing-algorithm-from-script\u002F","Run a Processing Algorithm from a Script in PyQGIS",".",[32,90,92],{"id":91},"run-a-basic-clip","Run a Basic Clip",[14,94,95,96,99,100,103],{},"The algorithm takes two layers: ",[24,97,98],{},"INPUT"," (the layer to trim) and ",[24,101,102],{},"OVERLAY"," (the mask). The example below clips roads currently loaded in the project by a study-area polygon and returns a temporary in-memory result.",[105,106,111],"pre",{"className":107,"code":108,"language":109,"meta":110,"style":110},"language-python shiki shiki-themes github-dark","import processing\nfrom qgis.core import QgsProject\n\ninput_layer = QgsProject.instance().mapLayersByName(\"roads\")[0]\noverlay_layer = QgsProject.instance().mapLayersByName(\"study_area\")[0]\n\nresult = processing.run(\"native:clip\", {\n    \"INPUT\": input_layer,\n    \"OVERLAY\": overlay_layer,\n    \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n})\n\nclipped = result[\"OUTPUT\"]\nprint(f\"Clipped layer has {clipped.featureCount()} features\")\n","python","",[24,112,113,126,140,147,173,192,197,214,223,232,247,253,258,274],{"__ignoreMap":110},[114,115,118,122],"span",{"class":116,"line":117},"line",1,[114,119,121],{"class":120},"snl16","import",[114,123,125],{"class":124},"s95oV"," processing\n",[114,127,129,132,135,137],{"class":116,"line":128},2,[114,130,131],{"class":120},"from",[114,133,134],{"class":124}," qgis.core ",[114,136,121],{"class":120},[114,138,139],{"class":124}," QgsProject\n",[114,141,143],{"class":116,"line":142},3,[114,144,146],{"emptyLinePlaceholder":145},true,"\n",[114,148,150,153,156,159,163,166,170],{"class":116,"line":149},4,[114,151,152],{"class":124},"input_layer ",[114,154,155],{"class":120},"=",[114,157,158],{"class":124}," QgsProject.instance().mapLayersByName(",[114,160,162],{"class":161},"sU2Wk","\"roads\"",[114,164,165],{"class":124},")[",[114,167,169],{"class":168},"sDLfK","0",[114,171,172],{"class":124},"]\n",[114,174,176,179,181,183,186,188,190],{"class":116,"line":175},5,[114,177,178],{"class":124},"overlay_layer ",[114,180,155],{"class":120},[114,182,158],{"class":124},[114,184,185],{"class":161},"\"study_area\"",[114,187,165],{"class":124},[114,189,169],{"class":168},[114,191,172],{"class":124},[114,193,195],{"class":116,"line":194},6,[114,196,146],{"emptyLinePlaceholder":145},[114,198,200,203,205,208,211],{"class":116,"line":199},7,[114,201,202],{"class":124},"result ",[114,204,155],{"class":120},[114,206,207],{"class":124}," processing.run(",[114,209,210],{"class":161},"\"native:clip\"",[114,212,213],{"class":124},", {\n",[114,215,217,220],{"class":116,"line":216},8,[114,218,219],{"class":161},"    \"INPUT\"",[114,221,222],{"class":124},": input_layer,\n",[114,224,226,229],{"class":116,"line":225},9,[114,227,228],{"class":161},"    \"OVERLAY\"",[114,230,231],{"class":124},": overlay_layer,\n",[114,233,235,238,241,244],{"class":116,"line":234},10,[114,236,237],{"class":161},"    \"OUTPUT\"",[114,239,240],{"class":124},": ",[114,242,243],{"class":161},"\"TEMPORARY_OUTPUT\"",[114,245,246],{"class":124},",\n",[114,248,250],{"class":116,"line":249},11,[114,251,252],{"class":124},"})\n",[114,254,256],{"class":116,"line":255},12,[114,257,146],{"emptyLinePlaceholder":145},[114,259,261,264,266,269,272],{"class":116,"line":260},13,[114,262,263],{"class":124},"clipped ",[114,265,155],{"class":120},[114,267,268],{"class":124}," result[",[114,270,271],{"class":161},"\"OUTPUT\"",[114,273,172],{"class":124},[114,275,277,280,283,286,289,292,295,298,301],{"class":116,"line":276},14,[114,278,279],{"class":168},"print",[114,281,282],{"class":124},"(",[114,284,285],{"class":120},"f",[114,287,288],{"class":161},"\"Clipped layer has ",[114,290,291],{"class":168},"{",[114,293,294],{"class":124},"clipped.featureCount()",[114,296,297],{"class":168},"}",[114,299,300],{"class":161}," features\"",[114,302,303],{"class":124},")\n",[14,305,306,309,310,313,314,317,318,321,322,325],{},[47,307,308],{},"Breakdown:"," ",[24,311,312],{},"processing.run"," returns a dictionary keyed by the algorithm's output names. With ",[24,315,316],{},"TEMPORARY_OUTPUT"," the value at ",[24,319,320],{},"result[\"OUTPUT\"]"," is a ready-to-use ",[24,323,324],{},"QgsVectorLayer"," backed by a scratch GeoPackage in the QGIS temp folder. Passing the layer objects directly (rather than file paths) avoids re-reading from disk and lets the algorithm reuse loaded data.",[14,327,328,329,331,332,75,334,336],{},"You can pass either a loaded ",[24,330,324],{}," or a file path string for ",[24,333,98],{},[24,335,102],{},". A path is convenient in batch scripts:",[105,338,340],{"className":107,"code":339,"language":109,"meta":110,"style":110},"result = processing.run(\"native:clip\", {\n    \"INPUT\": \"\u002Fdata\u002Froads.shp\",\n    \"OVERLAY\": \"\u002Fdata\u002Fstudy_area.gpkg|layername=boundary\",\n    \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n})\n",[24,341,342,354,365,376,386],{"__ignoreMap":110},[114,343,344,346,348,350,352],{"class":116,"line":117},[114,345,202],{"class":124},[114,347,155],{"class":120},[114,349,207],{"class":124},[114,351,210],{"class":161},[114,353,213],{"class":124},[114,355,356,358,360,363],{"class":116,"line":128},[114,357,219],{"class":161},[114,359,240],{"class":124},[114,361,362],{"class":161},"\"\u002Fdata\u002Froads.shp\"",[114,364,246],{"class":124},[114,366,367,369,371,374],{"class":116,"line":142},[114,368,228],{"class":161},[114,370,240],{"class":124},[114,372,373],{"class":161},"\"\u002Fdata\u002Fstudy_area.gpkg|layername=boundary\"",[114,375,246],{"class":124},[114,377,378,380,382,384],{"class":116,"line":149},[114,379,237],{"class":161},[114,381,240],{"class":124},[114,383,243],{"class":161},[114,385,246],{"class":124},[114,387,388],{"class":116,"line":175},[114,389,252],{"class":124},[14,391,392,394,395,398],{},[47,393,308],{}," The ",[24,396,397],{},"|layername="," suffix selects a specific layer inside a multi-layer GeoPackage. For a shapefile, the bare path is enough because it contains a single layer.",[32,400,402],{"id":401},"align-the-crs-before-clipping","Align the CRS Before Clipping",[14,404,405,406,408,409,412],{},"The single most common cause of an empty or wrong clip is a coordinate reference system mismatch. ",[24,407,26],{}," does ",[47,410,411],{},"not"," reproject the overlay to match the input; it expects both layers in the same CRS and compares raw coordinates. If your roads are in UTM and your study area is in EPSG:4326, their coordinate ranges never overlap and you get zero features back — with no error.",[14,414,415],{},"Check the CRS of both layers and reproject the overlay when they differ:",[105,417,419],{"className":107,"code":418,"language":109,"meta":110,"style":110},"import processing\nfrom qgis.core import QgsProject\n\ninput_layer = QgsProject.instance().mapLayersByName(\"roads\")[0]\noverlay_layer = QgsProject.instance().mapLayersByName(\"study_area\")[0]\n\nif input_layer.crs() != overlay_layer.crs():\n    reprojected = processing.run(\"native:reprojectlayer\", {\n        \"INPUT\": overlay_layer,\n        \"TARGET_CRS\": input_layer.crs(),\n        \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n    })[\"OUTPUT\"]\n    overlay_layer = reprojected\n\nresult = processing.run(\"native:clip\", {\n    \"INPUT\": input_layer,\n    \"OVERLAY\": overlay_layer,\n    \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n})\nprint(\"Output CRS:\", result[\"OUTPUT\"].crs().authid())\n",[24,420,421,427,437,441,457,473,477,491,505,512,520,531,540,550,554,567,574,581,592,597],{"__ignoreMap":110},[114,422,423,425],{"class":116,"line":117},[114,424,121],{"class":120},[114,426,125],{"class":124},[114,428,429,431,433,435],{"class":116,"line":128},[114,430,131],{"class":120},[114,432,134],{"class":124},[114,434,121],{"class":120},[114,436,139],{"class":124},[114,438,439],{"class":116,"line":142},[114,440,146],{"emptyLinePlaceholder":145},[114,442,443,445,447,449,451,453,455],{"class":116,"line":149},[114,444,152],{"class":124},[114,446,155],{"class":120},[114,448,158],{"class":124},[114,450,162],{"class":161},[114,452,165],{"class":124},[114,454,169],{"class":168},[114,456,172],{"class":124},[114,458,459,461,463,465,467,469,471],{"class":116,"line":175},[114,460,178],{"class":124},[114,462,155],{"class":120},[114,464,158],{"class":124},[114,466,185],{"class":161},[114,468,165],{"class":124},[114,470,169],{"class":168},[114,472,172],{"class":124},[114,474,475],{"class":116,"line":194},[114,476,146],{"emptyLinePlaceholder":145},[114,478,479,482,485,488],{"class":116,"line":199},[114,480,481],{"class":120},"if",[114,483,484],{"class":124}," input_layer.crs() ",[114,486,487],{"class":120},"!=",[114,489,490],{"class":124}," overlay_layer.crs():\n",[114,492,493,496,498,500,503],{"class":116,"line":216},[114,494,495],{"class":124},"    reprojected ",[114,497,155],{"class":120},[114,499,207],{"class":124},[114,501,502],{"class":161},"\"native:reprojectlayer\"",[114,504,213],{"class":124},[114,506,507,510],{"class":116,"line":225},[114,508,509],{"class":161},"        \"INPUT\"",[114,511,231],{"class":124},[114,513,514,517],{"class":116,"line":234},[114,515,516],{"class":161},"        \"TARGET_CRS\"",[114,518,519],{"class":124},": input_layer.crs(),\n",[114,521,522,525,527,529],{"class":116,"line":249},[114,523,524],{"class":161},"        \"OUTPUT\"",[114,526,240],{"class":124},[114,528,243],{"class":161},[114,530,246],{"class":124},[114,532,533,536,538],{"class":116,"line":255},[114,534,535],{"class":124},"    })[",[114,537,271],{"class":161},[114,539,172],{"class":124},[114,541,542,545,547],{"class":116,"line":260},[114,543,544],{"class":124},"    overlay_layer ",[114,546,155],{"class":120},[114,548,549],{"class":124}," reprojected\n",[114,551,552],{"class":116,"line":276},[114,553,146],{"emptyLinePlaceholder":145},[114,555,557,559,561,563,565],{"class":116,"line":556},15,[114,558,202],{"class":124},[114,560,155],{"class":120},[114,562,207],{"class":124},[114,564,210],{"class":161},[114,566,213],{"class":124},[114,568,570,572],{"class":116,"line":569},16,[114,571,219],{"class":161},[114,573,222],{"class":124},[114,575,577,579],{"class":116,"line":576},17,[114,578,228],{"class":161},[114,580,231],{"class":124},[114,582,584,586,588,590],{"class":116,"line":583},18,[114,585,237],{"class":161},[114,587,240],{"class":124},[114,589,243],{"class":161},[114,591,246],{"class":124},[114,593,595],{"class":116,"line":594},19,[114,596,252],{"class":124},[114,598,600,602,604,607,610,612],{"class":116,"line":599},20,[114,601,279],{"class":168},[114,603,282],{"class":124},[114,605,606],{"class":161},"\"Output CRS:\"",[114,608,609],{"class":124},", result[",[114,611,271],{"class":161},[114,613,614],{"class":124},"].crs().authid())\n",[14,616,617,619,620,623,624,626,627,630],{},[47,618,308],{}," Comparing ",[24,621,622],{},"QgsCoordinateReferenceSystem"," objects with ",[24,625,487],{}," is reliable. When they differ, ",[24,628,629],{},"native:reprojectlayer"," transforms the overlay into the input's CRS so the geometries share a coordinate space. The output inherits the input layer's CRS, never the overlay's.",[14,632,633,634,88],{},"For more on diagnosing and fixing projection problems, see ",[18,635,637],{"href":636},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002F","Coordinate Reference Systems",[32,639,641],{"id":640},"temporary-output-vs-file-output","Temporary Output vs File Output",[14,643,644,646,647,650],{},[24,645,316],{}," is ideal for interactive exploration and intermediate steps in a chain, but the result vanishes when QGIS closes. For a persistent deliverable, write to a real file by giving ",[24,648,649],{},"OUTPUT"," a path. The driver is inferred from the extension:",[105,652,654],{"className":107,"code":653,"language":109,"meta":110,"style":110},"import processing\n\nprocessing.run(\"native:clip\", {\n    \"INPUT\": \"\u002Fdata\u002Froads.shp\",\n    \"OVERLAY\": \"\u002Fdata\u002Fstudy_area.gpkg|layername=boundary\",\n    \"OUTPUT\": \"\u002Fdata\u002Foutput\u002Froads_clipped.gpkg\",\n})\n",[24,655,656,662,666,675,685,695,706],{"__ignoreMap":110},[114,657,658,660],{"class":116,"line":117},[114,659,121],{"class":120},[114,661,125],{"class":124},[114,663,664],{"class":116,"line":128},[114,665,146],{"emptyLinePlaceholder":145},[114,667,668,671,673],{"class":116,"line":142},[114,669,670],{"class":124},"processing.run(",[114,672,210],{"class":161},[114,674,213],{"class":124},[114,676,677,679,681,683],{"class":116,"line":149},[114,678,219],{"class":161},[114,680,240],{"class":124},[114,682,362],{"class":161},[114,684,246],{"class":124},[114,686,687,689,691,693],{"class":116,"line":175},[114,688,228],{"class":161},[114,690,240],{"class":124},[114,692,373],{"class":161},[114,694,246],{"class":124},[114,696,697,699,701,704],{"class":116,"line":194},[114,698,237],{"class":161},[114,700,240],{"class":124},[114,702,703],{"class":161},"\"\u002Fdata\u002Foutput\u002Froads_clipped.gpkg\"",[114,705,246],{"class":124},[114,707,708],{"class":116,"line":199},[114,709,252],{"class":124},[14,711,712,714,715,718,719,722,723,726],{},[47,713,308],{}," A ",[24,716,717],{},".gpkg"," extension writes a GeoPackage (recommended — no field-name truncation, full Unicode, single file). Use ",[24,720,721],{},".geojson"," for web delivery or ",[24,724,725],{},".shp"," only when a consumer specifically requires it. GeoPackage is the safest default for production outputs.",[14,728,729,730,733],{},"To both write a file and load it into the current project, use ",[24,731,732],{},"processing.runAndLoadResults",", which honors the layer name you supply:",[105,735,737],{"className":107,"code":736,"language":109,"meta":110,"style":110},"processing.runAndLoadResults(\"native:clip\", {\n    \"INPUT\": \"\u002Fdata\u002Froads.shp\",\n    \"OVERLAY\": \"\u002Fdata\u002Fstudy_area.gpkg|layername=boundary\",\n    \"OUTPUT\": \"\u002Fdata\u002Foutput\u002Froads_clipped.gpkg\",\n})\n",[24,738,739,748,758,768,778],{"__ignoreMap":110},[114,740,741,744,746],{"class":116,"line":117},[114,742,743],{"class":124},"processing.runAndLoadResults(",[114,745,210],{"class":161},[114,747,213],{"class":124},[114,749,750,752,754,756],{"class":116,"line":128},[114,751,219],{"class":161},[114,753,240],{"class":124},[114,755,362],{"class":161},[114,757,246],{"class":124},[114,759,760,762,764,766],{"class":116,"line":142},[114,761,228],{"class":161},[114,763,240],{"class":124},[114,765,373],{"class":161},[114,767,246],{"class":124},[114,769,770,772,774,776],{"class":116,"line":149},[114,771,237],{"class":161},[114,773,240],{"class":124},[114,775,703],{"class":161},[114,777,246],{"class":124},[114,779,780],{"class":116,"line":175},[114,781,252],{"class":124},[14,783,784,309,786,789,790,792,793,88],{},[47,785,308],{},[24,787,788],{},"runAndLoadResults"," runs the algorithm and adds the output to the layer tree automatically — handy in the Console but avoid it in headless batch scripts where no canvas exists. To load a ",[24,791,316],{}," result manually, call ",[24,794,795],{},"QgsProject.instance().addMapLayer(result[\"OUTPUT\"])",[32,797,799],{"id":798},"clip-vs-intersection-vs-difference","Clip vs Intersection vs Difference",[14,801,802],{},"These three overlay tools are easy to confuse:",[804,805,806,822],"table",{},[807,808,809],"thead",{},[810,811,812,816,819],"tr",{},[813,814,815],"th",{},"Algorithm",[813,817,818],{},"What it keeps",[813,820,821],{},"Attributes",[823,824,825,842,859],"tbody",{},[810,826,827,832,839],{},[828,829,830],"td",{},[24,831,26],{},[828,833,834,835,838],{},"Input geometry ",[47,836,837],{},"inside"," the overlay",[828,840,841],{},"Input attributes only",[810,843,844,849,852],{},[828,845,846],{},[24,847,848],{},"native:intersection",[828,850,851],{},"Geometry inside the overlay",[828,853,854,855,858],{},"Input ",[47,856,857],{},"and"," overlay attributes merged",[810,860,861,866,871],{},[828,862,863],{},[24,864,865],{},"native:difference",[828,867,834,868,838],{},[47,869,870],{},"outside",[828,872,841],{},[14,874,875,876,878,879,881,882,884,885,889],{},"Use ",[24,877,26],{}," when you only want a cookie-cutter of the input and do not care about the mask's attributes. Use ",[24,880,848],{}," when you need each output feature tagged with the polygon it fell into (for example, joining parcels to the zoning district that contains them). Use ",[24,883,865],{}," to ",[886,887,888],"em",{},"erase"," — keep everything outside the mask, such as land area minus water bodies:",[105,891,893],{"className":107,"code":892,"language":109,"meta":110,"style":110},"import processing\n\nland_minus_water = processing.run(\"native:difference\", {\n    \"INPUT\": \"\u002Fdata\u002Fland.gpkg\",\n    \"OVERLAY\": \"\u002Fdata\u002Flakes.gpkg\",\n    \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n})[\"OUTPUT\"]\n",[24,894,895,901,905,919,930,941,951],{"__ignoreMap":110},[114,896,897,899],{"class":116,"line":117},[114,898,121],{"class":120},[114,900,125],{"class":124},[114,902,903],{"class":116,"line":128},[114,904,146],{"emptyLinePlaceholder":145},[114,906,907,910,912,914,917],{"class":116,"line":142},[114,908,909],{"class":124},"land_minus_water ",[114,911,155],{"class":120},[114,913,207],{"class":124},[114,915,916],{"class":161},"\"native:difference\"",[114,918,213],{"class":124},[114,920,921,923,925,928],{"class":116,"line":149},[114,922,219],{"class":161},[114,924,240],{"class":124},[114,926,927],{"class":161},"\"\u002Fdata\u002Fland.gpkg\"",[114,929,246],{"class":124},[114,931,932,934,936,939],{"class":116,"line":175},[114,933,228],{"class":161},[114,935,240],{"class":124},[114,937,938],{"class":161},"\"\u002Fdata\u002Flakes.gpkg\"",[114,940,246],{"class":124},[114,942,943,945,947,949],{"class":116,"line":194},[114,944,237],{"class":161},[114,946,240],{"class":124},[114,948,243],{"class":161},[114,950,246],{"class":124},[114,952,953,956,958],{"class":116,"line":199},[114,954,955],{"class":124},"})[",[114,957,271],{"class":161},[114,959,172],{"class":124},[14,961,962,309,964,966,967,970,971,973,974,977],{},[47,963,308],{},[24,965,865],{}," is the geometric inverse of ",[24,968,969],{},"clip",". Swapping ",[24,972,969],{}," for ",[24,975,976],{},"difference"," with the same arguments returns the complementary part of the input.",[14,979,980,981,985],{},"Clipping pairs naturally with buffering when you need to trim features to a zone of influence — see ",[18,982,984],{"href":983},"\u002Fspatial-data-processing-automation\u002Fchaining-processing-algorithms\u002Fchain-buffer-and-clip-pyqgis\u002F","Chain a Buffer and Clip in PyQGIS"," for the combined workflow.",[32,987,989],{"id":988},"clip-many-layers-in-a-loop","Clip Many Layers in a Loop",[14,991,992],{},"A single clip is rarely the whole job. When several layers must be trimmed to the same study area, iterate them and write each result to its own file. Reproject the overlay once, before the loop, so the work is not repeated:",[105,994,996],{"className":107,"code":995,"language":109,"meta":110,"style":110},"import processing\nfrom pathlib import Path\nfrom qgis.core import QgsVectorLayer\n\noverlay = \"\u002Fdata\u002Fstudy_area.gpkg|layername=boundary\"\ninputs = [\"\u002Fdata\u002Froads.shp\", \"\u002Fdata\u002Frivers.shp\", \"\u002Fdata\u002Fparcels.shp\"]\noutput_dir = Path(\"\u002Fdata\u002Foutput\")\noutput_dir.mkdir(parents=True, exist_ok=True)\n\nfor path in inputs:\n    name = Path(path).stem\n    out_path = output_dir \u002F f\"{name}_clipped.gpkg\"\n    processing.run(\"native:clip\", {\n        \"INPUT\": path,\n        \"OVERLAY\": overlay,\n        \"OUTPUT\": str(out_path),\n    })\n    print(f\"Clipped {name} -> {out_path.name}\")\n",[24,997,998,1004,1016,1027,1031,1041,1066,1081,1106,1110,1124,1134,1163,1172,1179,1187,1199,1204],{"__ignoreMap":110},[114,999,1000,1002],{"class":116,"line":117},[114,1001,121],{"class":120},[114,1003,125],{"class":124},[114,1005,1006,1008,1011,1013],{"class":116,"line":128},[114,1007,131],{"class":120},[114,1009,1010],{"class":124}," pathlib ",[114,1012,121],{"class":120},[114,1014,1015],{"class":124}," Path\n",[114,1017,1018,1020,1022,1024],{"class":116,"line":142},[114,1019,131],{"class":120},[114,1021,134],{"class":124},[114,1023,121],{"class":120},[114,1025,1026],{"class":124}," QgsVectorLayer\n",[114,1028,1029],{"class":116,"line":149},[114,1030,146],{"emptyLinePlaceholder":145},[114,1032,1033,1036,1038],{"class":116,"line":175},[114,1034,1035],{"class":124},"overlay ",[114,1037,155],{"class":120},[114,1039,1040],{"class":161}," \"\u002Fdata\u002Fstudy_area.gpkg|layername=boundary\"\n",[114,1042,1043,1046,1048,1051,1053,1056,1059,1061,1064],{"class":116,"line":194},[114,1044,1045],{"class":124},"inputs ",[114,1047,155],{"class":120},[114,1049,1050],{"class":124}," [",[114,1052,362],{"class":161},[114,1054,1055],{"class":124},", ",[114,1057,1058],{"class":161},"\"\u002Fdata\u002Frivers.shp\"",[114,1060,1055],{"class":124},[114,1062,1063],{"class":161},"\"\u002Fdata\u002Fparcels.shp\"",[114,1065,172],{"class":124},[114,1067,1068,1071,1073,1076,1079],{"class":116,"line":199},[114,1069,1070],{"class":124},"output_dir ",[114,1072,155],{"class":120},[114,1074,1075],{"class":124}," Path(",[114,1077,1078],{"class":161},"\"\u002Fdata\u002Foutput\"",[114,1080,303],{"class":124},[114,1082,1083,1086,1090,1092,1095,1097,1100,1102,1104],{"class":116,"line":216},[114,1084,1085],{"class":124},"output_dir.mkdir(",[114,1087,1089],{"class":1088},"s9osk","parents",[114,1091,155],{"class":120},[114,1093,1094],{"class":168},"True",[114,1096,1055],{"class":124},[114,1098,1099],{"class":1088},"exist_ok",[114,1101,155],{"class":120},[114,1103,1094],{"class":168},[114,1105,303],{"class":124},[114,1107,1108],{"class":116,"line":225},[114,1109,146],{"emptyLinePlaceholder":145},[114,1111,1112,1115,1118,1121],{"class":116,"line":234},[114,1113,1114],{"class":120},"for",[114,1116,1117],{"class":124}," path ",[114,1119,1120],{"class":120},"in",[114,1122,1123],{"class":124}," inputs:\n",[114,1125,1126,1129,1131],{"class":116,"line":249},[114,1127,1128],{"class":124},"    name ",[114,1130,155],{"class":120},[114,1132,1133],{"class":124}," Path(path).stem\n",[114,1135,1136,1139,1141,1144,1147,1150,1153,1155,1158,1160],{"class":116,"line":255},[114,1137,1138],{"class":124},"    out_path ",[114,1140,155],{"class":120},[114,1142,1143],{"class":124}," output_dir ",[114,1145,1146],{"class":120},"\u002F",[114,1148,1149],{"class":120}," f",[114,1151,1152],{"class":161},"\"",[114,1154,291],{"class":168},[114,1156,1157],{"class":124},"name",[114,1159,297],{"class":168},[114,1161,1162],{"class":161},"_clipped.gpkg\"\n",[114,1164,1165,1168,1170],{"class":116,"line":260},[114,1166,1167],{"class":124},"    processing.run(",[114,1169,210],{"class":161},[114,1171,213],{"class":124},[114,1173,1174,1176],{"class":116,"line":276},[114,1175,509],{"class":161},[114,1177,1178],{"class":124},": path,\n",[114,1180,1181,1184],{"class":116,"line":556},[114,1182,1183],{"class":161},"        \"OVERLAY\"",[114,1185,1186],{"class":124},": overlay,\n",[114,1188,1189,1191,1193,1196],{"class":116,"line":569},[114,1190,524],{"class":161},[114,1192,240],{"class":124},[114,1194,1195],{"class":168},"str",[114,1197,1198],{"class":124},"(out_path),\n",[114,1200,1201],{"class":116,"line":576},[114,1202,1203],{"class":124},"    })\n",[114,1205,1206,1209,1211,1213,1216,1218,1220,1222,1225,1227,1230,1232,1234],{"class":116,"line":583},[114,1207,1208],{"class":168},"    print",[114,1210,282],{"class":124},[114,1212,285],{"class":120},[114,1214,1215],{"class":161},"\"Clipped ",[114,1217,291],{"class":168},[114,1219,1157],{"class":124},[114,1221,297],{"class":168},[114,1223,1224],{"class":161}," -> ",[114,1226,291],{"class":168},[114,1228,1229],{"class":124},"out_path.name",[114,1231,297],{"class":168},[114,1233,1152],{"class":161},[114,1235,303],{"class":124},[14,1237,1238,1240,1241,1244],{},[47,1239,308],{}," The overlay path is reused for every input, and ",[24,1242,1243],{},"Path(path).stem"," builds a clean per-layer output name. Each call writes a GeoPackage so the results persist. This same loop scales to a globbed folder of inputs and is the building block of a headless clipping pipeline.",[32,1246,1248],{"id":1247},"select-then-clip","Select Then Clip",[14,1250,1251,1252,1254,1255,1258],{},"Sometimes the mask is not a separate file but a feature you have already selected on the map — a single county from a counties layer, say. ",[24,1253,26],{}," honors a selection when you set the ",[24,1256,1257],{},"selected features only"," flag through the algorithm context, but the simplest robust approach is to materialize the selection first:",[105,1260,1262],{"className":107,"code":1261,"language":109,"meta":110,"style":110},"import processing\nfrom qgis.core import QgsProject\n\ncounties = QgsProject.instance().mapLayersByName(\"counties\")[0]\ncounties.selectByExpression('\"name\" = \\'Marion\\'')\n\nselected_mask = processing.run(\"native:saveselectedfeatures\", {\n    \"INPUT\": counties,\n    \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n})[\"OUTPUT\"]\n\nclipped = processing.run(\"native:clip\", {\n    \"INPUT\": \"\u002Fdata\u002Froads.shp\",\n    \"OVERLAY\": selected_mask,\n    \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n})[\"OUTPUT\"]\n",[24,1263,1264,1270,1280,1284,1302,1323,1327,1341,1348,1358,1366,1370,1382,1392,1399,1409],{"__ignoreMap":110},[114,1265,1266,1268],{"class":116,"line":117},[114,1267,121],{"class":120},[114,1269,125],{"class":124},[114,1271,1272,1274,1276,1278],{"class":116,"line":128},[114,1273,131],{"class":120},[114,1275,134],{"class":124},[114,1277,121],{"class":120},[114,1279,139],{"class":124},[114,1281,1282],{"class":116,"line":142},[114,1283,146],{"emptyLinePlaceholder":145},[114,1285,1286,1289,1291,1293,1296,1298,1300],{"class":116,"line":149},[114,1287,1288],{"class":124},"counties ",[114,1290,155],{"class":120},[114,1292,158],{"class":124},[114,1294,1295],{"class":161},"\"counties\"",[114,1297,165],{"class":124},[114,1299,169],{"class":168},[114,1301,172],{"class":124},[114,1303,1304,1307,1310,1313,1316,1318,1321],{"class":116,"line":175},[114,1305,1306],{"class":124},"counties.selectByExpression(",[114,1308,1309],{"class":161},"'\"name\" = ",[114,1311,1312],{"class":168},"\\'",[114,1314,1315],{"class":161},"Marion",[114,1317,1312],{"class":168},[114,1319,1320],{"class":161},"'",[114,1322,303],{"class":124},[114,1324,1325],{"class":116,"line":194},[114,1326,146],{"emptyLinePlaceholder":145},[114,1328,1329,1332,1334,1336,1339],{"class":116,"line":199},[114,1330,1331],{"class":124},"selected_mask ",[114,1333,155],{"class":120},[114,1335,207],{"class":124},[114,1337,1338],{"class":161},"\"native:saveselectedfeatures\"",[114,1340,213],{"class":124},[114,1342,1343,1345],{"class":116,"line":216},[114,1344,219],{"class":161},[114,1346,1347],{"class":124},": counties,\n",[114,1349,1350,1352,1354,1356],{"class":116,"line":225},[114,1351,237],{"class":161},[114,1353,240],{"class":124},[114,1355,243],{"class":161},[114,1357,246],{"class":124},[114,1359,1360,1362,1364],{"class":116,"line":234},[114,1361,955],{"class":124},[114,1363,271],{"class":161},[114,1365,172],{"class":124},[114,1367,1368],{"class":116,"line":249},[114,1369,146],{"emptyLinePlaceholder":145},[114,1371,1372,1374,1376,1378,1380],{"class":116,"line":255},[114,1373,263],{"class":124},[114,1375,155],{"class":120},[114,1377,207],{"class":124},[114,1379,210],{"class":161},[114,1381,213],{"class":124},[114,1383,1384,1386,1388,1390],{"class":116,"line":260},[114,1385,219],{"class":161},[114,1387,240],{"class":124},[114,1389,362],{"class":161},[114,1391,246],{"class":124},[114,1393,1394,1396],{"class":116,"line":276},[114,1395,228],{"class":161},[114,1397,1398],{"class":124},": selected_mask,\n",[114,1400,1401,1403,1405,1407],{"class":116,"line":556},[114,1402,237],{"class":161},[114,1404,240],{"class":124},[114,1406,243],{"class":161},[114,1408,246],{"class":124},[114,1410,1411,1413,1415],{"class":116,"line":569},[114,1412,955],{"class":124},[114,1414,271],{"class":161},[114,1416,172],{"class":124},[14,1418,1419,309,1421,1424,1425,1428],{},[47,1420,308],{},[24,1422,1423],{},"selectByExpression"," picks the mask feature by attribute, ",[24,1426,1427],{},"native:saveselectedfeatures"," turns that selection into a standalone temporary layer, and that layer becomes the clip overlay. This avoids editing the source counties layer and keeps the mask to exactly the feature you intended.",[32,1430,1432],{"id":1431},"qgis-version-compatibility","QGIS Version Compatibility",[14,1434,1435,1436,1439,1440,1442],{},"The examples target ",[47,1437,1438],{},"QGIS 3.34 LTR"," (Python 3.12), where ",[24,1441,26],{}," is stable and well established.",[804,1444,1445,1458],{},[807,1446,1447],{},[810,1448,1449,1452,1455],{},[813,1450,1451],{},"QGIS version",[813,1453,1454],{},"Python",[813,1456,1457],{},"Notes",[823,1459,1460,1476,1487],{},[810,1461,1462,1465,1468],{},[828,1463,1464],{},"3.28 LTR",[828,1466,1467],{},"3.9",[828,1469,1470,1472,1473,1475],{},[24,1471,26],{}," identical; ",[24,1474,312],{}," API unchanged.",[810,1477,1478,1481,1484],{},[828,1479,1480],{},"3.34 LTR",[828,1482,1483],{},"3.12",[828,1485,1486],{},"Baseline for this page.",[810,1488,1489,1492,1494],{},[828,1490,1491],{},"3.40 \u002F 3.44",[828,1493,1483],{},[828,1495,1496],{},"Same algorithm ID and parameters; faster GEOS-backed clipping on large layers.",[14,1498,1499,1500,1502,1503,1146,1505,1146,1507,1509,1510,1512],{},"The ",[24,1501,26],{}," algorithm ID, its ",[24,1504,98],{},[24,1506,102],{},[24,1508,649],{}," parameters, and the ",[24,1511,316],{}," token are unchanged across all current 3.x releases, so this code is portable without modification.",[32,1514,1516],{"id":1515},"troubleshooting","Troubleshooting",[37,1518,1519,1525,1539,1549,1559],{},[40,1520,1521,1524],{},[47,1522,1523],{},"Output has zero features."," Almost always a CRS mismatch — reproject the overlay into the input's CRS as shown above. Also confirm the two layers actually overlap spatially.",[40,1526,1527,1532,1533,1535,1536,88],{},[47,1528,1529,88],{},[24,1530,1531],{},"Could not load source layer"," A file path is wrong, or you forgot the ",[24,1534,397],{}," suffix for a multi-layer GeoPackage. Verify with ",[24,1537,1538],{},"QgsVectorLayer(path, \"test\", \"ogr\").isValid()",[40,1540,1541,1544,1545,1548],{},[47,1542,1543],{},"Invalid geometry errors."," Self-intersecting overlay polygons can abort the clip. Run ",[24,1546,1547],{},"native:fixgeometries"," on the overlay first, then clip the cleaned result.",[40,1550,1551,1554,1555,1558],{},[47,1552,1553],{},"Slivers or unexpected boundaries."," Overlapping or duplicate polygons in the overlay create double-clipped slivers. Dissolve the overlay with ",[24,1556,1557],{},"native:dissolve"," before clipping if it should act as a single mask.",[40,1560,1561,309,1564,1566,1567,1569,1570,88],{},[47,1562,1563],{},"Result not visible in the project.",[24,1565,316],{}," returns a layer but does not add it to the tree; call ",[24,1568,795],{}," or use ",[24,1571,788],{},[32,1573,1575],{"id":1574},"conclusion","Conclusion",[14,1577,1578,1580,1581,1583],{},[24,1579,26],{}," is the precise, repeatable way to trim a vector layer to a mask in PyQGIS. The keys to reliable results are matching the CRS of input and overlay before running, choosing ",[24,1582,316],{}," for intermediate steps versus a GeoPackage path for deliverables, and picking the right overlay tool — clip to cut, intersection to tag, difference to erase. With those settled, the same few lines scale from one-off Console work to fully automated pipelines.",[32,1585,1587],{"id":1586},"frequently-asked-questions","Frequently Asked Questions",[14,1589,1590,1593,1594,1596],{},[47,1591,1592],{},"Does native:clip reproject layers automatically?","\nNo. It compares coordinates directly and assumes both layers share a CRS. Reproject the overlay into the input's CRS with ",[24,1595,629],{}," first, or you may get an empty output with no warning.",[14,1598,1599,1602,1603,1605,1606,1608],{},[47,1600,1601],{},"Can I clip points and lines, or only polygons?","\nAny geometry type works as the ",[24,1604,98],{},". Points outside the mask are dropped; lines are split at the boundary and the outside segments removed. The ",[24,1607,102],{}," must be polygons.",[14,1610,1611,1614],{},[47,1612,1613],{},"What is the difference between clip and intersection?","\nClip keeps input attributes only and acts as a cookie cutter. Intersection also keeps the overlay's attributes, so each output feature records which mask polygon it intersected. Choose intersection when you need that tagging.",[14,1616,1617,1620,1621,1623,1624,1627,1628,1630],{},[47,1618,1619],{},"How do I keep the clipped layer after closing QGIS?","\nWrite ",[24,1622,649],{}," to a file path such as ",[24,1625,1626],{},"\u002Fdata\u002Froads_clipped.gpkg"," instead of ",[24,1629,316],{},". The driver is chosen from the extension; GeoPackage is the recommended default.",[32,1632,1634],{"id":1633},"related","Related",[37,1636,1637,1642,1648],{},[40,1638,1639],{},[18,1640,1641],{"href":20},"Vector Data Manipulation in PyQGIS",[40,1643,1644],{},[18,1645,1647],{"href":1646},"\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fmerge-multiple-shapefiles-pyqgis\u002F","Merge Multiple Shapefiles in PyQGIS",[40,1649,1650],{},[18,1651,984],{"href":983},[1653,1654,1655],"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 .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}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);}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":110,"searchDepth":128,"depth":128,"links":1657},[1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669],{"id":34,"depth":128,"text":35},{"id":91,"depth":128,"text":92},{"id":401,"depth":128,"text":402},{"id":640,"depth":128,"text":641},{"id":798,"depth":128,"text":799},{"id":988,"depth":128,"text":989},{"id":1247,"depth":128,"text":1248},{"id":1431,"depth":128,"text":1432},{"id":1515,"depth":128,"text":1516},{"id":1574,"depth":128,"text":1575},{"id":1586,"depth":128,"text":1587},{"id":1633,"depth":128,"text":1634},"Clip a vector layer by a mask polygon in PyQGIS with native:clip. Align CRS, choose temporary or file output, and load the trimmed result.","md",{},"\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fclip-vector-layer-pyqgis",{"title":5,"description":1670},"spatial-data-processing-automation\u002Fvector-data-manipulation\u002Fclip-vector-layer-pyqgis\u002Findex","PTo0ab02IFt6YiYaxH9DcVdH8QxIr-JsdFCsbSp_RWw",1781792483477]