5

Is there a way to create QGIS project file(.qgs) using only Python script outside QGIS Python console. I am trying to publish a map using QGIS Web Client using python.

For this, I am trying to do below

  1. Create .qgs file dynamically
  2. Add Legend and Layers to the .qgs file and save
  3. Set WFS,WCS parameters in the .qgs file

Finally use this file to view QGIS web client.

I tried to tweak the tool available at https://github.com/oware/Mxd2Qgs. I am successful to certain extent, i.e. creating a .qgs file. But I need some inputs on Getting layer (vector/raster) properties when path for the files is given.

code below

# Import system modules
from xml.dom.minidom import Document
import string
import os
import glob


#Read input parameters from GP dialog
output = "myworld.qgs"

#Create an output qgs file
f = open(output, "w")

# Create the minidom
doc = Document()

# Create the <qgis> base element
qgis = doc.createElement("qgis")
qgis.setAttribute("projectname", " ")
qgis.setAttribute("version", "2.4.0-Chugiak")
doc.appendChild(qgis)

# Create the <title> element
title = doc.createElement("title")
qgis.appendChild(title)


unit = doc.createTextNode("degrees")
xmin1 = doc.createTextNode(str("-180"))
ymin1 = doc.createTextNode(str("-90"))
xmax1 = doc.createTextNode(str("180"))
ymax1 = doc.createTextNode(str("90"))
proj4id = doc.createTextNode(str("+proj=longlat +datum=WGS84 +no_defs"))
srid1 = doc.createTextNode(str("4326"))
srid2 = doc.createTextNode(str("3452"))
epsg1 = doc.createTextNode(str("4326"))
epsg2 = doc.createTextNode(str("4326"))
description1 = doc.createTextNode(str("WGS 84"))
description2 = doc.createTextNode(str("WGS 84"))
ellipsoidacronym1 = doc.createTextNode(str("WGS84"))
ellipsoidacronym2 = doc.createTextNode(str("WGS84"))
geographicflag1 = doc.createTextNode("true")
geographicflag2 = doc.createTextNode("true")
pa=doc.createTextNode("longlat")
authid2 = doc.createTextNode("EPSG:"+str("4326"))
authid3 = doc.createTextNode("EPSG:"+str("4326"))
count2=0
# mapcanvas
def map_canvas():
    # Create the <mapcanvas> element
    mapcanvas = doc.createElement("mapcanvas")
    qgis.appendChild(mapcanvas)

# Create the <units> element
units = doc.createElement("units")
units.appendChild(unit)
mapcanvas.appendChild(units)

# Create the <extent> element
extent = doc.createElement("extent")
mapcanvas.appendChild(extent)

# Create the <xmin> element
xmin = doc.createElement("xmin")
xmin.appendChild(xmin1)
extent.appendChild(xmin)

# Create the <ymin> element
ymin = doc.createElement("ymin")
ymin.appendChild(ymin1)
extent.appendChild(ymin)

# Create the <xmax> element
xmax = doc.createElement("xmax")
xmax.appendChild(xmax1)
extent.appendChild(xmax)

# Create the <ymax> element
ymax = doc.createElement("ymax")
ymax.appendChild(ymax1)
extent.appendChild(ymax)

# Create the <projections> element
projections = doc.createElement("projections")
mapcanvas.appendChild(projections)

# Create the <destinationsrs> element
destinationsrs = doc.createElement("destinationsrs")
mapcanvas.appendChild(destinationsrs)

# Create the <spatialrefsys> element
spatialrefsys = doc.createElement("spatialrefsys")
destinationsrs.appendChild(spatialrefsys)

# Create the <proj4> element
proj4 = doc.createElement("proj4")
proj4.appendChild(proj4id)
spatialrefsys.appendChild(proj4)

# Create the <srsid> element
srsid = doc.createElement("srsid")
srsid.appendChild(srid2)
spatialrefsys.appendChild(srsid)

