__init__.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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,configFile=None):
  17. OWS.__init__(self,url,qstring,configFile)
  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].getcode())
  50. extent = self.getLayerExtent(layer,layer.crsOptions[0])
  51. elif layer.supportedCRS:
  52. lyrobj.setProjection(layer.supportedCRS[0].getcode())
  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. # bands
  70. if layer.axisDescriptions:
  71. self._addBandsMetadata(layer, lyrobj)
  72. if ds:
  73. self.getTime(ds,lyrobj)
  74. cls = mapscript.classObj(lyrobj)
  75. mapscript.styleObj(cls)
  76. except Exception,e:
  77. mapobj.removeLayer(lyrobj.index)
  78. logging.warning("Layer %s: %s, skipping." %\
  79. (name,e.message))
  80. self.saveMapfile(mapobj,mapfilename)
  81. return mapobj
  82. def getTime(self,ds,lyrobj):
  83. """Generate time index file, set approripate layer metadata"""
  84. # make time index file
  85. drv = ogr.GetDriverByName("ESRI Shapefile")
  86. tindex = '%s.%s.%s'%(lyrobj.name,self.service.lower(),"tindex")
  87. logging.info("Creating time index definition file %s.shp in %s" % (tindex,self.cachedir))
  88. tds = drv.CreateDataSource(os.path.join(self.cachedir,tindex))
  89. lyr = tds.CreateLayer(tindex)
  90. tile_field = ogr.FieldDefn("location", ogr.OFTString )
  91. tile_field.SetWidth( 256 )
  92. lyr.CreateField(tile_field)
  93. time_field = ogr.FieldDefn("time", ogr.OFTString )
  94. time_field.SetWidth( 256 )
  95. lyr.CreateField(time_field)
  96. timeMetadata = ""
  97. for sds in ds.GetSubDatasets():
  98. if sds[0].find('time') > -1:
  99. # crate mapfile metadata
  100. sdsname = sds[0].split(",")[0]
  101. sdsvalue = re.findall(r'".*"',sdsname)[0].replace('"',"")
  102. timeMetadata = timeMetadata+","+sdsvalue
  103. # create OGR tindex vector feature
  104. feature = ogr.Feature(lyr.GetLayerDefn())
  105. # feature geometry
  106. geotransform = ds.GetGeoTransform()
  107. w = ds.RasterXSize
  108. h = ds.RasterYSize
  109. bbox = {"minx":geotransform[0],"miny":geotransform[5]*h+geotransform[3],"maxx":geotransform[1]*w+geotransform[0],"maxy":geotransform[3]}
  110. 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)
  111. feature.SetGeometry(poly)
  112. # set time attribute
  113. feature.SetField("time","%s" % (sdsvalue))
  114. feature.SetField("location",sds[0])
  115. lyr.CreateFeature(feature)
  116. if timeMetadata.endswith(","):
  117. timeMetadata = re.sub(r",$","",timeMetadata)
  118. if timeMetadata.startswith(","):
  119. timeMetadata = re.sub(r"^,","",timeMetadata)
  120. if timeMetadata:
  121. logging.info("Setting %s to %s layer" % (timeMetadata, lyrobj.name))
  122. lyrobj.setMetaData("wms_timeextent", timeMetadata)
  123. lyrobj.setMetaData("wms_timeitem", "time")
  124. # NOTE: lyrobj.data will not be the wcs definition file
  125. # anymore, BUT the time index shapefile
  126. logging.info("Setting layer data to %s" %
  127. (os.path.join(tindex,tindex+".shp")))
  128. lyrobj.data = None
  129. lyrobj.tileindex = os.path.join(tindex,tindex+".shp")
  130. else:
  131. logging.info("No time subset found")
  132. def _addBandsMetadata(self, layer, lyrobj):
  133. """Adds wmcs_band* metadata to the lyrobj"""
  134. for i in layer.axisDescriptions:
  135. if i.name.lower() == "bands":
  136. lyrobj.setMetaData("wcs_bandcount",str(len(i.values)))
  137. lyrobj.setMetaData("wcs_rangeset_axes",str(i.name))
  138. lyrobj.setMetaData("wcs_rangeset_name",str(i.name))