Пример #1
0
def createAndParseSld(qgisLayerItem):
    document = QDomDocument()
    header = document.createProcessingInstruction(
        'xml', 'version=\'1.0\' encoding=\'UTF-8\'')
    document.appendChild(header)
    root = document.createElementNS('http://www.opengis.net/sld',
                                    'StyledLayerDescriptor')
    root.setAttribute('version', '1.0.0')
    root.setAttribute('xmlns:ogc', 'http://www.opengis.net/ogc')
    root.setAttribute('xmlns:sld', 'http://www.opengis.net/sld')
    root.setAttribute('xmlns:gml', 'http://www.opengis.net/gml')
    document.appendChild(root)

    namedLayerNode = document.createElement('sld:NamedLayer')
    root.appendChild(namedLayerNode)

    qgisLayerItem.layer.writeSld(namedLayerNode, document, '')

    nameNode = namedLayerNode.firstChildElement('se:Name')
    oldNameText = nameNode.firstChild()
    newname = qgisLayerItem.parentShogunLayer.source['layerNames']
    newNameText = document.createTextNode(newname)
    nameNode.appendChild(newNameText)
    nameNode.removeChild(oldNameText)

    userStyleNode = namedLayerNode.firstChildElement('UserStyle')
    userStyleNameNode = userStyleNode.firstChildElement('se:Name')
    userStyleNameText = userStyleNameNode.firstChild()
    userStyleNameNode.removeChild(userStyleNameText)
    userStyleNameNode.appendChild(
        document.createTextNode(qgisLayerItem.stylename))

    titleNode = document.createElement('sld:Title')
    title = document.createTextNode('A QGIS-Style for ' +
                                    qgisLayerItem.layer.name())
    titleNode.appendChild(title)
    userStyleNode.appendChild(titleNode)
    defaultNode = document.createElement('sld:IsDefault')
    defaultNode.appendChild(document.createTextNode('1'))
    userStyleNode.appendChild(defaultNode)

    featureTypeStyleNode = userStyleNode.firstChildElement(
        'se:FeatureTypeStyle')
    featureTypeStyleNameNode = document.createElement('sld:Name')
    featureTypeStyleNameNode.appendChild(document.createTextNode('name'))
    featureTypeStyleNode.appendChild(featureTypeStyleNameNode)

    rules = featureTypeStyleNode.elementsByTagName('se:Rule')
    for x in range(rules.length()):
        rule = rules.at(x)
        rule.removeChild(rule.firstChildElement('se:Description'))

    # Check if custom icons are used in symbology and replace the text:
    # search if tag 'se:OnlineResource' is in the sld document
    listOfGraphics = rule.toElement().elementsByTagName('se:OnlineResource')
    if not listOfGraphics.isEmpty():
        for x in range(listOfGraphics.length()):
            graphicNode = listOfGraphics.at(x)
            currentIcon = graphicNode.attributes().namedItem(
                'xlink:href').nodeValue()
            iconUrl = qgisLayerItem.ressource.prepareIconForUpload(currentIcon)
            graphicNode.toElement().setAttribute('xlink:href', iconUrl)
            graphicNode.toElement().setAttribute(
                'xmlns:xlink', 'http://www.w3.org/1999/xlink')

    sld = document.toString()

    # in qgis3 layer.writeSld() also incluedes labeling in the output sld,
    # whereas in qgis2 we have to do this manually by using this module's function
    # getLabelingAsSld
    ## TODO: The automatic sld labeling from QGIS 3 produces an extra rule for
    # every labeling style, thus leading to a less beautiful viewe in the
    # shogun2-webapp styler - is this a problem?

    if qgisLayerItem.layer.labelsEnabled() and PYTHON_VERSION < 3:
        labelSld = getLabelingAsSld(qgisLayerItem.layer)
        sld = sld.replace('</se:Rule>', labelSld + '</se:Rule>')

    sld = sld.replace('ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"',
                      'ogc:Filter')

    # the following fixes weird problems with the sld compability with the
    # shogun webapp
    sld = sld.replace('<ogc:And>', '')
    sld = sld.replace('</ogc:And>', '')
    sld = sld.replace('<se:Name> ', '<se:Name>')
    sld = sld.replace(' </se:Name>', '</se:Name>')

    sld = sld.replace('StyledLayerDescriptor', 'sld:StyledLayerDescriptor')
    sld = sld.replace('UserStyle', 'sld:UserStyle')
    sld = sld.replace('se:', 'sld:')
    sld = sld.replace('SvgParameter', 'CssParameter')
    sld = sld.replace('\n', '')
    sld = sld.replace('\t', '')

    return sld
