3

I have a gps file that I have converted to csv, I would like to convert a longitude/latitude to linestring if the next row have a diferent longitude/latitude (if the car mooved) and if not convert it to points.

I know how to convert a longitude/latitude but how can I do this test? If possible with a script for qgis

Here is my file .xlsx fichier xlsx

What I would like to do automatically, is add to qgis two layer (points and lines with the same column as the .xlsx) or create two csv (again, points and the other file, lines). Like this two pictures: File were the car is mooving and File where the car stoped

To resume... I'm trying to get the result of those images in csv using the .xlsx via pyqgis to have one layer points (car stoped) and one layer polylines (car mooved).

2
  • 2
    I´m not sure if I got what you mean. You say you want to create points if the car does not move, meaning you have a list of identical points. When car moves you want to convert those coordinates to a linestring? Jan 26, 2016 at 11:21
  • I want point when latitude and longitude of the current row = latitude and longitude of the next row. Meaning the car didn't moove.
    – MacMuffin
    Jan 27, 2016 at 6:56

2 Answers 2

4

When you read the CSV file into a Qgis layer, you can iterate over the features and apply some processing like this:

# path to CSV file
filename = 'e:/gps2geometry.csv'
# connection string for CSV file reader, \t: separated by tabs
uri = 'file:///%s?crs=%s&delimiter=%s&xField=%s&yField=%s&decimal=%s' 
    % (filename, 'EPSG:4326', '\t', 'X', 'Y', '.')
gpslayer = QgsVectorLayer(uri, 'gpslayer', 'delimitedtext')
if gpslayer:
    QgsMapLayerRegistry.instance().addMapLayer(gpslayer)
else:
    print 'Error: Cannot create gpslayer'

# layer for points, car holds
hold = QgsVectorLayer('Point?crs=epsg:4326', 'hold', 'memory')
# layer for polyline, car is driving
drive = QgsVectorLayer('LineString?crs=epsg:4326', 'drive', 'memory')

# get providers
prov_hold = hold.dataProvider()
prov_drive = drive.dataProvider()

v = []
first = True
p1 = QgsPoint(-9999, -9999)  # somewhere in nowhere
for feat in gpslayer.getFeatures():
    p2 = feat.geometry().asPoint()
    if not first:  # defacto skip first point
        if p2 == p1:  # current point equals last one, car is now holding
            if len(v) > 1:  # we are processing lines
                v.append(p1)  # append point to vertex list
                l = QgsFeature()
                l.setGeometry(QgsGeometry().fromPolyline(v))
                prov_drive.addFeatures([l])
                v = []
            else:  # processing points, so add one more point
                p = QgsFeature()
                p.setGeometry(QgsGeometry().fromPoint(p1))
                prov_hold.addFeatures([p])
        else:  # point differs from last: car is driving
            v.append(p1)

    # remember last point
    p1 = p2
    first = False

# append last point to points or polylines
if len(v) > 1:
    v.append(p2)
    l = QgsFeature()
    l.setGeometry(QgsGeometry().fromPolyline(v))
    prov_drive.addFeatures([l])
    v = []
else: 
    p = QgsFeature()
    p.setGeometry(QgsGeometry().fromPoint(p2))
    prov_hold.addFeatures([p])

# update layers and add them to map
hold.updateExtents()
QgsMapLayerRegistry.instance().addMapLayer(hold)

drive.updateExtents()
QgsMapLayerRegistry.instance().addMapLayer(drive)

This simple CSV file (columns STATUS, GEOM for explanation only):

X   Y   STATUS  GEOM
0   0   hold    point
0   0   hold    point
0   0   hold    vertex
1   0   drive   vertex
1   1   drive   vertex
1   1   hold    point
1   1   hold    vertex
0   1   drive   vertex
0   0   drive   vertex
0   0   hold    point
0   0   hold    point

gives this result (2 routes, 5 stops):

result

2
  • I'm trying something with your code, that help me a lot.
    – MacMuffin
    Jan 27, 2016 at 6:57
  • @MacMuffin Fine. I think it is possible to read the excel file with python module (openpyxl or xlwt), take the coordinates (and the other attributes) and create features from this. Then you must replace gpslayer.getFeatures() with an iterator over this new feature set.
    – Detlev
    Jan 27, 2016 at 7:33
3

You can copy the gps data to an excel-file (or any othe similar program). It will look samething like this:

ID A B

1 Lat Long

2 50.123 7.123

3 50.321 7.321

If it only contains the lat/long in one column ("51.123N7.123E") you have to devide that value to two columns.

Than you insert a new column C with the header "wkt" (=well known text) and in the wkt-column you put the following formula:

="LINESTRING("&B2&" "&A2&","&"&B3&" "&A3&")"

ID A B C

1 Lat Long wkt

2 50.123 7.123 LINESTRING(7.123 50.123,7.321 50.321)

3 50.321 7.321 LINESTRING(7.321 50.321,7.321 50.321)

In the last row I changed the formula to:

="LINESTRING("&B3&" "&A3&","&"&B3&" "&A3&")"

Like this the last line has a length of 0.

Save the file as *.csv and open QGIS and press the "comma" which opens the "open delimited text layer". There you have to set the seperator of your file, set the geometry definition to WKT and choose the geometry field and your coordinate system of your file.

Than you are set. If you want you can save that layer as a shapefile.

1
  • Great answer !! I will try ASAP and come back to valid your answer. Thank you Alex.
    – MacMuffin
    Jan 26, 2016 at 11:55

Your Answer

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

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