Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[processing][feature] Enhance the GDAL "Vector information" alg and add a new GDAL "Vector information (JSON)" alg #57976

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion python/plugins/processing/algs/gdal/GdalAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
from .ExecuteSql import ExecuteSql
from .OffsetCurve import OffsetCurve
from .ogr2ogr import ogr2ogr
from .ogrinfo import ogrinfo
from .ogrinfo import ogrinfo, ogrinfojson
from .OgrToPostGis import OgrToPostGis
from .ogr2ogrtopostgislist import Ogr2OgrToPostGisList
from .OneSideBuffer import OneSideBuffer
Expand Down Expand Up @@ -205,6 +205,9 @@ def loadAlgorithms(self):
if int(gdal.VersionInfo()) > 3010000:
self.algs.append(viewshed())

if int(gdal.VersionInfo()) >= 3070000:
self.algs.append(ogrinfojson())

for a in self.algs:
self.addAlgorithm(a)

Expand Down
77 changes: 67 additions & 10 deletions python/plugins/processing/algs/gdal/ogrinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@
from qgis.core import (QgsProcessingException,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterBoolean,
QgsProcessingParameterDefinition,
QgsProcessingParameterString,
QgsProcessingParameterFileDestination)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils


class ogrinfo(GdalAlgorithm):
INPUT = 'INPUT'
ALL_LAYERS = 'ALL_LAYERS'
SUMMARY_ONLY = 'SUMMARY_ONLY'
NO_METADATA = 'NO_METADATA'
EXTRA = 'EXTRA'
OUTPUT = 'OUTPUT'

def __init__(self):
Expand All @@ -39,16 +43,37 @@ def __init__(self):
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterBoolean(self.SUMMARY_ONLY,
self.tr('Summary output only'),
defaultValue=True))
self.addParameter(QgsProcessingParameterBoolean(self.ALL_LAYERS,
self.tr('Enable listing of all layers in the dataset'),
defaultValue=False))
if self.name() == 'ogrinfo':
self.addParameter(QgsProcessingParameterBoolean(self.SUMMARY_ONLY,
self.tr('Summary output only'),
defaultValue=True))
else:
self.addParameter(QgsProcessingParameterBoolean(self.FEATURES,
self.tr('Enable listing of features'),
defaultValue=False))

self.addParameter(QgsProcessingParameterBoolean(self.NO_METADATA,
self.tr('Suppress metadata info'),
defaultValue=False))

self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT,
self.tr('Layer information'),
self.tr('HTML files (*.html)')))
extra_param = QgsProcessingParameterString(self.EXTRA,
self.tr('Additional command-line parameters'),
defaultValue=None,
optional=True)
extra_param.setFlags(extra_param.flags() | QgsProcessingParameterDefinition.Flag.FlagAdvanced)
self.addParameter(extra_param)

if self.name() == 'ogrinfo':
self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT,
self.tr('Layer information'),
self.tr('HTML files (*.html)')))
else:
self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT,
self.tr('Layer information'),
self.tr('JSON files (*.json)')))

def name(self):
return 'ogrinfo'
Expand All @@ -66,20 +91,33 @@ def commandName(self):
return 'ogrinfo'

def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['-al']
if self.name() == 'ogrinfo':
arguments = ['-al']
else:
arguments = ['-json']

if self.name() == 'ogrinfo':
if self.parameterAsBoolean(parameters, self.SUMMARY_ONLY, context):
arguments.append('-so')
else:
if self.parameterAsBoolean(parameters, self.FEATURES, context):
arguments.append('-features')

if self.parameterAsBoolean(parameters, self.SUMMARY_ONLY, context):
arguments.append('-so')
if self.parameterAsBoolean(parameters, self.NO_METADATA, context):
arguments.append('-nomd')

if self.EXTRA in parameters and parameters[self.EXTRA] not in (None, ''):
extra = self.parameterAsString(parameters, self.EXTRA, context)
arguments.append(extra)

inLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))

input_details = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
arguments.append(input_details.connection_string)
arguments.append(input_details.layer_name)
if not self.parameterAsBoolean(parameters, self.ALL_LAYERS, context):
arguments.append(input_details.layer_name)

if input_details.open_options:
arguments.extend(input_details.open_options_as_arguments())
Expand All @@ -99,3 +137,22 @@ def processAlgorithm(self, parameters, context, feedback):
f.write('</pre>')

return {self.OUTPUT: output}


