[{"data":1,"prerenderedAt":1728},["ShallowReactive",2],{"doc:\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Fassign-crs-without-reprojecting-pyqgis":3},{"id":4,"title":5,"body":6,"description":1717,"extension":1718,"meta":1719,"navigation":182,"path":1724,"seo":1725,"stem":1726,"__hash__":1727},"docs\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Fassign-crs-without-reprojecting-pyqgis\u002Findex.md","Assign a CRS Without Reprojecting in PyQGIS",{"type":7,"value":8,"toc":1703},"minimark",[9,13,22,36,127,132,142,146,149,502,509,513,516,577,892,901,905,908,960,969,973,976,1128,1145,1149,1152,1246,1481,1486,1490,1493,1554,1568,1572,1587,1591,1622,1626,1634,1638,1644,1650,1659,1665,1669,1699],[10,11,5],"h1",{"id":12},"assign-a-crs-without-reprojecting-in-pyqgis",[14,15,16,17,21],"p",{},"A layer's CRS is a label: it tells QGIS how to interpret the numbers in the geometry. When the label is wrong — a shapefile with the wrong ",[18,19,20],"code",{},".prj",", a CSV loaded with the project's default CRS, an export that wrote WGS 84 over projected metres — the data appears in the wrong place, often in the ocean off West Africa or as a speck near the origin. Reprojecting such a layer makes things worse: it transforms coordinates that were never in the source system, moving the data further from the truth. The fix is to change the label and leave the numbers alone.",[14,23,24,25,30,31,35],{},"This recipe belongs to ",[26,27,29],"a",{"href":28},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002F","Coordinate Reference Systems",". It explains the difference between assigning and reprojecting, recognises mislabelled layers from their coordinates, tests candidate CRSs against a known location, relabels the layer for the session and permanently, and adds checks that stop the mistake recurring. Layers with no CRS at all are covered in ",[26,32,34],{"href":33},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Fhandling-missing-crs-in-pyqgis\u002F","handling missing CRS",".",[14,37,38],{},[39,40,45,49,53,60,69,79,86,92,97,101,106,111,115,118,121,124],"svg",{"viewBox":41,"role":42,"ariaLabel":43,"xmlns":44},"0 0 760 262","img","Assigning a CRS changes only the label and keeps coordinates, while reprojecting converts coordinates from the labelled CRS to another","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[46,47,48],"title",{},"Assigning versus reprojecting",[50,51,52],"desc",{},"Assigning a CRS changes only the label: the coordinate numbers stay the same and QGIS interprets them differently, which moves a mislabelled layer to its correct place. Reprojecting changes the numbers: it converts coordinates from the labelled CRS to another, which is right only if the label was right in the first place. Reprojecting a mislabelled layer converts wrong assumptions precisely.",[54,55],"rect",{"x":56,"y":56,"width":57,"height":58,"fill":59},"0","760","262","#f6f3ea",[61,62,68],"text",{"x":63,"y":64,"style":65,"fill":66,"textAnchor":67},"380","28","text-anchor:middle;font-size:14px;font-family:sans-serif;font-weight:bold","#17211d","middle","Change the label, or change the numbers?",[54,70],{"x":71,"y":72,"width":73,"height":74,"rx":75,"fill":76,"stroke":77,"style":78},"24","56","340","190","8","#e8efe6","#15803d","stroke-width:2",[61,80,85],{"x":81,"y":82,"style":83,"fill":84,"textAnchor":67},"194","94.78","text-anchor:middle;font-size:11.5px;font-family:sans-serif;font-weight:bold","#166534","assign (relabel)",[61,87,91],{"x":81,"y":88,"style":89,"fill":90,"textAnchor":67},"124.78","text-anchor:middle;font-size:10.5px;font-family:sans-serif","#2f3b35","numbers unchanged",[61,93,96],{"x":81,"y":94,"style":95,"fill":90,"textAnchor":67},"154.78","text-anchor:middle;font-size:10.0px;font-family:monospace","571244, 5934019",[61,98,100],{"x":81,"y":99,"style":89,"fill":90,"textAnchor":67},"184.78","label: 4326 → 25832",[61,102,105],{"x":81,"y":103,"style":89,"fill":104,"textAnchor":67},"214.78","#59645f","fixes a wrong label",[54,107],{"x":108,"y":72,"width":73,"height":74,"rx":75,"fill":109,"stroke":110,"style":78},"396","#eff3ff","#2563eb",[61,112,114],{"x":113,"y":82,"style":83,"fill":110,"textAnchor":67},"566","reproject (transform)",[61,116,117],{"x":113,"y":88,"style":89,"fill":90,"textAnchor":67},"numbers converted",[61,119,120],{"x":113,"y":94,"style":95,"fill":90,"textAnchor":67},"571244 → 9.94",[61,122,123],{"x":113,"y":99,"style":89,"fill":90,"textAnchor":67},"label: 25832 → 4326",[61,125,126],{"x":113,"y":103,"style":89,"fill":104,"textAnchor":67},"needs a right label first",[128,129,131],"h2",{"id":130},"prerequisites","Prerequisites",[133,134,135,139],"ul",{},[136,137,138],"li",{},"QGIS 3.34 LTR or newer, or the QGIS 4 series.",[136,140,141],{},"Some idea of where the data should be: a known town, a reference layer, the survey area. Diagnosing a CRS without one is guesswork.",[128,143,145],{"id":144},"recognise-a-mislabelled-layer","Recognise a mislabelled layer",[14,147,148],{},"The coordinates themselves usually reveal the true system. Geographic coordinates lie between −180 and 180, −90 and 90; projected coordinates are hundreds of thousands or millions of metres, often with recognisable ranges.",[150,151,156],"pre",{"className":152,"code":153,"language":154,"meta":155,"style":155},"language-python shiki shiki-themes github-dark","from qgis.core import QgsProject\n\ndef coordinate_fingerprint(layer):\n    e = layer.extent()\n    return {\"crs_label\": layer.crs().authid(),\n            \"x\": (round(e.xMinimum(), 3), round(e.xMaximum(), 3)),\n            \"y\": (round(e.yMinimum(), 3), round(e.yMaximum(), 3))}\n\ndef looks_geographic(e):\n    return -180 \u003C= e.xMinimum() \u003C= e.xMaximum() \u003C= 180 and -90 \u003C= e.yMinimum() \u003C= e.yMaximum() \u003C= 90\n\nfor lyr in QgsProject.instance().mapLayers().values():\n    if not hasattr(lyr, \"isSpatial\") or not lyr.isSpatial():\n        continue\n    e, crs = lyr.extent(), lyr.crs()\n    mismatch = crs.isGeographic() != looks_geographic(e)\n    flag = \"  \u003C-- label does not match coordinates\" if mismatch else \"\"\n    print(f\"{lyr.name():\u003C24} {coordinate_fingerprint(lyr)}{flag}\")\n","python","",[18,157,158,177,184,197,209,225,257,284,289,300,351,356,371,400,406,417,434,457],{"__ignoreMap":155},[159,160,163,167,171,174],"span",{"class":161,"line":162},"line",1,[159,164,166],{"class":165},"snl16","from",[159,168,170],{"class":169},"s95oV"," qgis.core ",[159,172,173],{"class":165},"import",[159,175,176],{"class":169}," QgsProject\n",[159,178,180],{"class":161,"line":179},2,[159,181,183],{"emptyLinePlaceholder":182},true,"\n",[159,185,187,190,194],{"class":161,"line":186},3,[159,188,189],{"class":165},"def",[159,191,193],{"class":192},"svObZ"," coordinate_fingerprint",[159,195,196],{"class":169},"(layer):\n",[159,198,200,203,206],{"class":161,"line":199},4,[159,201,202],{"class":169},"    e ",[159,204,205],{"class":165},"=",[159,207,208],{"class":169}," layer.extent()\n",[159,210,212,215,218,222],{"class":161,"line":211},5,[159,213,214],{"class":165},"    return",[159,216,217],{"class":169}," {",[159,219,221],{"class":220},"sU2Wk","\"crs_label\"",[159,223,224],{"class":169},": layer.crs().authid(),\n",[159,226,228,231,234,238,241,244,247,249,252,254],{"class":161,"line":227},6,[159,229,230],{"class":220},"            \"x\"",[159,232,233],{"class":169},": (",[159,235,237],{"class":236},"sDLfK","round",[159,239,240],{"class":169},"(e.xMinimum(), ",[159,242,243],{"class":236},"3",[159,245,246],{"class":169},"), ",[159,248,237],{"class":236},[159,250,251],{"class":169},"(e.xMaximum(), ",[159,253,243],{"class":236},[159,255,256],{"class":169},")),\n",[159,258,260,263,265,267,270,272,274,276,279,281],{"class":161,"line":259},7,[159,261,262],{"class":220},"            \"y\"",[159,264,233],{"class":169},[159,266,237],{"class":236},[159,268,269],{"class":169},"(e.yMinimum(), ",[159,271,243],{"class":236},[159,273,246],{"class":169},[159,275,237],{"class":236},[159,277,278],{"class":169},"(e.yMaximum(), ",[159,280,243],{"class":236},[159,282,283],{"class":169},"))}\n",[159,285,287],{"class":161,"line":286},8,[159,288,183],{"emptyLinePlaceholder":182},[159,290,292,294,297],{"class":161,"line":291},9,[159,293,189],{"class":165},[159,295,296],{"class":192}," looks_geographic",[159,298,299],{"class":169},"(e):\n",[159,301,303,305,308,311,314,317,320,323,325,328,331,333,336,338,341,343,346,348],{"class":161,"line":302},10,[159,304,214],{"class":165},[159,306,307],{"class":165}," -",[159,309,310],{"class":236},"180",[159,312,313],{"class":165}," \u003C=",[159,315,316],{"class":169}," e.xMinimum() ",[159,318,319],{"class":165},"\u003C=",[159,321,322],{"class":169}," e.xMaximum() ",[159,324,319],{"class":165},[159,326,327],{"class":236}," 180",[159,329,330],{"class":165}," and",[159,332,307],{"class":165},[159,334,335],{"class":236},"90",[159,337,313],{"class":165},[159,339,340],{"class":169}," e.yMinimum() ",[159,342,319],{"class":165},[159,344,345],{"class":169}," e.yMaximum() ",[159,347,319],{"class":165},[159,349,350],{"class":236}," 90\n",[159,352,354],{"class":161,"line":353},11,[159,355,183],{"emptyLinePlaceholder":182},[159,357,359,362,365,368],{"class":161,"line":358},12,[159,360,361],{"class":165},"for",[159,363,364],{"class":169}," lyr ",[159,366,367],{"class":165},"in",[159,369,370],{"class":169}," QgsProject.instance().mapLayers().values():\n",[159,372,374,377,380,383,386,389,392,395,397],{"class":161,"line":373},13,[159,375,376],{"class":165},"    if",[159,378,379],{"class":165}," not",[159,381,382],{"class":236}," hasattr",[159,384,385],{"class":169},"(lyr, ",[159,387,388],{"class":220},"\"isSpatial\"",[159,390,391],{"class":169},") ",[159,393,394],{"class":165},"or",[159,396,379],{"class":165},[159,398,399],{"class":169}," lyr.isSpatial():\n",[159,401,403],{"class":161,"line":402},14,[159,404,405],{"class":165},"        continue\n",[159,407,409,412,414],{"class":161,"line":408},15,[159,410,411],{"class":169},"    e, crs ",[159,413,205],{"class":165},[159,415,416],{"class":169}," lyr.extent(), lyr.crs()\n",[159,418,420,423,425,428,431],{"class":161,"line":419},16,[159,421,422],{"class":169},"    mismatch ",[159,424,205],{"class":165},[159,426,427],{"class":169}," crs.isGeographic() ",[159,429,430],{"class":165},"!=",[159,432,433],{"class":169}," looks_geographic(e)\n",[159,435,437,440,442,445,448,451,454],{"class":161,"line":436},17,[159,438,439],{"class":169},"    flag ",[159,441,205],{"class":165},[159,443,444],{"class":220}," \"  \u003C-- label does not match coordinates\"",[159,446,447],{"class":165}," if",[159,449,450],{"class":169}," mismatch ",[159,452,453],{"class":165},"else",[159,455,456],{"class":220}," \"\"\n",[159,458,460,463,466,469,472,475,478,481,484,486,489,492,495,497,499],{"class":161,"line":459},18,[159,461,462],{"class":236},"    print",[159,464,465],{"class":169},"(",[159,467,468],{"class":165},"f",[159,470,471],{"class":220},"\"",[159,473,474],{"class":236},"{",[159,476,477],{"class":169},"lyr.name()",[159,479,480],{"class":165},":\u003C24",[159,482,483],{"class":236},"}",[159,485,217],{"class":236},[159,487,488],{"class":169},"coordinate_fingerprint(lyr)",[159,490,491],{"class":236},"}{",[159,493,494],{"class":169},"flag",[159,496,483],{"class":236},[159,498,471],{"class":220},[159,500,501],{"class":169},")\n",[14,503,504,508],{},[505,506,507],"strong",{},"Breakdown:"," A layer labelled geographic whose x values are in the hundreds of thousands, or labelled projected whose values are small decimals, is mislabelled — that test catches the commonest cases in one pass. Finer clues come from the ranges: UTM eastings lie roughly between 160,000 and 840,000 m; northings in the northern hemisphere grow from 0 at the equator to about 9,300,000 m; national grids have characteristic offsets, such as a leading zone digit in older German Gauss–Krüger coordinates (3,4xx,xxx). Recognising them narrows the candidates quickly.",[128,510,512],{"id":511},"test-candidate-crss-against-a-known-location","Test candidate CRSs against a known location",[14,514,515],{},"With a short list of candidates, check each one: interpret the layer's coordinates in that CRS, transform a sample point to WGS 84, and see whether it lands where the data should be.",[14,517,518],{},[39,519,522,525,528,531,534,537,542,546,550,555,558,561,564,568,572,574],{"viewBox":520,"role":42,"ariaLabel":521,"xmlns":44},"0 0 760 222","A sample point interpreted in several candidate CRSs and transformed to WGS 84, with the candidate landing closest to the expected location chosen",[46,523,524],{},"Testing candidates",[50,526,527],{},"A sample point from the layer is interpreted in each candidate CRS and transformed to WGS 84. Candidate EPSG 25832 places it in the right town. Candidate EPSG 25833 places it hundreds of kilometres away. Candidate EPSG 31467 places it about a hundred metres off, because it is the same area but a different datum. The candidate within a few metres of the expected location wins.",[54,529],{"x":56,"y":56,"width":57,"height":530,"fill":59},"222",[61,532,533],{"x":63,"y":64,"style":65,"fill":66,"textAnchor":67},"Which label puts the point where it belongs?",[54,535],{"x":71,"y":72,"width":530,"height":536,"rx":75,"fill":76,"stroke":77,"style":78},"150",[61,538,541],{"x":539,"y":540,"style":83,"fill":84,"textAnchor":67},"135","106.78","EPSG:25832",[61,543,545],{"x":539,"y":544,"style":89,"fill":90,"textAnchor":67},"134.78","→ 9.94, 53.55",[61,547,549],{"x":539,"y":548,"style":89,"fill":104,"textAnchor":67},"162.78","0.2 km off ✓",[54,551],{"x":552,"y":72,"width":530,"height":536,"rx":75,"fill":553,"stroke":554,"style":78},"269","#fdf2e2","#b91c1c",[61,556,557],{"x":63,"y":540,"style":83,"fill":554,"textAnchor":67},"EPSG:25833",[61,559,560],{"x":63,"y":544,"style":89,"fill":90,"textAnchor":67},"→ 1.21, 53.40",[61,562,563],{"x":63,"y":548,"style":89,"fill":104,"textAnchor":67},"590 km off",[54,565],{"x":566,"y":72,"width":530,"height":536,"rx":75,"fill":553,"stroke":567,"style":78},"514","#b45309",[61,569,571],{"x":570,"y":540,"style":83,"fill":567,"textAnchor":67},"625","EPSG:31467",[61,573,545],{"x":570,"y":544,"style":89,"fill":90,"textAnchor":67},[61,575,576],{"x":570,"y":548,"style":89,"fill":104,"textAnchor":67},"0.1 km: datum?",[150,578,580],{"className":152,"code":579,"language":154,"meta":155,"style":155},"from qgis.core import (QgsCoordinateReferenceSystem, QgsCoordinateTransform,\n                       QgsPointXY, QgsDistanceArea)\n\nlayer = QgsProject.instance().mapLayersByName(\"survey_points\")[0]\nsample = next(layer.getFeatures()).geometry().centroid().asPoint()\nexpected = QgsPointXY(9.993, 53.551)            # roughly where the data should be (lon, lat)\nwgs84 = QgsCoordinateReferenceSystem(\"EPSG:4326\")\nda = QgsDistanceArea()\nda.setEllipsoid(\"EPSG:7030\")\n\nfor code in (\"EPSG:25832\", \"EPSG:25833\", \"EPSG:31467\", \"EPSG:3857\", \"EPSG:4326\"):\n    cand = QgsCoordinateReferenceSystem(code)\n    xf = QgsCoordinateTransform(cand, wgs84, QgsProject.instance())\n    try:\n        p = xf.transform(sample)\n    except Exception:\n        print(f\"{code:\u003C11} cannot interpret these coordinates\")\n        continue\n    km = da.measureLine(p, expected) \u002F 1000\n    print(f\"{code:\u003C11} → {p.x():8.3f}, {p.y():7.3f}  {km:10.1f} km from expected\")\n",[18,581,582,593,598,602,623,636,662,677,687,697,701,738,748,758,766,776,786,811,815,832],{"__ignoreMap":155},[159,583,584,586,588,590],{"class":161,"line":162},[159,585,166],{"class":165},[159,587,170],{"class":169},[159,589,173],{"class":165},[159,591,592],{"class":169}," (QgsCoordinateReferenceSystem, QgsCoordinateTransform,\n",[159,594,595],{"class":161,"line":179},[159,596,597],{"class":169},"                       QgsPointXY, QgsDistanceArea)\n",[159,599,600],{"class":161,"line":186},[159,601,183],{"emptyLinePlaceholder":182},[159,603,604,607,609,612,615,618,620],{"class":161,"line":199},[159,605,606],{"class":169},"layer ",[159,608,205],{"class":165},[159,610,611],{"class":169}," QgsProject.instance().mapLayersByName(",[159,613,614],{"class":220},"\"survey_points\"",[159,616,617],{"class":169},")[",[159,619,56],{"class":236},[159,621,622],{"class":169},"]\n",[159,624,625,628,630,633],{"class":161,"line":211},[159,626,627],{"class":169},"sample ",[159,629,205],{"class":165},[159,631,632],{"class":236}," next",[159,634,635],{"class":169},"(layer.getFeatures()).geometry().centroid().asPoint()\n",[159,637,638,641,643,646,649,652,655,658],{"class":161,"line":227},[159,639,640],{"class":169},"expected ",[159,642,205],{"class":165},[159,644,645],{"class":169}," QgsPointXY(",[159,647,648],{"class":236},"9.993",[159,650,651],{"class":169},", ",[159,653,654],{"class":236},"53.551",[159,656,657],{"class":169},")            ",[159,659,661],{"class":660},"sjoCn","# roughly where the data should be (lon, lat)\n",[159,663,664,667,669,672,675],{"class":161,"line":259},[159,665,666],{"class":169},"wgs84 ",[159,668,205],{"class":165},[159,670,671],{"class":169}," QgsCoordinateReferenceSystem(",[159,673,674],{"class":220},"\"EPSG:4326\"",[159,676,501],{"class":169},[159,678,679,682,684],{"class":161,"line":286},[159,680,681],{"class":169},"da ",[159,683,205],{"class":165},[159,685,686],{"class":169}," QgsDistanceArea()\n",[159,688,689,692,695],{"class":161,"line":291},[159,690,691],{"class":169},"da.setEllipsoid(",[159,693,694],{"class":220},"\"EPSG:7030\"",[159,696,501],{"class":169},[159,698,699],{"class":161,"line":302},[159,700,183],{"emptyLinePlaceholder":182},[159,702,703,705,708,710,713,716,718,721,723,726,728,731,733,735],{"class":161,"line":353},[159,704,361],{"class":165},[159,706,707],{"class":169}," code ",[159,709,367],{"class":165},[159,711,712],{"class":169}," (",[159,714,715],{"class":220},"\"EPSG:25832\"",[159,717,651],{"class":169},[159,719,720],{"class":220},"\"EPSG:25833\"",[159,722,651],{"class":169},[159,724,725],{"class":220},"\"EPSG:31467\"",[159,727,651],{"class":169},[159,729,730],{"class":220},"\"EPSG:3857\"",[159,732,651],{"class":169},[159,734,674],{"class":220},[159,736,737],{"class":169},"):\n",[159,739,740,743,745],{"class":161,"line":358},[159,741,742],{"class":169},"    cand ",[159,744,205],{"class":165},[159,746,747],{"class":169}," QgsCoordinateReferenceSystem(code)\n",[159,749,750,753,755],{"class":161,"line":373},[159,751,752],{"class":169},"    xf ",[159,754,205],{"class":165},[159,756,757],{"class":169}," QgsCoordinateTransform(cand, wgs84, QgsProject.instance())\n",[159,759,760,763],{"class":161,"line":402},[159,761,762],{"class":165},"    try",[159,764,765],{"class":169},":\n",[159,767,768,771,773],{"class":161,"line":408},[159,769,770],{"class":169},"        p ",[159,772,205],{"class":165},[159,774,775],{"class":169}," xf.transform(sample)\n",[159,777,778,781,784],{"class":161,"line":419},[159,779,780],{"class":165},"    except",[159,782,783],{"class":236}," Exception",[159,785,765],{"class":169},[159,787,788,791,793,795,797,799,801,804,806,809],{"class":161,"line":436},[159,789,790],{"class":236},"        print",[159,792,465],{"class":169},[159,794,468],{"class":165},[159,796,471],{"class":220},[159,798,474],{"class":236},[159,800,18],{"class":169},[159,802,803],{"class":165},":\u003C11",[159,805,483],{"class":236},[159,807,808],{"class":220}," cannot interpret these coordinates\"",[159,810,501],{"class":169},[159,812,813],{"class":161,"line":459},[159,814,405],{"class":165},[159,816,818,821,823,826,829],{"class":161,"line":817},19,[159,819,820],{"class":169},"    km ",[159,822,205],{"class":165},[159,824,825],{"class":169}," da.measureLine(p, expected) ",[159,827,828],{"class":165},"\u002F",[159,830,831],{"class":236}," 1000\n",[159,833,835,837,839,841,843,845,847,849,851,854,856,859,862,864,866,868,871,874,876,879,882,885,887,890],{"class":161,"line":834},20,[159,836,462],{"class":236},[159,838,465],{"class":169},[159,840,468],{"class":165},[159,842,471],{"class":220},[159,844,474],{"class":236},[159,846,18],{"class":169},[159,848,803],{"class":165},[159,850,483],{"class":236},[159,852,853],{"class":220}," → ",[159,855,474],{"class":236},[159,857,858],{"class":169},"p.x()",[159,860,861],{"class":165},":8.3f",[159,863,483],{"class":236},[159,865,651],{"class":220},[159,867,474],{"class":236},[159,869,870],{"class":169},"p.y()",[159,872,873],{"class":165},":7.3f",[159,875,483],{"class":236},[159,877,878],{"class":236},"  {",[159,880,881],{"class":169},"km",[159,883,884],{"class":165},":10.1f",[159,886,483],{"class":236},[159,888,889],{"class":220}," km from expected\"",[159,891,501],{"class":169},[14,893,894,896,897,900],{},[505,895,507],{}," Each candidate interprets the same raw numbers; only the right one puts the sample near the expected location. Measuring the distance on the ellipsoid makes the comparison objective. A candidate that is close but tens or hundreds of metres off often shares the projection but not the datum — for example an old national datum versus its modern successor — and deserves a second look with a better reference point. Coordinates far outside a candidate's valid area raise transformation errors, which the ",[18,898,899],{},"try"," block reports instead of crashing.",[128,902,904],{"id":903},"relabel-the-layer-for-the-session","Relabel the layer for the session",[14,906,907],{},"Once the right CRS is known, setting it on the layer moves the data to its correct position immediately, without touching a single coordinate.",[150,909,911],{"className":152,"code":910,"language":154,"meta":155,"style":155},"correct = QgsCoordinateReferenceSystem(\"EPSG:25832\")\nlayer.setCrs(correct)\nlayer.triggerRepaint()\nprint(\"now labelled\", layer.crs().authid(), \"; extent\", layer.extent().toString(0))\n",[18,912,913,926,931,936],{"__ignoreMap":155},[159,914,915,918,920,922,924],{"class":161,"line":162},[159,916,917],{"class":169},"correct ",[159,919,205],{"class":165},[159,921,671],{"class":169},[159,923,715],{"class":220},[159,925,501],{"class":169},[159,927,928],{"class":161,"line":179},[159,929,930],{"class":169},"layer.setCrs(correct)\n",[159,932,933],{"class":161,"line":186},[159,934,935],{"class":169},"layer.triggerRepaint()\n",[159,937,938,941,943,946,949,952,955,957],{"class":161,"line":199},[159,939,940],{"class":236},"print",[159,942,465],{"class":169},[159,944,945],{"class":220},"\"now labelled\"",[159,947,948],{"class":169},", layer.crs().authid(), ",[159,950,951],{"class":220},"\"; extent\"",[159,953,954],{"class":169},", layer.extent().toString(",[159,956,56],{"class":236},[159,958,959],{"class":169},"))\n",[14,961,962,964,965,968],{},[505,963,507],{}," ",[18,966,967],{},"setCrs"," changes the label only. The extent printed afterwards is numerically unchanged — the proof that nothing was transformed — but the layer now appears in the right place because QGIS interprets those numbers correctly. This change lives in the project; the file on disk still carries the wrong label, so the problem returns for anyone who opens the file directly.",[128,970,972],{"id":971},"make-the-fix-permanent","Make the fix permanent",[14,974,975],{},"To fix the source for everyone, write the corrected label into the data. For formats with sidecar files the label can be rewritten; for others, writing a corrected copy is safer.",[150,977,979],{"className":152,"code":978,"language":154,"meta":155,"style":155},"import processing\n\nfixed = processing.run(\"native:assignprojection\", {\n    \"INPUT\": layer, \"CRS\": correct, \"OUTPUT\": \"memory:\"})[\"OUTPUT\"]\nprocessing.run(\"native:savefeatures\", {\n    \"INPUT\": fixed, \"OUTPUT\": \"\u002Fdata\u002Ffixed\u002Fsurvey_points.gpkg\",\n    \"LAYER_NAME\": \"survey_points\"})\n\n# shapefile: rewrite the .prj in place\nprj = \"\u002Fdata\u002Finbox\u002Fsurvey_points.prj\"\nwith open(prj, \"w\") as fh:\n    fh.write(correct.toWkt(QgsCoordinateReferenceSystem.WKT1_ESRI))\n",[18,980,981,988,992,1008,1038,1048,1065,1077,1081,1086,1096,1118],{"__ignoreMap":155},[159,982,983,985],{"class":161,"line":162},[159,984,173],{"class":165},[159,986,987],{"class":169}," processing\n",[159,989,990],{"class":161,"line":179},[159,991,183],{"emptyLinePlaceholder":182},[159,993,994,997,999,1002,1005],{"class":161,"line":186},[159,995,996],{"class":169},"fixed ",[159,998,205],{"class":165},[159,1000,1001],{"class":169}," processing.run(",[159,1003,1004],{"class":220},"\"native:assignprojection\"",[159,1006,1007],{"class":169},", {\n",[159,1009,1010,1013,1016,1019,1022,1025,1028,1031,1034,1036],{"class":161,"line":199},[159,1011,1012],{"class":220},"    \"INPUT\"",[159,1014,1015],{"class":169},": layer, ",[159,1017,1018],{"class":220},"\"CRS\"",[159,1020,1021],{"class":169},": correct, ",[159,1023,1024],{"class":220},"\"OUTPUT\"",[159,1026,1027],{"class":169},": ",[159,1029,1030],{"class":220},"\"memory:\"",[159,1032,1033],{"class":169},"})[",[159,1035,1024],{"class":220},[159,1037,622],{"class":169},[159,1039,1040,1043,1046],{"class":161,"line":211},[159,1041,1042],{"class":169},"processing.run(",[159,1044,1045],{"class":220},"\"native:savefeatures\"",[159,1047,1007],{"class":169},[159,1049,1050,1052,1055,1057,1059,1062],{"class":161,"line":227},[159,1051,1012],{"class":220},[159,1053,1054],{"class":169},": fixed, ",[159,1056,1024],{"class":220},[159,1058,1027],{"class":169},[159,1060,1061],{"class":220},"\"\u002Fdata\u002Ffixed\u002Fsurvey_points.gpkg\"",[159,1063,1064],{"class":169},",\n",[159,1066,1067,1070,1072,1074],{"class":161,"line":259},[159,1068,1069],{"class":220},"    \"LAYER_NAME\"",[159,1071,1027],{"class":169},[159,1073,614],{"class":220},[159,1075,1076],{"class":169},"})\n",[159,1078,1079],{"class":161,"line":286},[159,1080,183],{"emptyLinePlaceholder":182},[159,1082,1083],{"class":161,"line":291},[159,1084,1085],{"class":660},"# shapefile: rewrite the .prj in place\n",[159,1087,1088,1091,1093],{"class":161,"line":302},[159,1089,1090],{"class":169},"prj ",[159,1092,205],{"class":165},[159,1094,1095],{"class":220}," \"\u002Fdata\u002Finbox\u002Fsurvey_points.prj\"\n",[159,1097,1098,1101,1104,1107,1110,1112,1115],{"class":161,"line":353},[159,1099,1100],{"class":165},"with",[159,1102,1103],{"class":236}," open",[159,1105,1106],{"class":169},"(prj, ",[159,1108,1109],{"class":220},"\"w\"",[159,1111,391],{"class":169},[159,1113,1114],{"class":165},"as",[159,1116,1117],{"class":169}," fh:\n",[159,1119,1120,1123,1126],{"class":161,"line":358},[159,1121,1122],{"class":169},"    fh.write(correct.toWkt(QgsCoordinateReferenceSystem.",[159,1124,1125],{"class":236},"WKT1_ESRI",[159,1127,959],{"class":169},[14,1129,1130,964,1132,1135,1136,1138,1139,1141,1142,35],{},[505,1131,507],{},[18,1133,1134],{},"native:assignprojection"," produces a layer with the new label and identical coordinates — the Processing equivalent of ",[18,1137,967],{},", usable in models and batch runs. Saving it to GeoPackage writes the CRS into the file's metadata tables. For shapefiles, rewriting the ",[18,1140,20],{}," with the ESRI flavour of WKT is the quick in-place fix; keep a backup of the original. Never fix a wrong label with ",[18,1143,1144],{},"native:reprojectlayer",[128,1146,1148],{"id":1147},"fix-many-files-at-once","Fix many files at once",[14,1150,1151],{},"Mislabelling tends to affect whole deliveries — every file exported by the same misconfigured tool. Once one file is diagnosed, the fix can be applied in bulk with a check that the result lands where expected.",[14,1153,1154],{},[39,1155,1158,1161,1164,1167,1182,1185,1191,1196,1200,1205,1210,1214,1217,1221,1226,1231,1235,1238,1242],{"viewBox":1156,"role":42,"ariaLabel":1157,"xmlns":44},"0 0 760 204","Bulk relabelling of a delivery with each result checked against the expected region before it is written",[46,1159,1160],{},"Bulk relabelling with a guard",[50,1162,1163],{},"Every file in the delivery is relabelled with the diagnosed CRS. After relabelling, its extent is transformed to WGS 84 and tested against the expected region. Files that land inside are written as fixed copies; files that land outside are listed for manual inspection instead of being changed blindly.",[54,1165],{"x":56,"y":56,"width":57,"height":1166,"fill":59},"204",[1168,1169,1170],"defs",{},[1171,1172,1178],"marker",{"id":1173,"viewBox":1174,"refX":75,"refY":1175,"markerWidth":1176,"markerHeight":1176,"orient":1177},"asgBatchArrow","0 0 10 10","5","7","auto-start-reverse",[1179,1180],"path",{"d":1181,"fill":90},"M0 0 L10 5 L0 10 z",[61,1183,1184],{"x":63,"y":64,"style":65,"fill":66,"textAnchor":67},"Relabel, check, then write",[54,1186],{"x":71,"y":1187,"width":1188,"height":1189,"rx":75,"fill":1190,"stroke":104,"style":78},"60","200","120","#fffdf7",[61,1192,1195],{"x":1193,"y":1194,"style":83,"fill":66,"textAnchor":67},"124","110.78","each file",[61,1197,1199],{"x":1193,"y":1198,"style":89,"fill":104,"textAnchor":67},"136.78","wrong label",[161,1201],{"x1":1202,"y1":1189,"x2":1203,"y2":1189,"stroke":90,"style":1204},"224","266","stroke-width:1.8;marker-end:url(#asgBatchArrow)",[54,1206],{"x":1207,"y":1187,"width":1188,"height":1189,"rx":75,"fill":1208,"stroke":1209,"style":78},"270","#eef7f4","#0f766e",[61,1211,1213],{"x":1212,"y":1194,"style":83,"fill":1209,"textAnchor":67},"370","assign CRS",[61,1215,1216],{"x":1212,"y":1198,"style":89,"fill":104,"textAnchor":67},"numbers kept",[161,1218],{"x1":1219,"y1":1189,"x2":1220,"y2":1189,"stroke":90,"style":1204},"470","512",[54,1222],{"x":1223,"y":1224,"width":1225,"height":1187,"rx":75,"fill":76,"stroke":77,"style":78},"516","52","220",[61,1227,1230],{"x":1228,"y":1229,"style":83,"fill":84,"textAnchor":67},"626","75.78","inside region",[61,1232,1234],{"x":1228,"y":1233,"style":89,"fill":104,"textAnchor":67},"95.78","write fixed copy",[54,1236],{"x":1223,"y":1237,"width":1225,"height":1187,"rx":75,"fill":553,"stroke":554,"style":78},"128",[61,1239,1241],{"x":1228,"y":1240,"style":83,"fill":554,"textAnchor":67},"151.78","outside",[61,1243,1245],{"x":1228,"y":1244,"style":89,"fill":104,"textAnchor":67},"171.78","list for review",[150,1247,1249],{"className":152,"code":1248,"language":154,"meta":155,"style":155},"from pathlib import Path\nfrom qgis.core import QgsVectorLayer, QgsRectangle\n\nregion = QgsRectangle(5.8, 47.2, 15.1, 55.1)        # expected area in lon\u002Flat\nto_wgs = QgsCoordinateTransform(correct, wgs84, QgsProject.instance())\nreview = []\nfor shp in sorted(Path(\"\u002Fdata\u002Finbox\").glob(\"*.shp\")):\n    lyr = QgsVectorLayer(str(shp), shp.stem, \"ogr\")\n    lyr.setCrs(correct)\n    box = to_wgs.transformBoundingBox(lyr.extent())\n    if region.contains(box):\n        processing.run(\"native:savefeatures\", {\n            \"INPUT\": lyr, \"OUTPUT\": f\"\u002Fdata\u002Ffixed\u002F{shp.stem}.gpkg\", \"LAYER_NAME\": shp.stem})\n    else:\n        review.append(shp.name)\nprint(len(review), \"files need manual review:\", review[:5])\n",[18,1250,1251,1263,1274,1278,1312,1322,1332,1359,1380,1385,1395,1402,1411,1446,1453,1458],{"__ignoreMap":155},[159,1252,1253,1255,1258,1260],{"class":161,"line":162},[159,1254,166],{"class":165},[159,1256,1257],{"class":169}," pathlib ",[159,1259,173],{"class":165},[159,1261,1262],{"class":169}," Path\n",[159,1264,1265,1267,1269,1271],{"class":161,"line":179},[159,1266,166],{"class":165},[159,1268,170],{"class":169},[159,1270,173],{"class":165},[159,1272,1273],{"class":169}," QgsVectorLayer, QgsRectangle\n",[159,1275,1276],{"class":161,"line":186},[159,1277,183],{"emptyLinePlaceholder":182},[159,1279,1280,1283,1285,1288,1291,1293,1296,1298,1301,1303,1306,1309],{"class":161,"line":199},[159,1281,1282],{"class":169},"region ",[159,1284,205],{"class":165},[159,1286,1287],{"class":169}," QgsRectangle(",[159,1289,1290],{"class":236},"5.8",[159,1292,651],{"class":169},[159,1294,1295],{"class":236},"47.2",[159,1297,651],{"class":169},[159,1299,1300],{"class":236},"15.1",[159,1302,651],{"class":169},[159,1304,1305],{"class":236},"55.1",[159,1307,1308],{"class":169},")        ",[159,1310,1311],{"class":660},"# expected area in lon\u002Flat\n",[159,1313,1314,1317,1319],{"class":161,"line":211},[159,1315,1316],{"class":169},"to_wgs ",[159,1318,205],{"class":165},[159,1320,1321],{"class":169}," QgsCoordinateTransform(correct, wgs84, QgsProject.instance())\n",[159,1323,1324,1327,1329],{"class":161,"line":227},[159,1325,1326],{"class":169},"review ",[159,1328,205],{"class":165},[159,1330,1331],{"class":169}," []\n",[159,1333,1334,1336,1339,1341,1344,1347,1350,1353,1356],{"class":161,"line":259},[159,1335,361],{"class":165},[159,1337,1338],{"class":169}," shp ",[159,1340,367],{"class":165},[159,1342,1343],{"class":236}," sorted",[159,1345,1346],{"class":169},"(Path(",[159,1348,1349],{"class":220},"\"\u002Fdata\u002Finbox\"",[159,1351,1352],{"class":169},").glob(",[159,1354,1355],{"class":220},"\"*.shp\"",[159,1357,1358],{"class":169},")):\n",[159,1360,1361,1364,1366,1369,1372,1375,1378],{"class":161,"line":286},[159,1362,1363],{"class":169},"    lyr ",[159,1365,205],{"class":165},[159,1367,1368],{"class":169}," QgsVectorLayer(",[159,1370,1371],{"class":236},"str",[159,1373,1374],{"class":169},"(shp), shp.stem, ",[159,1376,1377],{"class":220},"\"ogr\"",[159,1379,501],{"class":169},[159,1381,1382],{"class":161,"line":291},[159,1383,1384],{"class":169},"    lyr.setCrs(correct)\n",[159,1386,1387,1390,1392],{"class":161,"line":302},[159,1388,1389],{"class":169},"    box ",[159,1391,205],{"class":165},[159,1393,1394],{"class":169}," to_wgs.transformBoundingBox(lyr.extent())\n",[159,1396,1397,1399],{"class":161,"line":353},[159,1398,376],{"class":165},[159,1400,1401],{"class":169}," region.contains(box):\n",[159,1403,1404,1407,1409],{"class":161,"line":358},[159,1405,1406],{"class":169},"        processing.run(",[159,1408,1045],{"class":220},[159,1410,1007],{"class":169},[159,1412,1413,1416,1419,1421,1423,1425,1428,1430,1433,1435,1438,1440,1443],{"class":161,"line":373},[159,1414,1415],{"class":220},"            \"INPUT\"",[159,1417,1418],{"class":169},": lyr, ",[159,1420,1024],{"class":220},[159,1422,1027],{"class":169},[159,1424,468],{"class":165},[159,1426,1427],{"class":220},"\"\u002Fdata\u002Ffixed\u002F",[159,1429,474],{"class":236},[159,1431,1432],{"class":169},"shp.stem",[159,1434,483],{"class":236},[159,1436,1437],{"class":220},".gpkg\"",[159,1439,651],{"class":169},[159,1441,1442],{"class":220},"\"LAYER_NAME\"",[159,1444,1445],{"class":169},": shp.stem})\n",[159,1447,1448,1451],{"class":161,"line":402},[159,1449,1450],{"class":165},"    else",[159,1452,765],{"class":169},[159,1454,1455],{"class":161,"line":408},[159,1456,1457],{"class":169},"        review.append(shp.name)\n",[159,1459,1460,1462,1464,1467,1470,1473,1476,1478],{"class":161,"line":419},[159,1461,940],{"class":236},[159,1463,465],{"class":169},[159,1465,1466],{"class":236},"len",[159,1468,1469],{"class":169},"(review), ",[159,1471,1472],{"class":220},"\"files need manual review:\"",[159,1474,1475],{"class":169},", review[:",[159,1477,1175],{"class":236},[159,1479,1480],{"class":169},"])\n",[14,1482,1483,1485],{},[505,1484,507],{}," Relabelling every file blindly would mislabel any file that was actually correct. Testing each relabelled extent against the expected region — the data's country or project area in longitude and latitude — catches files that do not fit the diagnosis. Those go on a review list rather than being changed. The corrected copies are written as GeoPackages with the right CRS embedded, leaving the originals untouched for comparison.",[128,1487,1489],{"id":1488},"stop-it-happening-again","Stop it happening again",[14,1491,1492],{},"Most mislabelling comes from defaults: QGIS's \"CRS for new layers\" setting, a CSV import that assumes the project CRS, an export tool that writes WGS 84 regardless. Two settings and one habit prevent most of it.",[150,1494,1496],{"className":152,"code":1495,"language":154,"meta":155,"style":155},"from qgis.core import QgsSettings\n\ns = QgsSettings()\nprint(\"new layer CRS behaviour:\", s.value(\"app\u002Fprojections\u002FunknownCrsBehavior\"))\ns.setValue(\"app\u002Fprojections\u002FunknownCrsBehavior\", \"PromptUserForCrs\")\n",[18,1497,1498,1509,1513,1523,1540],{"__ignoreMap":155},[159,1499,1500,1502,1504,1506],{"class":161,"line":162},[159,1501,166],{"class":165},[159,1503,170],{"class":169},[159,1505,173],{"class":165},[159,1507,1508],{"class":169}," QgsSettings\n",[159,1510,1511],{"class":161,"line":179},[159,1512,183],{"emptyLinePlaceholder":182},[159,1514,1515,1518,1520],{"class":161,"line":186},[159,1516,1517],{"class":169},"s ",[159,1519,205],{"class":165},[159,1521,1522],{"class":169}," QgsSettings()\n",[159,1524,1525,1527,1529,1532,1535,1538],{"class":161,"line":199},[159,1526,940],{"class":236},[159,1528,465],{"class":169},[159,1530,1531],{"class":220},"\"new layer CRS behaviour:\"",[159,1533,1534],{"class":169},", s.value(",[159,1536,1537],{"class":220},"\"app\u002Fprojections\u002FunknownCrsBehavior\"",[159,1539,959],{"class":169},[159,1541,1542,1545,1547,1549,1552],{"class":161,"line":211},[159,1543,1544],{"class":169},"s.setValue(",[159,1546,1537],{"class":220},[159,1548,651],{"class":169},[159,1550,1551],{"class":220},"\"PromptUserForCrs\"",[159,1553,501],{"class":169},[14,1555,1556,1558,1559,1562,1563,1567],{},[505,1557,507],{}," Setting the unknown-CRS behaviour to prompt makes QGIS ask instead of silently assigning a default when a layer has no CRS, which is where many wrong labels originate. For delimited text, always pass ",[18,1560,1561],{},"crs="," explicitly in the URI, as shown in ",[26,1564,1566],{"href":1565},"\u002Fspatial-data-processing-automation\u002Flayer-data-sources-and-formats\u002Fload-csv-as-point-layer-pyqgis\u002F","loading a CSV as a point layer",". And make the coordinate-range check from the first section part of every import script: it costs milliseconds and catches the error at the point where it is cheapest to fix.",[128,1569,1571],{"id":1570},"qgis-version-compatibility","QGIS version compatibility",[14,1573,1574,651,1576,1578,1579,1582,1583,1586],{},[18,1575,967],{},[18,1577,1134],{}," and ",[18,1580,1581],{},"QgsCoordinateTransform"," behave the same on QGIS 3.34 LTR, 3.40 LTR and QGIS 4. The WKT flavour enum is ",[18,1584,1585],{},"QgsCoordinateReferenceSystem.WktVariant.WKT1_ESRI"," on QGIS 4. The settings key for unknown-CRS behaviour has been stable through QGIS 3, though its accepted values are best checked in the Options dialog of your version.",[128,1588,1590],{"id":1589},"troubleshooting","Troubleshooting",[133,1592,1593,1604,1610,1616],{},[136,1594,1595,1598,1599,1601,1602,35],{},[505,1596,1597],{},"The layer moved further away after \"fixing\"."," It was reprojected instead of relabelled; undo and use ",[18,1600,967],{}," or ",[18,1603,1134],{},[136,1605,1606,1609],{},[505,1607,1608],{},"Close but tens of metres off."," Right projection, wrong datum; test the datum variants of the candidate.",[136,1611,1612,1615],{},[505,1613,1614],{},"The fix disappears when reopening the file."," Only the project was changed; write the label into the file.",[136,1617,1618,1621],{},[505,1619,1620],{},"Every candidate fails."," The coordinates may be in a local engineering system or swapped axes; check the axis order and ask the data provider.",[128,1623,1625],{"id":1624},"conclusion","Conclusion",[14,1627,1628,1629,1601,1631,1633],{},"Treat a CRS as a label: recognise mislabelled layers from coordinate ranges, test candidate CRSs against a known location, relabel with ",[18,1630,967],{},[18,1632,1134],{}," without touching coordinates, write the corrected label into the data, guard bulk fixes with a region check, and configure QGIS to prompt rather than assume.",[128,1635,1637],{"id":1636},"frequently-asked-questions","Frequently Asked Questions",[14,1639,1640,1643],{},[505,1641,1642],{},"How do I know if a layer needs relabelling or reprojecting?","\nIf it is in the wrong place, relabel. If it is in the right place but you need it in another CRS, reproject.",[14,1645,1646,1649],{},[505,1647,1648],{},"Can the wrong label damage data?","\nOnly if someone reprojects or measures based on it. Relabelling itself is harmless and reversible.",[14,1651,1652,1655,1656,35],{},[505,1653,1654],{},"What if latitude and longitude are swapped?","\nThat is an axis-order problem, not a CRS label; swap coordinates with ",[18,1657,1658],{},"native:swapxy",[14,1660,1661,1664],{},[505,1662,1663],{},"Does relabelling change stored area fields?","\nNo, but those fields may have been computed under the wrong assumption — recompute them.",[128,1666,1668],{"id":1667},"related","Related",[133,1670,1671,1676,1681,1687,1693],{},[136,1672,1673,1675],{},[26,1674,29],{"href":28}," — the guide this recipe belongs to",[136,1677,1678],{},[26,1679,1680],{"href":33},"Handling Missing CRS in PyQGIS",[136,1682,1683],{},[26,1684,1686],{"href":1685},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Fbatch-reproject-vector-layers-pyqgis\u002F","Batch Reproject Vector Layers in PyQGIS",[136,1688,1689],{},[26,1690,1692],{"href":1691},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Ftransform-point-coordinates-pyqgis\u002F","Transform Point Coordinates Between CRS in PyQGIS",[136,1694,1695],{},[26,1696,1698],{"href":1697},"\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Fcreate-custom-crs-from-proj-string-pyqgis\u002F","Create a Custom CRS from a PROJ String in PyQGIS",[1700,1701,1702],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .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":155,"searchDepth":179,"depth":179,"links":1704},[1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716],{"id":130,"depth":179,"text":131},{"id":144,"depth":179,"text":145},{"id":511,"depth":179,"text":512},{"id":903,"depth":179,"text":904},{"id":971,"depth":179,"text":972},{"id":1147,"depth":179,"text":1148},{"id":1488,"depth":179,"text":1489},{"id":1570,"depth":179,"text":1571},{"id":1589,"depth":179,"text":1590},{"id":1624,"depth":179,"text":1625},{"id":1636,"depth":179,"text":1637},{"id":1667,"depth":179,"text":1668},"Fix layers whose coordinates are labelled with the wrong coordinate reference system — recognising a mislabelled layer from its coordinates, testing candidate CRSs, relabelling with setCrs or native:assignprojection, writing the fix permanently into the file, and never confusing assignment with reprojection.","md",{"slug":1720,"type":1721,"breadcrumb":1722,"datePublished":1723,"dateModified":1723},"assign-crs-without-reprojecting-pyqgis","article","Assign a CRS Without Reprojecting","2026-10-02","\u002Fspatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Fassign-crs-without-reprojecting-pyqgis",{"title":5,"description":1717},"spatial-data-processing-automation\u002Fcoordinate-reference-systems\u002Fassign-crs-without-reprojecting-pyqgis\u002Findex","SvoA3AjPRcccZ2BsqyZxdbvZj3j0vcKAEzbyZLB6VYk",1790966261089]