# Create the <srid> element
srid = doc.createElement("srid")
srid.appendChild(srid1)
spatialrefsys.appendChild(srid)

# Create the <authid> element
authid = doc.createElement("authid")
authid.appendChild(authid2)
spatialrefsys.appendChild(authid)

# Create the <description> element
description = doc.createElement("description")
description.appendChild(description1)
spatialrefsys.appendChild(description)

# Create the <projectionacronym> element
projectionacronym = doc.createElement("projectionacronym")
spatialrefsys.appendChild(projectionacronym)
projectionacronym.appendChild(pa)

# Create the <ellipsoidacronym element
ellipsoidacronym = doc.createElement("ellipsoidacronym")
ellipsoidacronym.appendChild(ellipsoidacronym1)
spatialrefsys.appendChild(ellipsoidacronym)

# Create the <geographicflag> element
geographicflag = doc.createElement("geographicflag")
geographicflag.appendChild(geographicflag1)
spatialrefsys.appendChild(geographicflag)



# Legend
# Legend
def legend_func():
    global count2
    # Create the <legend> element
    legend = doc.createElement("legend")
    qgis.appendChild(legend)


for lyr in os.listdir(r"C:\Build\xyz\shapefiles"):
     if lyr.endswith('.shp'):
        count2=count2+1 
        print lyr
        print "\n"
        # Create the <legendlayer> element
        legendlayer = doc.createElement("legendlayer")
        legendlayer.setAttribute("open", "true")
        legendlayer.setAttribute("checked", "Qt::Checked")
        legendlayer.setAttribute("name",lyr)

        legend.appendChild(legendlayer)

        # Create the <filegroup> element
        filegroup = doc.createElement("filegroup")
        filegroup.setAttribute("open", "true")
        filegroup.setAttribute("hidden", "false")
        legendlayer.appendChild(filegroup)

        # Create the <legendlayerfile> element
        legendlayerfile = doc.createElement("legendlayerfile")
        legendlayerfile.setAttribute("isInOverview", "0")
        legendlayerfile.setAttribute("layerid", lyr+str(20110427170816078))
        legendlayerfile.setAttribute("visible", "1")
        filegroup.appendChild(legendlayerfile)


# Project Layers
def project_layers():  
    # Create the <projectlayers> element
    projectlayers = doc.createElement("projectlayers")
    count1=str(count2)
    projectlayers.setAttribute("layercount", count1)
    qgis.appendChild(projectlayers)

