The toggle editing, all the way down to Digitizing.
I want to automate the process of doing linework/pipelining with Python. How can I automate it?
I have tried multiple ways, here’s the closest thing I got to doing it:
import processing
from pathlib import Path
from qgis.PyQt.QtCore import QVariant
from qgis.core import (
QgsProject, QgsProcessing, QgsVectorLayer, QgsField,
QgsVectorFileWriter, QgsCoordinateTransformContext
)
proj = QgsProject.instance()
layer = proj.mapLayersByName('highway')[0]
name = f'd_{layer.name()}'
if not proj.mapLayersByName(name):
res = processing.run('native:dissolve', {'INPUT': layer, 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT})
tmp = res['OUTPUT']
proj.addMapLayer(tmp).setName(name)
linework_path = (Path(__file__).parent / 'linework.shp').as_posix()
if not Path(linework_path).exists():
mem = QgsVectorLayer(f'LineString?crs={layer.crs().authid()}', 'linework', 'memory')
mem.dataProvider().addAttributes([QgsField('id', QVariant.Int)])
mem.updateFields()
opt = QgsVectorFileWriter.SaveVectorOptions()
opt.driverName = 'ESRI Shapefile'
QgsVectorFileWriter.writeAsVectorFormatV2(mem, linework_path, QgsCoordinateTransformContext(), opt)
proj.addMapLayer(QgsVectorLayer(linework_path, 'linework', 'ogr'))
########################################################################################################
import processing
from pathlib import Path
from qgis.PyQt.QtCore import QVariant
from qgis.core import (
QgsProject, QgsProcessing, QgsVectorLayer, QgsField, QgsFeature,
QgsGeometry, QgsPointXY, QgsVectorFileWriter, QgsCoordinateTransformContext
)
proj = QgsProject.instance()
d = proj.mapLayersByName('d_highway')[0]
net = processing.run('native:multiparttosingleparts', {'INPUT': d, 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT})['OUTPUT']
best_f = None
best_l = -1.0
for f in net.getFeatures():
l = f.geometry().length()
if l > best_l:
best_f, best_l = f, l
sel = QgsVectorLayer(f'LineString?crs={net.crs().authid()}', 'sel', 'memory')
dp = sel.dataProvider()
dp.addAttributes(net.fields())
sel.updateFields()
g = best_f.geometry()
nf = QgsFeature(sel.fields())
nf.setGeometry(QgsGeometry.fromPolylineXY([QgsPointXY(p.x(), p.y()) for p in g.asPolyline()]))
dp.addFeatures([nf])
rev = processing.run('native:reverselinedirection', {'INPUT': sel, 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT})['OUTPUT']
off = processing.run('native:offsetline', {
'INPUT': rev,
'DISTANCE': 1.0,
'SEGMENTS': 8,
'JOIN_STYLE': 1,
'MITER_LIMIT': 2,
'END_CAP_STYLE': 0,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
})['OUTPUT']
lw_list = proj.mapLayersByName('linework')
if not lw_list:
linework_path = (Path(__file__).parent / 'linework.shp').as_posix()
if Path(linework_path).exists():
proj.addMapLayer(QgsVectorLayer(linework_path, 'linework', 'ogr'))
else:
mem = QgsVectorLayer(f'LineString?crs={d.crs().authid()}', 'linework', 'memory')
mem.dataProvider().addAttributes([QgsField('id', QVariant.Int)])
mem.updateFields()
opt = QgsVectorFileWriter.SaveVectorOptions()
opt.driverName = 'ESRI Shapefile'
QgsVectorFileWriter.writeAsVectorFormatV2(mem, linework_path, QgsCoordinateTransformContext(), opt)
proj.addMapLayer(QgsVectorLayer(linework_path, 'linework', 'ogr'))
lw = proj.mapLayersByName('linework')[0]
buf = nf.geometry().buffer(5.0, 8)
lw.startEditing()
lw.deleteFeatures([fe.id() for fe in lw.getFeatures() if fe.geometry().intersects(buf)])
next_id = 1 + max([r['id'] for r in lw.getFeatures()] or [0])
for of in off.getFeatures():
out = QgsFeature(lw.fields())
out.setAttributes([next_id])
next_id += 1
out.setGeometry(of.geometry())
lw.dataProvider().addFeatures([out])
lw.commitChanges()
lw.triggerRepaint()