1

I would like to change the coordinates of QgsPoints imported from a csv file before saving it in shapefile.

I succeed to do all the step except the crs transformation, the output is keeping EPSG: 4326 instead of EPSG: 31370

#Set up inputs
absolute_path_to_csv_file = '/Users/X/Documents/.../Granulo.csv'
encoding = 'UTF-8'
delimiter = ';'
decimal = '.'
crs = 'epsg:4326'
x = 'X'
y = 'Y'

uri = f"file://{absolute_path_to_csv_file}?encoding={encoding}&delimiter={delimiter}&decimalPoint={decimal}&crs={crs}&xField={x}&yField={y}"

#Make a vector layer layer = QgsVectorLayer(uri, "Points", "delimitedtext")

#Check if layer is valid if not layer.isValid(): print ("Layer not loaded")

#Add CSV data QgsProject.instance().addMapLayer(layer)

#Transform CSV data

sourceCrs = QgsCoordinateReferenceSystem(4326) destCrs = QgsCoordinateReferenceSystem(31370) layer = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance()) myGeometryInstance.transform(layer)

#Write shapefile QgsVectorFileWriter.writeAsVectorFormat(layer, '/Users/X/Documents/.../Points.shp', "UTF-8", layer.crs(), "ESRI Shapefile", layerOptions=['SHPT=POINT'])

The error message I obtain is the following:

Traceback (most recent call last):
  File "/Applications/QGIS-LTR.app/Contents/MacOS/../Resources/python/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "<string>", line 29, in <module>
NameError: name 'myGeometryInstance' is not defined

I am working on MacOs with QGIS 3.28.5-Firenze and Python 3.9.5

The code use is adapted from Adding points with coordinates delimited by commas from CSV file in QGIS Python Console & Transforming single QgsGeometry object from one CRS to another using PyQGIS

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
C. Guff
  • 265
  • 1
  • 9

2 Answers2

2

A slightly simpler solution

# ... previous code

#Make a vector layer layer = QgsVectorLayer(uri, "Points", "delimitedtext")

#Check if layer is valid if not layer.isValid(): print ("Layer not loaded")

#Add CSV data QgsProject.instance().addMapLayer(layer)

#prepare transform CSV data sourceCrs = QgsCoordinateReferenceSystem(4326) destCrs = QgsCoordinateReferenceSystem(31370) tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())

#Write shapefile

----> set the CRS of the writer to the destination CRS in the options

options = QgsVectorFileWriter.SaveVectorOptions() options.ct = tr options.fileEncoding = "utf-8" options.driverName = "ESRI Shapefile" result_code, *_ = QgsVectorFileWriter.writeAsVectorFormatV3(layer, '/Users/X/Documents/.../Points.shp', QgsProject.instance().transformContext(), options)

Kalak
  • 3,848
  • 8
  • 26
0

There a couple of issues with your current code.

  • myGeometryInstance is undeclared in your code - hence the NameError you get
  • You are overwriting your layer variable with a QgsCoordinateTransform object.
  • The transformation should be applied to a feature's geometry (alluded to by the variable name myGeometryInstance).

Try these adaptations:

# ... previous code

#Make a vector layer layer = QgsVectorLayer(uri, "Points", "delimitedtext")

#Check if layer is valid if not layer.isValid(): print ("Layer not loaded")

#Add CSV data QgsProject.instance().addMapLayer(layer)

#Transform CSV data

sourceCrs = QgsCoordinateReferenceSystem(4326) destCrs = QgsCoordinateReferenceSystem(31370)

----> create the transform context (as a new variable)

tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())

----> iterate through the features in the layer

for feat in layer.getFeatures(): # ----> transform each feature in the layer (** be warned - this overwrites the feature's geometry **) myGeometryInstance = feat.geometry() myGeometryInstance.transform(tr)

#Write shapefile

----> set the CRS of the writer to the destination CRS

QgsVectorFileWriter.writeAsVectorFormat(layer, '/Users/X/Documents/.../Points.shp', "UTF-8", destCrs, "ESRI Shapefile", layerOptions=['SHPT=POINT'])

Kalak
  • 3,848
  • 8
  • 26
Matt
  • 16,843
  • 3
  • 21
  • 52
  • 1
    writeAsVectorFormat has been deprecated (which means it raises a warning to stop using it) for quite a while and should probably not be promoted as the function to use. – Kalak Aug 11 '23 at 12:56