I propose a solution using PyQGIS: the several codes instantly work from the Python Console, but they can easily be implemented in separate scripts (see the edit at the end of the answer). Each script will return a new memory vector layer storing the inverted lon/lat coordinates for the geometries.
I tested the solution on several datasets available from Natural Earth Data.
Solution for point vector layers
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:
After:
Solution for line vector layers
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:
After:
Solution for polygon vector layers
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:
After:
EDIT
The codes above were implemented by @gisnside in a separate script that can be added to the Processing Toolbox (it substantially adapts the proper code to the geometry type).
#!/usr/bin/python
# encoding: utf-8
# Created by mgri
# Adapted for processing toolbox by gisnside
# This script inverts X and Y coordinates of a vector layer
##Vector_tools=group
##Invert_XY=name
##vector_layer=vector
from qgis.core import *
layer = processing.getObject(vector_layer)
crs = layer.crs().toWkt()
geometryType = layer.geometryType()
if geometryType == QGis.Point:
# 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)
elif geometryType == QGis.Line:
# 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)
elif geometryType == QGis.Polygon:
# 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)