3

The following Python code is very helpful to reverse the direction of lines in QGIS:

layer = qgis.utils.iface.mapCanvas().currentLayer()
for feature in layer.selectedFeatures():
   geom = feature.geometry()
   nodes = geom.asPolyline()
   nodes.reverse() 
   newgeom = QgsGeometry.fromPolyline(nodes)
   layer.changeGeometry(feature.id(),newgeom)

(see https://gis.stackexchange.com/a/9285/77061)

Unfortunately, the code doesn't work for polygons. Replacing asPolyline() and fromPolyline(nodes) with asPolygon() and fromPolygon(nodes) hasn't helped. Is there a Python code that works for polygons?

if layer.geometryType() == 2:
    # ?

Edit:

For PostGIS and most likely some other data providers it's possible to digitize polygons clockwise and counter-clockwise. Creating a marker line symbology (e.g. triangle) for such layer may result in inward and outward rotated markers. So I want to reverse the direction of the anti-clockwise digitized polygons through the Python console.

enter image description here

eclipsed_by_the_moon
  • 1,855
  • 21
  • 44
  • 1
    There is no such thing as reversed polygon. Outer ring vertices go clockwise. – FelixIP Mar 19 '17 at 09:00
  • 1
    As far as I know, this depends on the data provider. In PostGIS it's possible to create polygon vertices clockwise and anti-clockwise. – eclipsed_by_the_moon Mar 19 '17 at 09:05
  • Internal handling of polygons in QGIS is uniform as far as I know. Drivers turn direction when data are saved if needed. – user30184 Mar 19 '17 at 09:27
  • 2
    Is it please possible to tell us why you want it? – Miro Mar 19 '17 at 11:10
  • Shapefile outer rings are clockwise; other data formats use left hand rule. If you succeed in flipping polygons to the incorrect orientation, you will likely cause random geometry manipulation failures. This goal is self-defeating. – Vince Mar 19 '17 at 11:17
  • @Miro Markers are rotated by 180 degrees if polygons are digitized counter-clockwise ('PostGIS data provider', 'New scratch layer'). I've added a screenshot. – eclipsed_by_the_moon Mar 19 '17 at 11:57
  • So the issue is visualization - you want to achieve that all polygons will have same (outward/inward) direction of markers? – Miro Mar 19 '17 at 14:49
  • @Vince It doesn‘t matter if a shape polygon is digitized counter-clockwise or if the nodes are reversed through some Python code. In both cases the polygon direction is fixed when saving the edits. So shape files shouldn‘t be an issue. – eclipsed_by_the_moon Mar 19 '17 at 15:14
  • So if you know it's not possible to intentionally mangle your data, what is the point of the question? – Vince Mar 19 '17 at 15:41
  • Please [edit] your question to clarify your problem and what you're trying to do. Your comments I think are making this less clear. Comments are for potential answerers to request more info or clarification, your response should be as edits to the question. – Midavalo Mar 19 '17 at 16:21
  • Have you tried saving everything out to a format that has only clock-wise or only counter-clock-wise polygons to enforce them all to draw the same way? – Midavalo Mar 19 '17 at 17:31
  • This is a good tip, but I was hoping for a Python based solution. – eclipsed_by_the_moon Mar 19 '17 at 20:17

1 Answers1

2

This code works for polygons but, 'changeGeometry' method has no effect even in edit mode. It's necessary to create a new geometry as memory layer.

layer = iface.mapCanvas().currentLayer()

new_geom = []

for feature in layer.getFeatures():
    geom = feature.geometry()
    nodes = geom.asPolygon()
    print nodes
    nodes[0].reverse()
    print nodes
    new_geom.append(QgsGeometry.fromPolygon(nodes).asPolygon())
    print layer.changeGeometry(feature.id(), newgeom)

epsg = layer.crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'polygon',
                           'memory')

prov = mem_layer.dataProvider()

feats = [ QgsFeature() for i in range(len(new_geom)) ]

for i, feat in enumerate(feats):
    feat.setAttributes([i])
    feat.setGeometry(QgsGeometry.fromPolygon(new_geom[i]))

prov.addFeatures(feats)

polygon_memlayer = [ feat.geometry().asPolygon() 
                     for feat in mem_layer.getFeatures() ]

print polygon_memlayer

After running the code at the Python Console of QGIS with this shapefile:

enter image description here

it could be observed, at Python Console, that the node order was effectively reversed.

enter image description here

xunilk
  • 29,891
  • 4
  • 41
  • 80