[GIS] Why does the script return ‘NoneType’

ogrosgeopython

I have this script and It return me some problem that I didn't find.

from osgeo import ogr
import os

class checkVectorMCV:

    def __init__(self, vector_path):

        self.vector_path = os.path.abspath(vector_path)
    def check_field_name(self):

        # Construindo a lista de campos do arquivo entregues

        daShapefile = self.vector_path
        print daShapefile, type(daShapefile)
        dataSource = ogr.Open(daShapefile)
        daLayer = dataSource.GetLayer(0)
        layerDefinition = daLayer.GetLayerDefn()

        #Construindo os campos dos arquivos entregues
        field = []

        for i in range(layerDefinition.GetFieldCount()):
            field.append(layerDefinition.GetFieldDefn(i).GetName())

        field = sorted(field)

        # Name of file with extension
        basename = os.path.basename(self.vector_path)

        # Name of file without extension
        name = os.path.splitext(basename)[0]

        #Comparação das listas de campos
        if (set(self.reference_field(name)) == set(field)) == False:
            return "Erro nos campos da camada: %s" % name;

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        ext = os.path.splitext(file)[-1].lower()
        #Print all files which have .shp extension
        if ext in extensions:
            arquivo = checkVectorMCV(file)         
            print arquivo.check_field_name()

The error:

Traceback (most recent call last):
      File "/home/infra/PycharmProjects/untitled/projeto_desenvolvimento_script/validacao_mapeamento_1.py", line 191, in <module>
        print arquivo.check_field_name()
      File "/home/infra/PycharmProjects/untitled/projeto_desenvolvimento_script/validacao_mapeamento_1.py", line 144, in check_field_name
        daLayer = dataSource.GetLayer(0)
    AttributeError: 'NoneType' object has no attribute 'GetLayer'

Best Answer

It seems to me that you you don't understand my answer in Loading a Shapefile in standalone PyQGIS script.

osgeo.ogr needs the complete path of a shapefile and for this complete path, simply use os.path.join(subdir, file) and not file only (-> AttributeError: 'NoneType' object has no attribute 'GetLayer')

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
       if file.endswith(".shp"):
           print checkVectorMCV(os.path.join(subdir, file))

And in your class (without the test)

class checkVectorMCV(object):
   def __init__(self, vector_path):
        self.vector_path = vector_path # and not os.path.abspath(vector_path)
   def check_field_name(self):
        # Construindo a lista de campos do arquivo entregues
        daShapefile = self.vector_path
        #print daShapefile, type(daShapefile)
        dataSource = ogr.Open(daShapefile)
        daLayer = dataSource.GetLayer(0)
        layerDefinition = daLayer.GetLayerDefn()
        #Construindo os campos dos arquivos entregues
        field = [layerDefinition.GetFieldDefn(i).GetName() for i in range(layerDefinition.GetFieldCount())]
        # test
        # Name of file without extension
        name = os.path.splitext(os.path.basename(self.vector_path))[0]
        return (name)

And it is easier with Fiona (another Python wrapper of OGR)

import fiona
class checkVectorMCV(object):
    def __init__(self, vector_path):
        self.vector_path = vector_path
    def check_field_name(self):
        self.dataSource = fiona.open(self.vector_path)
        field = self.dataSource.schema['properties'].keys()
        # tests
        name = os.path.splitext(os.path.basename(self.vector_path))[0]
        return (name)

Or GeoPandas (Python 2.7.x or 3.x)

import geopandas as gp
class checkVectorMCV(object):
    def __init__(self, vector_path):
       self.vector_path = vector_path #os.path.abspath(vector_path)
    def check_field_name(self):
       self.dataSource = gp.read_file(self.vector_path)
       field = self.dataSource.columns
       # test
       return (name)