Skip to content

Commit

Permalink
Merged changes to the Qgis->MapServer export tool from the Qt4 Ui bra…
Browse files Browse the repository at this point in the history
…nch to HEAD.

This only affects the tools/mapserver_export directory.



git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@4306 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
gsherman committed Dec 9, 2005
1 parent 20bfa6b commit 3e6db6d
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 5 deletions.
203 changes: 203 additions & 0 deletions tools/mapserver_export/ms_export.py
@@ -0,0 +1,203 @@
# This class exports a QGIS project file to a mapserver .map file.
# All the work is done in the writeMapFile method. The msexport binary
# presents a Qt based GUI that collects the needed information for this
# script.
#
# CHANGES SHOULD NOT BE MADE TO THE writeMapFile METHOD UNLESS YOU
# ARE CHANGING THE QgsMapserverExport CLASS AND YOU KNOW WHAT YOU ARE
# DOING
import sys, string
from xml.dom import minidom, Node

class Qgis2Map:
def __init__(self, projectFile, mapFile):
self.project = projectFile
self.mapFile = mapFile
# create the DOM
self.qgs = minidom.parse(projectFile)
# init the other members that are not set by the constructor
self.units = ''
self.imageType = ''
self.mapName = ''
self.width = ''
self.height = ''
self.minScale = ''
self.maxScale = ''
self.template = ''
self.header = ''
self.footer = ''


# Set the options collected from the GUI
def setOptions(self, units, image, mapname, width, height, minscale, maxscale, template, header, footer):
self.units = units
self.imageType = image
self.mapName = mapname
self.width = width
self.height = height
self.minScale = minscale
self.maxScale = maxscale
self.template = template
self.header = header
self.footer = footer
#
## All real work happens here by calling methods to write the
## various sections of the map file
def writeMapFile(self):
# open the output file
self.outFile = open(self.mapFile, 'w')
# write the general map and web settings
self.writeMapSection()
# write the projection section
self.writeProjectionSection()
# write the output format section
self.writeOutputFormat()
# write the legend section
self.writeLegendSection()

# write the WEB section
self.writeWebSection()

# write the LAYER sections
self.writeMapLayers()

# close the map file
self.outFile.close()

ret = "Writing the map file using " + self.project + " " + self.mapFile
return ret
#, self.mapFile, self.project

# Write the general parts of the map section
def writeMapSection(self):
print "Writing header\n"
self.outFile.write("# Map file created from QGIS project file " + self.project + "\n")
self.outFile.write("# Edit this file to customize for your map interface\n")
self.outFile.write("MAP\n")
self.outFile.write(" NAME " + self.mapName + "\n")
self.outFile.write(" # Map image size\n")
self.outFile.write(" SIZE " + self.width + " " + self.height + "\n")
self.outFile.write(" UNITS '" + self.units + "'\n")
self.outFile.write("\n")
# extents
xmin = self.qgs.getElementsByTagName("xmin")
self.outFile.write(" EXTENT ")
self.outFile.write(xmin[0].childNodes[0].nodeValue.encode())
self.outFile.write(" ")
ymin = self.qgs.getElementsByTagName("ymin")
self.outFile.write(ymin[0].childNodes[0].nodeValue.encode())
self.outFile.write(" ")
xmax = self.qgs.getElementsByTagName("xmax")
self.outFile.write(xmax[0].childNodes[0].nodeValue.encode())
self.outFile.write(" ")
ymax = self.qgs.getElementsByTagName("ymax")
self.outFile.write(ymax[0].childNodes[0].nodeValue.encode())
self.outFile.write("\n")

# Write the OUTPUTFORMAT section
def writeOutputFormat(self):
self.outFile.write(" # Background color for the map canvas -- change as desired\n")
self.outFile.write(" IMAGECOLOR 255 255 255\n")
self.outFile.write(" IMAGETYPE " + self.imageType + "\n")
self.outFile.write(" OUTPUTFORMAT\n")
self.outFile.write(" NAME " + self.imageType + "\n")
self.outFile.write(" DRIVER 'GD/" + self.imageType.upper() + "'\n")
self.outFile.write(" MIMETYPE 'image/" + self.imageType.lower() + "'\n")
self.outFile.write(" IMAGEMODE PC256\n")
self.outFile.write(" EXTENSION '" + self.imageType.lower() + "'\n")
self.outFile.write(" END\n")


# Write Projection section
def writeProjectionSection(self):
# Need to get the destination srs from one of the map layers since
# the project file doesn't contain the epsg id or proj4 text for
# the map apart from that defined in each layer

