Skip to content
Permalink
Browse files

Allow point clouds, mesh, vector tiles to be exported to qlr

and qml files through layer tree menu, and ensure that the
styles can be reapplied to the layer

Fixes #42111
Fixes #42112
  • Loading branch information
nyalldawson committed Mar 10, 2021
1 parent 3f5b165 commit d9f0bb5dfcf45791d21d5cf495c8d0655ab84a8d
Showing with 125 additions and 68 deletions.
  1. +2 −2 src/app/qgisapp.cpp
  2. +80 −47 src/app/qgsapplayertreeviewmenuprovider.cpp
  3. +43 −19 src/core/qgslayerdefinition.cpp
@@ -8916,6 +8916,8 @@ void QgisApp::saveStyleFile( QgsMapLayer *layer )

case QgsMapLayerType::RasterLayer:
case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::VectorTileLayer:
{
QgsSettings settings;
QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
@@ -8938,10 +8940,8 @@ void QgisApp::saveStyleFile( QgsMapLayer *layer )
break;
}

case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::PointCloudLayer:
break;

}
@@ -432,58 +432,91 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()

menu->addSeparator();

if ( vlayer )
// export menu
if ( layer )
{
if ( vlayer->isTemporary() )
{
QAction *actionMakePermanent = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mActionFileSave.svg" ) ), tr( "Make Permanent…" ), menu );
connect( actionMakePermanent, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->makeMemoryLayerPermanent( vlayer ); } );
menu->addAction( actionMakePermanent );
}
// save as vector file
QMenu *menuExportVector = new QMenu( tr( "E&xport" ), menu );
QAction *actionSaveAs = new QAction( tr( "Save Features &As…" ), menuExportVector );
connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } );
actionSaveAs->setEnabled( vlayer->isValid() );
menuExportVector->addAction( actionSaveAs );
QAction *actionSaveSelectedFeaturesAs = new QAction( tr( "Save &Selected Features As…" ), menuExportVector );
connect( actionSaveSelectedFeaturesAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile( nullptr, true ); } );
actionSaveSelectedFeaturesAs->setEnabled( vlayer->isValid() && vlayer->selectedFeatureCount() > 0 );
menuExportVector->addAction( actionSaveSelectedFeaturesAs );
QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportVector );
connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition );
menuExportVector->addAction( actionSaveAsDefinitionLayer );
if ( vlayer->isSpatial() )
switch ( layer->type() )
{
QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportVector );
connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } );
menuExportVector->addAction( actionSaveStyle );
case QgsMapLayerType::VectorLayer:
if ( vlayer )
{
if ( vlayer->isTemporary() )
{
QAction *actionMakePermanent = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mActionFileSave.svg" ) ), tr( "Make Permanent…" ), menu );
connect( actionMakePermanent, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->makeMemoryLayerPermanent( vlayer ); } );
menu->addAction( actionMakePermanent );
}
// save as vector file
QMenu *menuExportVector = new QMenu( tr( "E&xport" ), menu );
QAction *actionSaveAs = new QAction( tr( "Save Features &As…" ), menuExportVector );
connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } );
actionSaveAs->setEnabled( vlayer->isValid() );
menuExportVector->addAction( actionSaveAs );
QAction *actionSaveSelectedFeaturesAs = new QAction( tr( "Save &Selected Features As…" ), menuExportVector );
connect( actionSaveSelectedFeaturesAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile( nullptr, true ); } );
actionSaveSelectedFeaturesAs->setEnabled( vlayer->isValid() && vlayer->selectedFeatureCount() > 0 );
menuExportVector->addAction( actionSaveSelectedFeaturesAs );
QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportVector );
connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition );
menuExportVector->addAction( actionSaveAsDefinitionLayer );
if ( vlayer->isSpatial() )
{
QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportVector );
connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } );
menuExportVector->addAction( actionSaveStyle );
}
menu->addMenu( menuExportVector );
}
break;

case QgsMapLayerType::RasterLayer:
if ( rlayer )
{
QMenu *menuExportRaster = new QMenu( tr( "E&xport" ), menu );
QAction *actionSaveAs = new QAction( tr( "Save &As…" ), menuExportRaster );
QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportRaster );
QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportRaster );
connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } );
menuExportRaster->addAction( actionSaveAs );
actionSaveAs->setEnabled( rlayer->isValid() );
connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition );
menuExportRaster->addAction( actionSaveAsDefinitionLayer );
connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } );
menuExportRaster->addAction( actionSaveStyle );
menu->addMenu( menuExportRaster );
}
break;

