OWS.py 7.8 KB

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