self.outFile.write(" PROJECTION\n")

# Get the proj4 text from the first map layer's destination SRS
proj4Text = self.qgs.getElementsByTagName("destinationsrs")[0].getElementsByTagName("proj4")[0].childNodes[0].nodeValue.encode()
# the proj4 text string needs to be reformatted to make mapserver happy
self.outFile.write(self.formatProj4(proj4Text))

self.outFile.write(" END\n")

# Write the LEGEND section
def writeLegendSection(self):
self.outFile.write(" # Legend\n")
self.outFile.write(" LEGEND\n")
self.outFile.write(" IMAGECOLOR 255 255 255\n")
self.outFile.write(" STATUS ON\n")
self.outFile.write(" KEYSIZE 18 12\n")
self.outFile.write(" LABEL\n")
self.outFile.write(" TYPE BITMAP\n")
self.outFile.write(" SIZE MEDIUM\n")
self.outFile.write(" COLOR 0 0 89\n")
self.outFile.write(" END\n")
self.outFile.write(" END\n")

# Write the WEB section of the map file
def writeWebSection(self):
self.outFile.write("\n")
self.outFile.write(" # Web interface definition. Only the template parameter\n")
self.outFile.write(" # is required to display a map. See MapServer documentation\n")
self.outFile.write(" WEB\n")
self.outFile.write(" # Set IMAGEPATH to the path where MapServer should\n")
self.outFile.write(" # write its output.\n")
self.outFile.write(" IMAGEPATH '/tmp/'\n")
self.outFile.write("\n")
self.outFile.write(" # Set IMAGEURL to the url that points to IMAGEPATH\n")
self.outFile.write(" # as defined in your web server configuration\n")
self.outFile.write(" IMAGEURL '/map_output/'\n")
self.outFile.write("\n")

self.outFile.write(" # Template and header/footer settings\n")
self.outFile.write(" # Only the template parameter is required to display a map. See MapServer documentation\n")

self.outFile.write(" TEMPLATE " + self.template + "\n")
self.outFile.write(" HEADER " + self.header + "\n")
self.outFile.write(" FOOTER " + self.footer + "\n")
self.outFile.write(" END\n")

# Write the map layers
def writeMapLayers(self):
# get the list of maplayer nodes
maplayers = self.qgs.getElementsByTagName("maplayer")
for lyr in maplayers:
# The attributes of the maplayer tag contain the scale dependent settings,
# visibility, and layer type

self.outFile.write(" LAYER\n")
# write the name of the layer
self.outFile.write(" NAME '" + lyr.getElementsByTagName("layername")[0].childNodes[0].nodeValue.encode() + "'\n")
self.outFile.write(" TYPE '" + lyr.getAttribute("geometry").encode() + "'\n")
self.outFile.write(" STATUS ON\n")
self.outFile.write(" PROJECTION\n")
proj4Text = lyr.getElementsByTagName("proj4")[0].childNodes[0].nodeValue.encode()
self.outFile.write(self.formatProj4(proj4Text))



scaleDependent = lyr.getAttribute("scaleBasedVisibilityFlag").encode()
if scaleDependent == '1':
# get the min and max scale settings
minscale = lyr.getAttribute("minScale").encode()
maxscale = lyr.getAttribute("maxScale").encode()
if minscale > '':
self.outFile.write(" MINSCALE " + minscale + "\n")
if maxscale > '':
self.outFile.write(" MAXSCALE " + maxscale + "\n")

self.outFile.write(" END\n")


# Utility method to format a proj4 text string into mapserver format
def formatProj4(self, proj4text):
parms = proj4text.split(" ")
ret = ""
for p in parms:
p = p.replace("+","")
ret = ret + " '" + p + "'\n"
return ret

4 changes: 2 additions & 2 deletions tools/mapserver_export/msexport_wrap.cxx
Expand Up @@ -1355,9 +1355,9 @@ static swig_type_info *swig_types[10];
/*-----------------------------------------------
@(target):= _msexport.so
------------------------------------------------*/
#define SWIG_init initlibmsexport
#define SWIG_init init_msexport

#define SWIG_name "libmsexport"
#define SWIG_name "_msexport"

/* Includes the header in the wrapper code */
#include "qgsmapserverexport.h"
Expand Down
64 changes: 61 additions & 3 deletions tools/mapserver_export/qgsmapserverexport.cpp
Expand Up @@ -16,6 +16,7 @@ email : sherman at mrcc.com

