OWS.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. import urlparse
  4. import urllib
  5. from lxml import objectify
  6. import os,sys
  7. import tempfile
  8. import logging
  9. import ConfigParser
  10. import md5
  11. import mapscript
  12. from string import Template
  13. from owslib.wfs import WebFeatureService
  14. class OWS:
  15. capabilities = None
  16. url = None
  17. requestUrl = None
  18. mapobj = None
  19. qstring = None
  20. owsns11 = "http://www.opengis.net/ows/1.1"
  21. owsns = "http://www.opengis.net/ows"
  22. cachedir = None
  23. mapfileName = "mapfile.map"
  24. config = None
  25. parsedUrl = None
  26. service = None
  27. mapfilename = None
  28. def __init__(self,url=None,qstring=None,configFile=None):
  29. self.requestUrl = url
  30. if url:
  31. self.url = url
  32. self.__getCapabilities()
  33. if qstring:
  34. self.qstring = qstring
  35. configFiles = [
  36. os.path.join(os.path.dirname(__file__),"config.cfg")
  37. ]
  38. if sys.platform == "win32":
  39. pass # TODO Default conf. file on windows platform
  40. elif sys.platform == "linux2":
  41. configFiles.append("/etc/owsviewer.cfg")
  42. if configFile:
  43. configFiles.append(configFile)
  44. self.config = ConfigParser.ConfigParser()
  45. self.config.read(configFiles)
  46. logging.debug("Creating cachedir for %s in %s" % (self.url,self.config.get("OWSProxy","cachedir")))
  47. logging.debug("%s initialized"%self.service)
  48. def __getCapabilities(self):
  49. self.parsedUrl = urlparse.urlparse(self.url)
  50. self.capabilities = WebFeatureService(url=self.url)
  51. def getParams(self):
  52. return urlparse.parse_qs(self.qstring)
  53. def getOnlineResource(self,onlineresource,mapfilename=None):
  54. o = urlparse.urlparse(onlineresource)
  55. params = urlparse.parse_qs(o.query,keep_blank_values=True)
  56. params["owsUrl"] = self.url
  57. params["owsService"] = self.service
  58. params["map"] = self.getMapfileLocation(mapfilename)
  59. location = urlparse.urlunparse((o[0],o[1],o[2],o[3],urllib.urlencode(params,True),o[5]))
  60. logging.debug("Setting OnlineResource to %s"% location)
  61. return location
  62. def getMapfileLocation(self,mapfilename=None):
  63. # save the map if possible
  64. if mapfilename:
  65. mapfilename.replace("..","") # remove potential path change
  66. # mapfile must end with .map and cachedir must be at the
  67. # beginning of the mapfile name
  68. if mapfilename.endswith(".map") and \
  69. mapfilename.find(self.cachedir) == 0:
  70. return mapfilename
  71. else:
  72. # do not save anything
  73. return
  74. # save to new location otherwice
  75. else:
  76. return os.path.join(self.cachedir,self.mapfileName)
  77. def __getCacheDir(self):
  78. self.cachedir = tempfile.mkdtemp(prefix="%s-%s"%(self.service,
  79. md5.new(self.url).hexdigest()),
  80. dir=self.config.get("OWSProxy","cachedir"))
  81. os.chmod(self.cachedir, 0777)
  82. logging.debug("Cachedir %s created" % self.cachedir)
  83. open(os.path.join(self.cachedir,"url.txt"),"w").write(self.url)
  84. return self.cachedir
  85. def performRequest(self):
  86. request = mapscript.OWSRequest()
  87. request.loadParams()
  88. mapobj = None
  89. self.request=request.getValueByName("REQUEST")
  90. # if no 'map' parameter in URL, create new mapfile
  91. if not request.getValueByName("map"):
  92. logging.debug("Creating new mapfile")
  93. mapobj = self.makeMap()
  94. else:
  95. # there is 'map' parameter in URL and the file exists, load it
  96. logging.debug("Using existing mapfile %s" % request.getValueByName("map"))
  97. if os.path.isfile(request.getValueByName("map")):
  98. mapobj = mapscript.mapObj(request.getValueByName("map"))
  99. # there is 'map' parameter in URL BUT the file does not exist:
  100. # create
  101. else:
  102. mapobj = self.makeMap(request.getValueByName("map"))
  103. mapobj.OWSDispatch(request)
  104. def getMapObj(self,mapfilename=None):
  105. self.__getCacheDir()
  106. if self.url is not None and self.capabilities is None:
  107. self.__getCapabilities()
  108. mapobj = mapscript.mapObj()
  109. mapobj.setMetaData("wms_onlineresource",self.getOnlineResource(self.config.get("MapServer","onlineresource"),mapfilename))
  110. logging.debug("Setting SRS to %s"%self.config.get("MapServer","srs"))
  111. mapobj.setMetaData("wms_srs",self.config.get("MapServer","srs"))
  112. mapobj.setProjection("init=epsg:4326")
  113. mapobj.setSize(500,500)
  114. mapobj.setExtent(-180,-90,90,180)
  115. mapobj.shapepath = self.cachedir
  116. logging.debug("Setting ERRORFILE to %s"%self.config.get("MapServer","errorfile"))
  117. if not os.path.exists(self.config.get("MapServer","errorfile")):
  118. tmp = open(self.config.get("MapServer","errorfile"),"w")
  119. tmp.close()
  120. if os.access(self.config.get("MapServer","errorfile"), os.W_OK):
  121. mapobj.setConfigOption("MS_ERRORFILE",self.config.get("MapServer","errorfile"))
  122. else:
  123. logging.warning("Cannot set ERRORFILE to %s: %s "%\
  124. (self.config.get("MapServer","errorfile"),"Write access denided"))
  125. logging.debug("Setting IMAGEPATH to %s"%self.config.get("MapServer","imagepath"))
  126. mapobj.web.imagepath=self.config.get("MapServer","imagepath")
  127. mapobj.setMetaData("ows_enable_request","*")
  128. return mapobj
  129. def saveMapfile(self,mapobj,mapfilename):
  130. self.mapfilename = self.getMapfileLocation(mapfilename)
  131. if self.mapfilename:
  132. # save mapfile ONLY if GetCapabilities requested - it makes no
  133. # sense for other cases
  134. logging.info("Saving mapfile to %s" % self.mapfilename)
  135. mapobj.save(self.mapfilename)
  136. else:
  137. logging.info("Mapfile NOT saved")
  138. return self.mapfilename
  139. def getLayerUrl(self):
  140. layerurl = self.url
  141. if self.url.find("?") > -1:
  142. if not self.url.endswith("?") and\
  143. not self.url.endswith("&"):
  144. layerurl += "&"
  145. else:
  146. layerurl += "?"
  147. return layerurl
  148. def createLayerDefinitionFile(self, name,
  149. templatefile,time=None,target=None):
  150. layerurl = self.getLayerUrl()
  151. defFileName = None
  152. if target:
  153. defFileName = target
  154. else:
  155. defFileName = os.path.join(self.cachedir,'%s.%s'%(name,self.service.lower()))
  156. if time:
  157. time = "<DefaultTime>"+time+"</DefaultTime>"
  158. else:
  159. time = ""
  160. open(defFileName,'w').write(
  161. Template(open(templatefile).read()).substitute(
  162. dict(url= layerurl, name=name,time=time)))
  163. logging.debug("Created %s layer definition file" % defFileName)
  164. return defFileName
  165. def getService():
  166. qstring = os.environ["QUERY_STRING"]
  167. params = urlparse.parse_qs(qstring)
  168. owsUrl = urllib.unquote(params["owsUrl"][0])
  169. if params["owsService"][0].lower() == "wfs":
  170. from wfs import WFS
  171. return WFS(owsUrl,qstring)
  172. elif params["owsService"][0].lower() == "wcs":
  173. from wcs import WCS
  174. return WCS(owsUrl,qstring)