[Pywps-commits] r871 - in trunk: . pywps pywps/Process pywps/Wps

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Mon Nov 23 15:25:11 CET 2009


Author: jachym
Date: 2009-11-23 15:25:09 +0100 (Mon, 23 Nov 2009)
New Revision: 871

Modified:
   trunk/pywps/Process/InAndOutputs.py
   trunk/pywps/Wps/Execute.py
   trunk/pywps/default.cfg
   trunk/wps.py
Log:
basic support for OWS Services generated by UMN MapServer

Modified: trunk/pywps/Process/InAndOutputs.py
===================================================================
--- trunk/pywps/Process/InAndOutputs.py	2009-11-12 10:54:00 UTC (rev 870)
+++ trunk/pywps/Process/InAndOutputs.py	2009-11-23 14:25:09 UTC (rev 871)
@@ -33,7 +33,6 @@
     value = None
     ms = None # magic mimeTypes
 
-
     def __init__(self,identifier,title,abstract=None,
                 metadata=[],minOccurs=1,maxOccurs=1,type=None):
         """Input initialization
@@ -642,10 +641,14 @@
     """Complex value output"""
     formats = None
     format = None
+    projection = None
+    bbox = None
+    width = None
+    height = None
 
     def __init__(self,identifier,title,abstract=None,
                 metadata=[], formats=[{"mimeType":"text/xml"}],
-                asReference=False):
+                asReference=False, projection=None, bbox=None):
         """Complex output
 
         Mandatory parameters:
@@ -668,6 +671,10 @@
         asReference {Boolean} whether this output will be given back as
                 reference or as file
                 default: False
+        projection {String} proj4 text, used for the proj init parameter,
+                e.g. "epsg:4326", used for mapserver
+        bbox {Tupple} of 4 elements (minx,miny,maxx,maxy), used for
+                mapserver
         """
         Output.__init__(self,identifier,title,abstract=None,
                 metadata=[],type="ComplexValue", asReference=asReference)
@@ -685,6 +692,9 @@
 
         self.formats = formats
         self.format = formats[0]
+        
+        self.projection = projection
+        self.bbox = bbox
 
         self.ms = magic.open(magic.MAGIC_MIME)
         self.ms.load()
@@ -707,6 +717,7 @@
             raise Exception("Output type '%s' of '%s' output not known" %\
                     (type(value),self.identifier))
 
+
 class BoundingBoxOutput(Output):
     crss = None
     crs = None

Modified: trunk/pywps/Wps/Execute.py
===================================================================
--- trunk/pywps/Wps/Execute.py	2009-11-12 10:54:00 UTC (rev 870)
+++ trunk/pywps/Wps/Execute.py	2009-11-23 14:25:09 UTC (rev 871)
@@ -29,6 +29,11 @@
 from shutil import copyfile as COPY
 from shutil import rmtree as RMTREE
 
+try:
+    from mapscript import *
+except:
+    pass
+
 class Execute(Response):
     """
     This class performs the Execute request of WPS specification
@@ -75,7 +80,10 @@
     rawDataOutput = None
     logFile = None
 
+    mapObj = None
+    mapFileName = None
 
