| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- #!/usr/bin/env python
- # coding=utf-8
- import urlparse
- import urllib
- from lxml import objectify
- import os,sys
- import tempfile
- import logging
- import ConfigParser
- import md5
- import mapscript
- from string import Template
- from osgeo import osr
- from osgeo import ogr
- class OWS:
- capabilities = None
- url = None
- requestUrl = None
- mapobj = None
- qstring = None
- owsns11 = "http://www.opengis.net/ows/1.1"
- owsns = "http://www.opengis.net/ows"
- cachedir = None
- mapfileName = "mapfile.map"
- config = None
- parsedUrl = None
- service = None
- mapfilename = None
- def __init__(self,url=None,qstring=None,configFile=None):
- self.requestUrl = url
- if url:
- self.url = url
- self.__getCapabilities()
- if qstring:
- self.qstring = qstring
- configFiles = [
- os.path.join(os.path.dirname(__file__),"config.cfg")
- ]
- if sys.platform == "win32":
- pass # TODO Default conf. file on windows platform
- elif sys.platform == "linux2":
- configFiles.append("/etc/owsviewer.cfg")
- if configFile:
- configFiles.append(configFile)
- self.config = ConfigParser.ConfigParser()
- self.config.read(configFiles)
- logging.debug("Creating cachedir for %s in %s" % (self.url,self.config.get("OWSProxy","cachedir")))
- logging.debug("%s initialized"%self.service)
- def __getCapabilities(self):
- self.parsedUrl = urlparse.urlparse(self.url)
- if self.service == "WFS":
- from owslib.wfs import WebFeatureService
- self.capabilities = WebFeatureService(url=self.url,version="1.1.0")
- logging.debug("OWS Capabilities: %s",self.capabilities)
- elif self.service == "WCS":
- from owslib.wcs import WebCoverageService
- self.capabilities = WebCoverageService(url=self.url,version="1.0.0")
- def getParams(self):
- return urlparse.parse_qs(self.qstring)
- def getOnlineResource(self,onlineresource,mapfilename=None):
- o = urlparse.urlparse(onlineresource)
- params = urlparse.parse_qs(o.query,keep_blank_values=True)
- params["owsUrl"] = self.url
- params["owsService"] = self.service
- params["map"] = self.getMapfileLocation(mapfilename)
- location = urlparse.urlunparse((o[0],o[1],o[2],o[3],urllib.urlencode(params,True),o[5]))
- logging.debug("Setting OnlineResource to %s"% location)
- return location
- def getMapfileLocation(self,mapfilename=None):
- # save the map if possible
- if mapfilename:
- mapfilename.replace("..","") # remove potential path change
- # mapfile must end with .map and cachedir must be at the
- # beginning of the mapfile name
- if mapfilename.endswith(".map") and \
- mapfilename.find(self.cachedir) == 0:
- return mapfilename
-
- else:
- # do not save anything
- return
- # save to new location otherwice
- else:
- return os.path.join(self.cachedir,self.mapfileName)
- def __getCacheDir(self):
-
- self.cachedir = tempfile.mkdtemp(prefix="%s-%s"%(self.service,
- md5.new(self.url).hexdigest()),
- dir=self.config.get("OWSProxy","cachedir"))
- os.chmod(self.cachedir, 0777)
- logging.debug("Cachedir %s created" % self.cachedir)
- open(os.path.join(self.cachedir,"url.txt"),"w").write(self.url)
- return self.cachedir
- def performRequest(self):
- request = mapscript.OWSRequest()
- request.loadParams()
- mapobj = None
- self.request=request.getValueByName("REQUEST")
- # if no 'map' parameter in URL, create new mapfile
- if not request.getValueByName("map"):
- logging.debug("Creating new mapfile")
- mapobj = self.makeMap()
- else:
- # there is 'map' parameter in URL and the file exists, load it
- logging.debug("Using existing mapfile %s" % request.getValueByName("map"))
- if os.path.isfile(request.getValueByName("map")):
- mapobj = mapscript.mapObj(request.getValueByName("map"))
- # there is 'map' parameter in URL BUT the file does not exist:
- # create
- else:
- mapobj = self.makeMap(request.getValueByName("map"))
- # WFS Filter encoding, if available
- if request.getValueByName("fes"):
- self.setFilter(mapobj,request)
- # mapobj.getLayerByName(request.getValueByName("layers")).metadata.get("wfs_filter")
- # here is still fine
- # but it fails here:
- mapobj.OWSDispatch(request)
- def getMapObj(self,mapfilename=None):
- self.__getCacheDir()
- if self.url is not None and self.capabilities is None:
- self.__getCapabilities()
- mapobj = mapscript.mapObj()
- mapobj.setMetaData("wms_onlineresource",self.getOnlineResource(self.config.get("MapServer","onlineresource"),mapfilename))
- logging.debug("Setting SRS to %s"%self.config.get("MapServer","srs"))
- mapobj.setMetaData("wms_srs",self.config.get("MapServer","srs"))
- mapobj.setProjection("init=epsg:4326")
- mapobj.setSize(500,500)
- mapobj.setExtent(-180,-90,90,180)
- mapobj.shapepath = self.cachedir
- mapobj.setMetaData("wms_encoding","utf-8")
- errfile = self.config.get("MapServer","errorfile")
- logging.debug("Setting ERRORFILE to %s"%errfile)
- if not os.path.exists(errfile) and errfile != "stderr":
- tmp = open(errfile,"w")
- tmp.close()
- # file
- if os.access(errfile, os.W_OK):
- mapobj.setConfigOption("MS_ERRORFILE",errfile)
- # stderr
- elif errfile == "stderr":
- mapobj.setConfigOption("MS_ERRORFILE",errfile)
- # no error file set
- else:
- logging.warning("Cannot set ERRORFILE to %s: %s " % (errfile,"Write access denided"))
- logging.debug("Setting IMAGEPATH to %s"%self.config.get("MapServer","imagepath"))
- mapobj.web.imagepath=self.config.get("MapServer","imagepath")
- mapobj.setMetaData("ows_enable_request","*")
- return mapobj
- def saveMapfile(self,mapobj,mapfilename):
- self.mapfilename = self.getMapfileLocation(mapfilename)
- if self.mapfilename:
- # save mapfile ONLY if GetCapabilities requested - it makes no
- # sense for other cases
- logging.info("Saving mapfile to %s" % self.mapfilename)
- mapobj.save(self.mapfilename)
- else:
- logging.info("Mapfile NOT saved")
- return self.mapfilename
- def getLayerUrl(self):
- layerurl = self.url
- if self.url.find("?") > -1:
- if not self.url.endswith("?") and\
- not self.url.endswith("&"):
- layerurl += "&"
- else:
- layerurl += "?"
- return layerurl
- def createLayerDefinitionFile(self, name,
- templatefile,time=None,target=None):
- layerurl = self.getLayerUrl()
- defFileName = None
- if target:
- defFileName = target
- else:
- defFileName = os.path.join(self.cachedir,'%s.%s'%(name,self.service.lower()))
- if time:
- time = "<DefaultTime>"+time+"</DefaultTime>"
- else:
- time = ""
- open(defFileName,'w').write(
- Template(open(templatefile).read()).substitute(
- dict(url= layerurl, name=name,time=time)))
- logging.debug("Created %s layer definition file" % defFileName)
- return defFileName
- def getLayerExtent(self,layer,crs=None,wkt=None):
- """Get extent of layer in form of minx, miny, maxx,maxy
- """
- bbox = None
- if layer.boundingBoxWGS84:
- dest = osr.SpatialReference()
- if crs:
- try:
- crsSplit = crs.split(":")
- epsg = int(crsSplit[len(crsSplit)-1])
- dest.ImportFromEPSG(epsg)
- except (ValueError):
- logging.debug("Unable to parse crs '%s'" % crs)
- else:
- dest.ImportFromWkt(wkt)
- source = osr.SpatialReference()
- source.ImportFromEPSG(4326)
- bbox = []
- # TODO rewrite this using ogr CoordinateTransformation
- # http://www.gdal.org/ogr/osr_tutorial.html
- geom = ogr.CreateGeometryFromWkt("""POINT(%s %s)""" % (layer.boundingBoxWGS84[0],layer.boundingBoxWGS84[1]),source)
- geom.TransformTo(dest)
- bbox.append(geom.GetX())
- bbox.append(geom.GetY())
- geom = ogr.CreateGeometryFromWkt("""POINT(%s %s)""" % (layer.boundingBoxWGS84[2],layer.boundingBoxWGS84[3]),source)
- geom.TransformTo(dest)
- bbox.append(geom.GetX())
- bbox.append(geom.GetY())
- logging.debug("Setting extent for layer <%s> to %s" %\
- (layer.id,bbox))
- return bbox
- def setFilter(self,mapobj,request):
- """ Set WFS filter encoding
- """
- logging.debug("Setting filter for layer %s to %s" % (request.getValueByName("layers"),request.getValueByName("fes")))
- layerobj = mapobj.getLayerByName(request.getValueByName("layers"))
- layerobj.setMetaData("wfs_filter",request.getValueByName("fes"))
- # layerobj.metadata.get("wfs_filter") is still fine
-
- def getService():
- qstring = os.environ["QUERY_STRING"]
- params = urlparse.parse_qs(qstring)
-
- owsUrl = urllib.unquote(params["owsUrl"][0])
- if params["owsService"][0].lower() == "wfs":
- from wfs import WFS
- return WFS(owsUrl,qstring)
- elif params["owsService"][0].lower() == "wcs":
- from wcs import WCS
- return WCS(owsUrl,qstring)
-
|