How to invert lon/lat coordinates in QGIS using Python

This task is based on my answer to this question from gis.stackexchange.com.

Sometimes it happens that, when importing external files in QGIS (typically .CSV files), the fields specifying the longitude and latitude coordinates are accidentally inverted: this behavior will produce a different result in respect of the desired output.

If we don’t want to repeat the same procedure, we may run a simple python code, depending on the geometry type of the input layer, for inverting the coordinates and getting the desired result.

The following codes, available for point, line and polygon vector layers, instantly work from the Python Console (but they can easily be implemented in separate scripts).  Each script will return a new memory vector layer storing the inverted lon/lat coordinates for the geometries involved.

I tested the following code on several datasets available from Natural Earth Data.

Solution for point vector layers

Dataset

Download the point shapefile here.

Code

layer = iface.activeLayer()
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Point?crs='+ crs, 'inverted' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

for feat in layer.getFeatures():
attrs = feat.attributes()
geom = feat.geometry()
coords = geom.asPoint()
new_coords = (QgsPoint(coords[1], coords[0]))
geom=QgsGeometry.fromPoint(new_coords)

outGeom = QgsFeature()
outGeom.setGeometry(geom)
outGeom.setAttributes(attrs)
prov.addFeatures([outGeom])

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

Graphical Example

Before:

a

After:

d

Solution for line vector layers

Dataset

Download the line shapefile here.

Code

layer = iface.activeLayer()
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('LineString?crs='+ crs, 'inverted' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

for feat in layer.getFeatures():
attrs = feat.attributes()
geom = feat.geometry()
coords = geom.asMultiPolyline()
if coords:
new_coords = [[QgsPoint(y, x) for x, y in z] for z in coords]
geom=QgsGeometry.fromMultiPolyline(new_coords)
else:
coords = geom.asPolyline()
new_coords = [QgsPoint(y, x) for x, y in coords]
geom=QgsGeometry.fromPolyline(new_coords)

outGeom = QgsFeature()
outGeom.setGeometry(geom)
outGeom.setAttributes(attrs)
prov.addFeatures([outGeom])

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

Graphical Example

Before:

b

After:

e

Solution for polygon vector layers

Dataset

Download the polygon shapefile here.

Code

layer = iface.activeLayer()
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Polygon?crs='+ crs, 'inverted' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

for feat in layer.getFeatures():
attrs = feat.attributes()
geom = feat.geometry()
coords = geom.asMultiPolygon()
if coords:
new_coords=[[[QgsPoint(y, x) for x, y in z] for z in coord] for coord in coords]
geom=QgsGeometry.fromMultiPolygon(new_coords)
else:
coords = geom.asPolygon()
new_coords=[[QgsPoint(y, x) for x, y in z] for z in coords]
geom=QgsGeometry.fromPolygon(new_coords)

outGeom = QgsFeature()
outGeom.setGeometry(geom)
outGeom.setAttributes(attrs)
prov.addFeatures([outGeom])

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

Graphical Example

Before:

c

After:

f

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s