Count number of features in a geopackage and write to a file
I had done something similar with python. The script loops recursive through the directories starting from the startdir and then opens each geopackage and reads the gpkg_contents table - containing geometry type, extent, CRS, date and so on, the second query selects the number of features. The script works on the first featuretable in a geopackage only, may be you have to adjust this to your needs:
import sqlite3
import glob
import csv
root_dir = 'c:/startdir/'
result = root_dir + 'gpkg_result.csv'
with open(result, 'w', newline='') as myfile:
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
for filename in glob.iglob(root_dir + '**/*.gpkg', recursive=True):
con = sqlite3.connect(filename)
with con:
cursor = con.cursor()
cursor.execute("SELECT * FROM gpkg_contents;")
l1 = list(cursor.fetchall()[0])
cursor.execute("SELECT Count(*) FROM {};".format(l1[0]))
l2 = list(cursor.fetchall()[0])
cursor.execute("SELECT geometry_type_name FROM gpkg_geometry_columns")
l3 = list(cursor.fetchall()[0])
wr.writerow(l1+l2+l3)
A pyqgis script
It handles other formats (shp, tab, gpkg, geojson...) all formats that ogr can handle
But it does not handle sublayers
import os
import csv
from qgis.core import QgsVectorLayer
FOLDER = 'c:/folder/to/scan'
RESULT = 'c:/folder/metadata.csv'
def scan_directory(directory, extension=('.tab', '.shp', '.gpkg')):
"""return the list of files that matche the extension
Args:
directory (str): the folder to scan
extension (tuple, optional): the extension. Defaults to ('.tab', '.shp', '.gpkg').
"""
extension = tuple(map(str.lower, extension))
for root, dirs, files in os.walk(directory, topdown=False):
for filename in files:
if filename.lower().endswith(extension):
yield(root, filename, os.path.join(root, filename))
def get_metadata(layer):
"""Return metadata
Args:
layer ([ogr vectorlayer]): [Not sublayer]
Returns:
metadata: (name, comment, encoding....)
"""
name = layer.name()
comment = layer.dataComment()
encoding = layer.dataProvider().encoding()
datasource = layer.publicSource()
feature_count = layer.featureCount()
geom_type = geom_wkbtype = crs = extent = None
if layer.isSpatial():
geom_type = layer.geometryType()
if geom_type <0 or geom_type > QgsWkbTypes.NullGeometry:
print(f'{layer} invalid geometry type')
else:
geom_wkbtype = QgsWkbTypes.displayString(layer.wkbType())
geom_type = QgsWkbTypes.geometryDisplayString(geom_type)
if layer.crs().isValid():
crs = layer.crs().userFriendlyIdentifier(
QgsCoordinateReferenceSystem.FullString )
extent=layer.extent().toString()
return (name, comment, encoding, geom_type,
geom_wkbtype, crs, extent, feature_count, datasource)
with open(RESULT, 'w', newline='') as myfile:
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
wr.writerow(['name', 'comment', 'encoding',
'geom_type', 'geom_wkbtype', 'crs', 'extent', 'feature_count','datasource'])
for root, filename, path in scan_directory(FOLDER):
layer = QgsVectorLayer(path, filename,'ogr')
if not layer.isValid():
print(f'{layer.name()} is not valid')
continue
wr.writerow(get_metadata(layer))
Code available : https://gist.github.com/42a6b3ab8e1069e3e0523ca90c361aaa