for lyr in os.listdir(r"C:\Build\xyz\shapefiles"):

    if lyr.endswith('.shp'):

        print lyr
        print "\n"
        ds = doc.createTextNode(str(r"C:\Build\xyz\shapefiles"+"\\"+lyr))
        #Tool fails here as there is dependency on ArcGIS
        #Is there a way to replace below 2 lines ,with equivalents from QGIS?
        geometry1 = arcpy.Describe(lyr)
        geometry2 = str(geometry1.shapeType)

        name1 = doc.createTextNode(lyr+str(20110427170816078))
        name2 = doc.createTextNode(lyr)

       # Create the <maplayer> element
        maplayer = doc.createElement("maplayer")
        maplayer.setAttribute("minimumScale", "0")
        maplayer.setAttribute("maximumScale", "1e+08")
        maplayer.setAttribute("minLabelScale", "0")
        maplayer.setAttribute("maxLabelScale", "1e+08")
        maplayer.setAttribute("geometry", geometry2)
        maplayer.setAttribute("type", "vector")
        maplayer.setAttribute("hasScaleBasedVisibilityFlag", "0")
        maplayer.setAttribute("scaleBasedLabelVisibilityFlag", "0")
        projectlayers.appendChild(maplayer)

        # Create the <id> element
        id = doc.createElement("id")
        id.appendChild(name1)
        maplayer.appendChild(id)

        # Create the <datasource> element
        datasource = doc.createElement("datasource")
        datasource.appendChild(ds)
        maplayer.appendChild(datasource)

        # Create the <layername> element
        layername = doc.createElement("layername")
        layername.appendChild(name2)
        maplayer.appendChild(layername)

        # Create the <srs> element
        srs = doc.createElement("srs")
        maplayer.appendChild(srs)

        # Create the <spatialrefsys> element
        spatialrefsys = doc.createElement("spatialrefsys")
        srs.appendChild(spatialrefsys)

        # Create the <proj4> element
        proj4 = doc.createElement("proj4")
        spatialrefsys.appendChild(proj4)

        # Create the <srsid> element
        srsid = doc.createElement("srsid")
        spatialrefsys.appendChild(srsid)

        # Create the <srid> element
        srid = doc.createElement("srid")
        srid.appendChild(srid2)
        spatialrefsys.appendChild(srid)


        # Create the <authid> element
        authid = doc.createElement("authid")
        authid.appendChild(authid3)
        spatialrefsys.appendChild(authid)


        # Create the <description> element
        description = doc.createElement("description")
        description.appendChild(description2)
        spatialrefsys.appendChild(description)


        # Create the <projectionacronym> element
        projectionacronym = doc.createElement("projectionacronym")
        spatialrefsys.appendChild(projectionacronym)

        # Create the <ellipsoidacronym element
        ellipsoidacronym = doc.createElement("ellipsoidacronym")
        ellipsoidacronym.appendChild(ellipsoidacronym2)
        spatialrefsys.appendChild(ellipsoidacronym)


        # Create the <geographicflag> element
        geographicflag = doc.createElement("geographicflag")
        geographicflag.appendChild(geographicflag2)
        spatialrefsys.appendChild(geographicflag)

        # Create the <transparencyLevelInt> element
        transparencyLevelInt = doc.createElement("transparencyLevelInt")
        transparency2 = doc.createTextNode("255")
        transparencyLevelInt.appendChild(transparency2)
        maplayer.appendChild(transparencyLevelInt)

        # Create the <customproperties> element
        customproperties = doc.createElement("customproperties")
        maplayer.appendChild(customproperties)

        # Create the <provider> element
        provider = doc.createElement("provider")
        provider.setAttribute("encoding", "System")
        ogr = doc.createTextNode("ogr")
        provider.appendChild(ogr)
        maplayer.appendChild(provider)

        # Create the <singlesymbol> element
        singlesymbol = doc.createElement("singlesymbol")
        maplayer.appendChild(singlesymbol)

        # Create the <symbol> element
        symbol = doc.createElement("symbol")
        singlesymbol.appendChild(symbol)

        # Create the <lowervalue> element
        lowervalue = doc.createElement("lowervalue")
        symbol.appendChild(lowervalue)

        # Create the <uppervalue> element
        uppervalue = doc.createElement("uppervalue")
        symbol.appendChild(uppervalue)

        # Create the <label> element
        label = doc.createElement("label")
        symbol.appendChild(label)

        # Create the <rotationclassificationfieldname> element
        rotationclassificationfieldname = doc.createElement("rotationclassificationfieldname")
        symbol.appendChild(rotationclassificationfieldname)

        # Create the <scaleclassificationfieldname> element
        scaleclassificationfieldname = doc.createElement("scaleclassificationfieldname")
        symbol.appendChild(scaleclassificationfieldname)

        # Create the <symbolfieldname> element
        symbolfieldname = doc.createElement("symbolfieldname")
        symbol.appendChild(symbolfieldname)

         # Create the <outlinecolor> element
        outlinecolor = doc.createElement("outlinecolor")
        outlinecolor.setAttribute("red", "88")
        outlinecolor.setAttribute("blue", "99")
        outlinecolor.setAttribute("green", "37")
        symbol.appendChild(outlinecolor)

         # Create the <outlinestyle> element
        outlinestyle = doc.createElement("outlinestyle")
        outline = doc.createTextNode("SolidLine")
        outlinestyle.appendChild(outline)
        symbol.appendChild(outlinestyle)

         # Create the <outlinewidth> element
        outlinewidth = doc.createElement("outlinewidth")
        width = doc.createTextNode("0.26")
        outlinewidth.appendChild(width)
        symbol.appendChild(outlinewidth)

         # Create the <fillcolor> element
        fillcolor = doc.createElement("fillcolor")
        fillcolor.setAttribute("red", "90")
        fillcolor.setAttribute("blue", "210")
        fillcolor.setAttribute("green", "229")
        symbol.appendChild(fillcolor)

         # Create the <fillpattern> element
        fillpattern = doc.createElement("fillpattern")
        fill = doc.createTextNode("SolidPattern")
        fillpattern.appendChild(fill)
        symbol.appendChild(fillpattern)

         # Create the <texturepath> element
        texturepath = doc.createElement("texturepath")
        texturepath.setAttribute("null", "1")
        symbol.appendChild(texturepath)



