__init__.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. from OWS import OWS
  4. import mapscript
  5. from osgeo import gdal
  6. from osgeo import ogr
  7. from osgeo import osr
  8. import os
  9. import logging
  10. import re
  11. class WCS(OWS):
  12. service = "WCS"
  13. request = '' # GetCapabilies, ...
  14. parser = None
  15. version = None
  16. def __init__(self,url=None,qstring=None,configFiles=None):
  17. OWS.__init__(self,url,qstring)
  18. def makeMap(self,mapfilename=None):
  19. """Create mapscript.mapObj"""
  20. lyrobj = None
  21. self.version = self.capabilities.version
  22. mapobj = self.getMapObj(mapfilename)
  23. #
  24. # for each layer from the WCS Capabilities file, transform it to
  25. # mapscript.layerObj
  26. #
  27. for name in self.capabilities.contents:
  28. layer = self.capabilities.contents[name]
  29. logging.debug("Creating layer %s" % name)
  30. # create layer definition file
  31. # see http://www.gdal.org/frmt_wcs.html
  32. layerDefFile = self.createLayerDefinitionFile(name,
  33. os.path.join( os.path.dirname(__file__), "templates",'wcs.xml'))
  34. # create the layer
  35. ds = gdal.Open(layerDefFile)
  36. try:
  37. lyrobj = mapscript.layerObj(mapobj)
  38. lyrobj.name = name
  39. lyrobj.data = layerDefFile
  40. if layer.title:
  41. lyrobj.title = layer.title
  42. lyrobj.setMetaData("wms_title",layer.title)
  43. #if "{%s}%s" % (self.owsns11,"Abstract") in layer:
  44. # lyrobj.setMetaData("ows_abstract", layer["{%s}%s" % (self.owsns11,"Abstract")].text)
  45. lyrobj.setMetaData("wms_srs",self.config.get("MapServer","srs"))
  46. extent = None
  47. # processing
  48. if layer.crsOptions:
  49. lyrobj.setProjection(layer.crsOptions[0])
  50. extent = self.getLayerExtent(layer,layer.crsOptions[0])
  51. elif layer.supportedCRS:
  52. lyrobj.setProjection(layer.supportedCRS[0])
  53. extent = self.getLayerExtent(layer,layer.supportedCRS[0])
  54. else:
  55. sr = osr.SpatialReference()
  56. sr.ImportFromWkt(ds.GetProjection())
  57. if sr.AutoIdentifyEPSG() == 0:
  58. epsg = "{code}:{value}".format(code=sr.GetAuthorityName("PROJCS"),value=sr.GetAuthorityCode("PROJCS"))
  59. extent = self.getLayerExtent(layer,epsg)
  60. lyrobj.setProjection(epsg)
  61. else:
  62. extent = self.getLayerExtent(layer,wkt=ds.GetProjection())
  63. lyrobj.setProjection(sr.ExportToProj4())
  64. lyrobj.setMetaData("wms_extent","%s %s %s %s" % \
  65. (extent[0],extent[1],extent[2],extent[3]))
  66. lyrobj.type = mapscript.MS_LAYER_RASTER
  67. lyrobj.dump = mapscript.MS_TRUE
  68. lyrobj.template = "foo"
  69. if ds:
  70. self.getTime(ds,lyrobj)
  71. cls = mapscript.classObj(lyrobj)
  72. mapscript.styleObj(cls)
  73. except Exception,e:
  74. mapobj.removeLayer(lyrobj.index)
  75. logging.warning("Layer %s: %s, skipping." %\
  76. (name,e.message))
  77. self.saveMapfile(mapobj,mapfilename)
  78. return mapobj
  79. def getTime(self,ds,lyrobj):
  80. """Generate time index file, set approripate layer metadata"""
  81. # make time index file
  82. drv = ogr.GetDriverByName("ESRI Shapefile")
  83. tindex = '%s.%s.%s'%(lyrobj.name,self.service.lower(),"tindex")
  84. logging.info("Creating time index definition file %s.shp in %s" % (tindex,self.cachedir))
  85. tds = drv.CreateDataSource(os.path.join(self.cachedir,tindex))
  86. lyr = tds.CreateLayer(tindex)
  87. tile_field = ogr.FieldDefn("location", ogr.OFTString )
  88. tile_field.SetWidth( 256 )
  89. lyr.CreateField(tile_field)
  90. time_field = ogr.FieldDefn("time", ogr.OFTString )
  91. time_field.SetWidth( 256 )
  92. lyr.CreateField(time_field)
  93. timeMetadata = ""
  94. for sds in ds.GetSubDatasets():
  95. if sds[0].find('time') > -1:
  96. # crate mapfile metadata
  97. sdsname = sds[0].split(",")[0]
  98. sdsvalue = re.findall(r'".*"',sdsname)[0].replace('"',"")
  99. timeMetadata = timeMetadata+","+sdsvalue
  100. # create OGR tindex vector feature
  101. feature = ogr.Feature(lyr.GetLayerDefn())
  102. # feature geometry
  103. geotransform = ds.GetGeoTransform()
  104. w = ds.RasterXSize
  105. h = ds.RasterYSize
  106. bbox = {"minx":geotransform[0],"miny":geotransform[5]*h+geotransform[3],"maxx":geotransform[1]*w+geotransform[0],"maxy":geotransform[3]}
  107. poly = ogr.CreateGeometryFromWkt("""POLYGON((%(minx)s %(miny)s, %(maxx)s %(miny)s, %(maxx)s %(maxy)s, %(minx)s %(maxy)s, %(minx)s %(miny)s))""" % bbox)
  108. feature.SetGeometry(poly)
  109. # set time attribute
  110. feature.SetField("time","%s" % (sdsvalue))
  111. feature.SetField("location",sds[0])
  112. lyr.CreateFeature(feature)
  113. if timeMetadata.endswith(","):
  114. timeMetadata = re.sub(r",$","",timeMetadata)
  115. if timeMetadata.startswith(","):
  116. timeMetadata = re.sub(r"^,","",timeMetadata)
  117. if timeMetadata:
  118. logging.info("Setting %s to %s layer" % (timeMetadata, lyrobj.name))
  119. lyrobj.setMetaData("wms_timeextent", timeMetadata)
  120. lyrobj.setMetaData("wms_timeitem", "time")
  121. # NOTE: lyrobj.data will not be the wcs definition file
  122. # anymore, BUT the time index shapefile
  123. logging.info("Setting layer data to %s" %
  124. (os.path.join(tindex,tindex+".shp")))
  125. lyrobj.data = None
  126. lyrobj.tileindex = os.path.join(tindex,tindex+".shp")
  127. else:
  128. logging.info("No time subset found")