|
15 | 15 |
|
16 | 16 | #include "qgsalgorithmwritevectortiles.h"
|
17 | 17 |
|
| 18 | +#include "qgsprocessingparametervectortilewriterlayers.h" |
18 | 19 | #include "qgsvectorlayer.h"
|
19 | 20 | #include "qgsvectortilewriter.h"
|
20 | 21 |
|
21 | 22 | ///@cond PRIVATE
|
22 | 23 |
|
23 | 24 |
|
24 |
| -class QgsProcessingParameterVectorTileWriterLayers : public QgsProcessingParameterDefinition |
| 25 | +QString QgsWriteVectorTilesBaseAlgorithm::group() const |
25 | 26 | {
|
26 |
| -public: |
27 |
| - QgsProcessingParameterVectorTileWriterLayers( const QString &name, const QString &description = QString() ) |
28 |
| - : QgsProcessingParameterDefinition( name, description, QVariant(), false ) {} |
29 |
| - |
30 |
| - static QString typeName() { return QStringLiteral( "vectortilewriterlayers" ); } |
31 |
| - QgsProcessingParameterDefinition *clone() const override |
32 |
| - { |
33 |
| - return new QgsProcessingParameterVectorTileWriterLayers( *this ); |
34 |
| - } |
35 |
| - QString type() const override { return typeName(); } |
| 27 | + return QObject::tr( "Vector tiles" ); |
| 28 | +} |
36 | 29 |
|
37 |
| - bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const override |
38 |
| - { |
39 |
| - if ( !input.isValid() ) |
40 |
| - return mFlags & FlagOptional; |
| 30 | +QString QgsWriteVectorTilesBaseAlgorithm::groupId() const |
| 31 | +{ |
| 32 | + return QStringLiteral( "vectortiles" ); |
| 33 | +} |
41 | 34 |
|
42 |
| - if ( input.type() != QVariant::List ) |
43 |
| - return false; |
| 35 | +QString QgsWriteVectorTilesBaseAlgorithm::shortHelpString() const |
| 36 | +{ |
| 37 | + return QObject::tr( "This algorithm exports one or more vector layers to vector tiles - a data format optimized for fast map rendering and small data size." ); |
| 38 | +} |
44 | 39 |
|
45 |
| - const QVariantList inputList = input.toList(); |
46 |
| - for ( const QVariant &inputItem : inputList ) |
47 |
| - { |
48 |
| - if ( inputItem.type() != QVariant::Map ) |
49 |
| - return false; |
50 |
| - QVariantMap inputItemMap = inputItem.toMap(); |
| 40 | +void QgsWriteVectorTilesBaseAlgorithm::addBaseParameters() |
| 41 | +{ |
| 42 | + addParameter( new QgsProcessingParameterVectorTileWriterLayers( QStringLiteral( "LAYERS" ), QObject::tr( "Input layers" ) ) ); |
51 | 43 |
|
52 |
| - // "layer" is required - pointing to a vector layer |
53 |
| - if ( !inputItemMap.contains( "layer" ) ) |
54 |
| - return false; |
| 44 | + addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MIN_ZOOM" ), QObject::tr( "Minimum zoom level" ), QgsProcessingParameterNumber::Integer, 0, false, 0, 24 ) ); |
| 45 | + addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MAX_ZOOM" ), QObject::tr( "Maximum zoom level" ), QgsProcessingParameterNumber::Integer, 3, false, 0, 24 ) ); |
55 | 46 |
|
56 |
| - QVariant inputItemLayer = inputItemMap["layer"]; |
| 47 | + // optional extent |
| 48 | + addParameter( new QgsProcessingParameterExtent( QStringLiteral( "EXTENT" ), QObject::tr( "Extent" ), QVariant(), true ) ); |
| 49 | +} |
57 | 50 |
|
58 |
| - if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( inputItemLayer ) ) ) |
59 |
| - continue; |
| 51 | +QVariantMap QgsWriteVectorTilesBaseAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) |
| 52 | +{ |
| 53 | + int minZoom = parameterAsInt( parameters, QStringLiteral( "MIN_ZOOM" ), context ); |
| 54 | + int maxZoom = parameterAsInt( parameters, QStringLiteral( "MAX_ZOOM" ), context ); |
60 | 55 |
|
61 |
| - if ( !QgsProcessingUtils::mapLayerFromString( inputItemLayer.toString(), *context ) ) |
62 |
| - return false; |
63 |
| - } |
| 56 | + QVariant layersVariant = parameters.value( parameterDefinition( QStringLiteral( "LAYERS" ) )->name() ); |
| 57 | + const QList<QgsVectorTileWriter::Layer> layers = QgsProcessingParameterVectorTileWriterLayers::parameterAsLayers( layersVariant, context ); |
64 | 58 |
|
65 |
| - return true; |
| 59 | + for ( const QgsVectorTileWriter::Layer &layer : layers ) |
| 60 | + { |
| 61 | + if ( !layer.layer() ) |
| 62 | + throw QgsProcessingException( QObject::tr( "Unknown input layer" ) ); |
66 | 63 | }
|
67 | 64 |
|
68 |
| - // TODO: anything else? |
69 |
| - // - valueAsPythonString() |
70 |
| - // - asScriptCode() |
71 |
| - // - asPythonString() |
| 65 | + QgsVectorTileWriter writer; |
| 66 | + QVariantMap outputs; |
| 67 | + prepareWriter( writer, parameters, context, outputs ); |
| 68 | + |
| 69 | + writer.setMinZoom( minZoom ); |
| 70 | + writer.setMaxZoom( maxZoom ); |
| 71 | + writer.setLayers( layers ); |
| 72 | + writer.setTransformContext( context.transformContext() ); |
72 | 73 |
|
73 |
| - static QList<QgsVectorTileWriter::Layer> parameterAsLayers( const QVariant &layersVariant, QgsProcessingContext &context ) |
| 74 | + if ( parameters.contains( QStringLiteral( "EXTENT" ) ) ) |
74 | 75 | {
|
75 |
| - QList<QgsVectorTileWriter::Layer> layers; |
76 |
| - const QVariantList layersVariantList = layersVariant.toList(); |
77 |
| - for ( const QVariant &layerItem : layersVariantList ) |
78 |
| - { |
79 |
| - QVariantMap layerVariantMap = layerItem.toMap(); |
80 |
| - QVariant layerVariant = layerVariantMap["layer"]; |
81 |
| - |
82 |
| - QgsVectorLayer *inputLayer = nullptr; |
83 |
| - if ( ( inputLayer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( layerVariant ) ) ) ) |
84 |
| - { |
85 |
| - // good |
86 |
| - } |
87 |
| - else if ( ( inputLayer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerVariant.toString(), context ) ) ) ) |
88 |
| - { |
89 |
| - // good |
90 |
| - } |
91 |
| - else |
92 |
| - { |
93 |
| - // bad |
94 |
| - throw QgsProcessingException( "unknown input layer" ); |
95 |
| - } |
96 |
| - |
97 |
| - QgsVectorTileWriter::Layer writerLayer( inputLayer ); |
98 |
| - if ( layerVariantMap.contains( "filterExpression" ) ) |
99 |
| - writerLayer.setFilterExpression( layerVariantMap["filterExpression"].toString() ); |
100 |
| - if ( layerVariantMap.contains( "minZoom" ) ) |
101 |
| - writerLayer.setMinZoom( layerVariantMap["minZoom"].toInt() ); |
102 |
| - if ( layerVariantMap.contains( "maxZoom" ) ) |
103 |
| - writerLayer.setMaxZoom( layerVariantMap["maxZoom"].toInt() ); |
104 |
| - if ( layerVariantMap.contains( "layerName" ) ) |
105 |
| - writerLayer.setLayerName( layerVariantMap["layerName"].toString() ); |
106 |
| - layers << writerLayer; |
107 |
| - } |
108 |
| - return layers; |
| 76 | + QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, QgsCoordinateReferenceSystem( "EPSG:3857" ) ); |
| 77 | + writer.setExtent( extent ); |
109 | 78 | }
|
110 | 79 |
|
111 |
| -}; |
| 80 | + bool res = writer.writeTiles( feedback ); |
| 81 | + |
| 82 | + if ( !res ) |
| 83 | + throw QgsProcessingException( QObject::tr( "Failed to write vector tiles: " ) + writer.errorMessage() ); |
| 84 | + |
| 85 | + return outputs; |
| 86 | +} |
112 | 87 |
|
113 |
| -QString QgsWriteVectorTilesAlgorithm::name() const |
| 88 | +// |
| 89 | +// QgsWriteVectorTilesXyzAlgorithm |
| 90 | +// |
| 91 | + |
| 92 | +QString QgsWriteVectorTilesXyzAlgorithm::name() const |
114 | 93 | {
|
115 |
| - return QStringLiteral( "writevectortiles" ); |
| 94 | + return QStringLiteral( "writevectortiles_xyz" ); |
116 | 95 | }
|
117 | 96 |
|
118 |
| -QString QgsWriteVectorTilesAlgorithm::displayName() const |
| 97 | +QString QgsWriteVectorTilesXyzAlgorithm::displayName() const |
119 | 98 | {
|
120 |
| - return QObject::tr( "Write Vector Tiles" ); |
| 99 | + return QObject::tr( "Write Vector Tiles (XYZ)" ); |
121 | 100 | }
|
122 | 101 |
|
123 |
| -QString QgsWriteVectorTilesAlgorithm::group() const |
| 102 | +QgsProcessingAlgorithm *QgsWriteVectorTilesXyzAlgorithm::createInstance() const |
124 | 103 | {
|
125 |
| - return QObject::tr( "Vector tiles" ); |
| 104 | + return new QgsWriteVectorTilesXyzAlgorithm(); |
126 | 105 | }
|
127 | 106 |
|
128 |
| -QString QgsWriteVectorTilesAlgorithm::groupId() const |
| 107 | +void QgsWriteVectorTilesXyzAlgorithm::initAlgorithm( const QVariantMap & ) |
129 | 108 | {
|
130 |
| - return QStringLiteral( "vectortiles" ); |
| 109 | + addParameter( new QgsProcessingParameterFolderDestination( QStringLiteral( "OUTPUT_DIR" ), QObject::tr( "Output directry" ) ) ); |
| 110 | + addParameter( new QgsProcessingParameterString( QStringLiteral( "XYZ_TEMPLATE" ), QObject::tr( "File template" ), QStringLiteral( "{z}/{x}/{y}.pbf" ) ) ); |
| 111 | + |
| 112 | + addBaseParameters(); |
131 | 113 | }
|
132 | 114 |
|
133 |
| -QString QgsWriteVectorTilesAlgorithm::shortHelpString() const |
| 115 | +void QgsWriteVectorTilesXyzAlgorithm::prepareWriter( QgsVectorTileWriter &writer, const QVariantMap ¶meters, QgsProcessingContext &context, QVariantMap &outputs ) |
134 | 116 | {
|
135 |
| - return QObject::tr( "blah blah" ); // TODO |
| 117 | + QString outputDir = parameterAsString( parameters, QStringLiteral( "OUTPUT_DIR" ), context ); |
| 118 | + QString xyzTemplate = parameterAsString( parameters, QStringLiteral( "XYZ_TEMPLATE" ), context ); |
| 119 | + QgsDataSourceUri dsUri; |
| 120 | + dsUri.setParam( QStringLiteral( "type" ), QStringLiteral( "xyz" ) ); |
| 121 | + dsUri.setParam( QStringLiteral( "url" ), QUrl::fromLocalFile( outputDir + "/" + xyzTemplate ).toString() ); |
| 122 | + QString uri = dsUri.encodedUri(); |
| 123 | + |
| 124 | + writer.setDestinationUri( uri ); |
| 125 | + |
| 126 | + outputs.insert( QStringLiteral( "OUTPUT_DIR" ), outputDir ); |
136 | 127 | }
|
137 | 128 |
|
138 |
| -QgsProcessingAlgorithm *QgsWriteVectorTilesAlgorithm::createInstance() const |
| 129 | +// |
| 130 | +// QgsWriteVectorTilesMbtilesAlgorithm |
| 131 | +// |
| 132 | + |
| 133 | +QString QgsWriteVectorTilesMbtilesAlgorithm::name() const |
139 | 134 | {
|
140 |
| - return new QgsWriteVectorTilesAlgorithm(); |
| 135 | + return QStringLiteral( "writevectortiles_mbtiles" ); |
141 | 136 | }
|
142 | 137 |
|
143 |
| -void QgsWriteVectorTilesAlgorithm::initAlgorithm( const QVariantMap & ) |
| 138 | +QString QgsWriteVectorTilesMbtilesAlgorithm::displayName() const |
144 | 139 | {
|
145 |
| - addParameter( new QgsProcessingParameterVectorTileWriterLayers( "LAYERS", QObject::tr("Input layers") ) ); |
| 140 | + return QObject::tr( "Write Vector Tiles (MBTiles)" ); |
| 141 | +} |
146 | 142 |
|
147 |
| - addParameter( new QgsProcessingParameterString( "XYZ_TEMPLATE", QObject::tr("File template"), "/home/qgis/{z}/{x}/{y}.pbf" ) ); |
148 |
| - // TODO maybe use this: |
149 |
| - // addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Destination GeoPackage" ), QObject::tr( "GeoPackage files (*.gpkg)" ) ) ); |
| 143 | +QgsProcessingAlgorithm *QgsWriteVectorTilesMbtilesAlgorithm::createInstance() const |
| 144 | +{ |
| 145 | + return new QgsWriteVectorTilesMbtilesAlgorithm(); |
| 146 | +} |
150 | 147 |
|
151 |
| - addParameter( new QgsProcessingParameterNumber( "MIN_ZOOM", QObject::tr("Minimum zoom level"), QgsProcessingParameterNumber::Integer, 0, false, 0, 24 ) ); |
152 |
| - addParameter( new QgsProcessingParameterNumber( "MAX_ZOOM", QObject::tr("Maximum zoom level"), QgsProcessingParameterNumber::Integer, 3, false, 0, 24 ) ); |
| 148 | +void QgsWriteVectorTilesMbtilesAlgorithm::initAlgorithm( const QVariantMap & ) |
| 149 | +{ |
| 150 | + addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Destination MBTiles" ), QObject::tr( "MBTiles files (*.mbtiles)" ) ) ); |
153 | 151 |
|
154 |
| - // optional extent |
155 |
| - addParameter( new QgsProcessingParameterExtent( "EXTENT", QObject::tr("Extent"), QVariant(), true ) ); |
| 152 | + addBaseParameters(); |
156 | 153 |
|
157 |
| - // TODO: optional metadata (only for MBTiles? and with concrete values rather than single QVariantMap?) |
| 154 | + // optional metadata for MBTiles |
| 155 | + addParameter( new QgsProcessingParameterString( QStringLiteral( "META_NAME" ), QObject::tr( "Metadata: Name" ), QVariant(), false, true ) ); |
| 156 | + addParameter( new QgsProcessingParameterString( QStringLiteral( "META_DESCRIPTION" ), QObject::tr( "Metadata: Description" ), QVariant(), false, true ) ); |
| 157 | + addParameter( new QgsProcessingParameterString( QStringLiteral( "META_ATTRIBUTION" ), QObject::tr( "Metadata: Attribution" ), QVariant(), false, true ) ); |
| 158 | + addParameter( new QgsProcessingParameterString( QStringLiteral( "META_VERSION" ), QObject::tr( "Metadata: Version" ), QVariant(), false, true ) ); |
| 159 | + addParameter( new QgsProcessingParameterString( QStringLiteral( "META_TYPE" ), QObject::tr( "Metadata: Type" ), QVariant(), false, true ) ); |
| 160 | + addParameter( new QgsProcessingParameterString( QStringLiteral( "META_CENTER" ), QObject::tr( "Metadata: Center" ), QVariant(), false, true ) ); |
158 | 161 | }
|
159 | 162 |
|
160 |
| -QVariantMap QgsWriteVectorTilesAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) |
| 163 | +void QgsWriteVectorTilesMbtilesAlgorithm::prepareWriter( QgsVectorTileWriter &writer, const QVariantMap ¶meters, QgsProcessingContext &context, QVariantMap &outputs ) |
161 | 164 | {
|
162 |
| - int minZoom = parameterAsInt( parameters, QStringLiteral( "MIN_ZOOM" ), context ); |
163 |
| - int maxZoom = parameterAsInt( parameters, QStringLiteral( "MAX_ZOOM" ), context ); |
164 |
| - |
165 |
| - // prepare output URI |
166 |
| - QString xyzTemplate = parameterAsString( parameters, QStringLiteral( "XYZ_TEMPLATE" ), context ); |
| 165 | + QString outputFile = parameterAsFileOutput( parameters, QStringLiteral( "OUTPUT" ), context ); |
167 | 166 | QgsDataSourceUri dsUri;
|
168 |
| - dsUri.setParam( "type", "xyz" ); |
169 |
| - dsUri.setParam( "url", QUrl::fromLocalFile( xyzTemplate ).toString() ); |
| 167 | + dsUri.setParam( QStringLiteral( "type" ), QStringLiteral( "mbtiles" ) ); |
| 168 | + dsUri.setParam( QStringLiteral( "url" ), outputFile ); |
170 | 169 | QString uri = dsUri.encodedUri();
|
171 | 170 |
|
172 |
| - QVariant layersVariant = parameters.value( parameterDefinition( QStringLiteral( "LAYERS" ) )->name() ); |
173 |
| - QList<QgsVectorTileWriter::Layer> layers = QgsProcessingParameterVectorTileWriterLayers::parameterAsLayers( layersVariant, context ); |
174 |
| - |
175 |
| - QgsVectorTileWriter writer; |
176 | 171 | writer.setDestinationUri( uri );
|
177 |
| - writer.setMinZoom( minZoom ); |
178 |
| - writer.setMaxZoom( maxZoom ); |
179 |
| - writer.setLayers( layers ); |
180 |
| - writer.setTransformContext( context.transformContext() ); |
181 | 172 |
|
182 |
| - if ( parameters.contains( "EXTENT" ) ) |
183 |
| - { |
184 |
| - QgsRectangle extent = parameterAsExtent( parameters, "EXTENT", context, QgsCoordinateReferenceSystem( "EPSG:3857" ) ); |
185 |
| - writer.setExtent( extent ); |
186 |
| - } |
187 |
| - |
188 |
| - bool res = writer.writeTiles( feedback ); |
189 |
| - |
190 |
| - QVariantMap outputs; |
191 |
| - outputs["RESULT"] = res; |
192 |
| - return outputs; |
| 173 | + QString metaName = parameterAsString( parameters, QStringLiteral( "META_NAME" ), context ); |
| 174 | + QString metaDesciption = parameterAsString( parameters, QStringLiteral( "META_DESCRIPTION" ), context ); |
| 175 | + QString metaAttribution = parameterAsString( parameters, QStringLiteral( "META_ATTRIBUTION" ), context ); |
| 176 | + QString metaVersion = parameterAsString( parameters, QStringLiteral( "META_VERSION" ), context ); |
| 177 | + QString metaType = parameterAsString( parameters, QStringLiteral( "META_TYPE" ), context ); |
| 178 | + QString metaCenter = parameterAsString( parameters, QStringLiteral( "META_CENTER" ), context ); |
| 179 | + |
| 180 | + QVariantMap meta; |
| 181 | + if ( !metaName.isEmpty() ) |
| 182 | + meta["name"] = metaName; |
| 183 | + if ( !metaDesciption.isEmpty() ) |
| 184 | + meta["description"] = metaDesciption; |
| 185 | + if ( !metaAttribution.isEmpty() ) |
| 186 | + meta["attribution"] = metaAttribution; |
| 187 | + if ( !metaVersion.isEmpty() ) |
| 188 | + meta["version"] = metaVersion; |
| 189 | + if ( !metaType.isEmpty() ) |
| 190 | + meta["type"] = metaType; |
| 191 | + if ( !metaCenter.isEmpty() ) |
| 192 | + meta["center"] = metaCenter; |
| 193 | + |
| 194 | + writer.setMetadata( meta ); |
| 195 | + |
| 196 | + outputs.insert( QStringLiteral( "OUTPUT" ), outputFile ); |
193 | 197 | }
|
194 | 198 |
|
| 199 | + |
195 | 200 | ///@endcond
|
0 commit comments