case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::PointCloudLayer:
{
QMenu *menuExportRaster = new QMenu( tr( "E&xport" ), menu );
QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportRaster );
QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportRaster );
connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition );
menuExportRaster->addAction( actionSaveAsDefinitionLayer );
connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } );
menuExportRaster->addAction( actionSaveStyle );
menu->addMenu( menuExportRaster );
}
break;

case QgsMapLayerType::AnnotationLayer:
break;

case QgsMapLayerType::PluginLayer:
if ( mView->selectedLayerNodes().count() == 1 )
{
// disable duplication of plugin layers
duplicateLayersAction->setEnabled( false );
}
break;

}
menu->addMenu( menuExportVector );
}
else if ( rlayer )
{
QMenu *menuExportRaster = new QMenu( tr( "E&xport" ), menu );
QAction *actionSaveAs = new QAction( tr( "Save &As…" ), menuExportRaster );
QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportRaster );
QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportRaster );
connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } );
menuExportRaster->addAction( actionSaveAs );
actionSaveAs->setEnabled( rlayer->isValid() );
connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition );
menuExportRaster->addAction( actionSaveAsDefinitionLayer );
connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } );
menuExportRaster->addAction( actionSaveStyle );
menu->addMenu( menuExportRaster );
}
else if ( layer && layer->type() == QgsMapLayerType::PluginLayer && mView->selectedLayerNodes().count() == 1 )
{
// disable duplication of plugin layers
duplicateLayersAction->setEnabled( false );
menu->addSeparator();
}

menu->addSeparator();

// style-related actions
if ( layer && mView->selectedLayerNodes().count() == 1 )
{
@@ -30,6 +30,10 @@
#include "qgsvectorlayer.h"
#include "qgsvectortilelayer.h"
#include "qgsapplication.h"
#include "qgsmaplayerfactory.h"
#include "qgsmeshlayer.h"
#include "qgspointcloudlayer.h"
#include "qgsannotationlayer.h"

bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsProject *project, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
{
@@ -294,26 +298,42 @@ QList<QgsMapLayer *> QgsLayerDefinition::loadLayerDefinitionLayersInternal( QDom
const QString type = layerElem.attribute( QStringLiteral( "type" ) );
QgsMapLayer *layer = nullptr;

if ( type == QLatin1String( "vector" ) )
bool ok = false;
const QgsMapLayerType layerType = QgsMapLayerFactory::typeFromString( type, ok );
if ( ok )
{
layer = new QgsVectorLayer( );
}
else if ( type == QLatin1String( "raster" ) )
{
layer = new QgsRasterLayer;
}
else if ( type == QLatin1String( "vector-tile" ) )
{
layer = new QgsVectorTileLayer;
}
else if ( type == QLatin1String( "plugin" ) )
{
QString typeName = layerElem.attribute( QStringLiteral( "name" ) );
layer = QgsApplication::pluginLayerRegistry()->createLayer( typeName );
}
else
{
errorMessage = QObject::tr( "Unsupported layer type: %1" ).arg( type );
switch ( layerType )
{
case QgsMapLayerType::VectorLayer:
layer = new QgsVectorLayer();
break;

case QgsMapLayerType::RasterLayer:
layer = new QgsRasterLayer();
break;

case QgsMapLayerType::PluginLayer:
{
QString typeName = layerElem.attribute( QStringLiteral( "name" ) );
layer = QgsApplication::pluginLayerRegistry()->createLayer( typeName );
break;
}

case QgsMapLayerType::MeshLayer:
layer = new QgsMeshLayer();
break;

case QgsMapLayerType::VectorTileLayer:
layer = new QgsVectorTileLayer;
break;

case QgsMapLayerType::PointCloudLayer:
layer = new QgsPointCloudLayer();
break;

case QgsMapLayerType::AnnotationLayer:
break;
}
}

if ( layer )
@@ -323,6 +343,10 @@ QList<QgsMapLayer *> QgsLayerDefinition::loadLayerDefinitionLayersInternal( QDom
layer->readLayerXml( layerElem, context );
layers << layer;
}
else
{
errorMessage = QObject::tr( "Unsupported layer type: %1" ).arg( type );
}
layerElem = layerElem.nextSiblingElement( QStringLiteral( "maplayer" ) );
}
return layers;

0 comments on commit d9f0bb5

Please sign in to comment.