I'm new to Python and I'm having some dificulties. I want to create a simple layer with a line in the console of QGIS with Python. How can I do that?
[GIS] Creating line with three points with Python in QGIS
lineopenlayers-2pythonqgis
Related Solutions
This code will work on the lastest dev build of QGIS.
from qgis.utils import iface
from qgis.core import *
from PyQt4.QtCore import QVariant
import random
def createRandomPoints(count):
# Create a new memory layer to store the points.
vl = QgsVectorLayer("Point", "distance nodes", "memory")
pr = vl.dataProvider()
pr.addAttributes( [ QgsField("distance", QVariant.Int) ] )
layer = iface.mapCanvas().currentLayer()
# For each selected object
for feature in layer.selectedFeatures():
geom = feature.geometry()
length = geom.length()
feats = []
# Loop until we reach the needed count of points.
for i in xrange(0,count):
# Get the random distance along the line.
distance = random.uniform(0, length)
# Work out the location of the point at that distance.
point = geom.interpolate(distance)
# Create the new feature.
fet = QgsFeature()
fet.setAttributeMap( { 0 : distance } )
fet.setGeometry(point)
feats.append(fet)
pr.addFeatures(feats)
vl.updateExtents()
QgsMapLayerRegistry.instance().addMapLayer(vl)
I know you said you are not very familiar with Python code but you should be able to run this pretty easy. Copy the above code into a file (mine is called locate.py
) and place it in your ~/.qgis/python
if you are on Windows 7 that will be in C:\Users\{your user name}\.qgis\python\
or on Windows XP C:\Documents and Settings\{your user name}\.qgis\python\
Once the file is in the python folder open QGIS and select some line objects.
Then open the Python console and run the following code:
import locate.py
locate.createRandomPoints(10)
The result should look something like this
If you want to run it again just select some more lines and run locate.createRandomPoints(10)
in the Python console again.
Note: locate.createRandomPoints(10) the 10 here is the number of points to generate per line
I modified the redistribute_selection() function above to make ~/.qgis2/python/mytools.py :
from qgis.core import (QgsFeature, QgsGeometry,
QgsVectorLayer, QgsMapLayerRegistry,
QgsField)
from PyQt4.QtCore import QVariant
from qgis.utils import iface
import math
import numpy
def redistribute_geometry_vertices(geom,dist):
mylen=geom.length()
line=geom.asPolyline()
return QgsGeometry.fromPolyline([geom.interpolate(i).asPoint() for i in numpy.arange(0,mylen+dist,dist)])
def redistribute_geometry_vertices_num(geom,num):
mylen=geom.length()
line=geom.asPolyline()
return QgsGeometry.fromPolyline([geom.interpolate(i).asPoint() for i in numpy.linspace(0,mylen,num)])
def reverseGeometryVertices(geom):
nodes = geom.asPolyline()
nodes.reverse()
return QgsGeometry.fromPolyline(nodes)
def selection_update_geometry(userFunction, *args):
"""Redistribute the vertices along a polyline """
layer = iface.mapCanvas().currentLayer()
for feature in layer.selectedFeatures():
geom = feature.geometry()
if geom.isMultipart():
newgeom = QgsGeometry.fromMultiPolyline([userFunction(part,*args).asPolyline() for part in geom.asGeometryCollection()])
else:
newgeom=userFunction(geom,*args)
layer.changeGeometry(feature.id(),newgeom)
iface.mapCanvas().refresh()
Then I can type:
import mytools
mytools.selection_update_geometry(mytools.redistribute_geometry_vertices,.05)
mytools.selection_update_geometry(mytools.redistribute_geometry_vertices_num,5)
mytools.selection_update_geometry(mytools.reverseGeometryNodes)
There isn't any error handling in these functions (like checking if a layer is selected, editable, that the feature is a line, or that the user-supplied function returns compatible geometry) but they make it fairly easy to modify the geometry.
Best Answer
You must first understand how PyQGIS handles geometry (Geometry Handling)
The most important element is the point:
and a line or a segment of line are composed of two points:
So to construct a line:
and with a memory layer (geometry only, without the attributes):
the result is:
with 3 points, just add it as a new feature:
and the result is:
And with a for loop you can create a line with many segments: