Datasources2Vrt.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. """
  2. ***************************************************************************
  3. Datasources2Vrt.py
  4. ---------------------
  5. Date : May 2015
  6. Copyright : (C) 2015 by Luigi Pirelli
  7. Email : luipir at gmail dot com
  8. ***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************
  16. """
  17. __author__ = 'Luigi Pirelli'
  18. __date__ = 'May 2015'
  19. __copyright__ = '(C) 2015, Luigi Pirelli'
  20. import html
  21. import pathlib
  22. from qgis.PyQt.QtCore import QCoreApplication
  23. from qgis.core import (QgsProcessing,
  24. QgsProcessingException,
  25. QgsProcessingParameterMultipleLayers,
  26. QgsProcessingParameterBoolean,
  27. QgsProcessingParameterVectorDestination,
  28. QgsProcessingOutputString,
  29. QgsProcessingParameters
  30. )
  31. from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
  32. from processing.algs.gdal.GdalUtils import GdalUtils
  33. class Datasources2Vrt(GdalAlgorithm):
  34. INPUT = 'INPUT'
  35. UNIONED = 'UNIONED'
  36. OUTPUT = 'OUTPUT'
  37. VRT_STRING = 'VRT_STRING'
  38. def createCustomParametersWidget(self, parent):
  39. return None
  40. def group(self):
  41. return self.tr('Vector miscellaneous')
  42. def groupId(self):
  43. return 'vectormiscellaneous'
  44. def name(self):
  45. return 'buildvirtualvector'
  46. def displayName(self):
  47. return self.tr('Build virtual vector')
  48. def tags(self):
  49. return ['ogr', 'gdal', 'vrt', 'create']
  50. def shortHelpString(self):
  51. return self.tr("This algorithm creates a virtual layer that contains a set of vector layers.\n\n"
  52. "The output virtual layer will not be opened in the current project.")
  53. def __init__(self):
  54. super().__init__()
  55. def initAlgorithm(self, config=None):
  56. self.addParameter(QgsProcessingParameterMultipleLayers(self.INPUT,
  57. self.tr('Input datasources'),
  58. QgsProcessing.TypeVector))
  59. self.addParameter(QgsProcessingParameterBoolean(self.UNIONED,
  60. self.tr('Create "unioned" VRT'),
  61. defaultValue=False))
  62. class ParameterVectorVrtDestination(QgsProcessingParameterVectorDestination):
  63. def __init__(self, name, description):
  64. super().__init__(name, description)
  65. def clone(self):
  66. copy = ParameterVectorVrtDestination(self.name(), self.description())
  67. return copy
  68. def defaultFileExtension(self):
  69. return 'vrt'
  70. def createFileFilter(self):
  71. return '{} (*.vrt *.VRT)'.format(QCoreApplication.translate("GdalAlgorithm", 'VRT files'))
  72. def supportedOutputRasterLayerExtensions(self):
  73. return ['vrt']
  74. def isSupportedOutputValue(self, value, context):
  75. output_path = QgsProcessingParameters.parameterAsOutputLayer(self, value, context)
  76. if pathlib.Path(output_path).suffix.lower() != '.vrt':
  77. return False, QCoreApplication.translate("GdalAlgorithm", 'Output filename must use a .vrt extension')
  78. return True, ''
  79. self.addParameter(ParameterVectorVrtDestination(self.OUTPUT,
  80. self.tr('Virtual vector')))
  81. self.addOutput(QgsProcessingOutputString(self.VRT_STRING,
  82. self.tr('Virtual string')))
  83. def processAlgorithm(self, parameters, context, feedback):
  84. input_layers = self.parameterAsLayerList(parameters, self.INPUT, context)
  85. unioned = self.parameterAsBoolean(parameters, self.UNIONED, context)
  86. vrtPath = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
  87. vrt = '<OGRVRTDataSource>'
  88. if unioned:
  89. vrt += '<OGRVRTUnionLayer name="UnionedLayer">'
  90. total = 100.0 / len(input_layers) if input_layers else 0
  91. for current, layer in enumerate(input_layers):
  92. if feedback.isCanceled():
  93. break
  94. basePath = GdalUtils.ogrConnectionStringFromLayer(layer)
  95. layerName = GdalUtils.ogrLayerName(layer.source())
  96. vrt += f'<OGRVRTLayer name="{html.escape(layerName, True)}">'
  97. vrt += f'<SrcDataSource>{html.escape(basePath, True)}</SrcDataSource>'
  98. vrt += f'<SrcLayer>{html.escape(layerName, True)}</SrcLayer>'
  99. vrt += '</OGRVRTLayer>'
  100. feedback.setProgress(int(current * total))
  101. if unioned:
  102. vrt += '</OGRVRTUnionLayer>'
  103. vrt += '</OGRVRTDataSource>'
  104. with open(vrtPath, 'w', encoding='utf-8') as f:
  105. f.write(vrt)
  106. return {self.OUTPUT: vrtPath, self.VRT_STRING: vrt}
  107. def commandName(self):
  108. return ''