class ogrinfojson(ogrinfo):
FEATURES = 'FEATURES'

def name(self):
return 'ogrinfojson'

def displayName(self):
return self.tr('Vector information (JSON)')

def processAlgorithm(self, parameters, context, feedback):
console_output = GdalUtils.runGdal(self.getConsoleCommands(parameters, context, feedback))
output = self.parameterAsFileOutput(parameters, self.OUTPUT, context)
with open(output, 'w', newline='') as f:
for s in console_output[1:]:
f.write(str(s))

return {self.OUTPUT: output}
104 changes: 103 additions & 1 deletion python/plugins/processing/tests/GdalAlgorithmsVectorTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

import AlgorithmsTestBase
from processing.algs.gdal.ogr2ogr import ogr2ogr
from processing.algs.gdal.ogrinfo import ogrinfo
from processing.algs.gdal.ogrinfo import ogrinfo, ogrinfojson
from processing.algs.gdal.Buffer import Buffer
from processing.algs.gdal.Dissolve import Dissolve
from processing.algs.gdal.OffsetCurve import OffsetCurve
Expand Down Expand Up @@ -146,6 +146,27 @@ def testOgrInfo(self):
'-al -so ' +
source + ' polys2'])

source = os.path.join(testDataPath, 'polys.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'ALL_LAYERS': True,
'SUMMARY_ONLY': True,
'NO_METADATA': False}, context, feedback),
['ogrinfo',
'-al -so ' +
source])

source = os.path.join(testDataPath, 'polys.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'ALL_LAYERS': True,
'SUMMARY_ONLY': True,
'EXTRA': '-nocount',
'NO_METADATA': False}, context, feedback),
['ogrinfo',
'-al -so -nocount ' +
source])

source = os.path.join(testDataPath, 'filename with spaces.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
Expand Down Expand Up @@ -191,6 +212,87 @@ def testOgrInfo(self):
'-al -so -nomd "' +
source + '" filename_with_spaces --config X Y --config Z A'])

def testOgrInfoJson(self):
context = QgsProcessingContext()
feedback = QgsProcessingFeedback()
source = os.path.join(testDataPath, 'polys.gml')
alg = ogrinfojson()
alg.initAlgorithm()

self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FEATURES': True,
'NO_METADATA': False}, context, feedback),
['ogrinfo',
'-json -features ' +
source + ' polys2'])

source = os.path.join(testDataPath, 'polys.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'ALL_LAYERS': True,
'FEATURES': True,
'NO_METADATA': False}, context, feedback),
['ogrinfo',
'-json -features ' +
source])

source = os.path.join(testDataPath, 'polys.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'ALL_LAYERS': True,
'FEATURES': True,
'EXTRA': '-nocount',
'NO_METADATA': False}, context, feedback),
['ogrinfo',
'-json -features -nocount ' +
source])

source = os.path.join(testDataPath, 'filename with spaces.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FEATURES': True,
'NO_METADATA': False}, context, feedback),
['ogrinfo',
'-json -features "' +
source + '" filename_with_spaces'])

source = os.path.join(testDataPath, 'filename with spaces.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FEATURES': False,
'NO_METADATA': False}, context, feedback),
['ogrinfo',
'-json "' +
source + '" filename_with_spaces'])

source = os.path.join(testDataPath, 'filename with spaces.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'FEATURES': True,
'NO_METADATA': True}, context, feedback),
['ogrinfo',
'-json -features -nomd "' +
source + '" filename_with_spaces'])

source = os.path.join(testDataPath, 'filename with spaces.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source + '|option:X_POSSIBLE_NAMES=geom_x|option:Y_POSSIBLE_NAMES=geom_y',
'FEATURES': True,
'NO_METADATA': True}, context, feedback),
['ogrinfo',
'-json -features -nomd "' +
source + '" filename_with_spaces -oo X_POSSIBLE_NAMES=geom_x -oo Y_POSSIBLE_NAMES=geom_y'])

source = os.path.join(testDataPath, 'filename with spaces.gml')
self.assertEqual(
alg.getConsoleCommands({'INPUT': source + '|credential:X=Y|credential:Z=A',
'FEATURES': True,
'NO_METADATA': True}, context, feedback),
['ogrinfo',
'-json -features -nomd "' +
source + '" filename_with_spaces --config X Y --config Z A'])

def testBuffer(self):
context = QgsProcessingContext()
feedback = QgsProcessingFeedback()
Expand Down
Loading
Loading