3

I'd like to transfer manual processing steps to a python script. Though I'm not used to python yet.

The steps I do in QGIS:

  1. Loading csv via right click in browser window into layer window.
  2. the loaded table contains the coordinates in one column called "coords_lat_long". therefore, I split those coordinates in the Field Calculator using "lat" = left("coords_lat_long", strpos("coords_lat_long", ',')-1) and "long" = right("coords_lat_long", strpos("coords_lat_long", ',')-1)
  3. after saving that, I load the csv again using "Add Tab Delimited Layer", tab separated with x-value = long and y-value = lat and WGS84
  4. Then I export the layer to an existing GeoPackage and change the reference system to EPSG:2056 LV95.
  5. Finally I'll have my point layer.

However, how can I transfer those steps into a python script?

this is the layer, though, the coords_lat_long column is not always the last one/ 13th column.

What I have so far but can't extract lat and long:

uri = "thePathToMyCSV.csv"
csv_layer = iface.addVectorLayer(uri, "Standort_table", "ogr")
for field in csv_layer.fields():
    print(field.name())

f = QgsFeature()
csv_layer.startEditing()
lat_value = 'lat'
csv_layer.addAttribute(QgsField(lat_value, QVariant.Double))
long_value = 'long'
csv_layer.addAttribute(QgsField(long_value, QVariant.Double))
csv_layer.updateFields()

exp1 = QgsExpression('strpos("coords_lat_long", \',\')')
exp3 = QgsExpression('left(coords_lat_long, exp1)-1)')
exp4 = QgsExpression('right(coords_lat_long, exp1)-1)')

context = QgsExpressionContext()
context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(csv_layer))

with edit(csv_layer):
    for f in csv_layer.getFeatures():
        context.setFeature(f)
        f['lat'] = exp3.evaluate(context)
        f['long'] = exp4.evaluate(context)
        csv_layer.updateFeature(f)

2 Answers 2

3

You can use numpy.loadtxt() method to get the coordinates from the csv file.

import numpy as np

file_path = "/home/es/Documents/a.csv"
data = np.loadtxt(file_path, delimiter=",", skiprows=1)

iface.newProject()
uri = "Point?crs=EPSG:4326&field=lat:double&field=lon:double&index=yes"
layer = QgsVectorLayer(uri, "Layer", "memory")
QgsProject.instance().addMapLayer(layer)

for r in data:
    f = QgsFeature(layer.fields())
    f["lat"] = float(r[0])
    f["lon"] = float(r[1])

    geom = QgsGeometry.fromPointXY(QgsPointXY(r[0], r[1]))
    f.setGeometry(geom)

    layer.dataProvider().addFeatures([f])

layer.updateExtents()
1
  • Hey, thanks for your answer! I can't use the delimiter=',' because the table has other columns, which can contain commas as well. And the coords_lat_long does not always have the same column number, because there are other columns in the table. it also gives me errors when I'd like to use np.loadtxt(). It somehow has problems with converting string to float
    – mymymy
    Commented Jan 7, 2022 at 8:51
2

So if you have these points:

enter image description here

This is what I would do. I have edited my code so it can capture your coordinates column regardless of the index:

# Import modules
import csv
from qgis.core import *
from qgis.utils import *

# create empty list for poits
coords = []
input_csv = r"\Path\to\Points.csv"

#read data from csv file and store in lists
with open(input_csv, 'r') as f:
   # create a dict reader
   reader = csv.DictReader(f)
   for row in reader:
       # split coord
       lat = row["coords_lat_long"].split(",")[0]
       lon = row["coords_lat_long"].split(",")[1]
       # append point
       coords.append(QgsPoint(float(lon),float(lat)))

# Begin a new project
iface.newProject()
# Create a QgsFeature for every point(coord pair)
feats = [ QgsFeature() for i in range(len(coords)) ]

for i, feat in enumerate(feats):
    feat.setGeometry(coords[i])
   
# Create a memory layer
layer = QgsVectorLayer(
    "Point?crs=epsg:4326&index=yes",
    "temporary_points",
    "memory"
)
# Add the layer
QgsProject.instance().addMapLayer(layer)
# Add the feature to the layer provider
pr = layer.dataProvider()
pr.addFeatures(feats)

I have created a memory layer but you can export to Geopackage. After that, all you need to do is re-project the file to your desired CRS.

2
  • Hey, thanks for your answer. The main problem at the moment is, that my coordinates column (calles coords_lat_long) looks like: '39.09558, -2.82726' and is in string... I also do have other columns which I still need and the coords_lat_long column is not always at the same place of columns (using Indexes like float(row[2])) does not work then...
    – mymymy
    Commented Jan 7, 2022 at 8:03
  • @mymymy I have edited my answer to use column name instead of index and read string coord pair. Commented Jan 7, 2022 at 14:35

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.