20 #include <QDomDocument>
21 #include <QDomElement>
22 #include <QDomImplementation>
26 #include <QTextStream>
63 return QStringLiteral(
".qmd" );
66 return QStringLiteral(
".qml" );
72 const QString &lyrname,
73 const QString &source )
74 : mDataSource( source )
75 , mLayerName( lyrname )
77 , mUndoStack( new QUndoStack( this ) )
78 , mUndoStackStyles( new QUndoStack( this ) )
80 , mRefreshTimer( new QTimer( this ) )
85 connect( mRefreshTimer, &QTimer::timeout,
this, [ = ] {
triggerRepaint(
true ); } );
100 for (
const QString &s : constStyles )
141 if (
flags == mFlags )
228 mnl = layerElement.namedItem( QStringLiteral(
"provider" ) );
229 mne = mnl.toElement();
230 provider = mne.text();
233 mnl = layerElement.namedItem( QStringLiteral(
"datasource" ) );
234 mne = mnl.toElement();
238 QRegExp rx(
"authcfg=([a-z]|[A-Z]|[0-9]){7}" );
251 mnl = layerElement.namedItem( QStringLiteral(
"layername" ) );
252 mne = mnl.toElement();
257 QDomNode srsNode = layerElement.namedItem( QStringLiteral(
"srs" ) );
276 mnl = layerElement.namedItem( QStringLiteral(
"id" ) );
277 if ( ! mnl.isNull() )
279 mne = mnl.toElement();
280 if ( ! mne.isNull() && mne.text().length() > 10 )
286 setAutoRefreshInterval( layerElement.attribute( QStringLiteral(
"autoRefreshTime" ), QStringLiteral(
"0" ) ).toInt() );
287 setAutoRefreshEnabled( layerElement.attribute( QStringLiteral(
"autoRefreshEnabled" ), QStringLiteral(
"0" ) ).toInt() );
289 setRefreshOnNotifyEnabled( layerElement.attribute( QStringLiteral(
"refreshOnNotifyEnabled" ), QStringLiteral(
"0" ) ).toInt() );
292 mnl = layerElement.namedItem( QStringLiteral(
"layername" ) );
293 mne = mnl.toElement();
296 setName( context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1" ).arg( layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), mne.text() ) );
299 layerError = !
readXml( layerElement, context );
308 QDomElement shortNameElem = layerElement.firstChildElement( QStringLiteral(
"shortname" ) );
309 if ( !shortNameElem.isNull() )
315 QDomElement titleElem = layerElement.firstChildElement( QStringLiteral(
"title" ) );
316 if ( !titleElem.isNull() )
318 mTitle = titleElem.text();
322 QDomElement abstractElem = layerElement.firstChildElement( QStringLiteral(
"abstract" ) );
323 if ( !abstractElem.isNull() )
329 QDomElement keywordListElem = layerElement.firstChildElement( QStringLiteral(
"keywordList" ) );
330 if ( !keywordListElem.isNull() )
333 for ( QDomNode n = keywordListElem.firstChild(); !n.isNull(); n = n.nextSibling() )
335 kwdList << n.toElement().text();
341 QDomElement dataUrlElem = layerElement.firstChildElement( QStringLiteral(
"dataUrl" ) );
342 if ( !dataUrlElem.isNull() )
345 mDataUrlFormat = dataUrlElem.attribute( QStringLiteral(
"format" ), QString() );
349 QDomElement legendUrlElem = layerElement.firstChildElement( QStringLiteral(
"legendUrl" ) );
350 if ( !legendUrlElem.isNull() )
353 mLegendUrlFormat = legendUrlElem.attribute( QStringLiteral(
"format" ), QString() );
357 QDomElement attribElem = layerElement.firstChildElement( QStringLiteral(
"attribution" ) );
358 if ( !attribElem.isNull() )
361 mAttributionUrl = attribElem.attribute( QStringLiteral(
"href" ), QString() );
365 QDomElement metaUrlElem = layerElement.firstChildElement( QStringLiteral(
"metadataUrl" ) );
366 if ( !metaUrlElem.isNull() )
369 mMetadataUrlType = metaUrlElem.attribute( QStringLiteral(
"type" ), QString() );
374 QDomElement metadataElem = layerElement.firstChildElement( QStringLiteral(
"resourceMetadata" ) );
383 Q_UNUSED( layer_node )
398 layerElement.setAttribute( QStringLiteral(
"autoRefreshTime" ), QString::number( mRefreshTimer->interval() ) );
399 layerElement.setAttribute( QStringLiteral(
"autoRefreshEnabled" ), mRefreshTimer->isActive() ? 1 : 0 );
405 QDomElement layerId = document.createElement( QStringLiteral(
"id" ) );
406 QDomText layerIdText = document.createTextNode(
id() );
407 layerId.appendChild( layerIdText );
409 layerElement.appendChild( layerId );
412 QDomElement dataSource = document.createElement( QStringLiteral(
"datasource" ) );
414 QDomText dataSourceText = document.createTextNode( src );
415 dataSource.appendChild( dataSourceText );
416 layerElement.appendChild( dataSource );
419 QDomElement layerName = document.createElement( QStringLiteral(
"layername" ) );
420 QDomText layerNameText = document.createTextNode(
name() );
421 layerName.appendChild( layerNameText );
422 layerElement.appendChild( layerName );
427 QDomElement layerShortName = document.createElement( QStringLiteral(
"shortname" ) );
428 QDomText layerShortNameText = document.createTextNode(
mShortName );
429 layerShortName.appendChild( layerShortNameText );
430 layerElement.appendChild( layerShortName );
436 QDomElement layerTitle = document.createElement( QStringLiteral(
"title" ) );
437 QDomText layerTitleText = document.createTextNode(
mTitle );
438 layerTitle.appendChild( layerTitleText );
439 layerElement.appendChild( layerTitle );
445 QDomElement layerAbstract = document.createElement( QStringLiteral(
"abstract" ) );
446 QDomText layerAbstractText = document.createTextNode(
mAbstract );
447 layerAbstract.appendChild( layerAbstractText );
448 layerElement.appendChild( layerAbstract );
452 QStringList keywordStringList =
keywordList().split(
',' );
453 if ( !keywordStringList.isEmpty() )
455 QDomElement layerKeywordList = document.createElement( QStringLiteral(
"keywordList" ) );
456 for (
int i = 0; i < keywordStringList.size(); ++i )
458 QDomElement layerKeywordValue = document.createElement( QStringLiteral(
"value" ) );
459 QDomText layerKeywordText = document.createTextNode( keywordStringList.at( i ).trimmed() );
460 layerKeywordValue.appendChild( layerKeywordText );
461 layerKeywordList.appendChild( layerKeywordValue );
463 layerElement.appendChild( layerKeywordList );
468 if ( !aDataUrl.isEmpty() )
470 QDomElement layerDataUrl = document.createElement( QStringLiteral(
"dataUrl" ) );
471 QDomText layerDataUrlText = document.createTextNode( aDataUrl );
472 layerDataUrl.appendChild( layerDataUrlText );
473 layerDataUrl.setAttribute( QStringLiteral(
"format" ),
dataUrlFormat() );
474 layerElement.appendChild( layerDataUrl );
479 if ( !aLegendUrl.isEmpty() )
481 QDomElement layerLegendUrl = document.createElement( QStringLiteral(
"legendUrl" ) );
482 QDomText layerLegendUrlText = document.createTextNode( aLegendUrl );
483 layerLegendUrl.appendChild( layerLegendUrlText );
484 layerLegendUrl.setAttribute( QStringLiteral(
"format" ),
legendUrlFormat() );
485 layerElement.appendChild( layerLegendUrl );
490 if ( !aAttribution.isEmpty() )
492 QDomElement layerAttribution = document.createElement( QStringLiteral(
"attribution" ) );
493 QDomText layerAttributionText = document.createTextNode( aAttribution );
494 layerAttribution.appendChild( layerAttributionText );
495 layerAttribution.setAttribute( QStringLiteral(
"href" ),
attributionUrl() );
496 layerElement.appendChild( layerAttribution );
501 if ( !aMetadataUrl.isEmpty() )
503 QDomElement layerMetadataUrl = document.createElement( QStringLiteral(
"metadataUrl" ) );
504 QDomText layerMetadataUrlText = document.createTextNode( aMetadataUrl );
505 layerMetadataUrl.appendChild( layerMetadataUrlText );
506 layerMetadataUrl.setAttribute( QStringLiteral(
"type" ),
metadataUrlType() );
507 layerMetadataUrl.setAttribute( QStringLiteral(
"format" ),
metadataUrlFormat() );
508 layerElement.appendChild( layerMetadataUrl );
514 QDomElement stamp = document.createElement( QStringLiteral(
"timestamp" ) );
515 QDomText stampText = document.createTextNode(
timestamp().toString( Qt::ISODate ) );
516 stamp.appendChild( stampText );
517 layerElement.appendChild( stamp );
520 layerElement.appendChild( layerName );
527 QDomElement mySrsElement = document.createElement( QStringLiteral(
"srs" ) );
528 mCRS.
writeXml( mySrsElement, document );
529 layerElement.appendChild( mySrsElement );
532 QDomElement myMetadataElem = document.createElement( QStringLiteral(
"resourceMetadata" ) );
534 layerElement.appendChild( myMetadataElem );
537 return writeXml( layerElement, document, context );
544 QMetaEnum metaEnum = QMetaEnum::fromType<QgsMapLayer::StyleCategories>();
545 QString categoriesKeys( metaEnum.valueToKeys(
static_cast<int>( categories ) ) );
546 layerElement.setAttribute( QStringLiteral(
"styleCategories" ), categoriesKeys );
551 layerElement.setAttribute( QStringLiteral(
"hasScaleBasedVisibilityFlag" ),
hasScaleBasedVisibility() ? 1 : 0 );
552 layerElement.setAttribute( QStringLiteral(
"maxScale" ), QString::number(
maximumScale() ) );
553 layerElement.setAttribute( QStringLiteral(
"minScale" ), QString::number(
minimumScale() ) );
560 QDomElement renderer3DElem = document.createElement( QStringLiteral(
"renderer-3d" ) );
561 renderer3DElem.setAttribute( QStringLiteral(
"type" ), m3DRenderer->
type() );
562 m3DRenderer->
writeXml( renderer3DElem, context );
563 layerElement.appendChild( renderer3DElem );
571 QDomElement layerFlagsElem = document.createElement( QStringLiteral(
"flags" ) );
572 auto enumMap = qgsEnumMap<QgsMapLayer::LayerFlag>();
573 for (
auto it = enumMap.constBegin(); it != enumMap.constEnd(); ++it )
575 bool flagValue = mFlags.testFlag( it.key() );
576 QDomElement flagElem = document.createElement( it.value() );
577 flagElem.appendChild( document.createTextNode( QString::number( flagValue ) ) );
578 layerFlagsElem.appendChild( flagElem );
580 layerElement.appendChild( layerFlagsElem );
598 Q_UNUSED( layer_node )
629 mCustomProperties.
readXml( layerNode, keyStartsWith );
634 mCustomProperties.
writeXml( layerNode, doc );
639 QDomElement styleMgrElem = layerNode.firstChildElement( QStringLiteral(
"map-layer-style-manager" ) );
640 if ( !styleMgrElem.isNull() )
641 mStyleManager->
readXml( styleMgrElem );
643 mStyleManager->
reset();
650 QDomElement styleMgrElem = doc.createElement( QStringLiteral(
"map-layer-style-manager" ) );
651 mStyleManager->
writeXml( styleMgrElem );
652 layerNode.appendChild( styleMgrElem );
662 void QgsMapLayer::connectNotify(
const char *signal )
671 return !mScaleBasedVisibility ||
673 && ( mMaxScale == 0 || scale < mMaxScale ) );
678 return mScaleBasedVisibility;
683 return mRefreshTimer->isActive();
688 return mRefreshTimer->interval();
695 mRefreshTimer->stop();
696 mRefreshTimer->setInterval( 0 );
700 mRefreshTimer->setInterval( interval );
708 mRefreshTimer->stop();
709 else if ( mRefreshTimer->interval() > 0 )
710 mRefreshTimer->start();
738 mScaleBasedVisibility = enabled;
748 return QStringList();
790 QString layerName(
name );
791 layerName.replace(
'_',
' ' );
796 QString QgsMapLayer::baseURI( PropertyType type )
const
808 myURI = components[
"path"].toString();
811 QFileInfo myFileInfo( myURI );
814 if ( myFileInfo.exists() )
817 if ( myURI.endsWith( QLatin1String(
".gz" ), Qt::CaseInsensitive ) )
819 else if ( myURI.endsWith( QLatin1String(
".zip" ), Qt::CaseInsensitive ) )
821 else if ( myURI.endsWith( QLatin1String(
".tar" ), Qt::CaseInsensitive ) )
823 else if ( myURI.endsWith( QLatin1String(
".tar.gz" ), Qt::CaseInsensitive ) )
825 else if ( myURI.endsWith( QLatin1String(
".tgz" ), Qt::CaseInsensitive ) )
827 myFileInfo.setFile( myURI );
841 return baseURI( PropertyType::Metadata );
856 return baseURI( PropertyType::Style );
866 return loadNamedPropertyFromDatabase( db, uri, qmd, PropertyType::Metadata );
871 return loadNamedPropertyFromDatabase( db, uri, qml, PropertyType::Style );
874 bool QgsMapLayer::loadNamedPropertyFromDatabase(
const QString &db,
const QString &uri, QString &xml,
QgsMapLayer::PropertyType type )
878 bool resultFlag =
false;
886 QgsDebugMsgLevel( QStringLiteral(
"Trying to load style or metadata for \"%1\" from \"%2\"" ).arg( uri, db ), 4 );
888 if ( db.isEmpty() || !QFile( db ).exists() )
891 myResult = database.
open_v2( db, SQLITE_OPEN_READONLY,
nullptr );
892 if ( myResult != SQLITE_OK )
901 mySql = QStringLiteral(
"select qmd from tbl_metadata where metadata=?" );
905 mySql = QStringLiteral(
"select qml from tbl_styles where style=?" );
909 statement = database.
prepare( mySql, myResult );
910 if ( myResult == SQLITE_OK )
912 QByteArray param = uri.toUtf8();
914 if ( sqlite3_bind_text( statement.get(), 1, param.data(), param.length(), SQLITE_STATIC ) == SQLITE_OK &&
915 sqlite3_step( statement.get() ) == SQLITE_ROW )
917 xml = QString::fromUtf8(
reinterpret_cast< const char *
>( sqlite3_column_text( statement.get(), 0 ) ) );
927 return loadNamedProperty( uri, PropertyType::Style, resultFlag, categories );
930 QString QgsMapLayer::loadNamedProperty(
const QString &uri,
QgsMapLayer::PropertyType type,
bool &resultFlag, StyleCategories categories )
936 QDomDocument myDocument( QStringLiteral(
"qgis" ) );
940 QString myErrorMessage;
943 if ( myFile.open( QFile::ReadOnly ) )
947 resultFlag = myDocument.setContent( &myFile, &myErrorMessage, &line, &column );
949 myErrorMessage = tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
955 QgsDebugMsgLevel( QStringLiteral(
"project fileName: %1" ).arg( project.absoluteFilePath() ), 4 );
963 ( project.exists() &&
loadNamedStyleFromDatabase( project.absoluteDir().absoluteFilePath( project.baseName() +
".qmldb" ), uri, xml ) ) ||
966 resultFlag = myDocument.setContent( xml, &myErrorMessage, &line, &column );
969 myErrorMessage = tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
974 myErrorMessage = tr(
"Style not found in database" );
982 ( project.exists() &&
loadNamedMetadataFromDatabase( project.absoluteDir().absoluteFilePath( project.baseName() +
".qmldb" ), uri, xml ) ) ||
985 resultFlag = myDocument.setContent( xml, &myErrorMessage, &line, &column );
988 myErrorMessage = tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
993 myErrorMessage = tr(
"Metadata not found in database" );
1003 return myErrorMessage;
1011 myErrorMessage = tr(
"Loading style file %1 failed because:\n%2" ).arg( uri, myErrorMessage );
1016 myErrorMessage = tr(
"Loading metadata file %1 failed because:\n%2" ).arg( uri, myErrorMessage );
1019 return myErrorMessage;
1024 QDomElement myRoot = document.firstChildElement( QStringLiteral(
"qgis" ) );
1025 if ( myRoot.isNull() )
1027 errorMessage = tr(
"Root <qgis> element could not be found" );
1036 QDomElement myRoot = myDocument.firstChildElement( QStringLiteral(
"qgis" ) );
1037 if ( myRoot.isNull() )
1039 myErrorMessage = tr(
"Root <qgis> element could not be found" );
1044 QgsProjectVersion fileVersion( myRoot.attribute( QStringLiteral(
"version" ) ) );
1047 if ( thisVersion > fileVersion )
1064 if ( importLayerGeometryType != QgsWkbTypes::GeometryType::UnknownGeometry && vl->
geometryType() != importLayerGeometryType )
1066 myErrorMessage = tr(
"Cannot apply style with symbology to layer with a different geometry type" );
1073 return readSymbology( myRoot, myErrorMessage, context, categories );
1078 QDomImplementation DomImplementation;
1079 QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ), QStringLiteral(
"SYSTEM" ) );
1080 QDomDocument myDocument( documentType );
1082 QDomElement myRootNode = myDocument.createElement( QStringLiteral(
"qgis" ) );
1083 myRootNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
1084 myDocument.appendChild( myRootNode );
1088 errorMsg = QObject::tr(
"Could not save metadata" );
1097 QDomImplementation DomImplementation;
1098 QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ), QStringLiteral(
"SYSTEM" ) );
1099 QDomDocument myDocument( documentType );
1101 QDomElement myRootNode = myDocument.createElement( QStringLiteral(
"qgis" ) );
1102 myRootNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
1103 myDocument.appendChild( myRootNode );
1105 if ( !
writeSymbology( myRootNode, myDocument, errorMsg, context, categories ) )
1107 errorMsg = QObject::tr(
"Could not save symbology because:\n%1" ).arg( errorMsg );
1118 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>(
this );
1119 QString geoType = QString::number( vl->
geometryType() );
1122 QDomElement layerGeometryType = myDocument.createElement( QStringLiteral(
"layerGeometryType" ) );
1123 QDomText
type = myDocument.createTextNode( geoType );
1125 layerGeometryType.appendChild(
type );
1126 myRootNode.appendChild( layerGeometryType );
1147 QString QgsMapLayer::saveNamedProperty(
const QString &uri,
QgsMapLayer::PropertyType type,
bool &resultFlag, StyleCategories categories )
1155 if ( vlayer && vlayer->
providerType() == QLatin1String(
"ogr" ) )
1157 QStringList theURIParts = uri.split(
'|' );
1158 filename = theURIParts[0];
1160 else if ( vlayer && vlayer->
providerType() == QLatin1String(
"gpx" ) )
1162 QStringList theURIParts = uri.split(
'?' );
1163 filename = theURIParts[0];
1165 else if ( vlayer && vlayer->
providerType() == QLatin1String(
"delimitedtext" ) )
1167 filename = QUrl::fromEncoded( uri.toLatin1() ).toLocalFile();
1169 if ( filename.isEmpty() )
1177 QString myErrorMessage;
1178 QDomDocument myDocument;
1191 QFileInfo myFileInfo( filename );
1194 QFileInfo myDirInfo( myFileInfo.path() );
1195 if ( !myDirInfo.isWritable() )
1197 return tr(
"The directory containing your dataset needs to be writable!" );
1203 QFile myFile( myFileName );
1204 if ( myFile.open( QFile::WriteOnly | QFile::Truncate ) )
1206 QTextStream myFileStream( &myFile );
1208 myDocument.save( myFileStream, 2 );
1214 return tr(
"Created default metadata file as %1" ).arg( myFileName );
1217 return tr(
"Created default style file as %1" ).arg( myFileName );
1227 return tr(
"ERROR: Failed to created default metadata file as %1. Check file permissions and retry." ).arg( myFileName );
1230 return tr(
"ERROR: Failed to created default style file as %1. Check file permissions and retry." ).arg( myFileName );
1236 QString qml = myDocument.toString();
1243 if ( myResult != SQLITE_OK )
1245 return tr(
"User database could not be opened." );
1248 QByteArray param0 = uri.toUtf8();
1249 QByteArray param1 = qml.toUtf8();
1255 mySql = QStringLiteral(
"create table if not exists tbl_metadata(metadata varchar primary key,qmd varchar)" );
1259 mySql = QStringLiteral(
"create table if not exists tbl_styles(style varchar primary key,qml varchar)" );
1263 statement = database.
prepare( mySql, myResult );
1264 if ( myResult == SQLITE_OK )
1266 if ( sqlite3_step( statement.get() ) != SQLITE_DONE )
1272 return tr(
"The metadata table could not be created." );
1275 return tr(
"The style table could not be created." );
1283 mySql = QStringLiteral(
"insert into tbl_metadata(metadata,qmd) values (?,?)" );
1287 mySql = QStringLiteral(
"insert into tbl_styles(style,qml) values (?,?)" );
1290 statement = database.
prepare( mySql, myResult );
1291 if ( myResult == SQLITE_OK )
1293 if ( sqlite3_bind_text( statement.get(), 1, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
1294 sqlite3_bind_text( statement.get(), 2, param1.data(), param1.length(), SQLITE_STATIC ) == SQLITE_OK &&
1295 sqlite3_step( statement.get() ) == SQLITE_DONE )
1301 myErrorMessage = tr(
"The metadata %1 was saved to database" ).arg( uri );
1305 myErrorMessage = tr(
"The style %1 was saved to database" ).arg( uri );
1317 mySql = QStringLiteral(
"update tbl_metadata set qmd=? where metadata=?" );
1321 mySql = QStringLiteral(
"update tbl_styles set qml=? where style=?" );
1324 statement = database.
prepare( mySql, myResult );
1325 if ( myResult == SQLITE_OK )
1327 if ( sqlite3_bind_text( statement.get(), 2, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
1328 sqlite3_bind_text( statement.get(), 1, param1.data(), param1.length(), SQLITE_STATIC ) == SQLITE_OK &&
1329 sqlite3_step( statement.get() ) == SQLITE_DONE )
1335 myErrorMessage = tr(
"The metadata %1 was updated in the database." ).arg( uri );
1339 myErrorMessage = tr(
"The style %1 was updated in the database." ).arg( uri );
1349 myErrorMessage = tr(
"The metadata %1 could not be updated in the database." ).arg( uri );
1353 myErrorMessage = tr(
"The style %1 could not be updated in the database." ).arg( uri );
1364 myErrorMessage = tr(
"The metadata %1 could not be inserted into database." ).arg( uri );
1368 myErrorMessage = tr(
"The style %1 could not be inserted into database." ).arg( uri );
1375 return myErrorMessage;
1385 QDomDocument myDocument = QDomDocument();
1387 QDomNode header = myDocument.createProcessingInstruction( QStringLiteral(
"xml" ), QStringLiteral(
"version=\"1.0\" encoding=\"UTF-8\"" ) );
1388 myDocument.appendChild( header );
1390 const QgsVectorLayer *vlayer = qobject_cast<const QgsVectorLayer *>(
this );
1391 const QgsRasterLayer *rlayer = qobject_cast<const QgsRasterLayer *>(
this );
1392 if ( !vlayer && !rlayer )
1394 errorMsg = tr(
"Could not save symbology because:\n%1" )
1395 .arg( tr(
"Only vector and raster layers are supported" ) );
1400 QDomElement root = myDocument.createElementNS( QStringLiteral(
"http://www.opengis.net/sld" ), QStringLiteral(
"StyledLayerDescriptor" ) );
1401 QDomElement layerNode;
1404 root.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.1.0" ) );
1405 root.setAttribute( QStringLiteral(
"xsi:schemaLocation" ), QStringLiteral(
"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" ) );
1406 root.setAttribute( QStringLiteral(
"xmlns:ogc" ), QStringLiteral(
"http://www.opengis.net/ogc" ) );
1407 root.setAttribute( QStringLiteral(
"xmlns:se" ), QStringLiteral(
"http://www.opengis.net/se" ) );
1408 root.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1409 root.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
1410 myDocument.appendChild( root );
1413 layerNode = myDocument.createElement( QStringLiteral(
"NamedLayer" ) );
1414 root.appendChild( layerNode );
1421 root.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0.0" ) );
1422 root.setAttribute( QStringLiteral(
"xmlns:gml" ), QStringLiteral(
"http://www.opengis.net/gml" ) );
1423 root.setAttribute( QStringLiteral(
"xmlns:ogc" ), QStringLiteral(
"http://www.opengis.net/ogc" ) );
1424 root.setAttribute( QStringLiteral(
"xmlns:sld" ), QStringLiteral(
"http://www.opengis.net/sld" ) );
1425 myDocument.appendChild( root );
1428 layerNode = myDocument.createElement( QStringLiteral(
"UserLayer" ) );
1429 root.appendChild( layerNode );
1435 props[ QStringLiteral(
"scaleMinDenom" ) ] = QString::number( mMinScale );
1436 props[ QStringLiteral(
"scaleMaxDenom" ) ] = QString::number( mMaxScale );
1441 if ( !vlayer->
writeSld( layerNode, myDocument, errorMsg, props ) )
1443 errorMsg = tr(
"Could not save symbology because:\n%1" ).arg( errorMsg );
1450 if ( !rlayer->
writeSld( layerNode, myDocument, errorMsg, props ) )
1452 errorMsg = tr(
"Could not save symbology because:\n%1" ).arg( errorMsg );
1462 const QgsMapLayer *mlayer = qobject_cast<const QgsMapLayer *>(
this );
1465 QDomDocument myDocument;
1467 if ( !errorMsg.isNull() )
1475 if ( mlayer->
providerType() == QLatin1String(
"ogr" ) )
1477 QStringList theURIParts = uri.split(
'|' );
1478 filename = theURIParts[0];
1480 else if ( mlayer->
providerType() == QLatin1String(
"gpx" ) )
1482 QStringList theURIParts = uri.split(
'?' );
1483 filename = theURIParts[0];
1485 else if ( mlayer->
providerType() == QLatin1String(
"delimitedtext" ) )
1487 filename = QUrl::fromEncoded( uri.toLatin1() ).toLocalFile();
1489 if ( filename.isEmpty() )
1497 QFileInfo myFileInfo( filename );
1498 if ( myFileInfo.exists() || filename.endsWith( QLatin1String(
".sld" ), Qt::CaseInsensitive ) )
1500 QFileInfo myDirInfo( myFileInfo.path() );
1501 if ( !myDirInfo.isWritable() )
1503 return tr(
"The directory containing your dataset needs to be writable!" );
1507 QString myFileName = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() +
".sld";
1509 QFile myFile( myFileName );
1510 if ( myFile.open( QFile::WriteOnly | QFile::Truncate ) )
1512 QTextStream myFileStream( &myFile );
1514 myDocument.save( myFileStream, 2 );
1517 return tr(
"Created default style file as %1" ).arg( myFileName );
1522 return tr(
"ERROR: Failed to created SLD style file as %1. Check file permissions and retry." ).arg( filename );
1529 QDomDocument myDocument;
1533 QString myErrorMessage;
1535 QFile myFile( uri );
1536 if ( myFile.open( QFile::ReadOnly ) )
1539 resultFlag = myDocument.setContent( &myFile,
true, &myErrorMessage, &line, &column );
1541 myErrorMessage = tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
1546 myErrorMessage = tr(
"Unable to open file %1" ).arg( uri );
1551 return myErrorMessage;
1555 QDomElement myRoot = myDocument.firstChildElement( QStringLiteral(
"StyledLayerDescriptor" ) );
1556 if ( myRoot.isNull() )
1558 myErrorMessage = QStringLiteral(
"Error: StyledLayerDescriptor element not found in %1" ).arg( uri );
1560 return myErrorMessage;
1565 QDomElement namedLayerElem = myRoot.firstChildElement( QStringLiteral(
"NamedLayer" ) );
1566 if ( namedLayerElem.isNull() )
1568 myErrorMessage = QStringLiteral(
"Info: NamedLayer element not found." );
1570 return myErrorMessage;
1574 resultFlag =
readSld( namedLayerElem, errorMsg );
1577 myErrorMessage = tr(
"Loading style file %1 failed because:\n%2" ).arg( uri, errorMsg );
1578 return myErrorMessage;
1587 Q_UNUSED( errorMessage )
1589 Q_UNUSED( categories )
1598 Q_UNUSED( errorMessage )
1600 Q_UNUSED( categories )
1606 Q_UNUSED( dataSource )
1607 Q_UNUSED( baseName )
1608 Q_UNUSED( provider )
1610 Q_UNUSED( loadDefaultStyleFlag )
1620 QgsMapLayer::StyleCategories categories )
1625 QDomElement renderer3DElem = layerElement.firstChildElement( QStringLiteral(
"renderer-3d" ) );
1626 if ( !renderer3DElem.isNull() )
1628 QString type3D = renderer3DElem.attribute( QStringLiteral(
"type" ) );
1648 setScaleBasedVisibility( layerElement.attribute( QStringLiteral(
"hasScaleBasedVisibilityFlag" ) ).toInt() == 1 );
1649 if ( layerElement.hasAttribute( QStringLiteral(
"minimumScale" ) ) )
1652 setMaximumScale( layerElement.attribute( QStringLiteral(
"minimumScale" ) ).toDouble() );
1653 setMinimumScale( layerElement.attribute( QStringLiteral(
"maximumScale" ) ).toDouble() );
1657 setMaximumScale( layerElement.attribute( QStringLiteral(
"maxScale" ) ).toDouble() );
1658 setMinimumScale( layerElement.attribute( QStringLiteral(
"minScale" ) ).toDouble() );
1665 QDomElement flagsElem = layerElement.firstChildElement( QStringLiteral(
"flags" ) );
1666 LayerFlags
flags = mFlags;
1667 auto enumMap = qgsEnumMap<QgsMapLayer::LayerFlag>();
1668 for (
auto it = enumMap.constBegin(); it != enumMap.constEnd(); ++it )
1670 QDomNode flagNode = flagsElem.namedItem( it.value() );
1671 if ( flagNode.isNull() )
1673 bool flagValue = flagNode.toElement().text() ==
"1" ? true :
false;
1674 if (
flags.testFlag( it.key() ) && !flagValue )
1676 else if ( !
flags.testFlag( it.key() ) && flagValue )
1695 return mUndoStackStyles;
1700 return mCustomProperties.
keys();
1705 mCustomProperties.
setValue( key, value );
1710 mCustomProperties = properties;
1715 return mCustomProperties;
1720 return mCustomProperties.
value( value, defaultValue );
1725 mCustomProperties.
remove( key );
1755 const QString path = sourceParts.value( QStringLiteral(
"path" ) ).toString();
1756 if ( path.isEmpty() )
1760 const QStringList tempPaths = QStandardPaths::standardLocations( QStandardPaths::TempLocation );
1761 for (
const QString &tempPath : tempPaths )
1763 if ( path.startsWith( tempPath ) )
1785 mLegend->setParent(
this );
1799 return mStyleManager;
1804 if ( renderer == m3DRenderer )
1808 m3DRenderer = renderer;
1819 if ( mRepaintRequestedFired )
1822 mRepaintRequestedFired =
true;
1824 mRepaintRequestedFired =
false;
1854 bool QgsMapLayer::isReadOnly()
const
1861 return mOriginalXmlProperties;
1872 QString uuid = QUuid::createUuid().toString();
1874 QString
id = layerName +
'_' + uuid.mid( 1, uuid.length() - 2 );
1881 id.replace( QRegExp(
"[\\W]" ), QStringLiteral(
"_" ) );
1902 QSet<QgsMapLayerDependency> deps;
1903 const auto constODeps = oDeps;
1933 void QgsMapLayer::onNotifiedTriggerRepaint(
const QString &message )