def modify_layer_customproperty(qgis_vector_layer_obj, property_name, value_string): XMLDocument = QDomDocument("style") XMLMapLayers = XMLDocument.createElement("maplayers") XMLMapLayer = XMLDocument.createElement("maplayer") qgis_vector_layer_obj.writeLayerXML(XMLMapLayer, XMLDocument) if XMLMapLayer.firstChildElement("customproperties").hasChildNodes(): properties = XMLMapLayer.firstChildElement( "customproperties").childNodes() for i in range(0, properties.size()): property_attr = properties.at(i).attributes().namedItem('key') value_attr = properties.at(i).attributes().namedItem('value') if property_attr.nodeValue() == property_name: value_attr.setNodeValue(value_string) XMLMapLayers.appendChild(XMLMapLayer) XMLDocument.appendChild(XMLMapLayers) logger.debug( "Layer's customproperty '{0}' modified to value '{1}'!".format( property_name, value_string)) else: logger.warning( "Layer's customproperty '{}' did not get modified!".format( property_name)) qgis_vector_layer_obj.readLayerXML(XMLMapLayer) qgis_vector_layer_obj.reload() return qgis_vector_layer_obj
def update_composer(self, composer_name=None, config_files=None): """ Update the composer specified by composer_name using settings from multiple configurations files. The configuration files must contain sections that have an "active=True" option otherwise are ignored Also, all option from sections or subsections are ignored if thei value is None They are in the configuration just to show what are all the properties of a specific composer item be aware some options are more tricky to set, for exmple a color qithy jost red value is invalid, you need to set all options (alpha, red, green, blue) :param composer_name: :param config_files: :return: """ merged_cfg = self.merge_configs(config_files=config_files) # sname is necessary because writeXML can not append to empty QDomDocument sname = 'update' temp_doc = QDomDocument() temp_el = temp_doc.createElement(sname) temp_doc.appendChild(temp_el) composition = self.get_composition_object(composer_name=composer_name) for k, v in merged_cfg.items(): item_id = v['ComposerItem'].pop('id') item = composition.getComposerItemById(item_id) item.writeXML(temp_el, temp_doc) item_xml_str = temp_doc.toString().replace( '<%s>' % sname, '').replace('</%s>' % sname, '').strip() lxml_el = xml_jano.etree.fromstring(item_xml_str) for e in lxml_el.iter(): #for every element if e.tag in v.sections: cfgs = v[e.tag] for an, av in e.items(): try: __ = eval(cfgs[an]) if __ is not None: raise NameError except KeyError: pass except (NameError, SyntaxError): e.set(an, cfgs[an]) new_xml_str = xml_jano.etree.tostring(lxml_el) tdoc = QDomDocument() tdoc.setContent(new_xml_str) tel = tdoc.documentElement() #update item.readXML(tel, tdoc) try: item.update() item.updateItem() except AttributeError: pass composition.refreshItems()
def save(self, qgis_project_file=None): """ :param qgis_project_file: :return: """ out_file = qgis_project_file or self.qprjf logger.info('Saving %s to %s ' % (self.qprjf, out_file)) logger.debug('...creating main "qgis" element') #root with attrs doc = QDomDocument() qgisNode = doc.createElement('qgis') qgisNode.setAttribute('projectname', self.qprj.title()) qgisNode.setAttribute('version', QGis.QGIS_VERSION) doc.appendChild(qgisNode) #title title_node = doc.createElement('title') titleText = doc.createTextNode(self.qprj.title()) title_node.appendChild(titleText) qgisNode.appendChild(title_node) logger.debug('...creating transaction element') #transaction, added in 2.16 transactionNode = doc.createElement('autotransaction') try: transactionNode.setAttribute('active', int(self.qprj.autoTransaction())) except AttributeError: # qgis version < 2.16 transactionNode.setAttribute('active', 0) qgisNode.appendChild(transactionNode) logger.debug('...creating evaluateDefaultValues element') #evaluate defaults evaluateDefaultValuesNode = doc.createElement('evaluateDefaultValues') try: evaluateDefaultValuesNode.setAttribute( 'active', int(self.qprj.evaluateDefaultValues())) except AttributeError: evaluateDefaultValuesNode.setAttribute('active', 0) qgisNode.appendChild(evaluateDefaultValuesNode) #layer tree element logger.debug('...creating layer tree element') util.introspect(self.canvas, namefilter='legend') self.qprj.layerTreeRoot().writeXML(qgisNode) #relations, logger.debug('...creating relations element') relations_el = doc.createElement('relations') for rn, r in self.qprj.relationManager().relations().items(): r.writeXML(relations_el, doc) qgisNode.appendChild(relations_el) logger.debug('...creating map canvas/map settings element') #now map canvas self.canvas.writeProject(doc) logger.debug( '...creating layer order element for new (>2.4 version) projects ') #canvas bridge for layer order in new style (after 2.4 version) self.canvas_bridge.writeProject(doc) #and it seesm there is old style legend order (before 2.4 version ) so I add this element as well for compatibility if self.canvas_bridge.hasCustomLayerOrder(): logger.debug( '...creating legend element for old style (<2.4 version) projects to specifiy layer order ' ) clorder = self.canvas_bridge.defaultLayerOrder() lelem = QgsLayerTreeUtils.writeOldLegend( doc, self.qprj.layerTreeRoot(), self.canvas_bridge.hasCustomLayerOrder(), clorder) qgisNode.appendChild(lelem) # now the composers for composer_name in self.composers: logger.debug('...creating composer %s' % composer_name) lxml_composer_el = self.qpath_extract_element( qpath='Composer[@title="%s"]' % composer_name) title = lxml_composer_el.get('title') visible = lxml_composer_el.get('visible') qt_composer_doc = QDomDocument() qt_composer_doc.setContent( '<Composer title="%s" visible="%s"></Composer>' % (title, visible)) composer_el = qt_composer_doc.documentElement() #print qt_composer_doc.toString() composition = self.get_composition_object( composer_name=composer_name) assert composition.writeXML( composer_el, qt_composer_doc), 'Failed to write composer %s' % composer_name qgisNode.appendChild(qt_composer_doc.documentElement()) #util.introspect(self.qprj.layerTreeRoot(), namefilter='layer') projectLayersNode = doc.createElement('projectlayers') logger.debug('...creating project layers element') for ml in self.canvas.layers(): maplayerElem = doc.createElement('maplayer') ml.writeLayerXML(maplayerElem, doc) self.qprj.emit(QtCore.SIGNAL('writeMapLayer'), ml, maplayerElem, doc) projectLayersNode.appendChild(maplayerElem) qgisNode.appendChild(projectLayersNode) #TODO find out how to read all the properties logger.debug('...creating project properties') prop_content = self.__fetch_properties__() prop_doc = QDomDocument() prop_doc.setContent(prop_content) qgisNode.appendChild(prop_doc.documentElement()) # util.introspect(self.qprj ) # print xml.etree.tostring(self.qpath_extract_element('/properties')) # print self.qprj.entryList('Digitizing', '') # print self.qprj.entryList('/', '') # print self.qprj.readEntry('Digitizing', 'SnappingMode') # print self.qprj.property('Digitizing') self.qprj.visibilityPresetCollection().writeXML(doc) # and finally save it fh = QFile(out_file) qts = QTextStream(fh) if not fh.open(QIODevice.WriteOnly): raise IOError, unicode(fh.errorString()) qts.setCodec('UTF-8') doc.save(qts, 2)