__init__.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. if layer.crsOptions:
  48. lyrobj.setProjection(layer.crsOptions[0])
  49. extent = self.getLayerExtent(layer,layer.crsOptions[0])
  50. else:
  51. sr = osr.SpatialReference()
  52. sr.ImportFromWkt(ds.GetProjection())
  53. if sr.AutoIdentifyEPSG() == 0:
  54. epsg = "{code}:{value}".format(code=sr.GetAuthorityName("PROJCS"),value=sr.GetAuthorityCode("PROJCS"))
  55. extent = self.getLayerExtent(layer,epsg)
  56. lyrobj.setProjection(epsg)
  57. else:
  58. extent = self.getLayerExtent(layer,wkt=ds.GetProjection())
  59. lyrobj.setProjection(sr.ExportToProj4())
  60. lyrobj.setMetaData("wms_extent","%s %s %s %s" % \
  61. (extent[0],extent[1],extent[2],extent[3]))
  62. lyrobj.type = mapscript.MS_LAYER_RASTER
  63. lyrobj.dump = mapscript.MS_TRUE
  64. lyrobj.template = "foo"
  65. self.getTime(ds,lyrobj)
  66. cls = mapscript.classObj(lyrobj)
  67. mapscript.styleObj(cls)
  68. except Exception,e:
  69. mapobj.removeLayer(lyrobj.index)
  70. logging.warning("Layer %s: %s, skipping." %\
  71. (name,e.message))
  72. self.saveMapfile(mapobj,mapfilename)
  73. return mapobj
  74. def getTime(self,ds,lyrobj):
  75. """Generate time index file, set approripate layer metadata"""
  76. # make time index file
  77. drv = ogr.GetDriverByName("ESRI Shapefile")
  78. tindex = '%s.%s.%s'%(lyrobj.name,self.service.lower(),"tindex")
  79. logging.info("Creating time index definition file %s.shp in %s" % (tindex,self.cachedir))
  80. tds = drv.CreateDataSource(os.path.join(self.cachedir,tindex))
  81. lyr = tds.CreateLayer(tindex)
  82. tile_field = ogr.FieldDefn("location", ogr.OFTString )
  83. tile_field.SetWidth( 256 )
  84. lyr.CreateField(tile_field)
  85. time_field = ogr.FieldDefn("time", ogr.OFTString )
  86. time_field.SetWidth( 256 )
  87. lyr.CreateField(time_field)
  88. timeMetadata = ""
  89. for sds in ds.GetSubDatasets():
  90. if sds[0].find('time') > -1:
  91. # crate mapfile metadata
  92. sdsname = sds[0].split(",")[0]
  93. sdsvalue = re.findall(r'".*"',sdsname)[0].replace('"',"")
  94. timeMetadata = timeMetadata+","+sdsvalue
  95. # create OGR tindex vector feature
  96. feature = ogr.Feature(lyr.GetLayerDefn())
  97. # feature geometry
  98. geotransform = ds.GetGeoTransform()
  99. w = ds.RasterXSize
  100. h = ds.RasterYSize
  101. bbox = {"minx":geotransform[0],"miny":geotransform[5]*h+geotransform[3],"maxx":geotransform[1]*w+geotransform[0],"maxy":geotransform[3]}
  102. 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)
  103. feature.SetGeometry(poly)
  104. # set time attribute
  105. feature.SetField("time","%s" % (sdsvalue))
  106. feature.SetField("location",sds[0])
  107. lyr.CreateFeature(feature)
  108. if timeMetadata.endswith(","):
  109. timeMetadata = re.sub(r",$","",timeMetadata)
  110. if timeMetadata.startswith(","):
  111. timeMetadata = re.sub(r"^,","",timeMetadata)
  112. if timeMetadata:
  113. logging.info("Setting %s to %s layer" % (timeMetadata, lyrobj.name))
  114. lyrobj.setMetaData("wms_timeextent", timeMetadata)
  115. lyrobj.setMetaData("wms_timeitem", "time")
  116. # NOTE: lyrobj.data will not be the wcs definition file
  117. # anymore, BUT the time index shapefile
  118. logging.info("Setting layer data to %s" %
  119. (os.path.join(tindex,tindex+".shp")))
  120. lyrobj.data = None
  121. lyrobj.tileindex = os.path.join(tindex,tindex+".shp")
  122. else:
  123. logging.info("No time subset found")