Пример #2
0
def getStyleAsSld(layer, styleName):
    if layer.type() == layer.VectorLayer:
        document = QDomDocument()
        header = document.createProcessingInstruction("xml", "version=\"1.0\"")
        document.appendChild(header)

        root = document.createElementNS("http://www.opengis.net/sld",
                                        "StyledLayerDescriptor")
        root.setAttribute("version", "1.0.0")
        root.setAttribute("xmlns:ogc", "http://www.opengis.net/ogc")
        root.setAttribute("xmlns:sld", "http://www.opengis.net/sld")
        # root.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink" )
        # root.setAttribute(
        #     "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" )
        document.appendChild(root)

        namedLayerNode = document.createElement("sld:NamedLayer")
        root.appendChild(namedLayerNode)

        nameNode = document.createElement("sld:Name")
        featureTypeStyleElem = document.createElement("sld:FeatureTypeStyle")
        namedLayerNode.appendChild(nameNode)
        nameNode.appendChild(document.createTextNode(styleName))
        userNode = document.createElement("sld:UserStyle")
        namedLayerNode.appendChild(userNode)

        nameElem = document.createElement("sld:Name")
        nameElem.appendChild(document.createTextNode(styleName))
        userNode.appendChild(nameElem)
        titleElem = document.createElement("sld:Title")
        titleElem.appendChild(document.createTextNode(styleName))
        userNode.appendChild(titleElem)

        rule = layer.renderer().rootRule()
        props = {}  # QgsStringMap() can be see as a python dictionary
        rule_to_sld(rule, document, featureTypeStyleElem, props)
        userNode.appendChild(featureTypeStyleElem)

        return str(document.toString(4))
    elif layer.type() == layer.RasterLayer:
        renderer = layer.renderer()
        if isinstance(renderer, QgsSingleBandGrayRenderer):
            symbolizerCode = "<Opacity>%d</Opacity>" % renderer.opacity()
            symbolizerCode += (
                "<ChannelSelection><GrayChannel><SourceChannelName>" +
                str(renderer.grayBand()) +
                "</SourceChannelName></GrayChannel></ChannelSelection>")
            sld = RASTER_SLD_TEMPLATE.replace("SYMBOLIZER_CODE",
                                              symbolizerCode).replace(
                                                  "STYLE_NAME", layer.name())
            return sld
        elif isinstance(renderer, QgsSingleBandPseudoColorRenderer):
            symbolizerCode = "<ColorMap>"
            # band = renderer.usesBands()[0]
            items = \
                renderer.shader().rasterShaderFunction().colorRampItemList()
            for item in items:
                color = item.color
                rgb = '#%02x%02x%02x' % (color.red(), color.green(),
                                         color.blue())
                symbolizerCode += ('<ColorMapEntry color="' + rgb +
                                   '" quantity="' + str(item.value) + '" />')
            symbolizerCode += "</ColorMap>"
            sld = RASTER_SLD_TEMPLATE.replace("SYMBOLIZER_CODE",
                                              symbolizerCode).replace(
                                                  "STYLE_NAME", layer.name())
            return sld
        else:
            # we use some default styles in case we have an
            # unsupported renderer
            sldpath = os.path.join(os.path.dirname(__file__), "..",
                                   "resources")
            if layer.bandCount() == 1:
                sldfile = os.path.join(sldpath, "grayscale.sld")
            else:
                sldfile = os.path.join(sldpath, "rgb.sld")
            with open(sldfile, 'r', newline='') as f:
                sld = f.read()
            return sld
    else:
        return None