+
     def __init__(self,wps):
         """
         wps   - parent WPS instance
@@ -255,9 +263,46 @@
             # if succeeded
             if self.status == self.succeeded:
 
+                # mapscript support?
+                if mapObj:
+                    self.mapObj = mapObj()
+                    self.mapObj.setExtent(-180,-90,180,90)
+                    self.mapObj.setProjection("+init=epsg:4326")
+                    self.mapObj.name = "%s-%s"%(self.process.identifier,self.pid)
+                    self.mapObj.setMetaData("ows_title", self.wps.getConfigValue("wps","title"))
+                    self.mapObj.setMetaData("wms_abstract", self.wps.getConfigValue("wps","abstract"))
+                    self.mapObj.setMetaData("wcs_abstract", self.wps.getConfigValue("wps","abstract"))
+                    self.mapObj.setMetaData("wfs_abstract", self.wps.getConfigValue("wps","abstract"))
+                    self.mapObj.setMetaData("ows_keywordlist", self.wps.getConfigValue("wps","keywords"))
+                    self.mapObj.setMetaData("ows_fees", self.wps.getConfigValue("wps","fees"))
+                    self.mapObj.setMetaData("ows_accessconstraints", self.wps.getConfigValue("wps","constraints"))
+                    self.mapObj.setMetaData("ows_contactorganization", self.wps.getConfigValue("provider","providerName"))
+                    self.mapObj.setMetaData("ows_contactperson", self.wps.getConfigValue("provider","individualName"))
+                    self.mapObj.setMetaData("ows_contactposition", self.wps.getConfigValue("provider","positionName"))
+                    phone =  self.wps.getConfigValue("provider","phoneVoice")
+                    if phone:
+                        self.mapObj.setMetaData("ows_contactvoicetelephone", self.wps.getConfigValue("provider","phoneVoice"))
+                    phone = self.wps.getConfigValue("provider","phoneFacsimile")
+                    if phone:
+                        self.mapObj.setMetaData("ows_contactfacsimiletelephone", self.wps.getConfigValue("provider","phoneFacsimile"))
+                    self.mapObj.setMetaData("ows_address", self.wps.getConfigValue("provider","deliveryPoint"))
+                    self.mapObj.setMetaData("ows_city", self.wps.getConfigValue("provider","city"))
+                    self.mapObj.setMetaData("ows_country", self.wps.getConfigValue("provider","country"))
+                    self.mapObj.setMetaData("ows_postcode", self.wps.getConfigValue("provider","postalCode"))
+                    self.mapObj.setMetaData("ows_contactelectronicmailaddress", self.wps.getConfigValue("provider","electronicMailAddress"))
+                    self.mapObj.setMetaData("ows_role", self.wps.getConfigValue("provider","role"))
+
+                    self.mapFileName = os.path.join(self.wps.getConfigValue("server","outputPath"),"wps"+str(self.pid)+".map")
+
+                    self.mapObj.setMetaData("wms_onlineresource",self.wps.getConfigValue("mapserver","mapserveraddress")+"?map="+self.mapFileName)
+                else:
+                    self.wps.debug("GDAL could not be loaded, mapserver not supported","Warning")
+
                 # fill outputs
                 self.processOutputs()
+                self.mapObj.save(self.mapFileName)
 
+
                 # Response document
                 self.response = self.templateProcessor.process(self.template)
 
@@ -735,6 +780,7 @@
                         templateOutput = self._bboxOutput(output,templateOutput)
 
                 templateOutputs.append(templateOutput);
+
             except Exception,e:
                 self.cleanEnv()
                 traceback.print_exc(file=sys.stderr)
@@ -789,6 +835,7 @@
     def _asReferenceOutput(self,templateOutput, output):
 
         # copy the file to output directory
+        # literal value
         if output.type == "LiteralValue":
             f = open(os.path.join(
                         self.wps.getConfigValue("server","outputPath"),
@@ -797,6 +844,7 @@
             f.close()
             templateOutput["reference"] = self.wps.getConfigValue("server","outputUrl")+\
                     "/"+output.identifier+"-"+str(self.pid)
+        # complex value
         else:
             outName = output.value
             outSuffix = outName.split(".")[len(outName.split("."))-1]
@@ -806,12 +854,98 @@
                 COPY(output.value, outFile)
             templateOutput["reference"] = \
                     self.wps.getConfigValue("server","outputUrl")+"/"+outName
+            output.value = outFile
+
+            # mapscript supported
+            if self.mapObj:
+
+                # get projection and bounding box
+                if not output.projection or not output.bbox:
+                    try:
+                        from osgeo import gdal
+                        dataset = gdal.Open(output.value)
+                        if not output.projection:
+                            output.projection = dataset.GetProjection()
+                        if not output.projection:
+                            output.projection = self.mapObj.getProjection()
+                        if not output.bbox:
+                            geotransform = dataset.GetGeoTransform()
+                            output.bbox = (geotransform[0],
+                                        geotransform[3]+geotransform[5]*dataset.RasterYSize,
+                                        geotransform[0]+geotransform[1]*dataset.RasterXSize,
+                                        geotransform[3])
+                            output.width = dataset.RasterXSize
+                            output.height = dataset.RasterYSize
+
+                        myLayerObj = layerObj(self.mapObj)
+                        myLayerObj.setMetaData("wms_title", output.title)
+                        myLayerObj.setMetaData("wcs_label", output.title)
+                        myLayerObj.setMetaData("wfs_title", output.title)
+                        myLayerObj.group = self.process.identifier
+                        myLayerObj.setMetaData("wms_group_title",self.process.title)
+                        if self.process.abstract:
+                            myLayerObj.setMetaData("group_abstract",self.process.abstract)
+                        if output.abstract:
+                            myLayerObj.setMetaData("wms_abstract", output.abstract)
+                            myLayerObj.setMetaData("wcs_abstract", output.abstract)
+                            myLayerObj.setMetaData("wfs_abstract", output.abstract)
+                        myLayerObj.data = output.value
+                        myLayerObj.name = output.identifier
+
+                        if output.projection:
+                            myLayerObj.setProjection("epsg:4326")
+                        if output.bbox:
+                            myLayerObj.setExtent(output.bbox[0],output.bbox[1],output.bbox[2],output.bbox[3])
+
+                        # set the output to be WMS
+                        if output.format["mimeType"].find("tiff") == -1:
+                            templateOutput["reference"] = self._getMapServerWMS(output)
+                            myLayerObj.type = MS_LAYER_RASTER
+                        # make it WFS
+                        elif output.format["mimeType"].find("text")  > -1:
+                            templateOutput["reference"] = self._getMapServerWFS(output)
+                        # make it WCS
+                        else:
+                            myLayerObj.type = MS_LAYER_RASTER
+                            templateOutput["reference"] = self._getMapServerWCS(output)
+                    except ImportError:
+                        self.wps.debug("GDAL could not be loaded, mapserver not supported","Warning")
+
+ 
         templateOutput["mimetype"] = output.format["mimeType"]
         templateOutput["schema"] = output.format["encoding"]
         templateOutput["encoding"] = output.format["schema"]
 
         return templateOutput
 
+    def _getMapServerWMS(self,output):
+        """Get the URL for mapserver WMS request of the output"""
+        import urllib2
+        return urllib2.quote(self.wps.getConfigValue("mapserver","mapserveraddress")+
+                "?map="+self.mapFileName+
+                "&SERVICE=WMS"+ "&REQUEST=GetMap"+ "&VERSION=1.3.0"+
+                "&LAYERS="+output.identifier+"&STYLES=default&SRS="+output.projection.replace("+init=","")+
+                "&BBOX=%s,%s,%s,%s&"%(output.bbox[0],output.bbox[1],output.bbox[2],output.bbox[3])+
+                "&WIDTH=%s"%output.width+"&HEIGHT=%s"%output.height+"&FORMAT=%s"%output.format["mimeType"])
+
+    def _getMapServerWCS(self,output):
+        """Get the URL for mapserver WCS request of the output"""
+        import urllib2
+        return urllib2.quote(self.wps.getConfigValue("mapserver","mapserveraddress")+
+                "?map="+self.mapFileName+
+                "&SERVICE=WCS"+ "&REQUEST=GetCoverage"+ "&VERSION=1.0.0"+
+                "&COVERAGE="+output.identifier+"&CRS="+output.projection.replace("+init=","")+
+                "&BBOX=%s,%s,%s,%s&"%(output.bbox[0],output.bbox[1],output.bbox[2],output.bbox[3])+
+                "&WIDTH=%s"%output.width+"&HEIGHT=%s"%output.height+"&FORMAT=%s"%output.format["mimeType"])
+
+    def _getMapServerWFS(self,output):
+        """Get the URL for mapserver WFS request of the output"""
+        import urllib2
+        return urllib2.quote(self.wps.getConfigValue("mapserver","mapserveraddress")+
+                "?map="+self.mapFileName+
+                "&SERVICE=WFS"+ "&REQUEST=GetFeature"+ "&VERSION=1.0.0"+
+                "&TYPENAME="+output.identifier)
+
     def _samefile(self, src, dst):
         # Macintosh, Unix.
         if hasattr(os.path,'samefile'):
@@ -926,7 +1060,7 @@
         """
         os.chdir(self.curdir)
         def onError(*args):
