[{"data":1,"prerenderedAt":2121},["ShallowReactive",2],{"doc:\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fclip-vector-layer-pyqgis":3},{"id":4,"title":5,"body":6,"description":2109,"extension":2110,"meta":2111,"navigation":145,"path":2117,"seo":2118,"stem":2119,"__hash__":2120},"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":2095},"minimark",[9,13,28,31,36,69,89,93,104,304,326,337,390,399,402,568,575,579,589,592,791,807,814,818,827,886,903,910,958,972,976,979,1131,1198,1215,1285,1303,1311,1315,1318,1561,1570,1574,1584,1742,1754,1758,1768,1822,1838,1842,1845,1956,2011,2015,2023,2027,2036,2048,2054,2070,2074,2091],[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.",[14,400,401],{},"What the clip does to each geometry type is worth picturing before running it on real data, because the feature count almost never survives unchanged.",[14,403,404],{},[405,406,411,415,419,425,434,501,533],"svg",{"viewBox":407,"role":408,"ariaLabel":409,"xmlns":410},"0 0 760 246","img","A clip applied to a point layer, a line layer and a polygon layer, showing points dropped, lines split at the boundary and polygons trimmed","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[412,413,414],"title",{},"What a clip does to each geometry type",[416,417,418],"desc",{},"The same circular mask is applied to three layers. Points outside the mask are dropped entirely and the feature count falls. Lines crossing the boundary are cut, keeping only the inside segment, so a single road can become a shorter road or disappear. Polygons are trimmed at the boundary, keeping their attributes but changing their area.",[420,421],"rect",{"x":169,"y":169,"width":422,"height":423,"fill":424},"760","246","#f6f3ea",[426,427,433],"text",{"x":428,"y":429,"style":430,"fill":431,"textAnchor":432},"380","26","text-anchor:middle;font-size:14px;font-weight:bold;font-family:sans-serif","#17211d","middle","Attributes survive; geometry and feature count do not",[435,436,437,447,453,461,476,496],"g",{},[420,438],{"x":439,"y":440,"width":441,"height":442,"rx":443,"fill":444,"stroke":445,"style":446},"12","46","236","184","10","#fffdf7","#2563eb","stroke-width:2.5",[426,448,452],{"x":449,"y":450,"style":451,"fill":445,"textAnchor":432},"130","70","text-anchor:middle;font-size:12px;font-weight:bold;font-family:sans-serif","points",[454,455],"circle",{"cx":449,"cy":456,"r":457,"fill":458,"fillOpacity":459,"stroke":458,"style":460},"140","56","#0f766e",0.08,"stroke-width:2;stroke-dasharray:5 4",[435,462,464,469,473],{"fill":463},"#15803d",[454,465],{"cx":466,"cy":467,"r":468},"112","120","6",[454,470],{"cx":471,"cy":472,"r":468},"146","152",[454,474],{"cx":467,"cy":475,"r":468},"166",[435,477,480,484,488,492],{"fill":478,"fillOpacity":479},"#59645f",0.45,[454,481],{"cx":482,"cy":483,"r":468},"44","92",[454,485],{"cx":486,"cy":487,"r":468},"212","104",[454,489],{"cx":490,"cy":491,"r":468},"52","196",[454,493],{"cx":494,"cy":495,"r":468},"216","192",[426,497,500],{"x":449,"y":494,"style":498,"fill":499,"textAnchor":432},"text-anchor:middle;font-size:11px;font-family:sans-serif","#2f3b35","outside points dropped · 7 → 3",[435,502,503,507,510,512,517,521,524,527,530],{},[420,504],{"x":505,"y":440,"width":441,"height":442,"rx":443,"fill":444,"stroke":506,"style":446},"262","#b45309",[426,508,509],{"x":428,"y":450,"style":451,"fill":506,"textAnchor":432},"lines",[454,511],{"cx":428,"cy":456,"r":457,"fill":458,"fillOpacity":459,"stroke":458,"style":460},[513,514],"path",{"d":515,"fill":516,"stroke":478,"style":446,"strokeOpacity":479},"M286 104 L324 128","none",[513,518],{"d":519,"fill":516,"stroke":463,"style":520},"M324 128 L380 116 L428 148","stroke-width:3.5",[513,522],{"d":523,"fill":516,"stroke":478,"style":446,"strokeOpacity":479},"M428 148 L474 190",[513,525],{"d":526,"fill":516,"stroke":478,"style":446,"strokeOpacity":479},"M292 190 L336 174",[513,528],{"d":529,"fill":516,"stroke":463,"style":520},"M336 174 L392 182",[426,531,532],{"x":428,"y":494,"style":498,"fill":499,"textAnchor":432},"split at the boundary · length falls",[435,534,535,538,542,555,559,563,565],{},[420,536],{"x":537,"y":440,"width":441,"height":442,"rx":443,"fill":444,"stroke":463,"style":446},"512",[426,539,541],{"x":540,"y":450,"style":451,"fill":463,"textAnchor":432},"630","polygons",[543,544,545],"defs",{},[546,547,549,552],"mask",{"id":548},"clipTypeMask",[420,550],{"x":169,"y":169,"width":422,"height":423,"fill":551},"#000000",[454,553],{"cx":540,"cy":456,"r":457,"fill":554},"#ffffff",[513,556],{"d":557,"fill":516,"stroke":478,"style":558},"M552 190 L556 96 L664 88 L700 150 L648 200 Z","stroke-width:2;stroke-dasharray:4 3",[513,560],{"d":557,"fill":463,"fillOpacity":561,"stroke":463,"style":562},0.35,"stroke-width:2.5;mask:url(#clipTypeMask)",[454,564],{"cx":540,"cy":456,"r":457,"fill":516,"stroke":458,"style":460},[426,566,567],{"x":540,"y":494,"style":498,"fill":499,"textAnchor":432},"trimmed · area falls, attributes kept",[14,569,570,571,88],{},"The consequence worth planning for is that a clipped road is no longer the same road: its length attribute, if one was stored, is now wrong. Recomputing derived measurements after a clip is nearly always necessary — see ",[18,572,574],{"href":573},"\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fpyqgis-script-to-calculate-polygon-areas\u002F","PyQGIS Script to Calculate Polygon Areas",[32,576,578],{"id":577},"align-the-crs-before-clipping","Align the CRS Before Clipping",[14,580,581,582,584,585,588],{},"The single most common cause of an empty or wrong clip is a coordinate reference system mismatch. ",[24,583,26],{}," does ",[47,586,587],{},"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,590,591],{},"Check the CRS of both layers and reproject the overlay when they differ:",[105,593,595],{"className":107,"code":594,"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,596,597,603,613,617,633,649,653,667,681,688,696,707,716,726,730,743,750,757,768,773],{"__ignoreMap":110},[114,598,599,601],{"class":116,"line":117},[114,600,121],{"class":120},[114,602,125],{"class":124},[114,604,605,607,609,611],{"class":116,"line":128},[114,606,131],{"class":120},[114,608,134],{"class":124},[114,610,121],{"class":120},[114,612,139],{"class":124},[114,614,615],{"class":116,"line":142},[114,616,146],{"emptyLinePlaceholder":145},[114,618,619,621,623,625,627,629,631],{"class":116,"line":149},[114,620,152],{"class":124},[114,622,155],{"class":120},[114,624,158],{"class":124},[114,626,162],{"class":161},[114,628,165],{"class":124},[114,630,169],{"class":168},[114,632,172],{"class":124},[114,634,635,637,639,641,643,645,647],{"class":116,"line":175},[114,636,178],{"class":124},[114,638,155],{"class":120},[114,640,158],{"class":124},[114,642,185],{"class":161},[114,644,165],{"class":124},[114,646,169],{"class":168},[114,648,172],{"class":124},[114,650,651],{"class":116,"line":194},[114,652,146],{"emptyLinePlaceholder":145},[114,654,655,658,661,664],{"class":116,"line":199},[114,656,657],{"class":120},"if",[114,659,660],{"class":124}," input_layer.crs() ",[114,662,663],{"class":120},"!=",[114,665,666],{"class":124}," overlay_layer.crs():\n",[114,668,669,672,674,676,679],{"class":116,"line":216},[114,670,671],{"class":124},"    reprojected ",[114,673,155],{"class":120},[114,675,207],{"class":124},[114,677,678],{"class":161},"\"native:reprojectlayer\"",[114,680,213],{"class":124},[114,682,683,686],{"class":116,"line":225},[114,684,685],{"class":161},"        \"INPUT\"",[114,687,231],{"class":124},[114,689,690,693],{"class":116,"line":234},[114,691,692],{"class":161},"        \"TARGET_CRS\"",[114,694,695],{"class":124},": input_layer.crs(),\n",[114,697,698,701,703,705],{"class":116,"line":249},[114,699,700],{"class":161},"        \"OUTPUT\"",[114,702,240],{"class":124},[114,704,243],{"class":161},[114,706,246],{"class":124},[114,708,709,712,714],{"class":116,"line":255},[114,710,711],{"class":124},"    })[",[114,713,271],{"class":161},[114,715,172],{"class":124},[114,717,718,721,723],{"class":116,"line":260},[114,719,720],{"class":124},"    overlay_layer ",[114,722,155],{"class":120},[114,724,725],{"class":124}," reprojected\n",[114,727,728],{"class":116,"line":276},[114,729,146],{"emptyLinePlaceholder":145},[114,731,733,735,737,739,741],{"class":116,"line":732},15,[114,734,202],{"class":124},[114,736,155],{"class":120},[114,738,207],{"class":124},[114,740,210],{"class":161},[114,742,213],{"class":124},[114,744,746,748],{"class":116,"line":745},16,[114,747,219],{"class":161},[114,749,222],{"class":124},[114,751,753,755],{"class":116,"line":752},17,[114,754,228],{"class":161},[114,756,231],{"class":124},[114,758,760,762,764,766],{"class":116,"line":759},18,[114,761,237],{"class":161},[114,763,240],{"class":124},[114,765,243],{"class":161},[114,767,246],{"class":124},[114,769,771],{"class":116,"line":770},19,[114,772,252],{"class":124},[114,774,776,778,780,783,786,788],{"class":116,"line":775},20,[114,777,279],{"class":168},[114,779,282],{"class":124},[114,781,782],{"class":161},"\"Output CRS:\"",[114,784,785],{"class":124},", result[",[114,787,271],{"class":161},[114,789,790],{"class":124},"].crs().authid())\n",[14,792,793,795,796,799,800,802,803,806],{},[47,794,308],{}," Comparing ",[24,797,798],{},"QgsCoordinateReferenceSystem"," objects with ",[24,801,663],{}," is reliable. When they differ, ",[24,804,805],{},"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,808,809,810,88],{},"For more on diagnosing and fixing projection problems, see ",[18,811,813],{"href":812},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002F","Coordinate Reference Systems",[32,815,817],{"id":816},"temporary-output-vs-file-output","Temporary Output vs File Output",[14,819,820,822,823,826],{},[24,821,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,824,825],{},"OUTPUT"," a path. The driver is inferred from the extension:",[105,828,830],{"className":107,"code":829,"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,831,832,838,842,851,861,871,882],{"__ignoreMap":110},[114,833,834,836],{"class":116,"line":117},[114,835,121],{"class":120},[114,837,125],{"class":124},[114,839,840],{"class":116,"line":128},[114,841,146],{"emptyLinePlaceholder":145},[114,843,844,847,849],{"class":116,"line":142},[114,845,846],{"class":124},"processing.run(",[114,848,210],{"class":161},[114,850,213],{"class":124},[114,852,853,855,857,859],{"class":116,"line":149},[114,854,219],{"class":161},[114,856,240],{"class":124},[114,858,362],{"class":161},[114,860,246],{"class":124},[114,862,863,865,867,869],{"class":116,"line":175},[114,864,228],{"class":161},[114,866,240],{"class":124},[114,868,373],{"class":161},[114,870,246],{"class":124},[114,872,873,875,877,880],{"class":116,"line":194},[114,874,237],{"class":161},[114,876,240],{"class":124},[114,878,879],{"class":161},"\"\u002Fdata\u002Foutput\u002Froads_clipped.gpkg\"",[114,881,246],{"class":124},[114,883,884],{"class":116,"line":199},[114,885,252],{"class":124},[14,887,888,890,891,894,895,898,899,902],{},[47,889,308],{}," A ",[24,892,893],{},".gpkg"," extension writes a GeoPackage (recommended — no field-name truncation, full Unicode, single file). Use ",[24,896,897],{},".geojson"," for web delivery or ",[24,900,901],{},".shp"," only when a consumer specifically requires it. GeoPackage is the safest default for production outputs.",[14,904,905,906,909],{},"To both write a file and load it into the current project, use ",[24,907,908],{},"processing.runAndLoadResults",", which honors the layer name you supply:",[105,911,913],{"className":107,"code":912,"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,914,915,924,934,944,954],{"__ignoreMap":110},[114,916,917,920,922],{"class":116,"line":117},[114,918,919],{"class":124},"processing.runAndLoadResults(",[114,921,210],{"class":161},[114,923,213],{"class":124},[114,925,926,928,930,932],{"class":116,"line":128},[114,927,219],{"class":161},[114,929,240],{"class":124},[114,931,362],{"class":161},[114,933,246],{"class":124},[114,935,936,938,940,942],{"class":116,"line":142},[114,937,228],{"class":161},[114,939,240],{"class":124},[114,941,373],{"class":161},[114,943,246],{"class":124},[114,945,946,948,950,952],{"class":116,"line":149},[114,947,237],{"class":161},[114,949,240],{"class":124},[114,951,879],{"class":161},[114,953,246],{"class":124},[114,955,956],{"class":116,"line":175},[114,957,252],{"class":124},[14,959,960,309,962,965,966,968,969,88],{},[47,961,308],{},[24,963,964],{},"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,967,316],{}," result manually, call ",[24,970,971],{},"QgsProject.instance().addMapLayer(result[\"OUTPUT\"])",[32,973,975],{"id":974},"clip-vs-intersection-vs-difference","Clip vs Intersection vs Difference",[14,977,978],{},"These three overlay tools are easy to confuse:",[405,980,983,986,989,1019,1021,1026,1057,1086,1109],{"viewBox":981,"role":408,"ariaLabel":982,"xmlns":410},"0 0 760 300","Clip, intersection and difference compared on the same input rectangle crossing a circular mask",[412,984,985],{},"Clip vs intersection vs difference on one input and mask",[416,987,988],{},"The same blue input rectangle crosses a teal circular mask in three panels. native:clip keeps the green inside portion with input attributes only, native:intersection keeps the same inside geometry but merges input and overlay attributes, and native:difference keeps the outside portion with input attributes only.",[543,990,991,1001,1008],{},[546,992,994,997],{"id":993},"clipInA",[420,995],{"x":169,"y":169,"width":422,"height":996,"fill":551},"300",[454,998],{"cx":999,"cy":1000,"r":490,"fill":554},"128","180",[546,1002,1004,1006],{"id":1003},"clipInB",[420,1005],{"x":169,"y":169,"width":422,"height":996,"fill":551},[454,1007],{"cx":428,"cy":1000,"r":490,"fill":554},[546,1009,1011,1016],{"id":1010},"maskOutC",[420,1012],{"x":537,"y":1013,"width":1014,"height":1015,"fill":554},"60","240","210",[454,1017],{"cx":1018,"cy":1000,"r":490,"fill":551},"632",[420,1020],{"x":169,"y":169,"width":422,"height":996,"fill":424},[426,1022,1025],{"x":428,"y":1023,"style":1024,"fill":431,"textAnchor":432},"24","text-anchor:middle;font-size:13px;font-weight:bold;font-family:sans-serif","One input rectangle, one circular mask — three overlay tools",[435,1027,1029,1036,1042,1046,1049,1053],{"style":1028},"font-family:sans-serif",[420,1030],{"x":1031,"y":1032,"width":1033,"height":443,"fill":445,"fillOpacity":1034,"stroke":445,"style":1035},"288","36","14",0.12,"stroke-width:2",[426,1037,1041],{"x":1038,"y":1039,"style":1040,"fill":499},"308","45","font-size:11px","input",[454,1043],{"cx":1044,"cy":1045,"r":468,"fill":458,"fillOpacity":1034,"stroke":458,"style":558},"360","41",[426,1047,546],{"x":1048,"y":1039,"style":1040,"fill":499},"372",[420,1050],{"x":1051,"y":1032,"width":1033,"height":443,"fill":463,"fillOpacity":1052},"418",0.5,[426,1054,1056],{"x":1055,"y":1039,"style":1040,"fill":499},"438","kept",[435,1058,1059,1062,1065,1067,1071,1073,1077,1082],{},[420,1060],{"x":1061,"y":1013,"width":1014,"height":1015,"rx":443,"fill":444,"stroke":458,"style":1035},"8",[426,1063,26],{"x":999,"y":1064,"style":1024,"fill":431,"textAnchor":432},"88",[454,1066],{"cx":999,"cy":1000,"r":490,"fill":458,"fillOpacity":459,"stroke":458,"style":460},[420,1068],{"x":999,"y":1069,"width":1000,"height":1032,"fill":463,"fillOpacity":1052,"style":1070},"162","mask:url(#clipInA)",[454,1072],{"cx":999,"cy":1000,"r":490,"fill":516,"stroke":458,"style":460},[420,1074],{"x":1075,"y":1069,"width":1000,"height":1032,"fill":445,"fillOpacity":1076,"stroke":445,"style":1035},"38",0.06,[426,1078,1081],{"x":999,"y":1079,"style":1080,"fill":499,"textAnchor":432},"243","text-anchor:middle;font-size:11.5px;font-family:sans-serif","Keeps input INSIDE mask",[426,1083,1085],{"x":999,"y":1084,"style":1080,"fill":499,"textAnchor":432},"260","Input attributes only",[435,1087,1088,1090,1093,1095,1098,1100,1103,1106],{},[420,1089],{"x":1084,"y":1013,"width":1014,"height":1015,"rx":443,"fill":444,"stroke":445,"style":1035},[426,1091,1092],{"x":428,"y":1064,"style":1024,"fill":431,"textAnchor":432},"native:intersection",[454,1094],{"cx":428,"cy":1000,"r":490,"fill":458,"fillOpacity":459,"stroke":458,"style":460},[420,1096],{"x":428,"y":1069,"width":1000,"height":1032,"fill":463,"fillOpacity":1052,"style":1097},"mask:url(#clipInB)",[454,1099],{"cx":428,"cy":1000,"r":490,"fill":516,"stroke":458,"style":460},[420,1101],{"x":1102,"y":1069,"width":1000,"height":1032,"fill":445,"fillOpacity":1076,"stroke":445,"style":1035},"290",[426,1104,1105],{"x":428,"y":1079,"style":1080,"fill":499,"textAnchor":432},"Same inside geometry",[426,1107,1108],{"x":428,"y":1084,"style":1080,"fill":499,"textAnchor":432},"Input + overlay attributes",[435,1110,1111,1113,1116,1118,1122,1124,1126,1129],{},[420,1112],{"x":537,"y":1013,"width":1014,"height":1015,"rx":443,"fill":444,"stroke":506,"style":1035},[426,1114,1115],{"x":1018,"y":1064,"style":1024,"fill":431,"textAnchor":432},"native:difference",[454,1117],{"cx":1018,"cy":1000,"r":490,"fill":458,"fillOpacity":459,"stroke":458,"style":460},[420,1119],{"x":1120,"y":1069,"width":1000,"height":1032,"fill":463,"fillOpacity":1052,"style":1121},"542","mask:url(#maskOutC)",[454,1123],{"cx":1018,"cy":1000,"r":490,"fill":516,"stroke":458,"style":460},[420,1125],{"x":1120,"y":1069,"width":1000,"height":1032,"fill":516,"stroke":445,"style":1035},[426,1127,1128],{"x":1018,"y":1079,"style":1080,"fill":499,"textAnchor":432},"Keeps input OUTSIDE mask",[426,1130,1085],{"x":1018,"y":1084,"style":1080,"fill":499,"textAnchor":432},[1132,1133,1134,1150],"table",{},[1135,1136,1137],"thead",{},[1138,1139,1140,1144,1147],"tr",{},[1141,1142,1143],"th",{},"Algorithm",[1141,1145,1146],{},"What it keeps",[1141,1148,1149],{},"Attributes",[1151,1152,1153,1169,1185],"tbody",{},[1138,1154,1155,1160,1167],{},[1156,1157,1158],"td",{},[24,1159,26],{},[1156,1161,1162,1163,1166],{},"Input geometry ",[47,1164,1165],{},"inside"," the overlay",[1156,1168,1085],{},[1138,1170,1171,1175,1178],{},[1156,1172,1173],{},[24,1174,1092],{},[1156,1176,1177],{},"Geometry inside the overlay",[1156,1179,1180,1181,1184],{},"Input ",[47,1182,1183],{},"and"," overlay attributes merged",[1138,1186,1187,1191,1196],{},[1156,1188,1189],{},[24,1190,1115],{},[1156,1192,1162,1193,1166],{},[47,1194,1195],{},"outside",[1156,1197,1085],{},[14,1199,1200,1201,1203,1204,1206,1207,1209,1210,1214],{},"Use ",[24,1202,26],{}," when you only want a cookie-cutter of the input and do not care about the mask's attributes. Use ",[24,1205,1092],{}," 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,1208,1115],{}," to ",[1211,1212,1213],"em",{},"erase"," — keep everything outside the mask, such as land area minus water bodies:",[105,1216,1218],{"className":107,"code":1217,"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,1219,1220,1226,1230,1244,1255,1266,1276],{"__ignoreMap":110},[114,1221,1222,1224],{"class":116,"line":117},[114,1223,121],{"class":120},[114,1225,125],{"class":124},[114,1227,1228],{"class":116,"line":128},[114,1229,146],{"emptyLinePlaceholder":145},[114,1231,1232,1235,1237,1239,1242],{"class":116,"line":142},[114,1233,1234],{"class":124},"land_minus_water ",[114,1236,155],{"class":120},[114,1238,207],{"class":124},[114,1240,1241],{"class":161},"\"native:difference\"",[114,1243,213],{"class":124},[114,1245,1246,1248,1250,1253],{"class":116,"line":149},[114,1247,219],{"class":161},[114,1249,240],{"class":124},[114,1251,1252],{"class":161},"\"\u002Fdata\u002Fland.gpkg\"",[114,1254,246],{"class":124},[114,1256,1257,1259,1261,1264],{"class":116,"line":175},[114,1258,228],{"class":161},[114,1260,240],{"class":124},[114,1262,1263],{"class":161},"\"\u002Fdata\u002Flakes.gpkg\"",[114,1265,246],{"class":124},[114,1267,1268,1270,1272,1274],{"class":116,"line":194},[114,1269,237],{"class":161},[114,1271,240],{"class":124},[114,1273,243],{"class":161},[114,1275,246],{"class":124},[114,1277,1278,1281,1283],{"class":116,"line":199},[114,1279,1280],{"class":124},"})[",[114,1282,271],{"class":161},[114,1284,172],{"class":124},[14,1286,1287,309,1289,1291,1292,1295,1296,1298,1299,1302],{},[47,1288,308],{},[24,1290,1115],{}," is the geometric inverse of ",[24,1293,1294],{},"clip",". Swapping ",[24,1297,1294],{}," for ",[24,1300,1301],{},"difference"," with the same arguments returns the complementary part of the input.",[14,1304,1305,1306,1310],{},"Clipping pairs naturally with buffering when you need to trim features to a zone of influence — see ",[18,1307,1309],{"href":1308},"\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,1312,1314],{"id":1313},"clip-many-layers-in-a-loop","Clip Many Layers in a Loop",[14,1316,1317],{},"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,1319,1321],{"className":107,"code":1320,"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,1322,1323,1329,1341,1352,1356,1366,1391,1406,1431,1435,1449,1459,1488,1497,1504,1512,1524,1529],{"__ignoreMap":110},[114,1324,1325,1327],{"class":116,"line":117},[114,1326,121],{"class":120},[114,1328,125],{"class":124},[114,1330,1331,1333,1336,1338],{"class":116,"line":128},[114,1332,131],{"class":120},[114,1334,1335],{"class":124}," pathlib ",[114,1337,121],{"class":120},[114,1339,1340],{"class":124}," Path\n",[114,1342,1343,1345,1347,1349],{"class":116,"line":142},[114,1344,131],{"class":120},[114,1346,134],{"class":124},[114,1348,121],{"class":120},[114,1350,1351],{"class":124}," QgsVectorLayer\n",[114,1353,1354],{"class":116,"line":149},[114,1355,146],{"emptyLinePlaceholder":145},[114,1357,1358,1361,1363],{"class":116,"line":175},[114,1359,1360],{"class":124},"overlay ",[114,1362,155],{"class":120},[114,1364,1365],{"class":161}," \"\u002Fdata\u002Fstudy_area.gpkg|layername=boundary\"\n",[114,1367,1368,1371,1373,1376,1378,1381,1384,1386,1389],{"class":116,"line":194},[114,1369,1370],{"class":124},"inputs ",[114,1372,155],{"class":120},[114,1374,1375],{"class":124}," [",[114,1377,362],{"class":161},[114,1379,1380],{"class":124},", ",[114,1382,1383],{"class":161},"\"\u002Fdata\u002Frivers.shp\"",[114,1385,1380],{"class":124},[114,1387,1388],{"class":161},"\"\u002Fdata\u002Fparcels.shp\"",[114,1390,172],{"class":124},[114,1392,1393,1396,1398,1401,1404],{"class":116,"line":199},[114,1394,1395],{"class":124},"output_dir ",[114,1397,155],{"class":120},[114,1399,1400],{"class":124}," Path(",[114,1402,1403],{"class":161},"\"\u002Fdata\u002Foutput\"",[114,1405,303],{"class":124},[114,1407,1408,1411,1415,1417,1420,1422,1425,1427,1429],{"class":116,"line":216},[114,1409,1410],{"class":124},"output_dir.mkdir(",[114,1412,1414],{"class":1413},"s9osk","parents",[114,1416,155],{"class":120},[114,1418,1419],{"class":168},"True",[114,1421,1380],{"class":124},[114,1423,1424],{"class":1413},"exist_ok",[114,1426,155],{"class":120},[114,1428,1419],{"class":168},[114,1430,303],{"class":124},[114,1432,1433],{"class":116,"line":225},[114,1434,146],{"emptyLinePlaceholder":145},[114,1436,1437,1440,1443,1446],{"class":116,"line":234},[114,1438,1439],{"class":120},"for",[114,1441,1442],{"class":124}," path ",[114,1444,1445],{"class":120},"in",[114,1447,1448],{"class":124}," inputs:\n",[114,1450,1451,1454,1456],{"class":116,"line":249},[114,1452,1453],{"class":124},"    name ",[114,1455,155],{"class":120},[114,1457,1458],{"class":124}," Path(path).stem\n",[114,1460,1461,1464,1466,1469,1472,1475,1478,1480,1483,1485],{"class":116,"line":255},[114,1462,1463],{"class":124},"    out_path ",[114,1465,155],{"class":120},[114,1467,1468],{"class":124}," output_dir ",[114,1470,1471],{"class":120},"\u002F",[114,1473,1474],{"class":120}," f",[114,1476,1477],{"class":161},"\"",[114,1479,291],{"class":168},[114,1481,1482],{"class":124},"name",[114,1484,297],{"class":168},[114,1486,1487],{"class":161},"_clipped.gpkg\"\n",[114,1489,1490,1493,1495],{"class":116,"line":260},[114,1491,1492],{"class":124},"    processing.run(",[114,1494,210],{"class":161},[114,1496,213],{"class":124},[114,1498,1499,1501],{"class":116,"line":276},[114,1500,685],{"class":161},[114,1502,1503],{"class":124},": path,\n",[114,1505,1506,1509],{"class":116,"line":732},[114,1507,1508],{"class":161},"        \"OVERLAY\"",[114,1510,1511],{"class":124},": overlay,\n",[114,1513,1514,1516,1518,1521],{"class":116,"line":745},[114,1515,700],{"class":161},[114,1517,240],{"class":124},[114,1519,1520],{"class":168},"str",[114,1522,1523],{"class":124},"(out_path),\n",[114,1525,1526],{"class":116,"line":752},[114,1527,1528],{"class":124},"    })\n",[114,1530,1531,1534,1536,1538,1541,1543,1545,1547,1550,1552,1555,1557,1559],{"class":116,"line":759},[114,1532,1533],{"class":168},"    print",[114,1535,282],{"class":124},[114,1537,285],{"class":120},[114,1539,1540],{"class":161},"\"Clipped ",[114,1542,291],{"class":168},[114,1544,1482],{"class":124},[114,1546,297],{"class":168},[114,1548,1549],{"class":161}," -> ",[114,1551,291],{"class":168},[114,1553,1554],{"class":124},"out_path.name",[114,1556,297],{"class":168},[114,1558,1477],{"class":161},[114,1560,303],{"class":124},[14,1562,1563,1565,1566,1569],{},[47,1564,308],{}," The overlay path is reused for every input, and ",[24,1567,1568],{},"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,1571,1573],{"id":1572},"select-then-clip","Select Then Clip",[14,1575,1576,1577,1579,1580,1583],{},"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,1578,26],{}," honors a selection when you set the ",[24,1581,1582],{},"selected features only"," flag through the algorithm context, but the simplest robust approach is to materialize the selection first:",[105,1585,1587],{"className":107,"code":1586,"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,1588,1589,1595,1605,1609,1627,1648,1652,1666,1673,1683,1691,1695,1707,1717,1724,1734],{"__ignoreMap":110},[114,1590,1591,1593],{"class":116,"line":117},[114,1592,121],{"class":120},[114,1594,125],{"class":124},[114,1596,1597,1599,1601,1603],{"class":116,"line":128},[114,1598,131],{"class":120},[114,1600,134],{"class":124},[114,1602,121],{"class":120},[114,1604,139],{"class":124},[114,1606,1607],{"class":116,"line":142},[114,1608,146],{"emptyLinePlaceholder":145},[114,1610,1611,1614,1616,1618,1621,1623,1625],{"class":116,"line":149},[114,1612,1613],{"class":124},"counties ",[114,1615,155],{"class":120},[114,1617,158],{"class":124},[114,1619,1620],{"class":161},"\"counties\"",[114,1622,165],{"class":124},[114,1624,169],{"class":168},[114,1626,172],{"class":124},[114,1628,1629,1632,1635,1638,1641,1643,1646],{"class":116,"line":175},[114,1630,1631],{"class":124},"counties.selectByExpression(",[114,1633,1634],{"class":161},"'\"name\" = ",[114,1636,1637],{"class":168},"\\'",[114,1639,1640],{"class":161},"Marion",[114,1642,1637],{"class":168},[114,1644,1645],{"class":161},"'",[114,1647,303],{"class":124},[114,1649,1650],{"class":116,"line":194},[114,1651,146],{"emptyLinePlaceholder":145},[114,1653,1654,1657,1659,1661,1664],{"class":116,"line":199},[114,1655,1656],{"class":124},"selected_mask ",[114,1658,155],{"class":120},[114,1660,207],{"class":124},[114,1662,1663],{"class":161},"\"native:saveselectedfeatures\"",[114,1665,213],{"class":124},[114,1667,1668,1670],{"class":116,"line":216},[114,1669,219],{"class":161},[114,1671,1672],{"class":124},": counties,\n",[114,1674,1675,1677,1679,1681],{"class":116,"line":225},[114,1676,237],{"class":161},[114,1678,240],{"class":124},[114,1680,243],{"class":161},[114,1682,246],{"class":124},[114,1684,1685,1687,1689],{"class":116,"line":234},[114,1686,1280],{"class":124},[114,1688,271],{"class":161},[114,1690,172],{"class":124},[114,1692,1693],{"class":116,"line":249},[114,1694,146],{"emptyLinePlaceholder":145},[114,1696,1697,1699,1701,1703,1705],{"class":116,"line":255},[114,1698,263],{"class":124},[114,1700,155],{"class":120},[114,1702,207],{"class":124},[114,1704,210],{"class":161},[114,1706,213],{"class":124},[114,1708,1709,1711,1713,1715],{"class":116,"line":260},[114,1710,219],{"class":161},[114,1712,240],{"class":124},[114,1714,362],{"class":161},[114,1716,246],{"class":124},[114,1718,1719,1721],{"class":116,"line":276},[114,1720,228],{"class":161},[114,1722,1723],{"class":124},": selected_mask,\n",[114,1725,1726,1728,1730,1732],{"class":116,"line":732},[114,1727,237],{"class":161},[114,1729,240],{"class":124},[114,1731,243],{"class":161},[114,1733,246],{"class":124},[114,1735,1736,1738,1740],{"class":116,"line":745},[114,1737,1280],{"class":124},[114,1739,271],{"class":161},[114,1741,172],{"class":124},[14,1743,1744,309,1746,1749,1750,1753],{},[47,1745,308],{},[24,1747,1748],{},"selectByExpression"," picks the mask feature by attribute, ",[24,1751,1752],{},"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,1755,1757],{"id":1756},"qgis-version-compatibility","QGIS Version Compatibility",[14,1759,1760,1761,1764,1765,1767],{},"The examples target ",[47,1762,1763],{},"QGIS 3.34 LTR"," (Python 3.12), where ",[24,1766,26],{}," is stable and well established.",[1132,1769,1770,1783],{},[1135,1771,1772],{},[1138,1773,1774,1777,1780],{},[1141,1775,1776],{},"QGIS version",[1141,1778,1779],{},"Python",[1141,1781,1782],{},"Notes",[1151,1784,1785,1801,1812],{},[1138,1786,1787,1790,1793],{},[1156,1788,1789],{},"3.28 LTR",[1156,1791,1792],{},"3.9",[1156,1794,1795,1797,1798,1800],{},[24,1796,26],{}," identical; ",[24,1799,312],{}," API unchanged.",[1138,1802,1803,1806,1809],{},[1156,1804,1805],{},"3.34 LTR",[1156,1807,1808],{},"3.12",[1156,1810,1811],{},"Baseline for this page.",[1138,1813,1814,1817,1819],{},[1156,1815,1816],{},"3.40 \u002F 3.44",[1156,1818,1808],{},[1156,1820,1821],{},"Same algorithm ID and parameters; faster GEOS-backed clipping on large layers.",[14,1823,1824,1825,1827,1828,1471,1830,1471,1832,1834,1835,1837],{},"The ",[24,1826,26],{}," algorithm ID, its ",[24,1829,98],{},[24,1831,102],{},[24,1833,825],{}," parameters, and the ",[24,1836,316],{}," token are unchanged across all current 3.x releases, so this code is portable without modification.",[32,1839,1841],{"id":1840},"troubleshooting","Troubleshooting",[14,1843,1844],{},"An empty result is the symptom that covers three quite different causes, and working through them in order settles it in under a minute.",[14,1846,1847],{},[405,1848,1851,1854,1857,1860,1873,1876,1879,1884,1891,1895,1899,1902,1905,1908,1911,1914,1917,1924,1926,1930,1935,1939,1941,1944,1946,1949,1952,1954],{"viewBox":1849,"role":408,"ariaLabel":1850,"xmlns":410},"0 0 760 254","A diagnostic tree for an empty clip result, branching on whether the CRSs match, whether the extents overlap and whether the overlay geometry is valid",[412,1852,1853],{},"Diagnosing a clip that returned nothing",[416,1855,1856],{},"Starting from an empty output, three checks run in order. First compare the two layers' CRS identifiers; a mismatch is the most common cause. If they match, test whether the two extents intersect at all. If they do, validate the overlay geometry, since an invalid mask aborts the clip and returns nothing.",[420,1858],{"x":169,"y":169,"width":422,"height":1859,"fill":424},"254",[543,1861,1862],{},[1863,1864,1870],"marker",{"id":1865,"viewBox":1866,"refX":1061,"refY":1867,"markerWidth":1868,"markerHeight":1868,"orient":1869},"clipDiagArrow","0 0 10 10","5","7","auto-start-reverse",[513,1871],{"d":1872,"fill":499},"M0 0 L10 5 L0 10 z",[426,1874,1875],{"x":428,"y":429,"style":430,"fill":431,"textAnchor":432},"Zero features out — check these three, in this order",[420,1877],{"x":1102,"y":440,"width":1000,"height":482,"rx":1061,"fill":1878,"stroke":458,"style":446},"#26322d",[426,1880,1883],{"x":428,"y":1881,"style":451,"fill":1882,"textAnchor":432},"73","#d9f99d","empty output",[420,1885],{"x":1886,"y":1887,"width":1888,"height":1889,"rx":1061,"fill":444,"stroke":1890,"style":446},"16","122","228","62","#b91c1c",[426,1892,1894],{"x":449,"y":471,"style":1893,"fill":1890,"textAnchor":432},"text-anchor:middle;font-size:11.5px;font-weight:bold;font-family:sans-serif","1 · CRS mismatch",[426,1896,1898],{"x":449,"y":1897,"style":498,"fill":499,"textAnchor":432},"168","compare crs().authid()",[420,1900],{"x":1901,"y":1887,"width":1888,"height":1889,"rx":1061,"fill":444,"stroke":506,"style":446},"266",[426,1903,1904],{"x":428,"y":471,"style":1893,"fill":506,"textAnchor":432},"2 · no overlap",[426,1906,1907],{"x":428,"y":1897,"style":498,"fill":499,"textAnchor":432},"extent().intersects(other)",[420,1909],{"x":1910,"y":1887,"width":1888,"height":1889,"rx":1061,"fill":444,"stroke":445,"style":446},"516",[426,1912,1913],{"x":540,"y":471,"style":1893,"fill":445,"textAnchor":432},"3 · invalid overlay",[426,1915,1916],{"x":540,"y":1897,"style":498,"fill":499,"textAnchor":432},"isGeosValid() on the mask",[116,1918],{"x1":1919,"y1":1920,"x2":1921,"y2":1922,"stroke":499,"style":1923},"330","90","160","118","stroke-width:2;marker-end:url(#clipDiagArrow)",[116,1925],{"x1":428,"y1":1920,"x2":428,"y2":1922,"stroke":499,"style":1923},[116,1927],{"x1":1928,"y1":1920,"x2":1929,"y2":1922,"stroke":499,"style":1923},"430","600",[420,1931],{"x":1886,"y":1932,"width":1888,"height":1933,"rx":1061,"fill":444,"stroke":478,"style":1934},"200","40","stroke-width:1.5",[426,1936,1938],{"x":449,"y":1937,"style":498,"fill":499,"textAnchor":432},"225","reproject the overlay",[420,1940],{"x":1901,"y":1932,"width":1888,"height":1933,"rx":1061,"fill":444,"stroke":478,"style":1934},[426,1942,1943],{"x":428,"y":1937,"style":498,"fill":499,"textAnchor":432},"the layers are elsewhere",[420,1945],{"x":1910,"y":1932,"width":1888,"height":1933,"rx":1061,"fill":444,"stroke":478,"style":1934},[426,1947,1948],{"x":540,"y":1937,"style":498,"fill":499,"textAnchor":432},"run native:fixgeometries",[116,1950],{"x1":449,"y1":442,"x2":449,"y2":491,"stroke":478,"style":1951},"stroke-width:1.6;stroke-dasharray:3 3",[116,1953],{"x1":428,"y1":442,"x2":428,"y2":491,"stroke":478,"style":1951},[116,1955],{"x1":540,"y1":442,"x2":540,"y2":491,"stroke":478,"style":1951},[37,1957,1958,1964,1978,1988,1998],{},[40,1959,1960,1963],{},[47,1961,1962],{},"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,1965,1966,1971,1972,1974,1975,88],{},[47,1967,1968,88],{},[24,1969,1970],{},"Could not load source layer"," A file path is wrong, or you forgot the ",[24,1973,397],{}," suffix for a multi-layer GeoPackage. Verify with ",[24,1976,1977],{},"QgsVectorLayer(path, \"test\", \"ogr\").isValid()",[40,1979,1980,1983,1984,1987],{},[47,1981,1982],{},"Invalid geometry errors."," Self-intersecting overlay polygons can abort the clip. Run ",[24,1985,1986],{},"native:fixgeometries"," on the overlay first, then clip the cleaned result.",[40,1989,1990,1993,1994,1997],{},[47,1991,1992],{},"Slivers or unexpected boundaries."," Overlapping or duplicate polygons in the overlay create double-clipped slivers. Dissolve the overlay with ",[24,1995,1996],{},"native:dissolve"," before clipping if it should act as a single mask.",[40,1999,2000,309,2003,2005,2006,2008,2009,88],{},[47,2001,2002],{},"Result not visible in the project.",[24,2004,316],{}," returns a layer but does not add it to the tree; call ",[24,2007,971],{}," or use ",[24,2010,964],{},[32,2012,2014],{"id":2013},"conclusion","Conclusion",[14,2016,2017,2019,2020,2022],{},[24,2018,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,2021,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,2024,2026],{"id":2025},"frequently-asked-questions","Frequently Asked Questions",[14,2028,2029,2032,2033,2035],{},[47,2030,2031],{},"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,2034,805],{}," first, or you may get an empty output with no warning.",[14,2037,2038,2041,2042,2044,2045,2047],{},[47,2039,2040],{},"Can I clip points and lines, or only polygons?","\nAny geometry type works as the ",[24,2043,98],{},". Points outside the mask are dropped; lines are split at the boundary and the outside segments removed. The ",[24,2046,102],{}," must be polygons.",[14,2049,2050,2053],{},[47,2051,2052],{},"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,2055,2056,2059,2060,2062,2063,2066,2067,2069],{},[47,2057,2058],{},"How do I keep the clipped layer after closing QGIS?","\nWrite ",[24,2061,825],{}," to a file path such as ",[24,2064,2065],{},"\u002Fdata\u002Froads_clipped.gpkg"," instead of ",[24,2068,316],{},". The driver is chosen from the extension; GeoPackage is the recommended default.",[32,2071,2073],{"id":2072},"related","Related",[37,2075,2076,2081,2087],{},[40,2077,2078],{},[18,2079,2080],{"href":20},"Vector Data Manipulation in PyQGIS",[40,2082,2083],{},[18,2084,2086],{"href":2085},"\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fmerge-multiple-shapefiles-pyqgis\u002F","Merge Multiple Shapefiles in PyQGIS",[40,2088,2089],{},[18,2090,1309],{"href":1308},[2092,2093,2094],"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":2096},[2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108],{"id":34,"depth":128,"text":35},{"id":91,"depth":128,"text":92},{"id":577,"depth":128,"text":578},{"id":816,"depth":128,"text":817},{"id":974,"depth":128,"text":975},{"id":1313,"depth":128,"text":1314},{"id":1572,"depth":128,"text":1573},{"id":1756,"depth":128,"text":1757},{"id":1840,"depth":128,"text":1841},{"id":2013,"depth":128,"text":2014},{"id":2025,"depth":128,"text":2026},{"id":2072,"depth":128,"text":2073},"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",{"slug":2112,"type":2113,"breadcrumb":2114,"datePublished":2115,"dateModified":2116},"clip-vector-layer-pyqgis","article","Clip a Vector Layer","2025-05-28","2026-07-18","\u002Fspatial-data-processing-automation\u002Fvector-data-manipulation\u002Fclip-vector-layer-pyqgis",{"title":5,"description":2109},"spatial-data-processing-automation\u002Fvector-data-manipulation\u002Fclip-vector-layer-pyqgis\u002Findex","GEvP6QjawB3SWmgK3fjkOWJYTcZEmZx-MKYmH1fX0lM",1787823364724]