QGIS 动作中的不敏感大小写读取文件

Insensitive case reading file in QGIS action

我为 QGIS 操作编写了以下代码,以从 zip 文件中提取 shapefile 并将其加载到组中。

from PyQt4.QtCore import QFileInfo,QSettings
from qgis.core import QgsRasterLayer, QgsCoordinateReferenceSystem
import zipfile

s = QSettings()
oldValidation = s.value( "/Projections/defaultBehaviour" )
s.setValue( "/Projections/defaultBehaviour", "useProject" )
vl = QgsMapLayerRegistry.instance().mapLayersByName('catalogo_CTR')[0]
qgis.utils.iface.setActiveLayer(vl)
root = QgsProject.instance().layerTreeRoot()
group_name = "CTRN_10000"
group = root.findGroup(group_name)
if group == None:
    group = root.addGroup("CTRN_10000")
else:
    pass


ctr= '\\rvphnas02pw\Prodotti_Cartografici\Dati_Vettoriali\ctrn\c0101_CartografiaBase\c0101074_CTRN5000\2008\DB_SHAPE\ovest\[% A_CODICE %]o_p.zip'

fh = open(ctr, 'rb')
z = zipfile.ZipFile(fh)
for name in z.namelist():
    outpath = "D:\zip\"
    z.extract("[% A_CODICE %]o_p/fabbric.dbf", outpath)
    z.extract("[% A_CODICE %]o_p/FABBRIC.shx", outpath)
    z.extract("[% A_CODICE %]o_p/FABBRIC.shp", outpath)
fh.close()  


fileName = "D:\zip\[% A_CODICE %]o_p\FABBRIC.shp"
fileInfo = QFileInfo(fileName)
baseName = '[% A_CODICE %]'
rlayer = QgsVectorLayer(fileName, baseName) #usare QgsVectorLayer nel caso si volesse  caricare un vettore
crs = QgsCoordinateReferenceSystem()
crs.createFromSrid(3003) 
rlayer.setCrs(crs)
QgsMapLayerRegistry.instance().addMapLayer(rlayer, False)
group.insertChildNode(-1, QgsLayerTreeLayer(rlayer)) 

s.setValue( "/Projections/defaultBehaviour", oldValidation )

可以,但是有问题。 文件 FABBRIC.shp 、.shx、dbf 有时以大写字母书写,有时以小写字母书写(例如:FABBRIC.shp 或 fabbric.shp 或 fabbric.Shp...)。 所以我应该更改这部分代码:

   z.extract("[% A_CODICE %]o_p/fabbric.dbf", outpath)
   z.extract("[% A_CODICE %]o_p/FABBRIC.shx", outpath)
   z.extract("[% A_CODICE %]o_p/FABBRIC.shp", outpath)

这里:

fileName = "D:\zip\[% A_CODICE %]o_p\FABBRIC.shp"

用"insensitive case"解决方案。

也许这很简单,但我没有解决就停在这里。

给定存档的 namelist() 作为输入,这里有一些东西可以确定要使用的正确 shapefile 成员名称。您应该为每个名称调用 z.extract() returns。

def find_shapefile_names(shapefilenames, namelist):
    """ Return matching shapefile member names in the namelist ignoring letter case.
        The names in the shapefilenames list should be provided in all lowercase,
    """
    matches = []
    for name in namelist:
        lowercase_name = name.lower()
        if any(shapefilename in lowercase_name for shapefilename in shapefilenames):
            matches.append(name)
            if len(matches) == len(shapefilenames):
                return matches
    else:
        raise NameError('all shapefile names were not found in the namelist')

if __name__ == '__main__':
    from random import randint

    def random_namelist(prefix, shapefilenames):
        """ Generate a list of mixed-case shapefile names with a prefix. """
        chars = list(','.join(shapefilenames))
        for _ in range(len(chars) // 2):  # change case of half the letters
            i = randint(0, len(chars)-1)
            chars[i] = chars[i].upper()
        names = ''.join(chars).split(',')
        return [prefix+name for name in names]

    basename = '[% A_CODICE %]o_p/'
    shapefilenames = 'fabbric.dbf', 'fabbric.shx', 'fabbric.shp'

    for testnum in range(3):
        namelist = random_namelist(basename, shapefilenames)
        print('namelist test {}:'.format(testnum))
        for name in find_shapefile_names(shapefilenames, namelist):
            print('  ' + name)
        print('')