Monday, 20 July 2015

How does one modify selected geometry with a function in qgis python console?


My example use-case is that I want to redistribute vertices along lines as in:



I've written some functions to do some of the work:


import math

def redistribute_vertices_num(line,num):
return LineString([line.interpolate(i/float(num),normalized=True) for i in range(num+1)])

def redistribute_vertices_dist(line,dist):

return LineString([line.interpolate(i*float(dist)) for i in range(int(math.ceil(line.length/dist)))])

I would like to apply these functions (or other, modified functions) to the selected objects in the current layer to modify the layer. I'm looking for a general function like this:


edit_layer_selection_geometry(redistribute_vertices_dist,500)
# or
def my_function(line):
redistribute_vertices_dist(line,500)
edit_layer_selection_geometry(my_function)

...that might do something like the processing in How can I create a line with three points with Python in QGIS? or How can I switch line direction in QGIS? on the active layer with the user-defined function.



def edit_layer_selection_geometry(myfun, extra_arguments...):
layer = qgis.utils.iface.mapCanvas().currentLayer()
# check for selected_layer, editability ?
for feature in layer.selectedFeatures():
newgeom=myfun(feature,extra_arguments)
# update feature with geometry
layer.changeGeometry(feature.id(),newgeom)
...
# update layer stuff (extents?)


I'm looking for the edit_layer_selection_geometry() or an equivalent functionality, and I'm happy to modify the potential 'myfun' functions to fit requirements of the general function.


I've put this in my .qgis2/mycode.py directory:


from qgis.core import (QgsFeature, QgsGeometry,
QgsVectorLayer, QgsMapLayerRegistry,
QgsField)
from PyQt4.QtCore import QVariant
from qgis.utils import iface
import math




def redistribute_geometry_vertices(geom,dist):
mylen=geom.length()
line=geom.asPolyline()
return QgsGeometry.fromPolyline([geom.interpolate(i*float(dist)).asPoint() for i in range(int(math.ceil(mylen/dist)))])

def redistribute_selection(dist):
"""Redistribute the vertices along a polyline """
layer = iface.mapCanvas().currentLayer()
for feature in layer.selectedFeatures():

geom = feature.geometry()
newgeom=redistribute_geometry_vertices(geom,dist)
layer.changeGeometry(feature.id(),newgeom)

Then I can solve the use-case by selecting the layer and feature, opening the python console and typing:


import mycode
mycode.redistribute_selection(0.1)


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...