-1

I have a UTM project in QGIS and need to import some CSV files that are in Latitude Longitude format. When I import it using the GUI, it knows that it is in CRS: 4326 and does a ballpark reprojection to the project's CRS: 26910. Ballpark is fine, since this is a general orientation map rather than a technical spatial analysis.

Since I need to do this for 1000 layers on 400 iterations of the map, I'm not going to use the GUI, but am coding it in Python using the QGIS Python console. I have no trouble importing the CSV file into the project, but it comes in with the lat/long degrees showing up as meters, meaning that the points are all near the origin.

How can I convince QGIS, using PyQGIS, that the CSV is in 4326 and it needs to be reprojected to 26910, OR load the CSV in as a layer and then separately tell it to reproject that layer. I have tried several things that I found on StackExchange, ChatGPT instructions and QGIS docs without success.

(Python 3.9 from QGIS, QGIS 3.28.11, Windows 10)

A) Zone 10N is correct - All maps are in the middle of Zone 10N (California).

B) There are two types of CSVs:
Latitude,Longitude
37.805424,-122.467031
37.465664,-122.122325
37.521603,-122.199406 ...

and one with lots of extra rows, but the same basic coordinate system:
"ID","Plant","!Photo","Observer","Date","Longitude","Latitude","Source","County","Location Description","Location Quality","Citation"

"mg206520","Amsinckia lunaris","","observer","2023-05-24","-122.632282","37.986984","","Marin","South end of serpentine meadow","high","Calflora [web application]. 2023. Berkeley, California: The Calflora Database. Retrieved from https://www.calflora.org/ Oct 30, 2023."

Both types import successfully using PyQGIS and form points in the right configuration but located at 38.8 meters x -122.48 meters etc.

C) It is very similar to this problem, but needs to be done within Python so it can be scaled to hundreds of files QGIS Reprojecting csv point file to projected CRS

D) Sample code: I've gotten most of this from Stack Exchange or similar sources. Here are 3 I've tried; there are more with the same results. Unless noted otherwise, it creates a reprojected layer on top of the old one, still at -122 meters x 38 meters.

Reprojecting layer using PyQGIS

parameter = {
    'INPUT': lyr,
    'TARGET_CRS': 'EPSG:26910',
    'OUTPUT': 'memory:Reprojected'
}
result = processing.run('native:reprojectlayer', parameter)['OUTPUT']
QgsProject.instance().addMapLayer(result)

Setting project and layer CRS in PyQGIS with setCrs() has no effect on the map canvas

# Does nothing or makes them all vanish (no zoom to layer) depending on CRS picked
projectCrs = QgsCoordinateReferenceSystem.fromEpsgId(26910)
map.setCrs(projectCrs)
assert projectCrs.isValid()
print(projectCrs.isValid())
ams_lunaris.setCrs(projectCrs)
layerCrs = QgsCoordinateReferenceSystem.fromEpsgId(4326)
ams_lunaris.setCrs(layerCrs)
ams_lunaris.triggerRepaint()

Forgot where I got this one.

source_crs = QgsCoordinateReferenceSystem('EPSG:4326')
dest_crs = QgsCoordinateReferenceSystem('EPSG:26910')
# Transform the layer to the destination CRS
ams_lunaris.setCrs(source_crs)
ams_lunaris.transform(dest_crs)
#Gives Error: AttributeError: 'QgsVectorLayer' object has no attribute 'transform'
2
  • 2
    Welcome to GIS SE. Thank you for taking the Tour. I'd leave the ChatGPT suggestions in the trash, where they belong, and detail something that you tried, and describe how it did not meet your goal. We're way more willing to correct broken code than to do your coding for you. Note that UTM zone 10N is only appropriate for zone 10 points (+/- 1 zone), so all you need to be able to do is add 180 and divide by six.
    – Vince
    Commented Feb 2 at 1:09
  • 1
    Please show a sample of one your CSVs and the code you have already tried
    – Andre Geo
    Commented Feb 2 at 8:09

1 Answer 1

1

Reprojecting your delimited text layer is not the solution to your problem. You need to specify the correct CRS inside the uri when loading the csv file via pyqgis e.g. &crs=EPSG:4326.

A good tip is to load the csv manually via the gui and, if you are happy with it, select it in the table of contents and run:

print(iface.activeLayer().source())

You will get something like:

file:///C:/Users/qw2/Desktop/test/test_layers/calflora_records.csv?type=csv&trimFields=Yes&maxFields=10000&detectTypes=yes&xField=Longitude&yField=Latitude&crs=EPSG:4326&spatialIndex=no&subsetIndex=no&watchFile=no

You can then copy all or parts of this and use it as the uri string to load your csv via pyqgis.

I used this snippet (of course the file location part of the uri is for a test csv on my system):

uri = 'file:///C:/Users/qw2/Desktop/test/test_layers/calflora_records.csv?type=csv&trimFields=Yes&detectTypes=yes&xField=Longitude&yField=Latitude&crs=EPSG:4326'
vlayer = QgsVectorLayer(uri,'Cal_Flora_Records','delimitedtext')
QgsProject().instance().addMapLayer(vlayer)

This is the result:

enter image description here

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.