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
- Create
.qgs
file dynamically - Add Legend and Layers to the
.qgs
file and save - 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
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
- Create
.qgs
file dynamically - Add Legend and Layers to the
.qgs
file and save - 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()
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.
-
QgsMapLayerRegistry has been deprecated, use QgsProject. To get this to work on MacOS you need to edit your .bash_profile as described here: gis.stackexchange.com/questions/291579/…thayer– thayer2019年11月05日 15:16:29 +00:00Commented Nov 5, 2019 at 15:16