I have a folder with several shapefiles (around 75). I would like to create a new field into each .shp file which has to be filename. i.e: 20201003.shp --> 20200103.shp (New field 'Fecha' = 20200103)
I have tried this but nothing is done and no errors neither:
import os, datetime
`shapefolder = r'C:\Users\juavafer\Proyectos\Costas_CoastSat\Output\CMillor\Comparacion\matlab\Qgis'
newfieldname = 'test3'
for root, folder, files in os.walk(shapefolder):
#Find the shapefile
for file in files:
fullpath = os.path.join(root,file)
if os.path.isfile(fullpath) and fullpath.endswith('.shp'):
print(fullpath)
#Extract numbers from filename
datename = ''.join([num for num in file if num.isdigit()])
#Create a datetime object and convert to string in format 'YYYY-MM-DD', which is what a shapefile wants
QgsField(name='test3', type=QVariant.String, len=20)
newdatename = dt.strftime('%Y%m%d')
print(datename)
# dt = datetime.datetime.strptime(datename, '%Y%m%d')
# newdatename = dt.strftime('%Y%m%d')
print(datename)
#Add the field https://opensourceoptions.com/blog/pyqgis-adding-and-deleting-vector-layer-fields/
layer = QgsVectorLayer(fullpath)
layer.dataProvider().addAttributes([QgsField(newfieldname, QVariant.Date)])
layer.updateFields()
#Update each feature with date https://gis.stackexchange.com/questions/381174/setting-all-the-values-in-a-attribute-field-to-the-same-value-with-pyqgis)
attr_map = {}
field_index = layer.fields().indexFromName(newfieldname)
for f in layer.getFeatures():
attr_map[f.id()] = {field_index: newdatename}
layer.dataProvider().changeAttributeValues(attr_map)`
Bera
81.7k14 gold badges85 silver badges199 bronze badges
1 Answer 1
You can use pyqgis.
For a date fieldtype:
import os, datetime
shapefolder = r'C:\GIS\data\folder' #Where you have your 75 shapefiles (and no other shapefiles, including in any subdirectories!)
newfieldname = 'fecha'
for root, folder, files in os.walk(shapefolder):
#Find the shapefile
for file in files:
fullpath = os.path.join(root,file)
if os.path.isfile(fullpath) and fullpath.endswith('.shp'):
print(fullpath)
#Extract numbers from filename
datename = ''.join([num for num in file if num.isdigit()])
#Create a datetime object and convert to string in format 'YYYY-MM-DD', which is what a shapefile wants
dt = datetime.datetime.strptime(datename, '%Y%m%d')
newdatename = dt.strftime('%Y-%m-%d')
print(datename)
#Add the field https://opensourceoptions.com/blog/pyqgis-adding-and-deleting-vector-layer-fields/
layer = QgsVectorLayer(fullpath)
layer.dataProvider().addAttributes([QgsField(newfieldname, QVariant.Date)])
layer.updateFields()
#Update each feature with date https://gis.stackexchange.com/questions/381174/setting-all-the-values-in-a-attribute-field-to-the-same-value-with-pyqgis)
attr_map = {}
field_index = layer.fields().indexFromName(newfieldname)
for f in layer.getFeatures():
attr_map[f.id()] = {field_index: newdatename}
layer.dataProvider().changeAttributeValues(attr_map)
For a string field:
import os
shapefolder = r'C:\GIS\data\testdata\folder'
newfieldname = 'fecha'
for root, folder, files in os.walk(shapefolder):
#Find the shapefile
for file in files:
fullpath = os.path.join(root,file)
if os.path.isfile(fullpath) and fullpath.endswith('.shp'):
print(fullpath)
#Extract numbers from filename
datestr = ''.join([num for num in file if num.isdigit()])
print(datestr)
#Add the field
layer = QgsVectorLayer(fullpath)
layer.dataProvider().addAttributes([QgsField(name=newfieldname, type=QVariant.String, len=10)])
layer.updateFields()
#Update each feature with date (in a fast way using an attribute map: https://gis.stackexchange.com/questions/381174/setting-all-the-values-in-a-attribute-field-to-the-same-value-with-pyqgis)
attr_map = {}
field_index = layer.fields().indexFromName(newfieldname)
for f in layer.getFeatures():
attr_map[f.id()] = {field_index: datestr}
layer.dataProvider().changeAttributeValues(attr_map)
answered Apr 9, 2021 at 9:07
Explore related questions
See similar questions with these tags.
lang-py
base_file_name(layer_property(@layer_id,'source'))
you will get that. Not sure how to repeat that over 75 layers though. Note this requires the shapefiles to be loaded as layers to QGIS - have you got that?