25 #include <QDomDocument>
26 #include <QDomElement>
27 #include <QDomImplementation>
28 #include <QTextStream>
48 mDataSource( source ),
49 mLayerOrigName( lyrname ),
52 mBlendMode( QPainter::CompositionMode_SourceOver )
62 QDateTime dt = QDateTime::currentDateTime();
63 mID = lyrname + dt.toString(
"yyyyMMddhhmmsszzz" );
70 mID.replace( QRegExp(
"[\\W]" ),
"_" );
102 QgsDebugMsg(
"new original name: '" + name +
"'" );
151 Q_UNUSED( rendererContext );
157 Q_UNUSED( rendererContext );
171 mnl = layerElement.namedItem(
"provider" );
172 mne = mnl.toElement();
173 provider = mne.text();
176 mnl = layerElement.namedItem(
"datasource" );
177 mne = mnl.toElement();
181 if ( provider ==
"spatialite" )
187 else if ( provider ==
"ogr" )
189 QStringList theURIParts =
mDataSource.split(
"|" );
193 else if ( provider ==
"delimitedtext" )
195 QUrl urlSource = QUrl::fromEncoded(
mDataSource.toAscii() );
200 urlSource.setScheme(
"file" );
201 urlSource.setPath( file.path() );
204 QUrl urlDest = QUrl::fromLocalFile(
QgsProject::instance()->readPath( urlSource.toLocalFile() ) );
205 urlDest.setQueryItems( urlSource.queryItems() );
206 mDataSource = QString::fromAscii( urlDest.toEncoded() );
208 else if ( provider ==
"wms" )
223 QgsDebugMsg(
"Old WMS URI format detected -> converting to new format" );
228 QStringListIterator iter( parts );
229 while ( iter.hasNext() )
231 QString item = iter.next();
232 if ( item.startsWith(
"username=" ) )
234 uri.
setParam(
"username", item.mid( 9 ) );
236 else if ( item.startsWith(
"password=" ) )
238 uri.
setParam(
"password", item.mid( 9 ) );
240 else if ( item.startsWith(
"tiled=" ) )
246 QStringList params = item.mid( 6 ).split(
";" );
248 if ( params.size() == 2 )
250 uri.
setParam(
"maxWidth", params.takeFirst() );
251 uri.
setParam(
"maxHeight", params.takeFirst() );
253 else if ( params.size() > 2 )
257 uri.
setParam(
"tileMatrixSet",
"" );
260 else if ( item.startsWith(
"featureCount=" ) )
262 uri.
setParam(
"featureCount", item.mid( 13 ) );
264 else if ( item.startsWith(
"url=" ) )
266 uri.
setParam(
"url", item.mid( 4 ) );
268 else if ( item.startsWith(
"ignoreUrl=" ) )
270 uri.
setParam(
"ignoreUrl", item.mid( 10 ).split(
";" ) );
293 mnl = layerElement.namedItem(
"layername" );
294 mne = mnl.toElement();
296 QDomNode srsNode = layerElement.namedItem(
"srs" );
308 layerError = !
readXml( layerElement );
327 mnl = layerElement.namedItem(
"id" );
328 if ( ! mnl.isNull() )
330 mne = mnl.toElement();
331 if ( ! mne.isNull() && mne.text().length() > 10 )
343 mnl = layerElement.namedItem(
"layername" );
344 mne = mnl.toElement();
348 QDomElement titleElem = layerElement.firstChildElement(
"title" );
349 if ( !titleElem.isNull() )
351 mTitle = titleElem.text();
355 QDomElement abstractElem = layerElement.firstChildElement(
"abstract" );
356 if ( !abstractElem.isNull() )
362 QDomElement keywordListElem = layerElement.firstChildElement(
"keywordList" );
363 if ( !keywordListElem.isNull() )
366 for ( QDomNode n = keywordListElem.firstChild(); !n.isNull(); n = n.nextSibling() )
368 kwdList << n.toElement().text();
374 QDomElement dataUrlElem = layerElement.firstChildElement(
"dataUrl" );
375 if ( !dataUrlElem.isNull() )
382 QDomElement attribElem = layerElement.firstChildElement(
"attribution" );
383 if ( !attribElem.isNull() )
390 QDomElement metaUrlElem = layerElement.firstChildElement(
"metadataUrl" );
391 if ( !metaUrlElem.isNull() )
400 QDomNode transparencyNode = layer_node.namedItem(
"transparencyLevelInt" );
401 if ( ! transparencyNode.isNull() )
405 QDomElement myElement = transparencyNode.toElement();
406 setTransparency( myElement.text().toInt() );
418 Q_UNUSED( layer_node );
430 layerElement.setAttribute(
"minimumScale", QString::number(
minimumScale() ) );
431 layerElement.setAttribute(
"maximumScale", QString::number(
maximumScale() ) );
434 QDomElement layerId = document.createElement(
"id" );
435 QDomText layerIdText = document.createTextNode(
id() );
436 layerId.appendChild( layerIdText );
438 layerElement.appendChild( layerId );
441 QDomElement dataSource = document.createElement(
"datasource" );
456 QStringList theURIParts = src.split(
"|" );
458 src = theURIParts.join(
"|" );
460 else if ( vlayer && vlayer->
providerType() ==
"delimitedtext" )
462 QUrl urlSource = QUrl::fromEncoded( src.toAscii() );
463 QUrl urlDest = QUrl::fromLocalFile(
QgsProject::instance()->writePath( urlSource.toLocalFile() ) );
464 urlDest.setQueryItems( urlSource.queryItems() );
465 src = QString::fromAscii( urlDest.toEncoded() );
472 QDomText dataSourceText = document.createTextNode( src );
473 dataSource.appendChild( dataSourceText );
475 layerElement.appendChild( dataSource );
479 QDomElement layerName = document.createElement(
"layername" );
480 QDomText layerNameText = document.createTextNode(
originalName() );
481 layerName.appendChild( layerNameText );
484 QDomElement layerTitle = document.createElement(
"title" ) ;
485 QDomText layerTitleText = document.createTextNode(
title() );
486 layerTitle.appendChild( layerTitleText );
489 QDomElement layerAbstract = document.createElement(
"abstract" );
490 QDomText layerAbstractText = document.createTextNode(
abstract() );
491 layerAbstract.appendChild( layerAbstractText );
493 layerElement.appendChild( layerName );
494 layerElement.appendChild( layerTitle );
495 layerElement.appendChild( layerAbstract );
498 QStringList keywordStringList =
keywordList().split(
"," );
499 if ( keywordStringList.size() > 0 )
501 QDomElement layerKeywordList = document.createElement(
"keywordList" );
502 for (
int i = 0; i < keywordStringList.size(); ++i )
504 QDomElement layerKeywordValue = document.createElement(
"value" );
505 QDomText layerKeywordText = document.createTextNode( keywordStringList.at( i ).trimmed() );
506 layerKeywordValue.appendChild( layerKeywordText );
507 layerKeywordList.appendChild( layerKeywordValue );
509 layerElement.appendChild( layerKeywordList );
514 if ( !aDataUrl.isEmpty() )
516 QDomElement layerDataUrl = document.createElement(
"dataUrl" ) ;
517 QDomText layerDataUrlText = document.createTextNode( aDataUrl );
518 layerDataUrl.appendChild( layerDataUrlText );
520 layerElement.appendChild( layerDataUrl );
525 if ( !aAttribution.isEmpty() )
527 QDomElement layerAttribution = document.createElement(
"attribution" ) ;
528 QDomText layerAttributionText = document.createTextNode( aAttribution );
529 layerAttribution.appendChild( layerAttributionText );
531 layerElement.appendChild( layerAttribution );
536 if ( !aMetadataUrl.isEmpty() )
538 QDomElement layerMetadataUrl = document.createElement(
"metadataUrl" ) ;
539 QDomText layerMetadataUrlText = document.createTextNode( aMetadataUrl );
540 layerMetadataUrl.appendChild( layerMetadataUrlText );
543 layerElement.appendChild( layerMetadataUrl );
549 QDomElement stamp = document.createElement(
"timestamp" );
550 QDomText stampText = document.createTextNode(
timestamp().toString( Qt::ISODate ) );
551 stamp.appendChild( stampText );
552 layerElement.appendChild( stamp );
555 layerElement.appendChild( layerName );
562 QDomElement mySrsElement = document.createElement(
"srs" );
564 layerElement.appendChild( mySrsElement );
568 QDomElement transparencyLevelIntElement = document.createElement(
"transparencyLevelInt" );
569 QDomText transparencyLevelIntText = document.createTextNode( QString::number( getTransparency() ) );
570 transparencyLevelIntElement.appendChild( transparencyLevelIntText );
571 maplayer.appendChild( transparencyLevelIntElement );
578 return writeXml( layerElement, document );
585 Q_UNUSED( layer_node );
586 Q_UNUSED( document );
660 return QStringList();
700 settings.value(
"/qgis/capitaliseLayerName", QVariant(
false ) ).toBool();
702 QString layerName( name );
704 if ( capitaliseLayerName )
705 layerName = layerName.left( 1 ).toUpper() + layerName.mid( 1 );
715 if ( myURI.startsWith(
"/vsigzip/", Qt::CaseInsensitive ) )
717 myURI.remove( 0, 9 );
719 else if ( myURI.startsWith(
"/vsizip/", Qt::CaseInsensitive ) &&
720 myURI.endsWith(
".zip", Qt::CaseInsensitive ) )
723 myURI.remove( 0, 8 );
725 else if ( myURI.startsWith(
"/vsitar/", Qt::CaseInsensitive ) &&
726 ( myURI.endsWith(
".tar", Qt::CaseInsensitive ) ||
727 myURI.endsWith(
".tar.gz", Qt::CaseInsensitive ) ||
728 myURI.endsWith(
".tgz", Qt::CaseInsensitive ) ) )
731 myURI.remove( 0, 8 );
734 QFileInfo myFileInfo( myURI );
737 if ( myFileInfo.exists() )
740 if ( myURI.endsWith(
".gz", Qt::CaseInsensitive ) )
742 else if ( myURI.endsWith(
".zip", Qt::CaseInsensitive ) )
744 else if ( myURI.endsWith(
".tar", Qt::CaseInsensitive ) )
746 else if ( myURI.endsWith(
".tar.gz", Qt::CaseInsensitive ) )
748 else if ( myURI.endsWith(
".tgz", Qt::CaseInsensitive ) )
750 else if ( myURI.endsWith(
".gz", Qt::CaseInsensitive ) )
752 myFileInfo.setFile( myURI );
754 key = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() +
".qml";
771 QgsDebugMsg( QString(
"db = %1 uri = %2" ).arg( db ).arg( theURI ) );
773 bool theResultFlag =
false;
777 sqlite3_stmt *myPreparedStatement;
781 QgsDebugMsg( QString(
"Trying to load style for \"%1\" from \"%2\"" ).arg( theURI ).arg( db ) );
783 if ( !QFile( db ).exists() )
786 myResult = sqlite3_open_v2( db.toUtf8().data(), &myDatabase, SQLITE_OPEN_READONLY, NULL );
787 if ( myResult != SQLITE_OK )
792 QString mySql =
"select qml from tbl_styles where style=?";
793 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
794 if ( myResult == SQLITE_OK )
796 QByteArray param = theURI.toUtf8();
798 if ( sqlite3_bind_text( myPreparedStatement, 1, param.data(), param.length(), SQLITE_STATIC ) == SQLITE_OK &&
799 sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
801 qml = QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, 0 ) );
802 theResultFlag =
true;
805 sqlite3_finalize( myPreparedStatement );
808 sqlite3_close( myDatabase );
810 return theResultFlag;
817 theResultFlag =
false;
819 QDomDocument myDocument(
"qgis" );
823 QString myErrorMessage;
825 QFile myFile( theURI );
826 if ( myFile.open( QFile::ReadOnly ) )
829 theResultFlag = myDocument.setContent( &myFile, &myErrorMessage, &line, &column );
830 if ( !theResultFlag )
831 myErrorMessage =
tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
837 QgsDebugMsg( QString(
"project fileName: %1" ).arg( project.absoluteFilePath() ) );
841 ( project.exists() &&
loadNamedStyleFromDb( project.absoluteDir().absoluteFilePath( project.baseName() +
".qmldb" ), theURI, qml ) ) ||
844 theResultFlag = myDocument.setContent( qml, &myErrorMessage, &line, &column );
845 if ( !theResultFlag )
847 myErrorMessage =
tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
852 myErrorMessage =
tr(
"style not found in database" );
856 if ( !theResultFlag )
858 return myErrorMessage;
862 QgsProjectVersion fileVersion( myDocument.firstChildElement(
"qgis" ).attribute(
"version" ) );
865 if ( thisVersion > fileVersion )
868 "version of qgis (saved in " + fileVersion.text() +
870 "). Problems may occur." );
874 styleFile.updateRevision( thisVersion );
880 QDomElement myRoot = myDocument.firstChildElement(
"qgis" );
881 if ( myRoot.isNull() )
883 myErrorMessage =
tr(
"Error: qgis element could not be found in %1" ).arg( theURI );
884 theResultFlag =
false;
885 return myErrorMessage;
895 QDomNode transparencyNode = myRoot.namedItem(
"transparencyLevelInt" );
896 if ( ! transparencyNode.isNull() )
900 QDomElement myElement = transparencyNode.toElement();
901 setTransparency( myElement.text().toInt() );
907 if ( !theResultFlag )
909 myErrorMessage =
tr(
"Loading style file %1 failed because:\n%2" ).arg( theURI ).arg( errorMsg );
910 return myErrorMessage;
918 QDomImplementation DomImplementation;
919 QDomDocumentType documentType = DomImplementation.createDocumentType(
"qgis",
"http://mrcc.com/qgis.dtd",
"SYSTEM" );
920 QDomDocument myDocument( documentType );
922 QDomElement myRootNode = myDocument.createElement(
"qgis" );
924 myDocument.appendChild( myRootNode );
927 myRootNode.setAttribute(
"minimumScale", QString::number(
minimumScale() ) );
928 myRootNode.setAttribute(
"maximumScale", QString::number(
maximumScale() ) );
932 QDomElement transparencyLevelIntElement = myDocument.createElement(
"transparencyLevelInt" );
933 QDomText transparencyLevelIntText = myDocument.createTextNode( QString::number( getTransparency() ) );
934 transparencyLevelIntElement.appendChild( transparencyLevelIntText );
935 myRootNode.appendChild( transparencyLevelIntElement );
940 errorMsg =
QObject::tr(
"Could not save symbology because:\n%1" ).arg( errorMsg );
953 QString myErrorMessage;
954 QDomDocument myDocument;
965 QStringList theURIParts = theURI.split(
"|" );
966 filename = theURIParts[0];
968 else if ( vlayer && vlayer->
providerType() ==
"delimitedtext" )
970 filename = QUrl::fromEncoded( theURI.toAscii() ).toLocalFile();
977 QFileInfo myFileInfo( filename );
978 if ( myFileInfo.exists() || filename.endsWith(
".qml", Qt::CaseInsensitive ) )
980 QFileInfo myDirInfo( myFileInfo.path() );
981 if ( !myDirInfo.isWritable() )
983 return tr(
"The directory containing your dataset needs to be writable!" );
987 QString myFileName = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() +
".qml";
989 QFile myFile( myFileName );
990 if ( myFile.open( QFile::WriteOnly | QFile::Truncate ) )
992 QTextStream myFileStream( &myFile );
994 myDocument.save( myFileStream, 2 );
996 theResultFlag =
true;
997 return tr(
"Created default style file as %1" ).arg( myFileName );
1001 theResultFlag =
false;
1002 return tr(
"ERROR: Failed to created default style file as %1. Check file permissions and retry." ).arg( myFileName );
1007 QString qml = myDocument.toString();
1011 sqlite3_stmt *myPreparedStatement;
1016 if ( myResult != SQLITE_OK )
1018 return tr(
"User database could not be opened." );
1021 QByteArray param0 = theURI.toUtf8();
1022 QByteArray param1 = qml.toUtf8();
1024 QString mySql =
"create table if not exists tbl_styles(style varchar primary key,qml varchar)";
1025 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
1026 if ( myResult == SQLITE_OK )
1028 if ( sqlite3_step( myPreparedStatement ) != SQLITE_DONE )
1030 sqlite3_finalize( myPreparedStatement );
1031 sqlite3_close( myDatabase );
1032 theResultFlag =
false;
1033 return tr(
"The style table could not be created." );
1037 sqlite3_finalize( myPreparedStatement );
1039 mySql =
"insert into tbl_styles(style,qml) values (?,?)";
1040 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
1041 if ( myResult == SQLITE_OK )
1043 if ( sqlite3_bind_text( myPreparedStatement, 1, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
1044 sqlite3_bind_text( myPreparedStatement, 2, param1.data(), param1.length(), SQLITE_STATIC ) == SQLITE_OK &&
1045 sqlite3_step( myPreparedStatement ) == SQLITE_DONE )
1047 theResultFlag =
true;
1048 myErrorMessage =
tr(
"The style %1 was saved to database" ).arg( theURI );
1052 sqlite3_finalize( myPreparedStatement );
1054 if ( !theResultFlag )
1056 QString mySql =
"update tbl_styles set qml=? where style=?";
1057 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
1058 if ( myResult == SQLITE_OK )
1060 if ( sqlite3_bind_text( myPreparedStatement, 2, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
1061 sqlite3_bind_text( myPreparedStatement, 1, param1.data(), param1.length(), SQLITE_STATIC ) == SQLITE_OK &&
1062 sqlite3_step( myPreparedStatement ) == SQLITE_DONE )
1064 theResultFlag =
true;
1065 myErrorMessage =
tr(
"The style %1 was updated in the database." ).arg( theURI );
1069 theResultFlag =
false;
1070 myErrorMessage =
tr(
"The style %1 could not be updated in the database." ).arg( theURI );
1075 theResultFlag =
false;
1076 myErrorMessage =
tr(
"The style %1 could not be inserted into database." ).arg( theURI );
1079 sqlite3_finalize( myPreparedStatement );
1082 sqlite3_close( myDatabase );
1085 return myErrorMessage;
1090 QDomDocument myDocument = QDomDocument();
1092 QDomNode header = myDocument.createProcessingInstruction(
"xml",
"version=\"1.0\" encoding=\"UTF-8\"" );
1093 myDocument.appendChild( header );
1096 QDomElement root = myDocument.createElementNS(
"http://www.opengis.net/sld",
"StyledLayerDescriptor" );
1097 root.setAttribute(
"version",
"1.1.0" );
1098 root.setAttribute(
"xsi:schemaLocation",
"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" );
1099 root.setAttribute(
"xmlns:ogc",
"http://www.opengis.net/ogc" );
1100 root.setAttribute(
"xmlns:se",
"http://www.opengis.net/se" );
1101 root.setAttribute(
"xmlns:xlink",
"http://www.w3.org/1999/xlink" );
1102 root.setAttribute(
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance" );
1103 myDocument.appendChild( root );
1106 QDomElement namedLayerNode = myDocument.createElement(
"NamedLayer" );
1107 root.appendChild( namedLayerNode );
1112 errorMsg =
tr(
"Could not save symbology because:\n%1" )
1113 .arg(
"Non-vector layers not supported yet" );
1117 if ( !vlayer->
writeSld( namedLayerNode, myDocument, errorMsg ) )
1119 errorMsg =
tr(
"Could not save symbology because:\n%1" ).arg( errorMsg );
1129 QDomDocument myDocument;
1131 if ( !errorMsg.isNull() )
1133 theResultFlag =
false;
1143 QStringList theURIParts = theURI.split(
"|" );
1144 filename = theURIParts[0];
1148 filename = QUrl::fromEncoded( theURI.toAscii() ).toLocalFile();
1155 QFileInfo myFileInfo( filename );
1156 if ( myFileInfo.exists() || filename.endsWith(
".sld", Qt::CaseInsensitive ) )
1158 QFileInfo myDirInfo( myFileInfo.path() );
1159 if ( !myDirInfo.isWritable() )
1161 return tr(
"The directory containing your dataset needs to be writable!" );
1165 QString myFileName = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() +
".sld";
1167 QFile myFile( myFileName );
1168 if ( myFile.open( QFile::WriteOnly | QFile::Truncate ) )
1170 QTextStream myFileStream( &myFile );
1172 myDocument.save( myFileStream, 2 );
1174 theResultFlag =
true;
1175 return tr(
"Created default style file as %1" ).arg( myFileName );
1179 theResultFlag =
false;
1180 return tr(
"ERROR: Failed to created SLD style file as %1. Check file permissions and retry." ).arg( filename );
1187 theResultFlag =
false;
1189 QDomDocument myDocument;
1193 QString myErrorMessage;
1195 QFile myFile( theURI );
1196 if ( myFile.open( QFile::ReadOnly ) )
1199 theResultFlag = myDocument.setContent( &myFile,
true, &myErrorMessage, &line, &column );
1200 if ( !theResultFlag )
1201 myErrorMessage =
tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
1206 myErrorMessage =
tr(
"Unable to open file %1" ).arg( theURI );
1209 if ( !theResultFlag )
1211 return myErrorMessage;
1215 QDomElement myRoot = myDocument.firstChildElement(
"StyledLayerDescriptor" );
1216 if ( myRoot.isNull() )
1218 myErrorMessage = QString(
"Error: StyledLayerDescriptor element not found in %1" ).arg( theURI );
1219 theResultFlag =
false;
1220 return myErrorMessage;
1225 QDomElement namedLayerElem = myRoot.firstChildElement(
"NamedLayer" );
1226 if ( namedLayerElem.isNull() )
1228 myErrorMessage = QString(
"Info: NamedLayer element not found." );
1229 theResultFlag =
false;
1230 return myErrorMessage;
1234 theResultFlag =
readSld( namedLayerElem, errorMsg );
1235 if ( !theResultFlag )
1237 myErrorMessage =
tr(
"Loading style file %1 failed because:\n%2" ).arg( theURI ).arg( errorMsg );
1238 return myErrorMessage;
1268 QDomNode propsNode = layerNode.namedItem(
"customproperties" );
1269 if ( propsNode.isNull() )
1272 if ( !keyStartsWith.isEmpty() )
1275 QStringList keysToRemove;
1279 if ( pIt.key().startsWith( keyStartsWith ) )
1281 keysToRemove.push_back( pIt.key() );
1285 QStringList::const_iterator sIt = keysToRemove.constBegin();
1286 for ( ; sIt != keysToRemove.constEnd(); ++sIt )
1296 QDomNodeList nodes = propsNode.childNodes();
1298 for (
int i = 0; i < nodes.size(); i++ )
1300 QDomNode propNode = nodes.at( i );
1301 if ( propNode.isNull() || propNode.nodeName() !=
"property" )
1303 QDomElement propElement = propNode.toElement();
1305 QString key = propElement.attribute(
"key" );
1306 if ( key.isEmpty() || key.startsWith( keyStartsWith ) )
1308 QString value = propElement.attribute(
"value" );
1318 QDomNodeList propertyList = layerNode.toElement().elementsByTagName(
"customproperties" );
1319 for (
int i = 0; i < propertyList.size(); ++i )
1321 layerNode.removeChild( propertyList.at( i ) );
1324 QDomElement propsElement = doc.createElement(
"customproperties" );
1328 QDomElement propElement = doc.createElement(
"property" );
1329 propElement.setAttribute(
"key", it.key() );
1330 propElement.setAttribute(
"value", it.value().toString() );
1331 propsElement.appendChild( propElement );
1334 layerNode.appendChild( propsElement );