0

I am writing a script in pyqgis which should perform the following task:

  1. First it should read a csv file which we consider it as a input csv,csv file will be something like this:

    layer  ,columnname     ,condition        ,values              
    layer1 ,id             ,not blank        ,                    
    layer1 ,type           ,matching         ,type1,type2,type3,NA
    layer2 ,gisid          ,not blank,integer,                    
    layer2 ,layer_condition,matching         ,a,b,c,d             
    
  2. It should read layer name unique and check whether those layer is present or not

  3. layer will be having the columns mentioned in the csv it should check based on the condition column for example in layer1 for column id condition is not blank so all the features in the layer should not have any null values or blank spaces and for column like type condition is matching so all the feautre values should have one of the values mentioned in the values column.

So far i have tried the following code:

import csv

layer=QgsProject.instance().mapLayersByName('layer1')[0]

with open(r'layer1_Validation.csv') as file_obj:

    reader_obj = csv.DictReader(file_obj)

    for i,row in enumerate(reader_obj):
        
        if row['Condition'] == "Matching":

            a=row['values'].split(',')

            column=row['ColumnName']

            print(a)

            print(column)

            for f in layer.getFeatures():

                for s in a:

                    if f[column] == a:

                        print(f.id())

            break
asynts
  • 2,213
  • 2
  • 21
  • 35
Ayan
  • 13
  • 3
  • You didn't speak about your expected output. For example, if one features of `layer1` has an `id` equal to null, what do you expect from the code ? A simple message in the pyqgis console ? A warning ? Or maybe a `.txt` with a list of all the features with a not met condition ? – Timeless Sep 13 '22 at 11:38
  • 1
    thank you for the comment and yes i forgot to mention the output ,expected output is csv which should contain two column , first column will be the feature id with errors i mean which are not met conditiona and second column will be the comment which says what are the errors occured – Ayan Sep 13 '22 at 11:45
  • Thank you. Why do you need a `.csv` to read the conditions ? Is that because the conditions are not fix ? If not, we can simply implement the conditions directly in the code. – Timeless Sep 13 '22 at 12:24
  • .csv file is given by the user so i just gave an example in the above question of two columns their will be having more columns and more conditions which cannot be easily mentioned in the code and one more thing i need this code like a universal one for any shape files we it should work user will just add the conditions in csv it should give error report – Ayan Sep 13 '22 at 13:00
  • [Alright, this is a bit messy now.](https://stackoverflow.com/posts/73702111/revisions) It seems that OP originally tried to use the table syntax but didn't do it correctly and then just pasted the CSV directly. [Then, a user tried to edit it to use the correct table syntax.](https://stackoverflow.com/review/suggested-edits/32708245) However, he did not provide a proper description why the edits were made and I did not look at the revision history and rejected with an edit which simply put the CSV into a code block. Not optimal, but I'll leave it as is. – asynts Sep 14 '22 at 09:58

1 Answers1

0

For the above question i tried my self and came up with the following code:

import csv
import pandas as pd
csv_path = r"E:\sample.csv"
df=pd.read_csv(csv_path)
df1=df.loc[df['Condition'].eq('Matching')]['ColumnName'].values


for i in df['LayerName'].unique():
    layer=QgsProject.instance().mapLayersByName(i)[0]
    for field in layer.fields():
        current_field=field.name()
            if (current_field in  df1):
                with open(csv_path) as file_obj:
                    reader_obj = csv.DictReader(file_obj)
                    for row in reader_obj:
                        if row['Condition'] == "Matching" and row['ColumnName'] == current_field:
                            a=(word.strip() for word in row['values'].split(','))
                            query = "Select PID" + " from " + layer.name()+" where "+current_field+" not in "+str(tuple(a))+" or "+current_field+" is NULL group by PID"
                            vlayer = QgsVectorLayer( "?query={}".format(query), layer.name()+"_"+current_field+"_errors", "virtual" )
                             QgsProject.instance().addMapLayer(vlayer)
                             index = vlayer.featureCount()
                             vlayer.setName(vlayer.name()+"[{}]".format(str(index)))
                             if index == 0:
                                 QgsProject.instance().removeMapLayer(vlayer)

Above script will take the csv file as input and for the matching condition it checks and if their are any errors it creates the virtual layer

Ayan
  • 13
  • 3
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 19 '22 at 11:32