OWS.py 8.1 KB

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