[{"data":1,"prerenderedAt":2054},["ShallowReactive",2],{"doc:\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fload-wcs-coverage-pyqgis":3},{"id":4,"title":5,"body":6,"description":2043,"extension":2044,"meta":2045,"navigation":229,"path":2050,"seo":2051,"stem":2052,"__hash__":2053},"docs\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fload-wcs-coverage-pyqgis\u002Findex.md","Load a WCS Coverage in PyQGIS",{"type":7,"value":8,"toc":2028},"minimark",[9,13,17,26,116,121,148,152,155,490,513,517,524,743,764,768,771,849,971,984,988,991,1239,1252,1256,1259,1350,1722,1739,1743,1746,1858,1871,1875,1883,1887,1912,1916,1949,1953,1959,1963,1969,1978,1984,1990,1994,2024],[10,11,5],"h1",{"id":12},"load-a-wcs-coverage-in-pyqgis",[14,15,16],"p",{},"A Web Map Service returns pictures: rendered, coloured images meant for looking at. A Web Coverage Service returns data: the actual elevation values, temperatures or classification codes, in their native data type, ready for analysis. National mapping agencies publish elevation models through WCS, meteorological services publish gridded forecasts, and environmental agencies publish land cover and soil grids. When a script needs the numbers rather than the picture, WCS is the protocol to use.",[14,18,19,20,25],{},"This recipe belongs to ",[21,22,24],"a",{"href":23},"\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002F","Web Services and Remote Data in PyQGIS",". It discovers the coverages a server offers, loads one as a raster layer, chooses CRS, format and time, downloads a subset into a local GeoTIFF for analysis, and explains when WMS, WCS or a cloud-optimised file is the better source.",[14,27,28],{},[29,30,35,39,43,50,59,69,75,81,85,90,94,99,104,107,110,113],"svg",{"viewBox":31,"role":32,"ariaLabel":33,"xmlns":34},"0 0 760 262","img","WMS returning rendered RGB images for display compared with WCS returning raw values such as float elevations for analysis","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[36,37,38],"title",{},"Pictures versus values",[40,41,42],"desc",{},"A WMS request returns a rendered image: red, green and blue pixel colours chosen by the server's style, useful for display but not for computing slope or statistics. A WCS request returns the coverage values: for an elevation model, 32-bit floats in metres with NoData, so slope, profiles and zonal statistics give correct results. The same server often offers both.",[44,45],"rect",{"x":46,"y":46,"width":47,"height":48,"fill":49},"0","760","262","#f6f3ea",[51,52,58],"text",{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"380","28","text-anchor:middle;font-size:14px;font-family:sans-serif;font-weight:bold","#17211d","middle","WMS for looking, WCS for computing",[44,60],{"x":61,"y":62,"width":63,"height":64,"rx":65,"fill":66,"stroke":67,"style":68},"24","56","340","190","8","#eff3ff","#2563eb","stroke-width:2",[51,70,74],{"x":71,"y":72,"style":73,"fill":67,"textAnchor":57},"194","94.78","text-anchor:middle;font-size:11.5px;font-family:sans-serif;font-weight:bold","WMS",[51,76,80],{"x":71,"y":77,"style":78,"fill":79,"textAnchor":57},"124.78","text-anchor:middle;font-size:10.5px;font-family:sans-serif","#2f3b35","rendered RGB image",[51,82,84],{"x":71,"y":83,"style":78,"fill":79,"textAnchor":57},"154.78","server's colours",[51,86,89],{"x":71,"y":87,"style":78,"fill":88,"textAnchor":57},"184.78","#59645f","display only",[51,91,93],{"x":71,"y":92,"style":78,"fill":88,"textAnchor":57},"214.78","slope from it = nonsense",[44,95],{"x":96,"y":62,"width":63,"height":64,"rx":65,"fill":97,"stroke":98,"style":68},"396","#e8efe6","#15803d",[51,100,103],{"x":101,"y":72,"style":73,"fill":102,"textAnchor":57},"566","#166534","WCS",[51,105,106],{"x":101,"y":77,"style":78,"fill":79,"textAnchor":57},"raw values, e.g. Float32",[51,108,109],{"x":101,"y":83,"style":78,"fill":79,"textAnchor":57},"metres, NoData",[51,111,112],{"x":101,"y":87,"style":78,"fill":88,"textAnchor":57},"analysis-ready",[51,114,115],{"x":101,"y":92,"style":78,"fill":88,"textAnchor":57},"slope, profiles, stats",[117,118,120],"h2",{"id":119},"prerequisites","Prerequisites",[122,123,124,128,140],"ul",{},[125,126,127],"li",{},"QGIS 3.34 LTR or newer, or the QGIS 4 series.",[125,129,130,131,135,136,139],{},"The base URL of a WCS endpoint, for example ",[132,133,134],"code",{},"https:\u002F\u002Fgeo.example.org\u002Fwcs",". Opening ",[132,137,138],{},"…?SERVICE=WCS&REQUEST=GetCapabilities"," in a browser shows the offered coverages.",[125,141,142,143,147],{},"Credentials, if the service is protected, stored as an authentication configuration as in ",[21,144,146],{"href":145},"\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fload-wfs-layer-pyqgis\u002F","loading a WFS layer",".",[117,149,151],{"id":150},"discover-coverages","Discover coverages",[14,153,154],{},"The capabilities document lists each coverage with an identifier and title. QGIS's network classes fetch it with QGIS's proxy and authentication settings.",[156,157,162],"pre",{"className":158,"code":159,"language":160,"meta":161,"style":161},"language-python shiki shiki-themes github-dark","import xml.etree.ElementTree as ET\nfrom qgis.PyQt.QtCore import QUrl\nfrom qgis.PyQt.QtNetwork import QNetworkRequest\nfrom qgis.core import QgsBlockingNetworkRequest\n\nBASE = \"https:\u002F\u002Fgeo.example.org\u002Fwcs\"\nreq = QNetworkRequest(QUrl(f\"{BASE}?SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCapabilities\"))\nblocking = QgsBlockingNetworkRequest()\nif blocking.get(req) != QgsBlockingNetworkRequest.NoError:\n    raise RuntimeError(blocking.errorMessage())\nroot = ET.fromstring(bytes(blocking.reply().content()))\n\nns = {\"wcs\": \"http:\u002F\u002Fwww.opengis.net\u002Fwcs\u002F2.0\", \"ows\": \"http:\u002F\u002Fwww.opengis.net\u002Fows\u002F2.0\"}\nfor cs in root.iter(\"{http:\u002F\u002Fwww.opengis.net\u002Fwcs\u002F2.0}CoverageSummary\"):\n    cid = cs.find(\"wcs:CoverageId\", ns).text\n    title = cs.find(\"ows:Title\", ns)\n    print(f\"{cid:\u003C36} {title.text if title is not None else ''}\")\n","python","",[132,163,164,184,198,211,224,231,244,271,282,297,309,329,334,368,400,417,433],{"__ignoreMap":161},[165,166,169,173,177,180],"span",{"class":167,"line":168},"line",1,[165,170,172],{"class":171},"snl16","import",[165,174,176],{"class":175},"s95oV"," xml.etree.ElementTree ",[165,178,179],{"class":171},"as",[165,181,183],{"class":182},"sDLfK"," ET\n",[165,185,187,190,193,195],{"class":167,"line":186},2,[165,188,189],{"class":171},"from",[165,191,192],{"class":175}," qgis.PyQt.QtCore ",[165,194,172],{"class":171},[165,196,197],{"class":175}," QUrl\n",[165,199,201,203,206,208],{"class":167,"line":200},3,[165,202,189],{"class":171},[165,204,205],{"class":175}," qgis.PyQt.QtNetwork ",[165,207,172],{"class":171},[165,209,210],{"class":175}," QNetworkRequest\n",[165,212,214,216,219,221],{"class":167,"line":213},4,[165,215,189],{"class":171},[165,217,218],{"class":175}," qgis.core ",[165,220,172],{"class":171},[165,222,223],{"class":175}," QgsBlockingNetworkRequest\n",[165,225,227],{"class":167,"line":226},5,[165,228,230],{"emptyLinePlaceholder":229},true,"\n",[165,232,234,237,240],{"class":167,"line":233},6,[165,235,236],{"class":182},"BASE",[165,238,239],{"class":171}," =",[165,241,243],{"class":242},"sU2Wk"," \"https:\u002F\u002Fgeo.example.org\u002Fwcs\"\n",[165,245,247,250,253,256,259,262,265,268],{"class":167,"line":246},7,[165,248,249],{"class":175},"req ",[165,251,252],{"class":171},"=",[165,254,255],{"class":175}," QNetworkRequest(QUrl(",[165,257,258],{"class":171},"f",[165,260,261],{"class":242},"\"",[165,263,264],{"class":182},"{BASE}",[165,266,267],{"class":242},"?SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCapabilities\"",[165,269,270],{"class":175},"))\n",[165,272,274,277,279],{"class":167,"line":273},8,[165,275,276],{"class":175},"blocking ",[165,278,252],{"class":171},[165,280,281],{"class":175}," QgsBlockingNetworkRequest()\n",[165,283,285,288,291,294],{"class":167,"line":284},9,[165,286,287],{"class":171},"if",[165,289,290],{"class":175}," blocking.get(req) ",[165,292,293],{"class":171},"!=",[165,295,296],{"class":175}," QgsBlockingNetworkRequest.NoError:\n",[165,298,300,303,306],{"class":167,"line":299},10,[165,301,302],{"class":171},"    raise",[165,304,305],{"class":182}," RuntimeError",[165,307,308],{"class":175},"(blocking.errorMessage())\n",[165,310,312,315,317,320,323,326],{"class":167,"line":311},11,[165,313,314],{"class":175},"root ",[165,316,252],{"class":171},[165,318,319],{"class":182}," ET",[165,321,322],{"class":175},".fromstring(",[165,324,325],{"class":182},"bytes",[165,327,328],{"class":175},"(blocking.reply().content()))\n",[165,330,332],{"class":167,"line":331},12,[165,333,230],{"emptyLinePlaceholder":229},[165,335,337,340,342,345,348,351,354,357,360,362,365],{"class":167,"line":336},13,[165,338,339],{"class":175},"ns ",[165,341,252],{"class":171},[165,343,344],{"class":175}," {",[165,346,347],{"class":242},"\"wcs\"",[165,349,350],{"class":175},": ",[165,352,353],{"class":242},"\"http:\u002F\u002Fwww.opengis.net\u002Fwcs\u002F2.0\"",[165,355,356],{"class":175},", ",[165,358,359],{"class":242},"\"ows\"",[165,361,350],{"class":175},[165,363,364],{"class":242},"\"http:\u002F\u002Fwww.opengis.net\u002Fows\u002F2.0\"",[165,366,367],{"class":175},"}\n",[165,369,371,374,377,380,383,385,388,391,394,397],{"class":167,"line":370},14,[165,372,373],{"class":171},"for",[165,375,376],{"class":175}," cs ",[165,378,379],{"class":171},"in",[165,381,382],{"class":175}," root.iter(",[165,384,261],{"class":242},[165,386,387],{"class":182},"{http",[165,389,390],{"class":171},":",[165,392,393],{"class":182},"\u002F\u002Fwww.opengis.net\u002Fwcs\u002F2.0}",[165,395,396],{"class":242},"CoverageSummary\"",[165,398,399],{"class":175},"):\n",[165,401,403,406,408,411,414],{"class":167,"line":402},15,[165,404,405],{"class":175},"    cid ",[165,407,252],{"class":171},[165,409,410],{"class":175}," cs.find(",[165,412,413],{"class":242},"\"wcs:CoverageId\"",[165,415,416],{"class":175},", ns).text\n",[165,418,420,423,425,427,430],{"class":167,"line":419},16,[165,421,422],{"class":175},"    title ",[165,424,252],{"class":171},[165,426,410],{"class":175},[165,428,429],{"class":242},"\"ows:Title\"",[165,431,432],{"class":175},", ns)\n",[165,434,436,439,442,444,446,449,452,455,458,460,463,465,468,471,474,477,480,483,485,487],{"class":167,"line":435},17,[165,437,438],{"class":182},"    print",[165,440,441],{"class":175},"(",[165,443,258],{"class":171},[165,445,261],{"class":242},[165,447,448],{"class":182},"{",[165,450,451],{"class":175},"cid",[165,453,454],{"class":171},":\u003C36",[165,456,457],{"class":182},"}",[165,459,344],{"class":182},[165,461,462],{"class":175},"title.text ",[165,464,287],{"class":171},[165,466,467],{"class":175}," title ",[165,469,470],{"class":171},"is",[165,472,473],{"class":171}," not",[165,475,476],{"class":182}," None",[165,478,479],{"class":171}," else",[165,481,482],{"class":242}," ''",[165,484,457],{"class":182},[165,486,261],{"class":242},[165,488,489],{"class":175},")\n",[14,491,492,496,497,500,501,504,505,508,509,147],{},[493,494,495],"strong",{},"Breakdown:"," WCS 2.0 lists coverages as ",[132,498,499],{},"CoverageSummary"," elements with a ",[132,502,503],{},"CoverageId",", the name the provider needs. Older servers speak WCS 1.0 or 1.1 with different element names; the QGIS provider handles all three, but a hand-written parser must match the version requested. ",[132,506,507],{},"QgsBlockingNetworkRequest"," is fine in scripts; inside plugins, use the asynchronous request classes to keep the interface responsive, as described in ",[21,510,512],{"href":511},"\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fmake-http-requests-with-qgsnetworkaccessmanager-pyqgis\u002F","making HTTP requests with QgsNetworkAccessManager",[117,514,516],{"id":515},"load-a-coverage-as-a-layer","Load a coverage as a layer",[14,518,519,520,523],{},"The ",[132,521,522],{},"wcs"," provider takes a URI listing the server URL and coverage identifier, plus optional CRS, format and caching options.",[156,525,527],{"className":158,"code":526,"language":160,"meta":161,"style":161},"from qgis.core import QgsDataSourceUri, QgsRasterLayer, QgsProject\n\nuri = QgsDataSourceUri()\nuri.setParam(\"url\", BASE)\nuri.setParam(\"identifier\", \"dem_1m\")\nuri.setParam(\"crs\", \"EPSG:25832\")\nuri.setParam(\"format\", \"image\u002Ftiff\")\nuri.setParam(\"cache\", \"PreferNetwork\")\n\ndem = QgsRasterLayer(str(uri.encodedUri(), \"utf-8\"), \"DEM (WCS)\", \"wcs\")\nif not dem.isValid():\n    raise RuntimeError(dem.error().summary())\nprov = dem.dataProvider()\nprint(dem.bandCount(), \"band(s);\", prov.dataType(1), \"; NoData:\",\n      prov.sourceNoDataValue(1) if prov.sourceHasNoDataValue(1) else None)\nQgsProject.instance().addMapLayer(dem)\n",[132,528,529,540,544,554,568,582,596,610,624,628,659,668,677,687,712,738],{"__ignoreMap":161},[165,530,531,533,535,537],{"class":167,"line":168},[165,532,189],{"class":171},[165,534,218],{"class":175},[165,536,172],{"class":171},[165,538,539],{"class":175}," QgsDataSourceUri, QgsRasterLayer, QgsProject\n",[165,541,542],{"class":167,"line":186},[165,543,230],{"emptyLinePlaceholder":229},[165,545,546,549,551],{"class":167,"line":200},[165,547,548],{"class":175},"uri ",[165,550,252],{"class":171},[165,552,553],{"class":175}," QgsDataSourceUri()\n",[165,555,556,559,562,564,566],{"class":167,"line":213},[165,557,558],{"class":175},"uri.setParam(",[165,560,561],{"class":242},"\"url\"",[165,563,356],{"class":175},[165,565,236],{"class":182},[165,567,489],{"class":175},[165,569,570,572,575,577,580],{"class":167,"line":226},[165,571,558],{"class":175},[165,573,574],{"class":242},"\"identifier\"",[165,576,356],{"class":175},[165,578,579],{"class":242},"\"dem_1m\"",[165,581,489],{"class":175},[165,583,584,586,589,591,594],{"class":167,"line":233},[165,585,558],{"class":175},[165,587,588],{"class":242},"\"crs\"",[165,590,356],{"class":175},[165,592,593],{"class":242},"\"EPSG:25832\"",[165,595,489],{"class":175},[165,597,598,600,603,605,608],{"class":167,"line":246},[165,599,558],{"class":175},[165,601,602],{"class":242},"\"format\"",[165,604,356],{"class":175},[165,606,607],{"class":242},"\"image\u002Ftiff\"",[165,609,489],{"class":175},[165,611,612,614,617,619,622],{"class":167,"line":273},[165,613,558],{"class":175},[165,615,616],{"class":242},"\"cache\"",[165,618,356],{"class":175},[165,620,621],{"class":242},"\"PreferNetwork\"",[165,623,489],{"class":175},[165,625,626],{"class":167,"line":284},[165,627,230],{"emptyLinePlaceholder":229},[165,629,630,633,635,638,641,644,647,650,653,655,657],{"class":167,"line":299},[165,631,632],{"class":175},"dem ",[165,634,252],{"class":171},[165,636,637],{"class":175}," QgsRasterLayer(",[165,639,640],{"class":182},"str",[165,642,643],{"class":175},"(uri.encodedUri(), ",[165,645,646],{"class":242},"\"utf-8\"",[165,648,649],{"class":175},"), ",[165,651,652],{"class":242},"\"DEM (WCS)\"",[165,654,356],{"class":175},[165,656,347],{"class":242},[165,658,489],{"class":175},[165,660,661,663,665],{"class":167,"line":311},[165,662,287],{"class":171},[165,664,473],{"class":171},[165,666,667],{"class":175}," dem.isValid():\n",[165,669,670,672,674],{"class":167,"line":331},[165,671,302],{"class":171},[165,673,305],{"class":182},[165,675,676],{"class":175},"(dem.error().summary())\n",[165,678,679,682,684],{"class":167,"line":336},[165,680,681],{"class":175},"prov ",[165,683,252],{"class":171},[165,685,686],{"class":175}," dem.dataProvider()\n",[165,688,689,692,695,698,701,704,706,709],{"class":167,"line":370},[165,690,691],{"class":182},"print",[165,693,694],{"class":175},"(dem.bandCount(), ",[165,696,697],{"class":242},"\"band(s);\"",[165,699,700],{"class":175},", prov.dataType(",[165,702,703],{"class":182},"1",[165,705,649],{"class":175},[165,707,708],{"class":242},"\"; NoData:\"",[165,710,711],{"class":175},",\n",[165,713,714,717,719,722,724,727,729,731,734,736],{"class":167,"line":402},[165,715,716],{"class":175},"      prov.sourceNoDataValue(",[165,718,703],{"class":182},[165,720,721],{"class":175},") ",[165,723,287],{"class":171},[165,725,726],{"class":175}," prov.sourceHasNoDataValue(",[165,728,703],{"class":182},[165,730,721],{"class":175},[165,732,733],{"class":171},"else",[165,735,476],{"class":182},[165,737,489],{"class":175},[165,739,740],{"class":167,"line":419},[165,741,742],{"class":175},"QgsProject.instance().addMapLayer(dem)\n",[14,744,745,747,748,751,752,755,756,759,760,763],{},[493,746,495],{}," The WCS provider expects an encoded URI, which ",[132,749,750],{},"QgsDataSourceUri.encodedUri()"," produces; it returns bytes, hence the decode. ",[132,753,754],{},"identifier"," is the coverage id from the capabilities; ",[132,757,758],{},"crs"," asks for a CRS the server supports; ",[132,761,762],{},"format"," selects the transfer encoding — GeoTIFF preserves data type and NoData. Checking the band data type is a quick confirmation that real values arrived: a Float32 elevation band is data, a Byte RGB triplet would mean the server returned a rendered image. The layer requests data for the current view as you pan and zoom.",[117,765,767],{"id":766},"choose-crs-format-and-time","Choose CRS, format and time",[14,769,770],{},"Coverage servers can return data in several CRSs and formats, and many coverages have a time dimension — daily forecasts, monthly composites.",[14,772,773],{},[29,774,777,780,783,786,789,795,800,804,808,811,814,817,820,825,829,832,835,839,843,846],{"viewBox":775,"role":32,"ariaLabel":776,"xmlns":34},"0 0 760 222","Key WCS request parameters: native CRS, a lossless format, a time slice and the native resolution",[36,778,779],{},"Request parameters that matter",[40,781,782],{},"CRS: request the coverage's native CRS when possible to avoid server-side resampling. Format: GeoTIFF keeps data type and NoData; PNG or JPEG lose them. Time: for temporal coverages, a time parameter selects one slice. Resolution follows the request size, so ask for the native pixel size when downloading for analysis.",[44,784],{"x":46,"y":46,"width":47,"height":785,"fill":49},"222",[51,787,788],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"CRS, format, time, resolution",[44,790],{"x":61,"y":62,"width":791,"height":792,"rx":65,"fill":793,"stroke":794,"style":68},"168","150","#eef7f4","#0f766e",[51,796,799],{"x":797,"y":798,"style":73,"fill":794,"textAnchor":57},"108","108.78","CRS",[51,801,803],{"x":797,"y":802,"style":78,"fill":88,"textAnchor":57},"134.78","native if possible",[51,805,807],{"x":797,"y":806,"style":78,"fill":88,"textAnchor":57},"160.78","avoid resampling",[44,809],{"x":810,"y":62,"width":791,"height":792,"rx":65,"fill":66,"stroke":67,"style":68},"206",[51,812,762],{"x":813,"y":798,"style":73,"fill":67,"textAnchor":57},"290",[51,815,816],{"x":813,"y":802,"style":78,"fill":88,"textAnchor":57},"image\u002Ftiff",[51,818,819],{"x":813,"y":806,"style":78,"fill":88,"textAnchor":57},"keeps values",[44,821],{"x":822,"y":62,"width":791,"height":792,"rx":65,"fill":823,"stroke":824,"style":68},"388","#fdf2e2","#b45309",[51,826,828],{"x":827,"y":798,"style":73,"fill":824,"textAnchor":57},"472","time",[51,830,831],{"x":827,"y":802,"style":78,"fill":88,"textAnchor":57},"one slice",[51,833,834],{"x":827,"y":806,"style":78,"fill":88,"textAnchor":57},"for forecasts",[44,836],{"x":837,"y":62,"width":838,"height":792,"rx":65,"fill":97,"stroke":98,"style":68},"570","166",[51,840,842],{"x":841,"y":798,"style":73,"fill":102,"textAnchor":57},"653","resolution",[51,844,845],{"x":841,"y":802,"style":78,"fill":88,"textAnchor":57},"native pixel",[51,847,848],{"x":841,"y":806,"style":78,"fill":88,"textAnchor":57},"for analysis",[156,850,852],{"className":158,"code":851,"language":160,"meta":161,"style":161},"temporal = QgsDataSourceUri()\ntemporal.setParam(\"url\", \"https:\u002F\u002Fmet.example.org\u002Fwcs\")\ntemporal.setParam(\"identifier\", \"temperature_2m\")\ntemporal.setParam(\"crs\", \"EPSG:4326\")\ntemporal.setParam(\"format\", \"image\u002Ftiff\")\ntemporal.setParam(\"time\", \"2026-10-02T12:00:00Z\")\n\nt2m = QgsRasterLayer(str(temporal.encodedUri(), \"utf-8\"), \"T2m 12:00\", \"wcs\")\nprint(t2m.isValid(), t2m.dataProvider().dataType(1))\n",[132,853,854,863,877,890,903,915,929,933,960],{"__ignoreMap":161},[165,855,856,859,861],{"class":167,"line":168},[165,857,858],{"class":175},"temporal ",[165,860,252],{"class":171},[165,862,553],{"class":175},[165,864,865,868,870,872,875],{"class":167,"line":186},[165,866,867],{"class":175},"temporal.setParam(",[165,869,561],{"class":242},[165,871,356],{"class":175},[165,873,874],{"class":242},"\"https:\u002F\u002Fmet.example.org\u002Fwcs\"",[165,876,489],{"class":175},[165,878,879,881,883,885,888],{"class":167,"line":200},[165,880,867],{"class":175},[165,882,574],{"class":242},[165,884,356],{"class":175},[165,886,887],{"class":242},"\"temperature_2m\"",[165,889,489],{"class":175},[165,891,892,894,896,898,901],{"class":167,"line":213},[165,893,867],{"class":175},[165,895,588],{"class":242},[165,897,356],{"class":175},[165,899,900],{"class":242},"\"EPSG:4326\"",[165,902,489],{"class":175},[165,904,905,907,909,911,913],{"class":167,"line":226},[165,906,867],{"class":175},[165,908,602],{"class":242},[165,910,356],{"class":175},[165,912,607],{"class":242},[165,914,489],{"class":175},[165,916,917,919,922,924,927],{"class":167,"line":233},[165,918,867],{"class":175},[165,920,921],{"class":242},"\"time\"",[165,923,356],{"class":175},[165,925,926],{"class":242},"\"2026-10-02T12:00:00Z\"",[165,928,489],{"class":175},[165,930,931],{"class":167,"line":246},[165,932,230],{"emptyLinePlaceholder":229},[165,934,935,938,940,942,944,947,949,951,954,956,958],{"class":167,"line":273},[165,936,937],{"class":175},"t2m ",[165,939,252],{"class":171},[165,941,637],{"class":175},[165,943,640],{"class":182},[165,945,946],{"class":175},"(temporal.encodedUri(), ",[165,948,646],{"class":242},[165,950,649],{"class":175},[165,952,953],{"class":242},"\"T2m 12:00\"",[165,955,356],{"class":175},[165,957,347],{"class":242},[165,959,489],{"class":175},[165,961,962,964,967,969],{"class":167,"line":284},[165,963,691],{"class":182},[165,965,966],{"class":175},"(t2m.isValid(), t2m.dataProvider().dataType(",[165,968,703],{"class":182},[165,970,270],{"class":175},[14,972,973,975,976,978,979,983],{},[493,974,495],{}," Requesting the coverage's native CRS avoids server-side resampling, which can blur values or change NoData handling. GeoTIFF is the format that reliably carries floats and NoData; PNG and JPEG are image formats and quantise values. For temporal coverages, the ",[132,977,828],{}," parameter selects one slice in ISO 8601 form; loading several times means several layers, which can then be stepped through with the ",[21,980,982],{"href":981},"\u002Fpyqgis-cartography-visualization\u002Ftemporal-and-3d-visualization\u002Fanimate-with-temporal-controller-pyqgis\u002F","temporal controller",". The capabilities and DescribeCoverage responses list supported CRSs, formats and time positions.",[117,985,987],{"id":986},"download-a-subset-for-analysis","Download a subset for analysis",[14,989,990],{},"A WCS layer re-requests data whenever the view changes, which is wasteful for analysis and unreliable for long jobs. Downloading the area of interest once into a local GeoTIFF gives a stable input.",[156,992,994],{"className":158,"code":993,"language":160,"meta":161,"style":161},"import processing\nfrom qgis.core import QgsRectangle\n\narea = QgsRectangle(565000, 5928000, 575000, 5938000)       # in EPSG:25832\nlocal = processing.run(\"gdal:cliprasterbyextent\", {\n    \"INPUT\": dem,\n    \"PROJWIN\": f\"{area.xMinimum()},{area.xMaximum()},{area.yMinimum()},{area.yMaximum()} [EPSG:25832]\",\n    \"NODATA\": None,\n    \"OPTIONS\": \"COMPRESS=DEFLATE|PREDICTOR=3|TILED=YES\",\n    \"DATA_TYPE\": 0,\n    \"OUTPUT\": \"\u002Fdata\u002Fcache\u002Fdem_1m_subset.tif\",\n})[\"OUTPUT\"]\n\ncheck = QgsRasterLayer(local, \"DEM subset\")\nprint(check.width(), \"x\", check.height(), \"pixels at\", round(check.rasterUnitsPerPixelX(), 2), \"m\")\n",[132,995,996,1003,1014,1018,1053,1069,1077,1128,1140,1152,1163,1175,1186,1190,1205],{"__ignoreMap":161},[165,997,998,1000],{"class":167,"line":168},[165,999,172],{"class":171},[165,1001,1002],{"class":175}," processing\n",[165,1004,1005,1007,1009,1011],{"class":167,"line":186},[165,1006,189],{"class":171},[165,1008,218],{"class":175},[165,1010,172],{"class":171},[165,1012,1013],{"class":175}," QgsRectangle\n",[165,1015,1016],{"class":167,"line":200},[165,1017,230],{"emptyLinePlaceholder":229},[165,1019,1020,1023,1025,1028,1031,1033,1036,1038,1041,1043,1046,1049],{"class":167,"line":213},[165,1021,1022],{"class":175},"area ",[165,1024,252],{"class":171},[165,1026,1027],{"class":175}," QgsRectangle(",[165,1029,1030],{"class":182},"565000",[165,1032,356],{"class":175},[165,1034,1035],{"class":182},"5928000",[165,1037,356],{"class":175},[165,1039,1040],{"class":182},"575000",[165,1042,356],{"class":175},[165,1044,1045],{"class":182},"5938000",[165,1047,1048],{"class":175},")       ",[165,1050,1052],{"class":1051},"sjoCn","# in EPSG:25832\n",[165,1054,1055,1058,1060,1063,1066],{"class":167,"line":226},[165,1056,1057],{"class":175},"local ",[165,1059,252],{"class":171},[165,1061,1062],{"class":175}," processing.run(",[165,1064,1065],{"class":242},"\"gdal:cliprasterbyextent\"",[165,1067,1068],{"class":175},", {\n",[165,1070,1071,1074],{"class":167,"line":233},[165,1072,1073],{"class":242},"    \"INPUT\"",[165,1075,1076],{"class":175},": dem,\n",[165,1078,1079,1082,1084,1086,1088,1090,1093,1095,1098,1100,1103,1105,1107,1109,1112,1114,1116,1118,1121,1123,1126],{"class":167,"line":246},[165,1080,1081],{"class":242},"    \"PROJWIN\"",[165,1083,350],{"class":175},[165,1085,258],{"class":171},[165,1087,261],{"class":242},[165,1089,448],{"class":182},[165,1091,1092],{"class":175},"area.xMinimum()",[165,1094,457],{"class":182},[165,1096,1097],{"class":242},",",[165,1099,448],{"class":182},[165,1101,1102],{"class":175},"area.xMaximum()",[165,1104,457],{"class":182},[165,1106,1097],{"class":242},[165,1108,448],{"class":182},[165,1110,1111],{"class":175},"area.yMinimum()",[165,1113,457],{"class":182},[165,1115,1097],{"class":242},[165,1117,448],{"class":182},[165,1119,1120],{"class":175},"area.yMaximum()",[165,1122,457],{"class":182},[165,1124,1125],{"class":242}," [EPSG:25832]\"",[165,1127,711],{"class":175},[165,1129,1130,1133,1135,1138],{"class":167,"line":273},[165,1131,1132],{"class":242},"    \"NODATA\"",[165,1134,350],{"class":175},[165,1136,1137],{"class":182},"None",[165,1139,711],{"class":175},[165,1141,1142,1145,1147,1150],{"class":167,"line":284},[165,1143,1144],{"class":242},"    \"OPTIONS\"",[165,1146,350],{"class":175},[165,1148,1149],{"class":242},"\"COMPRESS=DEFLATE|PREDICTOR=3|TILED=YES\"",[165,1151,711],{"class":175},[165,1153,1154,1157,1159,1161],{"class":167,"line":299},[165,1155,1156],{"class":242},"    \"DATA_TYPE\"",[165,1158,350],{"class":175},[165,1160,46],{"class":182},[165,1162,711],{"class":175},[165,1164,1165,1168,1170,1173],{"class":167,"line":311},[165,1166,1167],{"class":242},"    \"OUTPUT\"",[165,1169,350],{"class":175},[165,1171,1172],{"class":242},"\"\u002Fdata\u002Fcache\u002Fdem_1m_subset.tif\"",[165,1174,711],{"class":175},[165,1176,1177,1180,1183],{"class":167,"line":331},[165,1178,1179],{"class":175},"})[",[165,1181,1182],{"class":242},"\"OUTPUT\"",[165,1184,1185],{"class":175},"]\n",[165,1187,1188],{"class":167,"line":336},[165,1189,230],{"emptyLinePlaceholder":229},[165,1191,1192,1195,1197,1200,1203],{"class":167,"line":370},[165,1193,1194],{"class":175},"check ",[165,1196,252],{"class":171},[165,1198,1199],{"class":175}," QgsRasterLayer(local, ",[165,1201,1202],{"class":242},"\"DEM subset\"",[165,1204,489],{"class":175},[165,1206,1207,1209,1212,1215,1218,1221,1223,1226,1229,1232,1234,1237],{"class":167,"line":402},[165,1208,691],{"class":182},[165,1210,1211],{"class":175},"(check.width(), ",[165,1213,1214],{"class":242},"\"x\"",[165,1216,1217],{"class":175},", check.height(), ",[165,1219,1220],{"class":242},"\"pixels at\"",[165,1222,356],{"class":175},[165,1224,1225],{"class":182},"round",[165,1227,1228],{"class":175},"(check.rasterUnitsPerPixelX(), ",[165,1230,1231],{"class":182},"2",[165,1233,649],{"class":175},[165,1235,1236],{"class":242},"\"m\"",[165,1238,489],{"class":175},[14,1240,1241,1243,1244,1247,1248,147],{},[493,1242,495],{}," Clipping the WCS layer by extent makes GDAL request exactly that window and write it to disk, keeping the native data type with ",[132,1245,1246],{},"DATA_TYPE"," 0. The pixel size printed afterwards should match the coverage's native resolution; if it is coarser, the request was resampled and should be repeated with an explicit resolution. Large areas may exceed a server's maximum response size — download in tiles and merge, as in ",[21,1249,1251],{"href":1250},"\u002Fspatial-data-processing-automation\u002Fraster-analysis-workflows\u002Fmerge-raster-tiles-into-mosaic-pyqgis\u002F","merging raster tiles into a mosaic",[117,1253,1255],{"id":1254},"download-large-areas-in-tiles","Download large areas in tiles",[14,1257,1258],{},"Servers cap the size of a single response — often a few thousand pixels on a side. For a large area at native resolution, request a grid of tiles, each within the limit, and assemble them locally.",[14,1260,1261],{},[29,1262,1265,1268,1271,1274,1289,1292,1298,1303,1307,1311,1316,1320,1324,1328,1332,1336,1340,1343,1347],{"viewBox":1263,"role":32,"ariaLabel":1264,"xmlns":34},"0 0 760 196","An area of interest split into grid-aligned tiles within the server limit, downloaded with retries and assembled into one raster",[36,1266,1267],{},"Tiled download",[40,1269,1270],{},"The area of interest is divided into tiles small enough for the server's maximum response size, each snapped to the coverage's pixel grid. Each tile is downloaded as a GeoTIFF; failed tiles are retried. A VRT or merge assembles the tiles into one raster covering the whole area.",[44,1272],{"x":46,"y":46,"width":47,"height":1273,"fill":49},"196",[1275,1276,1277],"defs",{},[1278,1279,1285],"marker",{"id":1280,"viewBox":1281,"refX":65,"refY":1282,"markerWidth":1283,"markerHeight":1283,"orient":1284},"wcsTilesArrow","0 0 10 10","5","7","auto-start-reverse",[1286,1287],"path",{"d":1288,"fill":79},"M0 0 L10 5 L0 10 z",[51,1290,1291],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"Split, download, assemble",[44,1293],{"x":61,"y":1294,"width":1295,"height":1296,"rx":65,"fill":1297,"stroke":88,"style":68},"60","200","120","#fffdf7",[51,1299,1302],{"x":1300,"y":1301,"style":73,"fill":56,"textAnchor":57},"124","99.78","area of interest",[51,1304,1306],{"x":1300,"y":1305,"style":78,"fill":88,"textAnchor":57},"123.78","too big for one",[51,1308,1310],{"x":1300,"y":1309,"style":78,"fill":88,"textAnchor":57},"147.78","request",[167,1312],{"x1":1313,"y1":1296,"x2":1314,"y2":1296,"stroke":79,"style":1315},"224","266","stroke-width:1.8;marker-end:url(#wcsTilesArrow)",[44,1317],{"x":1318,"y":1294,"width":1319,"height":1296,"rx":65,"fill":793,"stroke":794,"style":68},"270","220",[51,1321,1323],{"x":53,"y":1322,"style":73,"fill":794,"textAnchor":57},"87.78","tiles",[51,1325,1327],{"x":53,"y":1326,"style":78,"fill":88,"textAnchor":57},"111.78","≤ server limit",[51,1329,1331],{"x":53,"y":1330,"style":78,"fill":88,"textAnchor":57},"135.78","grid-aligned",[51,1333,1335],{"x":53,"y":1334,"style":78,"fill":88,"textAnchor":57},"159.78","retry failures",[167,1337],{"x1":1338,"y1":1296,"x2":1339,"y2":1296,"stroke":79,"style":1315},"490","532",[44,1341],{"x":1342,"y":1294,"width":1295,"height":1296,"rx":65,"fill":97,"stroke":98,"style":68},"536",[51,1344,1346],{"x":1345,"y":1326,"style":73,"fill":102,"textAnchor":57},"636","VRT \u002F merge",[51,1348,1349],{"x":1345,"y":1330,"style":78,"fill":88,"textAnchor":57},"one raster",[156,1351,1353],{"className":158,"code":1352,"language":160,"meta":161,"style":161},"import math\nfrom pathlib import Path\n\nTILE_PX = 2000\npx = dem.rasterUnitsPerPixelX()\nstep = TILE_PX * px\ntiles = []\nfor i in range(math.ceil(area.width() \u002F step)):\n    for j in range(math.ceil(area.height() \u002F step)):\n        x0 = area.xMinimum() + i * step\n        y0 = area.yMinimum() + j * step\n        x1, y1 = min(x0 + step, area.xMaximum()), min(y0 + step, area.yMaximum())\n        out = f\"\u002Fdata\u002Fcache\u002Fdem_tiles\u002Ft_{i:03d}_{j:03d}.tif\"\n        if not Path(out).exists():\n            processing.run(\"gdal:cliprasterbyextent\", {\n                \"INPUT\": dem, \"PROJWIN\": f\"{x0},{x1},{y0},{y1} [EPSG:25832]\",\n                \"DATA_TYPE\": 0, \"OPTIONS\": \"COMPRESS=DEFLATE|TILED=YES\", \"OUTPUT\": out})\n        tiles.append(out)\nvrt = processing.run(\"gdal:buildvirtualraster\", {\n    \"INPUT\": tiles, \"SEPARATE\": False, \"OUTPUT\": \"\u002Fdata\u002Fcache\u002Fdem_area.vrt\"})[\"OUTPUT\"]\n",[132,1354,1355,1362,1374,1378,1388,1398,1414,1424,1445,1464,1485,1503,1532,1570,1580,1589,1644,1670,1676,1691],{"__ignoreMap":161},[165,1356,1357,1359],{"class":167,"line":168},[165,1358,172],{"class":171},[165,1360,1361],{"class":175}," math\n",[165,1363,1364,1366,1369,1371],{"class":167,"line":186},[165,1365,189],{"class":171},[165,1367,1368],{"class":175}," pathlib ",[165,1370,172],{"class":171},[165,1372,1373],{"class":175}," Path\n",[165,1375,1376],{"class":167,"line":200},[165,1377,230],{"emptyLinePlaceholder":229},[165,1379,1380,1383,1385],{"class":167,"line":213},[165,1381,1382],{"class":182},"TILE_PX",[165,1384,239],{"class":171},[165,1386,1387],{"class":182}," 2000\n",[165,1389,1390,1393,1395],{"class":167,"line":226},[165,1391,1392],{"class":175},"px ",[165,1394,252],{"class":171},[165,1396,1397],{"class":175}," dem.rasterUnitsPerPixelX()\n",[165,1399,1400,1403,1405,1408,1411],{"class":167,"line":233},[165,1401,1402],{"class":175},"step ",[165,1404,252],{"class":171},[165,1406,1407],{"class":182}," TILE_PX",[165,1409,1410],{"class":171}," *",[165,1412,1413],{"class":175}," px\n",[165,1415,1416,1419,1421],{"class":167,"line":246},[165,1417,1418],{"class":175},"tiles ",[165,1420,252],{"class":171},[165,1422,1423],{"class":175}," []\n",[165,1425,1426,1428,1431,1433,1436,1439,1442],{"class":167,"line":273},[165,1427,373],{"class":171},[165,1429,1430],{"class":175}," i ",[165,1432,379],{"class":171},[165,1434,1435],{"class":182}," range",[165,1437,1438],{"class":175},"(math.ceil(area.width() ",[165,1440,1441],{"class":171},"\u002F",[165,1443,1444],{"class":175}," step)):\n",[165,1446,1447,1450,1453,1455,1457,1460,1462],{"class":167,"line":284},[165,1448,1449],{"class":171},"    for",[165,1451,1452],{"class":175}," j ",[165,1454,379],{"class":171},[165,1456,1435],{"class":182},[165,1458,1459],{"class":175},"(math.ceil(area.height() ",[165,1461,1441],{"class":171},[165,1463,1444],{"class":175},[165,1465,1466,1469,1471,1474,1477,1479,1482],{"class":167,"line":299},[165,1467,1468],{"class":175},"        x0 ",[165,1470,252],{"class":171},[165,1472,1473],{"class":175}," area.xMinimum() ",[165,1475,1476],{"class":171},"+",[165,1478,1430],{"class":175},[165,1480,1481],{"class":171},"*",[165,1483,1484],{"class":175}," step\n",[165,1486,1487,1490,1492,1495,1497,1499,1501],{"class":167,"line":311},[165,1488,1489],{"class":175},"        y0 ",[165,1491,252],{"class":171},[165,1493,1494],{"class":175}," area.yMinimum() ",[165,1496,1476],{"class":171},[165,1498,1452],{"class":175},[165,1500,1481],{"class":171},[165,1502,1484],{"class":175},[165,1504,1505,1508,1510,1513,1516,1518,1521,1524,1527,1529],{"class":167,"line":331},[165,1506,1507],{"class":175},"        x1, y1 ",[165,1509,252],{"class":171},[165,1511,1512],{"class":182}," min",[165,1514,1515],{"class":175},"(x0 ",[165,1517,1476],{"class":171},[165,1519,1520],{"class":175}," step, area.xMaximum()), ",[165,1522,1523],{"class":182},"min",[165,1525,1526],{"class":175},"(y0 ",[165,1528,1476],{"class":171},[165,1530,1531],{"class":175}," step, area.yMaximum())\n",[165,1533,1534,1537,1539,1542,1545,1547,1550,1553,1555,1558,1560,1563,1565,1567],{"class":167,"line":336},[165,1535,1536],{"class":175},"        out ",[165,1538,252],{"class":171},[165,1540,1541],{"class":171}," f",[165,1543,1544],{"class":242},"\"\u002Fdata\u002Fcache\u002Fdem_tiles\u002Ft_",[165,1546,448],{"class":182},[165,1548,1549],{"class":175},"i",[165,1551,1552],{"class":171},":03d",[165,1554,457],{"class":182},[165,1556,1557],{"class":242},"_",[165,1559,448],{"class":182},[165,1561,1562],{"class":175},"j",[165,1564,1552],{"class":171},[165,1566,457],{"class":182},[165,1568,1569],{"class":242},".tif\"\n",[165,1571,1572,1575,1577],{"class":167,"line":370},[165,1573,1574],{"class":171},"        if",[165,1576,473],{"class":171},[165,1578,1579],{"class":175}," Path(out).exists():\n",[165,1581,1582,1585,1587],{"class":167,"line":402},[165,1583,1584],{"class":175},"            processing.run(",[165,1586,1065],{"class":242},[165,1588,1068],{"class":175},[165,1590,1591,1594,1597,1600,1602,1604,1606,1608,1611,1613,1615,1617,1620,1622,1624,1626,1629,1631,1633,1635,1638,1640,1642],{"class":167,"line":419},[165,1592,1593],{"class":242},"                \"INPUT\"",[165,1595,1596],{"class":175},": dem, ",[165,1598,1599],{"class":242},"\"PROJWIN\"",[165,1601,350],{"class":175},[165,1603,258],{"class":171},[165,1605,261],{"class":242},[165,1607,448],{"class":182},[165,1609,1610],{"class":175},"x0",[165,1612,457],{"class":182},[165,1614,1097],{"class":242},[165,1616,448],{"class":182},[165,1618,1619],{"class":175},"x1",[165,1621,457],{"class":182},[165,1623,1097],{"class":242},[165,1625,448],{"class":182},[165,1627,1628],{"class":175},"y0",[165,1630,457],{"class":182},[165,1632,1097],{"class":242},[165,1634,448],{"class":182},[165,1636,1637],{"class":175},"y1",[165,1639,457],{"class":182},[165,1641,1125],{"class":242},[165,1643,711],{"class":175},[165,1645,1646,1649,1651,1653,1655,1658,1660,1663,1665,1667],{"class":167,"line":435},[165,1647,1648],{"class":242},"                \"DATA_TYPE\"",[165,1650,350],{"class":175},[165,1652,46],{"class":182},[165,1654,356],{"class":175},[165,1656,1657],{"class":242},"\"OPTIONS\"",[165,1659,350],{"class":175},[165,1661,1662],{"class":242},"\"COMPRESS=DEFLATE|TILED=YES\"",[165,1664,356],{"class":175},[165,1666,1182],{"class":242},[165,1668,1669],{"class":175},": out})\n",[165,1671,1673],{"class":167,"line":1672},18,[165,1674,1675],{"class":175},"        tiles.append(out)\n",[165,1677,1679,1682,1684,1686,1689],{"class":167,"line":1678},19,[165,1680,1681],{"class":175},"vrt ",[165,1683,252],{"class":171},[165,1685,1062],{"class":175},[165,1687,1688],{"class":242},"\"gdal:buildvirtualraster\"",[165,1690,1068],{"class":175},[165,1692,1694,1696,1699,1702,1704,1707,1709,1711,1713,1716,1718,1720],{"class":167,"line":1693},20,[165,1695,1073],{"class":242},[165,1697,1698],{"class":175},": tiles, ",[165,1700,1701],{"class":242},"\"SEPARATE\"",[165,1703,350],{"class":175},[165,1705,1706],{"class":182},"False",[165,1708,356],{"class":175},[165,1710,1182],{"class":242},[165,1712,350],{"class":175},[165,1714,1715],{"class":242},"\"\u002Fdata\u002Fcache\u002Fdem_area.vrt\"",[165,1717,1179],{"class":175},[165,1719,1182],{"class":242},[165,1721,1185],{"class":175},[14,1723,1724,1726,1727,1441,1730,1733,1734,1738],{},[493,1725,495],{}," Tiles of 2,000 pixels at native resolution stay under typical limits; check the server's documentation or its ",[132,1728,1729],{},"MaxWidth",[132,1731,1732],{},"MaxHeight"," hints. Skipping tiles that already exist makes the loop restartable after a network failure — rerun it and only missing tiles are fetched. Starting tiles at the area's origin and stepping by whole pixels keeps them aligned with each other. A VRT assembles the result without copying, as in ",[21,1735,1737],{"href":1736},"\u002Fspatial-data-processing-automation\u002Fraster-analysis-workflows\u002Fbuild-virtual-raster-vrt-pyqgis\u002F","building a virtual raster","; translate it to one GeoTIFF if a single file is needed.",[117,1740,1742],{"id":1741},"record-where-the-data-came-from","Record where the data came from",[14,1744,1745],{},"Downloaded coverages lose their link to the server. Writing the source, coverage id and request time into the file's metadata keeps the provenance.",[156,1747,1749],{"className":158,"code":1748,"language":160,"meta":161,"style":161},"from osgeo import gdal\nfrom datetime import datetime, timezone\n\nds = gdal.Open(local, gdal.GA_Update)\nds.SetMetadata({\"SOURCE_SERVICE\": BASE, \"COVERAGE_ID\": \"dem_1m\",\n                \"RETRIEVED_UTC\": datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")})\nds = None\nprint(gdal.Info(local).splitlines()[0])\n",[132,1750,1751,1763,1775,1779,1794,1817,1837,1846],{"__ignoreMap":161},[165,1752,1753,1755,1758,1760],{"class":167,"line":168},[165,1754,189],{"class":171},[165,1756,1757],{"class":175}," osgeo ",[165,1759,172],{"class":171},[165,1761,1762],{"class":175}," gdal\n",[165,1764,1765,1767,1770,1772],{"class":167,"line":186},[165,1766,189],{"class":171},[165,1768,1769],{"class":175}," datetime ",[165,1771,172],{"class":171},[165,1773,1774],{"class":175}," datetime, timezone\n",[165,1776,1777],{"class":167,"line":200},[165,1778,230],{"emptyLinePlaceholder":229},[165,1780,1781,1784,1786,1789,1792],{"class":167,"line":213},[165,1782,1783],{"class":175},"ds ",[165,1785,252],{"class":171},[165,1787,1788],{"class":175}," gdal.Open(local, gdal.",[165,1790,1791],{"class":182},"GA_Update",[165,1793,489],{"class":175},[165,1795,1796,1799,1802,1804,1806,1808,1811,1813,1815],{"class":167,"line":226},[165,1797,1798],{"class":175},"ds.SetMetadata({",[165,1800,1801],{"class":242},"\"SOURCE_SERVICE\"",[165,1803,350],{"class":175},[165,1805,236],{"class":182},[165,1807,356],{"class":175},[165,1809,1810],{"class":242},"\"COVERAGE_ID\"",[165,1812,350],{"class":175},[165,1814,579],{"class":242},[165,1816,711],{"class":175},[165,1818,1819,1822,1825,1828,1831,1834],{"class":167,"line":233},[165,1820,1821],{"class":242},"                \"RETRIEVED_UTC\"",[165,1823,1824],{"class":175},": datetime.now(timezone.utc).strftime(",[165,1826,1827],{"class":242},"\"%Y-%m-",[165,1829,1830],{"class":182},"%d",[165,1832,1833],{"class":242},"T%H:%M:%SZ\"",[165,1835,1836],{"class":175},")})\n",[165,1838,1839,1841,1843],{"class":167,"line":246},[165,1840,1783],{"class":175},[165,1842,252],{"class":171},[165,1844,1845],{"class":182}," None\n",[165,1847,1848,1850,1853,1855],{"class":167,"line":273},[165,1849,691],{"class":182},[165,1851,1852],{"class":175},"(gdal.Info(local).splitlines()[",[165,1854,46],{"class":182},[165,1856,1857],{"class":175},"])\n",[14,1859,1860,1862,1863,1866,1867,147],{},[493,1861,495],{}," GeoTIFF metadata items travel with the file and appear in QGIS's layer properties and in ",[132,1864,1865],{},"gdalinfo",". Recording the retrieval time matters most for coverages that change — forecasts, near-real-time land cover — where \"the DEM from the WCS\" is ambiguous without a date. The same habit is shown for vector services in ",[21,1868,1870],{"href":1869},"\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fload-ogc-api-features-layer-pyqgis\u002F","loading an OGC API Features layer",[117,1872,1874],{"id":1873},"wcs-wms-or-a-cog","WCS, WMS or a COG?",[14,1876,1877,1878,1882],{},"Use WMS when you only need to see the data. Use WCS when you need values and the provider publishes through it. Increasingly, providers publish raster data as Cloud Optimized GeoTIFFs on object storage instead — simpler for them, faster for you, and readable with the same GDAL machinery; see ",[21,1879,1881],{"href":1880},"\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fread-cloud-optimized-geotiff-pyqgis\u002F","reading a Cloud Optimized GeoTIFF",". Where both WCS and COG are offered, COG is usually the more reliable choice for scripted downloads.",[117,1884,1886],{"id":1885},"qgis-version-compatibility","QGIS version compatibility",[14,1888,519,1889,1891,1892,356,1894,356,1896,356,1898,1900,1901,1904,1905,1908,1909,147],{},[132,1890,522],{}," provider supports WCS 1.0, 1.1 and 2.0 servers on QGIS 3.34 LTR, 3.40 LTR and QGIS 4. URI parameters such as ",[132,1893,754],{},[132,1895,758],{},[132,1897,762],{},[132,1899,828],{}," and ",[132,1902,1903],{},"cache"," are stable across these releases. On QGIS 4, ",[132,1906,1907],{},"QgsBlockingNetworkRequest.NoError"," is ",[132,1910,1911],{},"QgsBlockingNetworkRequest.ErrorCode.NoError",[117,1913,1915],{"id":1914},"troubleshooting","Troubleshooting",[122,1917,1918,1928,1937,1943],{},[125,1919,1920,1923,1924,1927],{},[493,1921,1922],{},"The layer is invalid."," The identifier is the title rather than the CoverageId, or the server only speaks an older version; try ",[132,1925,1926],{},"version=1.0.0"," in the URI.",[125,1929,1930,1933,1934,1936],{},[493,1931,1932],{},"Values look like colours (0–255)."," The server returned a rendered image; request ",[132,1935,816],{}," and check the coverage is data, not imagery.",[125,1938,1939,1942],{},[493,1940,1941],{},"Downloads fail for large areas."," The server limits response size; download in tiles.",[125,1944,1945,1948],{},[493,1946,1947],{},"NoData appears as a real value."," The format dropped NoData; use GeoTIFF and set NoData explicitly if needed.",[117,1950,1952],{"id":1951},"conclusion","Conclusion",[14,1954,1955,1956,1958],{},"Discover coverage ids from GetCapabilities, load them with the ",[132,1957,522],{}," provider in their native CRS and GeoTIFF format, select a time slice for temporal coverages, download the area of interest once into a compressed local GeoTIFF for analysis, record provenance in its metadata, and prefer COG sources where providers offer them.",[117,1960,1962],{"id":1961},"frequently-asked-questions","Frequently Asked Questions",[14,1964,1965,1968],{},[493,1966,1967],{},"Can I compute slope directly on a WCS layer?","\nYes, but download first: analysis on a live service is slower and can fail mid-run.",[14,1970,1971,1974,1975,1977],{},[493,1972,1973],{},"Does QGIS cache WCS responses?","\nYes, through its network cache, controlled by the ",[132,1976,1903],{}," URI parameter and QGIS's cache settings.",[14,1979,1980,1983],{},[493,1981,1982],{},"What is DescribeCoverage?","\nA request returning one coverage's details — grid, CRSs, range type — useful for choosing resolution and format.",[14,1985,1986,1989],{},[493,1987,1988],{},"Is WCS being replaced?","\nOGC API – Coverages is its successor; adoption is still early, and WCS remains widely deployed.",[117,1991,1993],{"id":1992},"related","Related",[122,1995,1996,2001,2007,2012,2018],{},[125,1997,1998,2000],{},[21,1999,24],{"href":23}," — the guide this recipe belongs to",[125,2002,2003],{},[21,2004,2006],{"href":2005},"\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fload-wms-layer-pyqgis\u002F","Load a WMS Layer in PyQGIS",[125,2008,2009],{},[21,2010,2011],{"href":1880},"Read a Cloud Optimized GeoTIFF in PyQGIS",[125,2013,2014],{},[21,2015,2017],{"href":2016},"\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fdownload-files-with-qgsfiledownloader-pyqgis\u002F","Download Files with QgsFileDownloader in PyQGIS",[125,2019,2020],{},[21,2021,2023],{"href":2022},"\u002Fspatial-data-processing-automation\u002Fraster-analysis-workflows\u002Fclip-raster-by-mask-layer-pyqgis\u002F","Clip a Raster by a Mask Layer in PyQGIS",[2025,2026,2027],"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 .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sjoCn, html code.shiki .sjoCn{--shiki-default:#9AA79F}",{"title":161,"searchDepth":186,"depth":186,"links":2029},[2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040,2041,2042],{"id":119,"depth":186,"text":120},{"id":150,"depth":186,"text":151},{"id":515,"depth":186,"text":516},{"id":766,"depth":186,"text":767},{"id":986,"depth":186,"text":987},{"id":1254,"depth":186,"text":1255},{"id":1741,"depth":186,"text":1742},{"id":1873,"depth":186,"text":1874},{"id":1885,"depth":186,"text":1886},{"id":1914,"depth":186,"text":1915},{"id":1951,"depth":186,"text":1952},{"id":1961,"depth":186,"text":1962},{"id":1992,"depth":186,"text":1993},"Read raster data from OGC Web Coverage Services in PyQGIS — discovering coverages from GetCapabilities, loading them with the wcs provider, choosing CRS, format and time, downloading a subset as a GeoTIFF for analysis, and knowing how WCS differs from WMS imagery.","md",{"slug":2046,"type":2047,"breadcrumb":2048,"datePublished":2049,"dateModified":2049},"load-wcs-coverage-pyqgis","article","Load a WCS Coverage","2026-10-02","\u002Fspatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fload-wcs-coverage-pyqgis",{"title":5,"description":2043},"spatial-data-processing-automation\u002Fweb-services-and-remote-data\u002Fload-wcs-coverage-pyqgis\u002Findex","7DmOJmNtGD55GvNHFuqANNqsl1q1BboiKsrSoYW9MuI",1790966266193]