-            print >>self.logFile, "PYWPS Error: Could not remove temporary dir"
+            self.wps.debug("Could not remove temporary dir","Error")
 
         for i in range(len(self.dirsToBeRemoved)):
             dir = self.dirsToBeRemoved[0]

Modified: trunk/pywps/default.cfg
===================================================================
--- trunk/pywps/default.cfg	2009-11-12 10:54:00 UTC (rev 870)
+++ trunk/pywps/default.cfg	2009-11-23 14:25:09 UTC (rev 871)
@@ -43,3 +43,8 @@
 gisbase=/usr/lib/grass/
 ldLibraryPath=/usr/lib/grass/lib
 gisdbase=grassdata/
+
+[mapserver]
+mapserveraddress=http://localhost/cgi-bin/mapserv
+projdatapath=/usr/lib/proj/
+projs=epsg:4326,epsg:102067,epsg:3059,epsg:900913

Modified: trunk/wps.py
===================================================================
--- trunk/wps.py	2009-11-12 10:54:00 UTC (rev 870)
+++ trunk/wps.py	2009-11-23 14:25:09 UTC (rev 871)
@@ -122,7 +122,7 @@
             restPath= os.getenv("PATH_INFO").split(os.sep)[1:]
         except:
             pass
-        print >>sys.stderr, serverPath, scriptName, restPath
+        self.debug("%s %s %s"% (serverPath, scriptName, restPath))
 
         # decide, which method to use
         # HTTP GET vs. HTTP POST
@@ -256,14 +256,14 @@
             value = True
         return value
 
-    def debug(self,debug):
+    def debug(self,debug,code="Debug"):
         """Print debug argument to standard error
         """
 
         dbg = self.getConfigValue("server","debug")
         if dbg == True or (type(dbg) == type("") and \
                 dbg.lower() == "true") or int(dbg) != 0:
-            print >>sys.stderr, "PyWPS Debug: %s" % debug.__str__()[0:160],
+            print >>sys.stderr, "PyWPS %s: %s" % (code,debug.__str__()[0:160]),
             if len(debug.__str__()) > 160:
                 print >>sys.stderr, "...",
             print >>sys.stderr, "\n"



More information about the Pywps-commits mailing list