#include <Python.h>

#include <iostream>
#include <QFileDialog>
#include <qfileinfo.h>
#include <qlineedit.h>
Expand Down Expand Up @@ -91,7 +92,65 @@ void QgsMapserverExport::on_chkExpLayersOnly_clicked(bool isChecked)
btnChooseHeaderFile->setEnabled(!isChecked);
btnChooseTemplateFile->setEnabled(!isChecked);
}
/** End of Slots **/

void QgsMapserverExport::on_buttonOk_clicked()
{

char *cstr;
PyObject *pstr, *pmod, *pclass, *pinst, *pmeth, *pargs;
//TODO Need to append the path to the qgis python files using the path to the
// Python files in the QGIS install directory
PyRun_SimpleString("import sys");
QString curdir = "/home/gsherman/development/qgis_qt_port/tools/mapserver_export";
QString sysCmd = QString("sys.path.append('%1')").arg(curdir);
PyRun_SimpleString(sysCmd.ascii());

// Import the module
std::cout << "Importing module" << std::endl;
pmod = PyImport_ImportModule("ms_export");

std::cout << "Getting Qgis2Map constructor as python obj" << std::endl;
pclass = PyObject_GetAttrString(pmod, "Qgis2Map");
Py_DECREF(pmod);
std::cout << "Creating args to pass to the constructor" << std::endl;
pargs = Py_BuildValue("(ss)", txtQgisFilePath->text().ascii(),txtMapFilePath->text().ascii());
//XXX for testing: pargs = Py_BuildValue("(ss)", "foo", "bar");

pinst = PyEval_CallObject(pclass, pargs);

Py_DECREF(pclass);
Py_DECREF(pargs);

// Set the various options for the conversion only if we are doing a full
// export (ie more than just layer info)
if(!chkExpLayersOnly->isChecked())
{
std::cout << "Initializing all options" << std::endl;
pmeth = PyObject_GetAttrString(pinst, "setOptions");
pargs = Py_BuildValue("(ssssssssss)",
cmbMapUnits->currentText().ascii(), cmbMapImageType->currentText().ascii(),
txtMapName->text().ascii(), txtMapWidth->text().ascii(), txtMapHeight->text().ascii(),
txtMinScale->text().ascii(), txtMaxScale->text().ascii(),
txtWebTemplate->text().ascii(), txtWebFooter->text().ascii(),txtWebHeader->text().ascii());
pstr = PyEval_CallObject(pmeth, pargs);

Py_DECREF(pargs);
Py_DECREF(pmeth);

}
// Get the writeMapFile method from the Qgis2Map class
pmeth = PyObject_GetAttrString(pinst, "writeMapFile");
pargs = Py_BuildValue("( )");
// Execute the writeMapFile method to parse the QGIS project file and create the .map file
pstr = PyEval_CallObject(pmeth, pargs);
// Show the return value
PyArg_Parse(pstr, "s", &cstr);
std::cout << cstr << std::endl;

Py_DECREF(pstr);

}
/** End of Auto-connected Slots **/

// Write the map file
bool QgsMapserverExport::write()
Expand Down Expand Up @@ -399,7 +458,6 @@ void QgsMapserverExport::initPy()
// init the python interpreter
Py_Initialize();
// spit something to stdout
PyRun_SimpleString("print '>>>>>>>>>>>>>>>>>>>This is from python in mapserverexport!'");

PyRun_SimpleString("print '>>>>>>>>>>>>>>>>>>> Python initialized <<<<<<<<<<<<<<<<<<<'");
}

1 change: 1 addition & 0 deletions tools/mapserver_export/qgsmapserverexport.h
Expand Up @@ -55,6 +55,7 @@ Q_OBJECT
void on_btnChooseFile_clicked();
void on_chkExpLayersOnly_clicked(bool);
void on_btnChooseProjectFile_clicked();
void on_buttonOk_clicked();
private:
void initPy();
void writeMapFile(void);
Expand Down
8 changes: 8 additions & 0 deletions tools/mapserver_export/test_export.py
@@ -0,0 +1,8 @@
#!/usr/bin/python

# test script to export a sample QGIS project file to mapserver
import ms_export
ex = ms_export.Qgis2Map('./lakes.qgs', './lakes.map')
ex.setOptions( 'Meters', 'PNG', 'TestMap', '800', '600', '','','template', 'header', 'footer')

ex.writeMapFile()

0 comments on commit 3e6db6d

Please sign in to comment.