[{"data":1,"prerenderedAt":1756},["ShallowReactive",2],{"doc:\u002Fspatial-data-processing-automation\u002Fgeometry-operations-and-predicates\u002Fbuffer-geometry-pyqgis":3},{"id":4,"title":5,"body":6,"description":1745,"extension":1746,"meta":1747,"navigation":222,"path":1752,"seo":1753,"stem":1754,"__hash__":1755},"docs\u002Fspatial-data-processing-automation\u002Fgeometry-operations-and-predicates\u002Fbuffer-geometry-pyqgis\u002Findex.md","Buffer a Geometry in PyQGIS",{"type":7,"value":8,"toc":1732},"minimark",[9,13,17,26,147,152,183,187,190,345,355,358,404,417,421,428,512,557,668,672,675,826,847,851,865,1141,1154,1158,1161,1272,1475,1492,1496,1502,1578,1584,1588,1645,1649,1661,1665,1671,1677,1693,1702,1706,1728],[10,11,5],"h1",{"id":12},"buffer-a-geometry-in-pyqgis",[14,15,16],"p",{},"Buffering is the workhorse of proximity analysis: a 50 m zone around a road, a 500 m catchment around a school, a negative buffer to shrink a parcel back from its boundary. The PyQGIS call is a single method, and almost every problem people hit with it comes down to one of three things — the distance being interpreted in the wrong units, the corner approximation being too coarse, or the input geometry being invalid.",[14,18,19,20,25],{},"This page is a focused recipe within ",[21,22,24],"a",{"href":23},"\u002Fspatial-data-processing-automation\u002Fgeometry-operations-and-predicates\u002F","Geometry Operations and Spatial Predicates in PyQGIS",". It covers buffering a single geometry, the parameters that control the shape, buffering a whole layer with a per-feature distance, and the CRS discipline that keeps the result meaningful.",[14,27,28],{},[29,30,35,39,43,50,59,103,124],"svg",{"viewBox":31,"role":32,"ariaLabel":33,"xmlns":34},"0 0 760 268","img","A line and a polygon each buffered, showing the rounded expansion around the source geometry and a negative buffer shrinking a polygon inward","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[36,37,38],"title",{},"What a buffer produces for each geometry type",[40,41,42],"desc",{},"Three panels. A point buffered by a positive distance becomes a circle. A line buffered becomes a corridor with rounded ends. A polygon buffered by a negative distance shrinks inward, and the original outline is shown dashed for comparison.",[44,45],"rect",{"x":46,"y":46,"width":47,"height":48,"fill":49},"0","760","268","#f6f3ea",[51,52,58],"text",{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"380","26","text-anchor:middle;font-size:14px;font-weight:bold;font-family:sans-serif","#17211d","middle","A buffer always returns a polygon — whatever went in",[60,61,62,72,78,84,87,92,98],"g",{},[44,63],{"x":64,"y":65,"width":66,"height":67,"rx":68,"fill":69,"stroke":70,"style":71},"12","44","236","200","10","#fffdf7","#2563eb","stroke-width:2.5",[51,73,77],{"x":74,"y":75,"style":76,"fill":70,"textAnchor":57},"130","70","text-anchor:middle;font-size:12.5px;font-weight:bold;font-family:sans-serif","point → circle",[79,80],"circle",{"cx":74,"cy":81,"r":82,"fill":70,"fillOpacity":83,"stroke":70,"style":71},"150","52",0.2,[79,85],{"cx":74,"cy":81,"r":86,"fill":56},"6",[88,89],"line",{"x1":74,"y1":81,"x2":90,"y2":81,"stroke":56,"style":91},"182","stroke-width:1.5;stroke-dasharray:4 3",[51,93,97],{"x":94,"y":95,"style":96,"fill":56,"textAnchor":57},"156","142","text-anchor:middle;font-size:11px;font-family:sans-serif","d",[51,99,102],{"x":74,"y":100,"style":96,"fill":101,"textAnchor":57},"226","#2f3b35","buffer(50)",[60,104,105,109,112,118,121],{},[44,106],{"x":107,"y":65,"width":66,"height":67,"rx":68,"fill":69,"stroke":108,"style":71},"262","#0f766e",[51,110,111],{"x":53,"y":75,"style":76,"fill":108,"textAnchor":57},"line → corridor",[113,114],"path",{"d":115,"fill":116,"stroke":108,"style":117},"M300 190 L346 132 L410 164 L458 110","none","stroke-width:44;stroke-opacity:0.24;stroke-linecap:round;stroke-linejoin:round",[113,119],{"d":115,"fill":116,"stroke":108,"style":120},"stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round",[51,122,123],{"x":53,"y":100,"style":96,"fill":101,"textAnchor":57},"rounded caps by default",[60,125,126,130,134,139,144],{},[44,127],{"x":128,"y":65,"width":66,"height":67,"rx":68,"fill":69,"stroke":129,"style":71},"512","#b45309",[51,131,133],{"x":132,"y":75,"style":76,"fill":129,"textAnchor":57},"630","polygon → shrunk",[113,135],{"d":136,"fill":116,"stroke":137,"style":138},"M552 196 L556 116 L634 96 L706 132 L692 200 Z","#59645f","stroke-width:2;stroke-dasharray:5 4;stroke-linejoin:round",[113,140],{"d":141,"fill":129,"fillOpacity":142,"stroke":129,"style":143},"M572 182 L575 128 L632 114 L688 140 L678 186 Z",0.22,"stroke-width:2.5;stroke-linejoin:round",[51,145,146],{"x":132,"y":100,"style":96,"fill":101,"textAnchor":57},"buffer(-20) erodes inward",[148,149,151],"h2",{"id":150},"prerequisites","Prerequisites",[153,154,155,163,170],"ul",{},[156,157,158,162],"li",{},[159,160,161],"strong",{},"QGIS 3.34 LTR"," (bundled Python 3.12) or newer.",[156,164,165,166,169],{},"A layer in a ",[159,167,168],{},"projected CRS"," whose units are metres. This is not optional advice — see the CRS section below.",[156,171,172,173,177,178,182],{},"Valid input geometry. Run ",[174,175,176],"code",{},"geometry.isGeosValid()"," first if the data came from a CAD export or a hand-digitised source; ",[21,179,181],{"href":180},"\u002Fspatial-data-processing-automation\u002Fgeometry-operations-and-predicates\u002Ffix-invalid-geometries-pyqgis\u002F","Find and Fix Invalid Geometries"," covers the repair.",[148,184,186],{"id":185},"buffer-a-single-geometry","Buffer a single geometry",[14,188,189],{},"The method takes a distance and a segment count, and returns a new polygon.",[191,192,197],"pre",{"className":193,"code":194,"language":195,"meta":196,"style":196},"language-python shiki shiki-themes github-dark","from qgis.core import QgsProject\n\nlayer = QgsProject.instance().mapLayersByName(\"schools\")[0]\ngeometry = next(layer.getFeatures()).geometry()\n\nbuffered = geometry.buffer(500.0, 12)\n\nprint(buffered.area(), \"m²\")\nprint(round(3.14159 * 500 ** 2), \"m² for a true circle\")\n","python","",[174,198,199,217,224,249,263,268,290,295,309],{"__ignoreMap":196},[200,201,203,207,211,214],"span",{"class":88,"line":202},1,[200,204,206],{"class":205},"snl16","from",[200,208,210],{"class":209},"s95oV"," qgis.core ",[200,212,213],{"class":205},"import",[200,215,216],{"class":209}," QgsProject\n",[200,218,220],{"class":88,"line":219},2,[200,221,223],{"emptyLinePlaceholder":222},true,"\n",[200,225,227,230,233,236,240,243,246],{"class":88,"line":226},3,[200,228,229],{"class":209},"layer ",[200,231,232],{"class":205},"=",[200,234,235],{"class":209}," QgsProject.instance().mapLayersByName(",[200,237,239],{"class":238},"sU2Wk","\"schools\"",[200,241,242],{"class":209},")[",[200,244,46],{"class":245},"sDLfK",[200,247,248],{"class":209},"]\n",[200,250,252,255,257,260],{"class":88,"line":251},4,[200,253,254],{"class":209},"geometry ",[200,256,232],{"class":205},[200,258,259],{"class":245}," next",[200,261,262],{"class":209},"(layer.getFeatures()).geometry()\n",[200,264,266],{"class":88,"line":265},5,[200,267,223],{"emptyLinePlaceholder":222},[200,269,271,274,276,279,282,285,287],{"class":88,"line":270},6,[200,272,273],{"class":209},"buffered ",[200,275,232],{"class":205},[200,277,278],{"class":209}," geometry.buffer(",[200,280,281],{"class":245},"500.0",[200,283,284],{"class":209},", ",[200,286,64],{"class":245},[200,288,289],{"class":209},")\n",[200,291,293],{"class":88,"line":292},7,[200,294,223],{"emptyLinePlaceholder":222},[200,296,298,301,304,307],{"class":88,"line":297},8,[200,299,300],{"class":245},"print",[200,302,303],{"class":209},"(buffered.area(), ",[200,305,306],{"class":238},"\"m²\"",[200,308,289],{"class":209},[200,310,312,314,317,320,322,325,328,331,334,337,340,343],{"class":88,"line":311},9,[200,313,300],{"class":245},[200,315,316],{"class":209},"(",[200,318,319],{"class":245},"round",[200,321,316],{"class":209},[200,323,324],{"class":245},"3.14159",[200,326,327],{"class":205}," *",[200,329,330],{"class":245}," 500",[200,332,333],{"class":205}," **",[200,335,336],{"class":245}," 2",[200,338,339],{"class":209},"), ",[200,341,342],{"class":238},"\"m² for a true circle\"",[200,344,289],{"class":209},[14,346,347,350,351,354],{},[159,348,349],{},"Breakdown:"," The first argument is the distance in ",[159,352,353],{},"map units"," — metres in a projected CRS. The second is the number of straight segments used to approximate each quarter circle, so 12 gives 48 segments around a full circle. The area comparison is the quickest way to see the approximation at work: at 12 segments the polygon comes within about 0.1 % of a true circle, which is more than enough for analysis and cheap to render.",[14,356,357],{},"A negative distance erodes rather than expands, which is useful for pulling a working area back from a boundary. Be aware it can return an empty geometry when the shrink exceeds the shape's half-width:",[191,359,361],{"className":193,"code":360,"language":195,"meta":196,"style":196},"eroded = geometry.buffer(-20.0, 12)\nif eroded.isEmpty():\n    print(\"the polygon is narrower than 40 m somewhere\")\n",[174,362,363,384,392],{"__ignoreMap":196},[200,364,365,368,370,372,375,378,380,382],{"class":88,"line":202},[200,366,367],{"class":209},"eroded ",[200,369,232],{"class":205},[200,371,278],{"class":209},[200,373,374],{"class":205},"-",[200,376,377],{"class":245},"20.0",[200,379,284],{"class":209},[200,381,64],{"class":245},[200,383,289],{"class":209},[200,385,386,389],{"class":88,"line":219},[200,387,388],{"class":205},"if",[200,390,391],{"class":209}," eroded.isEmpty():\n",[200,393,394,397,399,402],{"class":88,"line":226},[200,395,396],{"class":245},"    print",[200,398,316],{"class":209},[200,400,401],{"class":238},"\"the polygon is narrower than 40 m somewhere\"",[200,403,289],{"class":209},[14,405,406,408,409,412,413,416],{},[159,407,349],{}," ",[174,410,411],{},"isEmpty()"," rather than ",[174,414,415],{},"isNull()"," is the right check here — the operation succeeded, it simply produced nothing. Skipping the check means downstream code receives an empty polygon whose area is zero and whose predicates are all false, which is very hard to trace back.",[148,418,420],{"id":419},"control-the-shape-segments-caps-and-joins","Control the shape: segments, caps and joins",[14,422,423,424,427],{},"The default rounded corners are not always wanted. A road corridor usually wants flat ends; a cadastral offset usually wants mitred corners. ",[174,425,426],{},"buffer()"," has an extended form for that.",[191,429,431],{"className":193,"code":430,"language":195,"meta":196,"style":196},"from qgis.core import Qgis, QgsGeometry\n\ncorridor = geometry.buffer(\n    25.0,                                # distance\n    8,                                   # segments per quarter circle\n    Qgis.EndCapStyle.Flat,               # square off the ends\n    Qgis.JoinStyle.Miter,                # sharp corners\n    2.0,                                 # miter limit\n)\n",[174,432,433,444,448,458,470,481,489,497,508],{"__ignoreMap":196},[200,434,435,437,439,441],{"class":88,"line":202},[200,436,206],{"class":205},[200,438,210],{"class":209},[200,440,213],{"class":205},[200,442,443],{"class":209}," Qgis, QgsGeometry\n",[200,445,446],{"class":88,"line":219},[200,447,223],{"emptyLinePlaceholder":222},[200,449,450,453,455],{"class":88,"line":226},[200,451,452],{"class":209},"corridor ",[200,454,232],{"class":205},[200,456,457],{"class":209}," geometry.buffer(\n",[200,459,460,463,466],{"class":88,"line":251},[200,461,462],{"class":245},"    25.0",[200,464,465],{"class":209},",                                ",[200,467,469],{"class":468},"sjoCn","# distance\n",[200,471,472,475,478],{"class":88,"line":265},[200,473,474],{"class":245},"    8",[200,476,477],{"class":209},",                                   ",[200,479,480],{"class":468},"# segments per quarter circle\n",[200,482,483,486],{"class":88,"line":270},[200,484,485],{"class":209},"    Qgis.EndCapStyle.Flat,               ",[200,487,488],{"class":468},"# square off the ends\n",[200,490,491,494],{"class":88,"line":292},[200,492,493],{"class":209},"    Qgis.JoinStyle.Miter,                ",[200,495,496],{"class":468},"# sharp corners\n",[200,498,499,502,505],{"class":88,"line":297},[200,500,501],{"class":245},"    2.0",[200,503,504],{"class":209},",                                 ",[200,506,507],{"class":468},"# miter limit\n",[200,509,510],{"class":88,"line":311},[200,511,289],{"class":209},[14,513,514,408,516,519,520,523,524,527,528,531,532,519,535,284,537,540,541,544,545,548,549,552,553,556],{},[159,515,349],{},[174,517,518],{},"EndCapStyle"," is ",[174,521,522],{},"Round"," (the default), ",[174,525,526],{},"Flat"," (stops exactly at the endpoint) or ",[174,529,530],{},"Square"," (extends by the buffer distance then squares off) — the distinction only affects line inputs. ",[174,533,534],{},"JoinStyle",[174,536,522],{},[174,538,539],{},"Miter"," or ",[174,542,543],{},"Bevel",", and controls the outside of every corner. The miter limit caps how far a sharp corner is allowed to project; without it, a near-doubling-back vertex produces a long spike. On QGIS 3.28 these enums live on ",[174,546,547],{},"QgsGeometry"," (",[174,550,551],{},"QgsGeometry.CapFlat","); the ",[174,554,555],{},"Qgis."," spelling is the current one.",[14,558,559],{},[29,560,563,566,569,572,576,629],{"viewBox":561,"role":32,"ariaLabel":562,"xmlns":34},"0 0 760 256","The three end cap styles and three join styles compared on the same line, showing round, flat and square ends and round, mitre and bevel corners",[36,564,565],{},"Cap and join styles on the same input line",[40,567,568],{},"The upper row shows a line buffered with round, flat and square end caps, with the source line drawn over each. The lower row shows a corner buffered with round, mitre and bevel joins, where the mitre produces a sharp point and the bevel a cut-off corner.",[44,570],{"x":46,"y":46,"width":47,"height":571,"fill":49},"256",[51,573,575],{"x":53,"y":574,"style":55,"fill":56,"textAnchor":57},"24","Caps change the ends; joins change the corners",[60,577,578,584,591,596,601,603,606,609,614,616,619,622,627],{},[51,579,583],{"x":580,"y":581,"style":582,"fill":56},"34","72","font-size:12px;font-weight:bold;font-family:sans-serif","caps",[44,585],{"x":586,"y":587,"width":588,"height":581,"rx":589,"fill":69,"stroke":70,"style":590},"96","42","196","8","stroke-width:2",[51,592,522],{"x":593,"y":594,"style":595,"fill":70,"textAnchor":57},"194","62","text-anchor:middle;font-size:11.5px;font-family:sans-serif",[88,597],{"x1":74,"y1":598,"x2":599,"y2":598,"stroke":70,"style":600},"90","258","stroke-width:28;stroke-opacity:0.25;stroke-linecap:round",[88,602],{"x1":74,"y1":598,"x2":599,"y2":598,"stroke":70,"style":590},[44,604],{"x":605,"y":587,"width":588,"height":581,"rx":589,"fill":69,"stroke":108,"style":590},"300",[51,607,526],{"x":608,"y":594,"style":595,"fill":108,"textAnchor":57},"398",[88,610],{"x1":611,"y1":598,"x2":612,"y2":598,"stroke":108,"style":613},"334","462","stroke-width:28;stroke-opacity:0.25;stroke-linecap:butt",[88,615],{"x1":611,"y1":598,"x2":612,"y2":598,"stroke":108,"style":590},[44,617],{"x":618,"y":587,"width":588,"height":581,"rx":589,"fill":69,"stroke":129,"style":590},"504",[51,620,530],{"x":621,"y":594,"style":595,"fill":129,"textAnchor":57},"602",[88,623],{"x1":624,"y1":598,"x2":625,"y2":598,"stroke":129,"style":626},"538","666","stroke-width:28;stroke-opacity:0.25;stroke-linecap:square",[88,628],{"x1":624,"y1":598,"x2":625,"y2":598,"stroke":129,"style":590},[60,630,631,635,639,642,646,648,650,652,656,658,660,662,666],{},[51,632,634],{"x":580,"y":633,"style":582,"fill":56},"186","joins",[44,636],{"x":586,"y":637,"width":588,"height":638,"rx":589,"fill":69,"stroke":70,"style":590},"132","104",[51,640,522],{"x":593,"y":641,"style":595,"fill":70,"textAnchor":57},"152",[113,643],{"d":644,"fill":116,"stroke":70,"style":645},"M130 216 L194 172 L258 216","stroke-width:26;stroke-opacity:0.25;stroke-linejoin:round;stroke-linecap:butt",[113,647],{"d":644,"fill":116,"stroke":70,"style":590},[44,649],{"x":605,"y":637,"width":588,"height":638,"rx":589,"fill":69,"stroke":108,"style":590},[51,651,539],{"x":608,"y":641,"style":595,"fill":108,"textAnchor":57},[113,653],{"d":654,"fill":116,"stroke":108,"style":655},"M334 216 L398 172 L462 216","stroke-width:26;stroke-opacity:0.25;stroke-linejoin:miter;stroke-linecap:butt",[113,657],{"d":654,"fill":116,"stroke":108,"style":590},[44,659],{"x":618,"y":637,"width":588,"height":638,"rx":589,"fill":69,"stroke":129,"style":590},[51,661,543],{"x":621,"y":641,"style":595,"fill":129,"textAnchor":57},[113,663],{"d":664,"fill":116,"stroke":129,"style":665},"M538 216 L602 172 L666 216","stroke-width:26;stroke-opacity:0.25;stroke-linejoin:bevel;stroke-linecap:butt",[113,667],{"d":664,"fill":116,"stroke":129,"style":590},[148,669,671],{"id":670},"buffer-a-whole-layer-by-an-attribute","Buffer a whole layer by an attribute",[14,673,674],{},"For a layer, the Processing algorithm is the right tool — it handles the iteration, writes the output, and accepts a data-defined distance so each feature can have its own.",[191,676,678],{"className":193,"code":677,"language":195,"meta":196,"style":196},"import processing\nfrom qgis.core import QgsProperty\n\nparams = {\n    \"INPUT\": \"\u002Fdata\u002Froads.gpkg|layername=roads\",\n    \"DISTANCE\": QgsProperty.fromExpression('\"lanes\" * 4.5'),\n    \"SEGMENTS\": 8,\n    \"END_CAP_STYLE\": 1,      # 0 round, 1 flat, 2 square\n    \"JOIN_STYLE\": 0,         # 0 round, 1 mitre, 2 bevel\n    \"DISSOLVE\": False,\n    \"OUTPUT\": \"\u002Fdata\u002Foutput\u002Froad_corridors.gpkg\",\n}\nprocessing.run(\"native:buffer\", params)\n",[174,679,680,687,698,702,712,726,740,751,767,782,795,808,814],{"__ignoreMap":196},[200,681,682,684],{"class":88,"line":202},[200,683,213],{"class":205},[200,685,686],{"class":209}," processing\n",[200,688,689,691,693,695],{"class":88,"line":219},[200,690,206],{"class":205},[200,692,210],{"class":209},[200,694,213],{"class":205},[200,696,697],{"class":209}," QgsProperty\n",[200,699,700],{"class":88,"line":226},[200,701,223],{"emptyLinePlaceholder":222},[200,703,704,707,709],{"class":88,"line":251},[200,705,706],{"class":209},"params ",[200,708,232],{"class":205},[200,710,711],{"class":209}," {\n",[200,713,714,717,720,723],{"class":88,"line":265},[200,715,716],{"class":238},"    \"INPUT\"",[200,718,719],{"class":209},": ",[200,721,722],{"class":238},"\"\u002Fdata\u002Froads.gpkg|layername=roads\"",[200,724,725],{"class":209},",\n",[200,727,728,731,734,737],{"class":88,"line":270},[200,729,730],{"class":238},"    \"DISTANCE\"",[200,732,733],{"class":209},": QgsProperty.fromExpression(",[200,735,736],{"class":238},"'\"lanes\" * 4.5'",[200,738,739],{"class":209},"),\n",[200,741,742,745,747,749],{"class":88,"line":292},[200,743,744],{"class":238},"    \"SEGMENTS\"",[200,746,719],{"class":209},[200,748,589],{"class":245},[200,750,725],{"class":209},[200,752,753,756,758,761,764],{"class":88,"line":297},[200,754,755],{"class":238},"    \"END_CAP_STYLE\"",[200,757,719],{"class":209},[200,759,760],{"class":245},"1",[200,762,763],{"class":209},",      ",[200,765,766],{"class":468},"# 0 round, 1 flat, 2 square\n",[200,768,769,772,774,776,779],{"class":88,"line":311},[200,770,771],{"class":238},"    \"JOIN_STYLE\"",[200,773,719],{"class":209},[200,775,46],{"class":245},[200,777,778],{"class":209},",         ",[200,780,781],{"class":468},"# 0 round, 1 mitre, 2 bevel\n",[200,783,785,788,790,793],{"class":88,"line":784},10,[200,786,787],{"class":238},"    \"DISSOLVE\"",[200,789,719],{"class":209},[200,791,792],{"class":245},"False",[200,794,725],{"class":209},[200,796,798,801,803,806],{"class":88,"line":797},11,[200,799,800],{"class":238},"    \"OUTPUT\"",[200,802,719],{"class":209},[200,804,805],{"class":238},"\"\u002Fdata\u002Foutput\u002Froad_corridors.gpkg\"",[200,807,725],{"class":209},[200,809,811],{"class":88,"line":810},12,[200,812,813],{"class":209},"}\n",[200,815,817,820,823],{"class":88,"line":816},13,[200,818,819],{"class":209},"processing.run(",[200,821,822],{"class":238},"\"native:buffer\"",[200,824,825],{"class":209},", params)\n",[14,827,828,830,831,834,835,839,840,842,843,846],{},[159,829,349],{}," Wrapping the distance in ",[174,832,833],{},"QgsProperty.fromExpression()"," is what turns a fixed buffer into a per-feature one — the same mechanism that drives ",[21,836,838],{"href":837},"\u002Fpyqgis-fundamentals-environment-setup\u002Fworking-with-qgis-expressions\u002Fdata-defined-symbol-size-expression-pyqgis\u002F","data-defined symbol size",". The style parameters are integer codes here rather than the ",[174,841,555],{}," enums used by the geometry method, which is an inconsistency worth remembering. ",[174,844,845],{},"DISSOLVE: True"," merges all the buffers into a single feature, which is what you want for a \"total area within reach\" question and wrong for anything that needs to stay attributable to its source feature.",[148,848,850],{"id":849},"get-the-units-right","Get the units right",[14,852,853,855,856,859,860,864],{},[174,854,426],{}," works in map units and has no idea what they mean. In EPSG:4326 a distance of ",[174,857,858],{},"500"," is five hundred ",[861,862,863],"em",{},"degrees"," — roughly one and a half times around the planet. The result is not an error; it is a geometry covering the whole world, which is why this mistake often survives into production.",[191,866,868],{"className":193,"code":867,"language":195,"meta":196,"style":196},"import processing\nfrom qgis.core import QgsCoordinateReferenceSystem, QgsProject\n\nlayer = QgsProject.instance().mapLayersByName(\"schools\")[0]\n\nif layer.crs().isGeographic():\n    centre = layer.extent().center()\n    zone = int((centre.x() + 180) \u002F 6) + 1\n    epsg = (32600 if centre.y() >= 0 else 32700) + zone\n    layer = processing.run(\"native:reprojectlayer\", {\n        \"INPUT\": layer,\n        \"TARGET_CRS\": QgsCoordinateReferenceSystem(f\"EPSG:{epsg}\"),\n        \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n    })[\"OUTPUT\"]\n\nbuffers = processing.run(\"native:buffer\", {\n    \"INPUT\": layer, \"DISTANCE\": 500, \"SEGMENTS\": 8,\n    \"OUTPUT\": \"TEMPORARY_OUTPUT\",\n})[\"OUTPUT\"]\n",[174,869,870,876,887,891,907,911,918,928,963,1000,1016,1024,1052,1064,1075,1080,1094,1120,1131],{"__ignoreMap":196},[200,871,872,874],{"class":88,"line":202},[200,873,213],{"class":205},[200,875,686],{"class":209},[200,877,878,880,882,884],{"class":88,"line":219},[200,879,206],{"class":205},[200,881,210],{"class":209},[200,883,213],{"class":205},[200,885,886],{"class":209}," QgsCoordinateReferenceSystem, QgsProject\n",[200,888,889],{"class":88,"line":226},[200,890,223],{"emptyLinePlaceholder":222},[200,892,893,895,897,899,901,903,905],{"class":88,"line":251},[200,894,229],{"class":209},[200,896,232],{"class":205},[200,898,235],{"class":209},[200,900,239],{"class":238},[200,902,242],{"class":209},[200,904,46],{"class":245},[200,906,248],{"class":209},[200,908,909],{"class":88,"line":265},[200,910,223],{"emptyLinePlaceholder":222},[200,912,913,915],{"class":88,"line":270},[200,914,388],{"class":205},[200,916,917],{"class":209}," layer.crs().isGeographic():\n",[200,919,920,923,925],{"class":88,"line":292},[200,921,922],{"class":209},"    centre ",[200,924,232],{"class":205},[200,926,927],{"class":209}," layer.extent().center()\n",[200,929,930,933,935,938,941,944,947,950,953,956,958,960],{"class":88,"line":297},[200,931,932],{"class":209},"    zone ",[200,934,232],{"class":205},[200,936,937],{"class":245}," int",[200,939,940],{"class":209},"((centre.x() ",[200,942,943],{"class":205},"+",[200,945,946],{"class":245}," 180",[200,948,949],{"class":209},") ",[200,951,952],{"class":205},"\u002F",[200,954,955],{"class":245}," 6",[200,957,949],{"class":209},[200,959,943],{"class":205},[200,961,962],{"class":245}," 1\n",[200,964,965,968,970,972,975,978,981,984,987,990,993,995,997],{"class":88,"line":311},[200,966,967],{"class":209},"    epsg ",[200,969,232],{"class":205},[200,971,548],{"class":209},[200,973,974],{"class":245},"32600",[200,976,977],{"class":205}," if",[200,979,980],{"class":209}," centre.y() ",[200,982,983],{"class":205},">=",[200,985,986],{"class":245}," 0",[200,988,989],{"class":205}," else",[200,991,992],{"class":245}," 32700",[200,994,949],{"class":209},[200,996,943],{"class":205},[200,998,999],{"class":209}," zone\n",[200,1001,1002,1005,1007,1010,1013],{"class":88,"line":784},[200,1003,1004],{"class":209},"    layer ",[200,1006,232],{"class":205},[200,1008,1009],{"class":209}," processing.run(",[200,1011,1012],{"class":238},"\"native:reprojectlayer\"",[200,1014,1015],{"class":209},", {\n",[200,1017,1018,1021],{"class":88,"line":797},[200,1019,1020],{"class":238},"        \"INPUT\"",[200,1022,1023],{"class":209},": layer,\n",[200,1025,1026,1029,1032,1035,1038,1041,1044,1047,1050],{"class":88,"line":810},[200,1027,1028],{"class":238},"        \"TARGET_CRS\"",[200,1030,1031],{"class":209},": QgsCoordinateReferenceSystem(",[200,1033,1034],{"class":205},"f",[200,1036,1037],{"class":238},"\"EPSG:",[200,1039,1040],{"class":245},"{",[200,1042,1043],{"class":209},"epsg",[200,1045,1046],{"class":245},"}",[200,1048,1049],{"class":238},"\"",[200,1051,739],{"class":209},[200,1053,1054,1057,1059,1062],{"class":88,"line":816},[200,1055,1056],{"class":238},"        \"OUTPUT\"",[200,1058,719],{"class":209},[200,1060,1061],{"class":238},"\"TEMPORARY_OUTPUT\"",[200,1063,725],{"class":209},[200,1065,1067,1070,1073],{"class":88,"line":1066},14,[200,1068,1069],{"class":209},"    })[",[200,1071,1072],{"class":238},"\"OUTPUT\"",[200,1074,248],{"class":209},[200,1076,1078],{"class":88,"line":1077},15,[200,1079,223],{"emptyLinePlaceholder":222},[200,1081,1083,1086,1088,1090,1092],{"class":88,"line":1082},16,[200,1084,1085],{"class":209},"buffers ",[200,1087,232],{"class":205},[200,1089,1009],{"class":209},[200,1091,822],{"class":238},[200,1093,1015],{"class":209},[200,1095,1097,1099,1102,1105,1107,1109,1111,1114,1116,1118],{"class":88,"line":1096},17,[200,1098,716],{"class":238},[200,1100,1101],{"class":209},": layer, ",[200,1103,1104],{"class":238},"\"DISTANCE\"",[200,1106,719],{"class":209},[200,1108,858],{"class":245},[200,1110,284],{"class":209},[200,1112,1113],{"class":238},"\"SEGMENTS\"",[200,1115,719],{"class":209},[200,1117,589],{"class":245},[200,1119,725],{"class":209},[200,1121,1123,1125,1127,1129],{"class":88,"line":1122},18,[200,1124,800],{"class":238},[200,1126,719],{"class":209},[200,1128,1061],{"class":238},[200,1130,725],{"class":209},[200,1132,1134,1137,1139],{"class":88,"line":1133},19,[200,1135,1136],{"class":209},"})[",[200,1138,1072],{"class":238},[200,1140,248],{"class":209},[14,1142,1143,408,1145,1148,1149,1153],{},[159,1144,349],{},[174,1146,1147],{},"isGeographic()"," is the guard — it is true for EPSG:4326 and every other lat\u002Flon system, and false for anything metric. Deriving the UTM zone from the layer's own centre means the script works anywhere without a hard-coded EPSG code. Reprojecting to a temporary layer keeps the source untouched. The full treatment of this pattern is in ",[21,1150,1152],{"href":1151},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002F","Coordinate Reference Systems in PyQGIS",".",[148,1155,1157],{"id":1156},"multi-ring-buffers","Multi-ring buffers",[14,1159,1160],{},"Distance bands — under 100 m, 100 to 250 m, 250 to 500 m — are a common deliverable, and the naive approach of buffering three times leaves you with nested polygons that all overlap. Subtracting each ring from the next produces true, non-overlapping bands.",[14,1162,1163],{},[29,1164,1167,1170,1173,1176,1179,1206],{"viewBox":1165,"role":32,"ariaLabel":1166,"xmlns":34},"0 0 760 248","Three nested buffers compared with three non-overlapping distance bands produced by subtracting each smaller buffer from the next",[36,1168,1169],{},"Nested buffers versus true distance bands",[40,1171,1172],{},"On the left, three concentric buffers at one hundred, two hundred and fifty and five hundred metres are drawn stacked, so the inner area is covered by all three polygons. On the right, each buffer has had the previous one subtracted, producing three separate rings whose areas sum to the largest buffer without any overlap.",[44,1174],{"x":46,"y":46,"width":47,"height":1175,"fill":49},"248",[51,1177,1178],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"Three buffers overlap; three bands do not",[60,1180,1181,1185,1191,1194,1196,1199,1202],{},[44,1182],{"x":1183,"y":65,"width":605,"height":1184,"rx":68,"fill":69,"stroke":129,"style":71},"40","188",[51,1186,1190],{"x":1187,"y":1188,"style":1189,"fill":129,"textAnchor":57},"190","68","text-anchor:middle;font-size:12px;font-weight:bold;font-family:sans-serif","three stacked buffers",[79,1192],{"cx":1187,"cy":81,"r":1193,"fill":129,"fillOpacity":83,"stroke":129,"style":590},"66",[79,1195],{"cx":1187,"cy":81,"r":65,"fill":129,"fillOpacity":83,"stroke":129,"style":590},[79,1197],{"cx":1187,"cy":81,"r":1198,"fill":129,"fillOpacity":83,"stroke":129,"style":590},"22",[79,1200],{"cx":1187,"cy":81,"r":1201,"fill":56},"4",[51,1203,1205],{"x":1187,"y":1204,"style":96,"fill":101,"textAnchor":57},"228","the centre is covered three times",[60,1207,1208,1212,1216,1236,1240,1244,1247,1249,1251,1253,1255,1261,1265,1269],{},[44,1209],{"x":1210,"y":65,"width":605,"height":1184,"rx":68,"fill":69,"stroke":1211,"style":71},"420","#15803d",[51,1213,1215],{"x":1214,"y":1188,"style":1189,"fill":1211,"textAnchor":57},"570","three distance bands",[1217,1218,1219,1229],"defs",{},[1220,1221,1223,1226],"mask",{"id":1222},"bufBandOuter",[79,1224],{"cx":1214,"cy":81,"r":1193,"fill":1225},"#ffffff",[79,1227],{"cx":1214,"cy":81,"r":65,"fill":1228},"#000000",[1220,1230,1232,1234],{"id":1231},"bufBandMid",[79,1233],{"cx":1214,"cy":81,"r":65,"fill":1225},[79,1235],{"cx":1214,"cy":81,"r":1198,"fill":1228},[79,1237],{"cx":1214,"cy":81,"r":1193,"fill":1211,"fillOpacity":1238,"style":1239},0.18,"mask:url(#bufBandOuter)",[79,1241],{"cx":1214,"cy":81,"r":65,"fill":1211,"fillOpacity":1242,"style":1243},0.38,"mask:url(#bufBandMid)",[79,1245],{"cx":1214,"cy":81,"r":1198,"fill":1211,"fillOpacity":1246},0.6,[79,1248],{"cx":1214,"cy":81,"r":1193,"fill":116,"stroke":1211,"style":590},[79,1250],{"cx":1214,"cy":81,"r":65,"fill":116,"stroke":1211,"style":590},[79,1252],{"cx":1214,"cy":81,"r":1198,"fill":116,"stroke":1211,"style":590},[79,1254],{"cx":1214,"cy":81,"r":1201,"fill":56},[51,1256,1260],{"x":1257,"y":1258,"style":1259,"fill":101},"646","112","font-size:11px;font-family:sans-serif","500 m",[51,1262,1264],{"x":1263,"y":81,"style":1259,"fill":101},"624","250 m",[51,1266,1268],{"x":1267,"y":633,"style":1259,"fill":101},"596","100 m",[51,1270,1271],{"x":1214,"y":1204,"style":96,"fill":1211,"textAnchor":57},"each point belongs to exactly one band",[191,1273,1275],{"className":193,"code":1274,"language":195,"meta":196,"style":196},"from qgis.core import QgsProject\n\nlayer = QgsProject.instance().mapLayersByName(\"schools\")[0]\ngeometry = next(layer.getFeatures()).geometry()\n\nbands, previous = [], None\nfor distance in (100, 250, 500):\n    ring = geometry.buffer(distance, 12)\n    bands.append(ring if previous is None else ring.difference(previous))\n    previous = ring\n\nfor distance, band in zip((100, 250, 500), bands):\n    print(f\"up to {distance} m: {band.area():,.0f} m²\")\n",[174,1276,1277,1287,1291,1307,1317,1321,1334,1362,1376,1397,1407,1411,1439],{"__ignoreMap":196},[200,1278,1279,1281,1283,1285],{"class":88,"line":202},[200,1280,206],{"class":205},[200,1282,210],{"class":209},[200,1284,213],{"class":205},[200,1286,216],{"class":209},[200,1288,1289],{"class":88,"line":219},[200,1290,223],{"emptyLinePlaceholder":222},[200,1292,1293,1295,1297,1299,1301,1303,1305],{"class":88,"line":226},[200,1294,229],{"class":209},[200,1296,232],{"class":205},[200,1298,235],{"class":209},[200,1300,239],{"class":238},[200,1302,242],{"class":209},[200,1304,46],{"class":245},[200,1306,248],{"class":209},[200,1308,1309,1311,1313,1315],{"class":88,"line":251},[200,1310,254],{"class":209},[200,1312,232],{"class":205},[200,1314,259],{"class":245},[200,1316,262],{"class":209},[200,1318,1319],{"class":88,"line":265},[200,1320,223],{"emptyLinePlaceholder":222},[200,1322,1323,1326,1328,1331],{"class":88,"line":270},[200,1324,1325],{"class":209},"bands, previous ",[200,1327,232],{"class":205},[200,1329,1330],{"class":209}," [], ",[200,1332,1333],{"class":245},"None\n",[200,1335,1336,1339,1342,1345,1347,1350,1352,1355,1357,1359],{"class":88,"line":292},[200,1337,1338],{"class":205},"for",[200,1340,1341],{"class":209}," distance ",[200,1343,1344],{"class":205},"in",[200,1346,548],{"class":209},[200,1348,1349],{"class":245},"100",[200,1351,284],{"class":209},[200,1353,1354],{"class":245},"250",[200,1356,284],{"class":209},[200,1358,858],{"class":245},[200,1360,1361],{"class":209},"):\n",[200,1363,1364,1367,1369,1372,1374],{"class":88,"line":297},[200,1365,1366],{"class":209},"    ring ",[200,1368,232],{"class":205},[200,1370,1371],{"class":209}," geometry.buffer(distance, ",[200,1373,64],{"class":245},[200,1375,289],{"class":209},[200,1377,1378,1381,1383,1386,1389,1392,1394],{"class":88,"line":311},[200,1379,1380],{"class":209},"    bands.append(ring ",[200,1382,388],{"class":205},[200,1384,1385],{"class":209}," previous ",[200,1387,1388],{"class":205},"is",[200,1390,1391],{"class":245}," None",[200,1393,989],{"class":205},[200,1395,1396],{"class":209}," ring.difference(previous))\n",[200,1398,1399,1402,1404],{"class":88,"line":784},[200,1400,1401],{"class":209},"    previous ",[200,1403,232],{"class":205},[200,1405,1406],{"class":209}," ring\n",[200,1408,1409],{"class":88,"line":797},[200,1410,223],{"emptyLinePlaceholder":222},[200,1412,1413,1415,1418,1420,1423,1426,1428,1430,1432,1434,1436],{"class":88,"line":810},[200,1414,1338],{"class":205},[200,1416,1417],{"class":209}," distance, band ",[200,1419,1344],{"class":205},[200,1421,1422],{"class":245}," zip",[200,1424,1425],{"class":209},"((",[200,1427,1349],{"class":245},[200,1429,284],{"class":209},[200,1431,1354],{"class":245},[200,1433,284],{"class":209},[200,1435,858],{"class":245},[200,1437,1438],{"class":209},"), bands):\n",[200,1440,1441,1443,1445,1447,1450,1452,1455,1457,1460,1462,1465,1468,1470,1473],{"class":88,"line":816},[200,1442,396],{"class":245},[200,1444,316],{"class":209},[200,1446,1034],{"class":205},[200,1448,1449],{"class":238},"\"up to ",[200,1451,1040],{"class":245},[200,1453,1454],{"class":209},"distance",[200,1456,1046],{"class":245},[200,1458,1459],{"class":238}," m: ",[200,1461,1040],{"class":245},[200,1463,1464],{"class":209},"band.area()",[200,1466,1467],{"class":205},":,.0f",[200,1469,1046],{"class":245},[200,1471,1472],{"class":238}," m²\"",[200,1474,289],{"class":209},[14,1476,1477,1479,1480,1483,1484,1487,1488,1491],{},[159,1478,349],{}," Each iteration buffers to the full distance and then subtracts the previous, smaller buffer, so the band is a true annulus rather than a disc. Keeping ",[174,1481,1482],{},"previous"," as the ",[861,1485,1486],{},"un-subtracted"," buffer is what makes the next subtraction correct — subtracting the previous band instead would leave the inner discs in place. Because the bands do not overlap, their areas sum to the area of the largest buffer, which is a useful assertion to add in a test. For a whole layer, ",[174,1489,1490],{},"native:multiringconstantbuffer"," does the same thing in one call.",[148,1493,1495],{"id":1494},"qgis-version-compatibility","QGIS version compatibility",[14,1497,1498,1499,1501],{},"The examples target ",[159,1500,161],{}," (Python 3.12).",[1503,1504,1505,1521],"table",{},[1506,1507,1508],"thead",{},[1509,1510,1511,1515,1518],"tr",{},[1512,1513,1514],"th",{},"QGIS version",[1512,1516,1517],{},"Python",[1512,1519,1520],{},"Notes",[1522,1523,1524,1546,1557],"tbody",{},[1509,1525,1526,1530,1533],{},[1527,1528,1529],"td",{},"3.28 LTR",[1527,1531,1532],{},"3.9",[1527,1534,1535,1536,1538,1539,1542,1543,1545],{},"Use ",[174,1537,551],{}," \u002F ",[174,1540,1541],{},"QgsGeometry.JoinStyleMiter"," instead of the ",[174,1544,555],{}," enums.",[1509,1547,1548,1551,1554],{},[1527,1549,1550],{},"3.34 LTR",[1527,1552,1553],{},"3.12",[1527,1555,1556],{},"Baseline. Both enum spellings accepted.",[1509,1558,1559,1562,1564],{},[1527,1560,1561],{},"3.40 \u002F 3.44",[1527,1563,1553],{},[1527,1565,1566,1569,1570,1573,1574,1577],{},[174,1567,1568],{},"Qgis.EndCapStyle"," and ",[174,1571,1572],{},"Qgis.JoinStyle"," are the documented forms; ",[174,1575,1576],{},"native:buffer"," parameters unchanged.",[14,1579,1580,1581,1583],{},"The ",[174,1582,1576],{}," algorithm ID and its parameter names have not changed across 3.x, so the Processing form is the more portable of the two.",[148,1585,1587],{"id":1586},"troubleshooting","Troubleshooting",[153,1589,1590,1596,1609,1618,1624,1633],{},[156,1591,1592,1595],{},[159,1593,1594],{},"The buffer covers the entire world."," The layer is in a geographic CRS and the distance was read as degrees. Reproject to a metric CRS first.",[156,1597,1598,1604,1605,1608],{},[159,1599,1600,1603],{},[174,1601,1602],{},"GEOSBuffer"," errors or an empty result."," The input geometry is invalid. Run ",[174,1606,1607],{},"makeValid()"," on it before buffering.",[156,1610,1611,1614,1615,1153],{},[159,1612,1613],{},"Corners have long spikes."," A mitre join with no limit on a near-reversing vertex. Lower the miter limit or switch to ",[174,1616,1617],{},"JoinStyle.Round",[156,1619,1620,1623],{},[159,1621,1622],{},"The circle looks like a polygon."," The segment count is too low. Raise it from the default; 8 to 12 is the usual range, and beyond 24 the extra vertices cost more than they show.",[156,1625,1626,1629,1630,1632],{},[159,1627,1628],{},"A negative buffer returns nothing."," The shrink distance exceeds half the narrowest width of the shape. Check with ",[174,1631,411],{}," and reduce the distance.",[156,1634,1635,1638,1639,1641,1642,1153],{},[159,1636,1637],{},"Buffers overlap where you wanted one shape."," Set ",[174,1640,845],{}," in the Processing call, or union the results with ",[174,1643,1644],{},"QgsGeometry.unaryUnion()",[148,1646,1648],{"id":1647},"conclusion","Conclusion",[14,1650,1651,1653,1654,1656,1657,1660],{},[174,1652,426],{}," is a one-line call whose correctness rests almost entirely on the inputs: a projected CRS so the distance means metres, valid geometry so GEOS can do the work, and a segment count and join style chosen for what the output is for. For whole layers, ",[174,1655,1576],{}," with a ",[174,1658,1659],{},"QgsProperty"," distance gives per-feature control without a Python loop.",[148,1662,1664],{"id":1663},"frequently-asked-questions","Frequently Asked Questions",[14,1666,1667,1670],{},[159,1668,1669],{},"Why is my buffer enormous?","\nThe layer is in a geographic CRS such as EPSG:4326, so the distance is being interpreted in degrees rather than metres. Reproject to a metric CRS — a UTM zone derived from the data extent is a safe default — before buffering.",[14,1672,1673,1676],{},[159,1674,1675],{},"What does the segments argument actually control?","\nThe number of straight line segments used to approximate each quarter of a circular corner. Eight gives 32 segments around a full circle, which is visually smooth and within a fraction of a percent of the true area.",[14,1678,1679,1682,1683,1483,1686,1689,1690,1692],{},[159,1680,1681],{},"Can each feature have a different buffer distance?","\nYes. Pass ",[174,1684,1685],{},"QgsProperty.fromExpression('\"width\" \u002F 2')",[174,1687,1688],{},"DISTANCE"," parameter to ",[174,1691,1576],{},". The expression is evaluated per feature exactly like a data-defined symbol property.",[14,1694,1695,1698,1699,1701],{},[159,1696,1697],{},"Why does a negative buffer return an empty geometry?","\nBecause the erosion distance is larger than half the width of the shape at its narrowest point, so nothing survives. This is a valid result rather than an error — test with ",[174,1700,411],{}," before using it.",[148,1703,1705],{"id":1704},"related","Related",[153,1707,1708,1713,1719,1724],{},[156,1709,1710,1712],{},[21,1711,24],{"href":23}," — the guide this recipe belongs to",[156,1714,1715],{},[21,1716,1718],{"href":1717},"\u002Fspatial-data-processing-automation\u002Fchaining-processing-algorithms\u002Fchain-buffer-and-clip-pyqgis\u002F","Chain a Buffer and Clip in PyQGIS",[156,1720,1721],{},[21,1722,1723],{"href":180},"Find and Fix Invalid Geometries in PyQGIS",[156,1725,1726],{},[21,1727,1152],{"href":1151},[1729,1730,1731],"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 .sjoCn, html code.shiki .sjoCn{--shiki-default:#9AA79F}",{"title":196,"searchDepth":219,"depth":219,"links":1733},[1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744],{"id":150,"depth":219,"text":151},{"id":185,"depth":219,"text":186},{"id":419,"depth":219,"text":420},{"id":670,"depth":219,"text":671},{"id":849,"depth":219,"text":850},{"id":1156,"depth":219,"text":1157},{"id":1494,"depth":219,"text":1495},{"id":1586,"depth":219,"text":1587},{"id":1647,"depth":219,"text":1648},{"id":1663,"depth":219,"text":1664},{"id":1704,"depth":219,"text":1705},"Buffer geometries in PyQGIS with QgsGeometry.buffer and native:buffer. Choose segments, cap and join styles, buffer by an attribute, and avoid degree-unit mistakes.","md",{"slug":1748,"type":1749,"breadcrumb":1750,"datePublished":1751,"dateModified":1751},"buffer-geometry-pyqgis","article","Buffer a Geometry","2026-08-01","\u002Fspatial-data-processing-automation\u002Fgeometry-operations-and-predicates\u002Fbuffer-geometry-pyqgis",{"title":5,"description":1745},"spatial-data-processing-automation\u002Fgeometry-operations-and-predicates\u002Fbuffer-geometry-pyqgis\u002Findex","twU9_LVKVlTFvO57HE2xZmZ-2BRUmh_vmerT0p-vyT8",1785585990476]