How to add postcode layer to selected buildings layer #QGIS

Sample code:

from time import sleep
def stopped(task):
	QgsMessageLog.logMessage(
		'Task "{name}" was canceled'.format(
			name=task.description()),
		'task', Qgis.Info)

def completed(exception, result=None):

    buildings=result['buildings']
    finalFeature=result['finalFeature']
    buildings.startEditing()

    for i, featBuilds in enumerate(finalFeature):
        buildings.updateFeature(featBuilds) 
    buildings.commitChanges()
    
def run(task, wait_time):
    QgsMessageLog.logMessage('Started task {}'.format(task.description()),
                                 'Add post code on buildings', Qgis.Info)

    postcodes = QgsProject.instance().mapLayersByName('ex_postCodes')[0]
    buildings = QgsProject.instance().mapLayersByName('ex_buildings')[0]

    fields = []
    [fields.append(f.name()) for f in buildings.fields()]
    newfield = 'post_code'
    if newfield not in fields:
        postcode_field = QgsField(newfield, QVariant.Int)
        prov = buildings.dataProvider()
        prov.addAttributes([postcode_field])
        buildings.updateFields()

    wait_time = wait_time / 100

    # Create a column for post codes in buildings
    total_features = buildings.featureCount() + postcodes.featureCount()
    prc = 0

    new_postcode_index = buildings.fields().indexFromName(newfield)
    finalFeature = []
    for i, featBuilds in enumerate(buildings.selectedFeatures()):
        task.setProgress((prc/total_features)*100)
        #sleep(wait_time)
        overlapping = []
        check_IF_write_value = False
        for featPostc in postcodes.getFeatures():
            prc += 1
            num_post_code = featPostc.attribute(featPostc.fieldNameIndex(newfield))
            if featBuilds.geometry().within(featPostc.geometry()):
                featBuilds['post_code'] = num_post_code
                finalFeature.append(featBuilds)
                check_IF_write_value = True
            else:
                areaA = featBuilds.geometry().intersection(featPostc.geometry()).area()
                areaB = featBuilds.geometry().area()
                overlapping.append([(areaA/areaB)*100, num_post_code])
            if not check_IF_write_value:
                featBuilds.setAttribute(new_postcode_index, max(overlapping)[1])
                featBuilds['post_code'] = max(overlapping)[1]
                finalFeature.append(featBuilds)
        if task.isCanceled():
            stopped(task)
            return None
    return {'finalFeature': finalFeature, 'buildings': buildings,
            'task': task}

task = QgsTask.fromFunction(u'Task', run,
					on_finished=completed, wait_time=4)
QgsApplication.taskManager().addTask(task)
Advertisements

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.