map_canvas()
legend_func()
project_layers()


#  Write to qgis file

try:
    f.write(doc.toprettyxml())
finally:
    f.close()

print 'Done'

2 Answers 2

5

Struggled a bit for last 2 days. Abandoned XML approach. Able to accomplish first 2 tasks.

Need to check how I can accomplish setting WFS,WCS parameters

  1. Create .qgs file dynamically
  2. Add Legend and Layers to the .qgs file and save
  3. Set WFS,WCS parameters in the .qgs file

code below

from xml.dom.minidom import Document
import string
import os
import sys
from qgis.core import *
from qgis.gui import *
from PyQt4.QtCore import *
from PyQt4.QtGui import QApplication
from PyQt4.QtXml import *


#Read input parameters from GP dialog
strProjetName = "C:/OSGeo4W/apache/htdocs/QGIS-Web-Client-master/projects/myworld.qgs"

  if os.path.isfile(strProjetName):
       os.remove(strProjetName)

  def add_Layers():
      QGISAPP = QgsApplication(sys.argv, True)     
      QgsApplication.setPrefixPath(r"C:\OSGeo4W\apps\qgis", True)
      QgsApplication.initQgis()     
      QgsProject.instance().setFileName(strProjetName)
      print QgsProject.instance().fileName()


for file1 in os.listdir(r"C:\myprojects\world"):
     if file1.endswith('.shp'):
         layer = QgsVectorLayer(r"C:\myprojects\world"+r"\\"+file1, file1, "ogr")
         print file1
         print layer.isValid()
         # Add layer to the registry
         QgsMapLayerRegistry.instance().addMapLayer(layer)


QgsProject.instance().write()
QgsApplication.exitQgis()

add_Layers()
0

I wasn't able to get the above code to work. I don't know if it's based on an older API or if it was run in QGIS, but here's some code that works as a standalone script. It uses rasters instead of vectors but the idea is the same.

import glob
import os
import sys
from qgis.core import (QgsProject, QgsRasterLayer,\
    QgsMapLayerRegistry, QgsApplication)
from qgis.gui import QgisInterface
from PyQt4.QtCore import QFileInfo

strProjectName = "my_project.qgs"
raster_directory = "/path/to/rasters/"

# start the qgis application
QgsApplication.setPrefixPath("/path/to/qgis", True)
qgs = QgsApplication([], False)
qgs.initQgis()

# start a project
project = QgsProject.instance()
project_path = QFileInfo(strProjectName)

# add files to the project and register them
for filename in glob.glob(raster_directory + "**jp2"):
    split_fname = os.path.split(filename)
    basename = os.path.splitext(split_fname[1])[0]
    layer = QgsRasterLayer(filename, basename)
    if not layer.isValid():
        print("file {} is not a valid raster file".format(split_fname[1]))
    # Add layer to the registry
    QgsMapLayerRegistry.instance().addMapLayer(layer)

# write the project file
project.write(project_path)

# stop qgis
qgs.exitQgis()

The QGIS API sure is a weird beast.

This answer talks a little about how to group things which is something you might be wanting to do if you're generating QGIS project files programmatically.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.