Skip to content
Permalink
Browse files

Added feature to save vector layers styles to postgis (when provider …

…is postgres) and load one of them adding a new postgis vector layer
  • Loading branch information
Emilio Loi
Emilio Loi committed Apr 12, 2013
1 parent 41f7418 commit c3bbfeecaab0572eea5a8d3bd2edc0b39b1e7c30
@@ -39,6 +39,7 @@
#include "qgsprojectfiletransform.h"
#include "qgsdatasourceuri.h"
#include "qgsvectorlayer.h"
#include "qgsproviderregistry.h"

QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
QString lyrname,
@@ -742,6 +743,7 @@ bool QgsMapLayer::loadNamedStyleFromDb( const QString db, const QString theURI,
sqlite3_close( myDatabase );

return theResultFlag;

}

QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
@@ -751,8 +753,8 @@ QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
theResultFlag = false;

QDomDocument myDocument( "qgis" );

// location of problem associated with errorMsg

int line, column;
QString myErrorMessage;

@@ -773,7 +775,7 @@ QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
QString qml;
if ( loadNamedStyleFromDb( QDir( QgsApplication::qgisSettingsDirPath() ).absoluteFilePath( "qgis.qmldb" ), theURI, qml ) ||
( project.exists() && loadNamedStyleFromDb( project.absoluteDir().absoluteFilePath( project.baseName() + ".qmldb" ), theURI, qml ) ) ||
loadNamedStyleFromDb( QDir( QgsApplication::pkgDataPath() ).absoluteFilePath( "resources/qgis.qmldb" ), theURI, qml ) )
loadNamedStyleFromDb( QDir( QgsApplication::pkgDataPath() ).absoluteFilePath( "resources/qgis.qmldb" ), theURI, qml )/* || (loadStyleExternalMethod && loadStyleExternalMethod(theURI, qml, myErrorMessage))*/)
{
theResultFlag = myDocument.setContent( qml, &myErrorMessage, &line, &column );
if ( !theResultFlag )
@@ -87,6 +87,11 @@ typedef bool saveStyle_t(
QString& errCause
);

typedef QString loadStyle_t(
const QString& uri,
QString& errCause
);



QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
@@ -131,6 +136,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
// check if there is a default style / propertysheet defined
// for this layer and if so apply it
bool defaultLoadedFlag = false;

if ( loadDefaultStyleFlag )
{
loadDefaultStyle( defaultLoadedFlag );
@@ -3727,7 +3733,7 @@ void QgsVectorLayer::saveStyleToDatabase(QString name, QString owner, QString de
if ( !saveStyleExternalMethod )
{
delete myLib;
msgError = QObject::tr( "Provider %1 has no createEmptyLayer method" ).arg( mProviderKey );
msgError = QObject::tr( "Provider %1 has no saveStyle method" ).arg( mProviderKey );
return;
}

@@ -3749,3 +3755,55 @@ void QgsVectorLayer::saveStyleToDatabase(QString name, QString owner, QString de
saveStyleExternalMethod(mDataSource, qmlStyle, sldStyle, name, description,
owner, useAsDefault, msgError);
}

QString QgsVectorLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
{
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
bool styleFound = false;
if ( myLib )
{
loadStyle_t* loadStyleExternalMethod = ( loadStyle_t * ) cast_to_fptr( myLib->resolve( "loadStyle" ) );
if ( loadStyleExternalMethod )
{
QString qml, errorMsg;
qml = loadStyleExternalMethod( mDataSource, errorMsg );
if( qml.compare( tr( "" ) ) )
{
QDomDocument myDocument( "qgis" );
myDocument.setContent( qml );

QDomElement myRoot = myDocument.firstChildElement( "qgis" );

if( myRoot.isNull() )
{
theResultFlag = false;
return tr( "Error: qgis element could not be found in %1" ).arg( theURI );;
}
toggleScaleBasedVisibility( myRoot.attribute( "hasScaleBasedVisibilityFlag" ).toInt() == 1 );
setMinimumScale( myRoot.attribute( "minimumScale" ).toFloat() );
setMaximumScale( myRoot.attribute( "maximumScale" ).toFloat() );

#if 0
//read transparency level
QDomNode transparencyNode = myRoot.namedItem( "transparencyLevelInt" );
if ( ! transparencyNode.isNull() )
{
// set transparency level only if it's in project
// (otherwise it sets the layer transparent)
QDomElement myElement = transparencyNode.toElement();
setTransparency( myElement.text().toInt() );
}
#endif

styleFound = readSymbology( myRoot, errorMsg );
return errorMsg;
}
}
}
if( !styleFound )
{
return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
}
return tr( "" );
}
@@ -384,6 +384,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
virtual void saveStyleToDatabase( QString name, QString owner, QString description,
bool useAsDefault, QString &msgError );

virtual QString loadNamedStyle( const QString theURI, bool &theResultFlag );

/** convert a saved attribute editor element into a AttributeEditor structure as it's used internally.
* @param elem the DOM element
* @param parent the QObject which will own this object
@@ -3249,7 +3249,7 @@ QGISEXTERN bool saveStyle( const QString& uri, const QString& qmlStyle, const QS
QString createTabeQuery = QObject::tr( "CREATE TABLE public.%1 ( f_table_catalog varchar(256), f_table_schema varchar(256), f_table_name varchar(256), f_geometry_column varchar(256), styleName varchar(30), styleQML xml, styleSLD xml, useAsDefault boolean, description text, owner varchar(30), ui xml, update_time timestamp DEFAULT CURRENT_TIMESTAMP );" ).arg( styleTableName );

res = conn->PQexec( createTabeQuery );
if ( res.PQresultStatus() != PGRES_TUPLES_OK )
if ( res.PQresultStatus() != PGRES_COMMAND_OK )
{
errCause = QObject::tr( "Unable to save layer style. Unable to create style table" );
conn->disconnect();
@@ -3262,8 +3262,8 @@ QGISEXTERN bool saveStyle( const QString& uri, const QString& qmlStyle, const QS
f_table_name = dsUri.table();
f_geometry_column = dsUri.geometryColumn();

QString sql = QObject::tr( "INSERT INTO temporaly_name_for_style_table("
"f_table_catalog, f_table_schema, f_table_name, f_geometry_column, "
QString sql = QObject::tr( "INSERT INTO %10( f_table_catalog, "
"f_table_schema, f_table_name, f_geometry_column, "
"styleName, styleQML, styleSLD, useAsDefault, "
"description, owner) "
"VALUES(%1,%2,%3,%4,%5,XMLPARSE(DOCUMENT %6),"
@@ -3276,7 +3276,8 @@ QGISEXTERN bool saveStyle( const QString& uri, const QString& qmlStyle, const QS
.arg( QgsPostgresConn::quotedValue( qmlStyle ) )
.arg( QgsPostgresConn::quotedValue( sldStyle ) )
.arg( QgsPostgresConn::quotedValue( styleDescription ) )
.arg( QgsPostgresConn::quotedValue( owner ) );
.arg( QgsPostgresConn::quotedValue( owner ) )
.arg( styleTableName );

if( useAsDefault )
{
@@ -3298,3 +3299,39 @@ QGISEXTERN bool saveStyle( const QString& uri, const QString& qmlStyle, const QS
}
return true;
}


QGISEXTERN QString loadStyle( const QString& uri, QString& errCause )
{
QgsDataSourceURI dsUri( uri );
QString styleTableName = QObject::tr( "layer_styles" );
QString f_table_catalog, f_table_schema, f_table_name, f_geometry_column;

QgsPostgresConn* conn = QgsPostgresConn::connectDb( dsUri.connectionInfo(), false );
if ( !conn )
{
errCause = QObject::tr( "Connection to database failed" );
return false;
}

f_table_catalog = dsUri.database();
f_table_schema = dsUri.schema();
f_table_name = dsUri.table();
f_geometry_column = dsUri.geometryColumn();

QString selectQmlQuery = QObject::tr( "SELECT styleQML FROM %1 WHERE f_table_catalog=%2 AND f_table_schema=%3 AND f_table_name=%4 AND f_geometry_column=%5 ORDER BY (CASE WHEN useAsDefault THEN 1 ELSE 2 END), update_time DESC LIMIT 1;")
.arg( styleTableName )
.arg( QgsPostgresConn::quotedValue( f_table_catalog ) )
.arg( QgsPostgresConn::quotedValue( f_table_schema ) )
.arg( QgsPostgresConn::quotedValue(f_table_name ) )
.arg( QgsPostgresConn::quotedValue(f_geometry_column ) );

PGresult* result = conn->PQexec( selectQmlQuery );
if( PQntuples(result) == 1 )
{
char* c = PQgetvalue( result, 0, 0 );
return QObject::tr( c );;
}

return tr( "" );
}

0 comments on commit c3bbfee

Please sign in to comment.
You can’t perform that action at this time.