With QGIS 3.14 and the field calculator :
I have two layers, one with stream network and one with watersheds.
I would like to attribute the name of the watershed to the streams contained inside it with an expression in the field calculator. How to include the "within" condition ?
I guess it should be something like that
CASE
WHEN within( $geometry , $geometry) THEN
get_feature('watersheds',"name", $currentfeature )
END
But replacing the second $geometry
with a reference to the polygons of the watershed layer
With PyQGIS 3
I also tried the following PyQGIS code , that requires some more informations.
streamInput The layer containing the stream network has one unique ID per each stream ('IDjoin2')
The layer of watersheds contains several "levels" of watersheds. The main streams belongs to the bigger watersheds, and the smallest have their own little watershed, but also belongs to bigger ones. There are 7 levels of watersheds : the 1st one is the bigger one, the last one is the smallest.
streamBvInput A spatial join (1-to-many) with the watersheds layer allowed me to have, for each stream, all the watersheds in which it is contained.
csv_path I need to get, for each stream, the name of the smallest watershed that contains it, that's why I calculated statistics on the above layer, to obtain the maximum level of watershed for each IDjoin2/stream.
project = QgsProject.instance()
#input layers
streamInput = QgsProject.instance().mapLayersByName('Reseau_Hydro_..._Nom')[0]
streamBvInput = QgsProject.instance().mapLayersByName('Reseau_Hydro_..._Nom_intersectBVmulti')[0]
csv_path = 'C:/Users/.../IDjoin2_intesect_maxBV.csv'
streamLayer = project.mapLayer(streamInput.id())
streamBvLayer = project.mapLayer(streamBvInput.id())
if not (streamLayer.isEditable()):
streamLayer.startEditing()
layerStreamFields = streamLayer.fields()
with open(csv_path, newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader: #broswe into statistics csv file
# get the highest level of watershed for each stream
IDcsv = int(row['IDjoin2'])
searchBVmax = row['max']
iterStreamBV = streamBvLayer.getFeatures()
for featureBV in iterStreamBV: #broswe into the join file
searchIDbv = featureBV['IDjoin2']
if (IDcsv == searchIDbv): # if ID in csv and bvInput are identical
if (featureBV['NIVEAU_BAS'] == searchBVmax) :
#if watershed level in csv and bvInput are identical
BVname = featureBV['NOM_COURS_1']
# get the name of the watershed
iterStreamFeatures = streamLayer.getFeatures()
for featureS in iterStreamFeatures:
searchIDj = featureS['IDjoin2']
if (searchIDj == searchIDbv):
featureS.setAttribute('NomBV2',BVname)
attribute the name to the stream in streamInput
streamLayer.updateFeature(featureParcelle)
streamLayer.commitChanges()
But as soon as I run this script QGIS is freezing, and I received no error messages. I began testing the code almost line per line, and it looks like a part of the problem comes from the size of the layer "streamBvInput", that contains more than 114 000 features.