3

I have a CSV file with a field that is in the following format

Latitude Longitude Altitude Accuracy, Latitude Longitude Altitude Accuracy [etc]

e.g. 51.1 -4.2 100 5, 51.2 -4.1 110 5, 51.1 -4.1 200 10 [not 3 real points!]

These represent nodes / vertices on a line, stored in a single "cell"

I would like to import this CSV into QGIS and there is an obvious problem for me if I try to formulate a LINESTRING ZM() - the x and y values are transposed so QGIS imports a line Y,X rather than X,Y.

To explain what I thought of doing (so you can see that I'm trying!):

using Excel I can create a new column and a formula

="Linestring ZM("& G2 &")" [where G2 is the cell with string of coordinates]

Then import the csv as Delimited Text - QGIS detects this field as WKT, but can't differentiate the Y,X

The other option would be to import the csv "raw" as a table and then process it as a virtual layer, but I can't get LINESTRING ZM geometry to work in my SQL - I thought it might be

ST_GeomFromEWKT('SRID=4326;LINESTRING ZM((' || "[field]" || '))') as geom

but that doesn't work (in QGIS 3.20)

I know KML lists its coordinates as Latitude Longitude so I'm wondering if there is another format that can accept the coordinates in this order?

Or is there a simple script to swap coordinates from Y,X to X,Y?

There are many rows so manual editing is not an option...

1
  • 1
    Can you add a sample of it as text?
    – BERA
    Nov 12, 2021 at 18:16

2 Answers 2

4

You can read the csv file using python:

import csv

#Create a line vector layer
vl = QgsVectorLayer("LineString?crs=EPSG:4326&index=yes", "myLayer", "memory")
provider = vl.dataProvider()

with open(r'/home/bera/Desktop/lines.txt', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for e, row in enumerate(spamreader):
        if e>0: #Skip header
            f = QgsFeature() #Create a new feature
            linevertices = []
            row = [float(i.replace(',','')) for i in row]
            for i in range(0,len(row)+1,4): #For each group of four values
                vals = row[i:i+4]
                if len(vals)==4:
                    Latitude, Longitude, Altitude, Accuracy = vals
                    linevertices.append(QgsPoint(Latitude, Longitude, Altitude)) #Create a point and append to list
            gLine = QgsGeometry.fromPolyline(linevertices) #Create a line from the point list
            f.setGeometry(gLine)
            provider.addFeature(f)

QgsProject.instance().addMapLayer(vl)

enter image description here

1
  • 1
    This looks like a powerful option. I think I can almost follow it (I don't speak python), so what I will need to learn to do is integrate this with an import of the whole file with headers to identify which (named) one has the geometry. That's a whole question in itself, but maybe the PyQGIS cook book will have a recipe... And I get to learn a new skill! Appreciate the effort in this answer.
    – SeeWhy
    Nov 12, 2021 at 20:01
1

You could also try Swap X and Y coordinates tool (in the Processing Toolbox > Vector geometry).

Which brings your dummy linestring from somewhere around Seychelles:

enter image description here

To a place near Plymouth.

enter image description here

1
  • They were random(ish) coordinates, but that is really helpful, thank you. I'll try it.
    – SeeWhy
    Nov 12, 2021 at 19:48

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.