__init__.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. # mapobjects exists, do not do any new layers
  24. if mapobj.numlayers:
  25. return mapobj
  26. #
  27. # for each layer from the WCS Capabilities file, transform it to
  28. # mapscript.layerObj
  29. #
  30. for name in self.capabilities.contents:
  31. layer = self.capabilities.contents[name]
  32. logging.debug("Creating layer %s" % name)
  33. # create layer definition file
  34. # see http://www.gdal.org/frmt_wcs.html
  35. layerDefFile = self.createLayerDefinitionFile(name,
  36. os.path.join( os.path.dirname(__file__), "templates",'wcs.xml'))
  37. # create the layer
  38. ds = gdal.Open(layerDefFile)
  39. try:
  40. lyrobj = mapscript.layerObj(mapobj)
  41. lyrobj.name = name
  42. lyrobj.data = layerDefFile
  43. if layer.title:
  44. lyrobj.title = layer.title
  45. lyrobj.setMetaData("wms_title",layer.title)
  46. #if "{%s}%s" % (self.owsns11,"Abstract") in layer:
  47. # lyrobj.setMetaData("ows_abstract", layer["{%s}%s" % (self.owsns11,"Abstract")].text)
  48. lyrobj.setMetaData("wms_srs",self.config.get("MapServer","srs"))
  49. extent = None
  50. # processing
  51. if layer.crsOptions:
  52. lyrobj.setProjection(layer.crsOptions[0].getcode())
  53. extent = self.getLayerExtent(layer,layer.crsOptions[0])
  54. elif layer.supportedCRS:
  55. lyrobj.setProjection(layer.supportedCRS[0].getcode())
  56. extent = self.getLayerExtent(layer,layer.supportedCRS[0])
  57. else:
  58. sr = osr.SpatialReference()
  59. sr.ImportFromWkt(ds.GetProjection())
  60. if sr.AutoIdentifyEPSG() == 0:
  61. epsg = "{code}:{value}".format(code=sr.GetAuthorityName("PROJCS"),value=sr.GetAuthorityCode("PROJCS"))
  62. extent = self.getLayerExtent(layer,epsg)
  63. lyrobj.setProjection(epsg)
  64. else:
  65. extent = self.getLayerExtent(layer,wkt=ds.GetProjection())
  66. lyrobj.setProjection(sr.ExportToProj4())
  67. lyrobj.setMetaData("wms_extent","%s %s %s %s" % \
  68. (extent[0],extent[1],extent[2],extent[3]))
  69. lyrobj.type = mapscript.MS_LAYER_RASTER
  70. lyrobj.dump = mapscript.MS_TRUE
  71. lyrobj.template = "foo"
  72. # bands
  73. if layer.axisDescriptions:
  74. self._addBandsMetadata(layer, lyrobj)
  75. if ds:
  76. self.getTime(ds,lyrobj)
  77. cls = mapscript.classObj(lyrobj)
  78. mapscript.styleObj(cls)
  79. except Exception,e:
  80. mapobj.removeLayer(lyrobj.index)
  81. logging.warning("Layer %s: %s, skipping." %\
  82. (name,e.message))
  83. self.saveMapfile(mapobj,mapfilename)
  84. return mapobj
  85. def getTime(self,ds,lyrobj):
  86. """Generate time index file, set approripate layer metadata"""
  87. # make time index file
  88. drv = ogr.GetDriverByName("ESRI Shapefile")
  89. tindex = '%s.%s.%s'%(lyrobj.name,self.service.lower(),"tindex")
  90. logging.info("Creating time index definition file %s.shp in %s" % (tindex,self.cachedir))
  91. tds = drv.CreateDataSource(os.path.join(self.cachedir,tindex))
  92. lyr = tds.CreateLayer(tindex)
  93. tile_field = ogr.FieldDefn("location", ogr.OFTString )
  94. tile_field.SetWidth( 256 )
  95. lyr.CreateField(tile_field)
  96. time_field = ogr.FieldDefn("time", ogr.OFTString )
  97. time_field.SetWidth( 256 )
  98. lyr.CreateField(time_field)
  99. timeMetadata = ""
  100. for sds in ds.GetSubDatasets():
  101. if sds[0].find('time') > -1:
  102. # crate mapfile metadata
  103. sdsname = sds[0].split(",")[0]
  104. sdsvalue = re.findall(r'".*"',sdsname)[0].replace('"',"")
  105. timeMetadata = timeMetadata+","+sdsvalue
  106. # create OGR tindex vector feature
  107. feature = ogr.Feature(lyr.GetLayerDefn())
  108. # feature geometry
  109. geotransform = ds.GetGeoTransform()
  110. w = ds.RasterXSize
  111. h = ds.RasterYSize
  112. bbox = {"minx":geotransform[0],"miny":geotransform[5]*h+geotransform[3],"maxx":geotransform[1]*w+geotransform[0],"maxy":geotransform[3]}
  113. 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)
  114. feature.SetGeometry(poly)
  115. # set time attribute
  116. feature.SetField("time","%s" % (sdsvalue))
  117. feature.SetField("location",sds[0])
  118. lyr.CreateFeature(feature)
  119. if timeMetadata.endswith(","):
  120. timeMetadata = re.sub(r",$","",timeMetadata)
  121. if timeMetadata.startswith(","):
  122. timeMetadata = re.sub(r"^,","",timeMetadata)
  123. if timeMetadata:
  124. logging.info("Setting %s to %s layer" % (timeMetadata, lyrobj.name))
  125. lyrobj.setMetaData("wms_timeextent", timeMetadata)
  126. lyrobj.setMetaData("wms_timeitem", "time")
  127. # NOTE: lyrobj.data will not be the wcs definition file
  128. # anymore, BUT the time index shapefile
  129. logging.info("Setting layer data to %s" %
  130. (os.path.join(tindex,tindex+".shp")))
  131. lyrobj.data = None
  132. lyrobj.tileindex = os.path.join(tindex,tindex+".shp")
  133. else:
  134. logging.info("No time subset found")
  135. def _addBandsMetadata(self, layer, lyrobj):
  136. """Adds wmcs_band* metadata to the lyrobj"""
  137. for i in layer.axisDescriptions:
  138. if i.name.lower() == "bands":
  139. lyrobj.setMetaData("wcs_bandcount",str(len(i.values)))
  140. lyrobj.setMetaData("wcs_rangeset_axes",str(i.name))
  141. lyrobj.setMetaData("wcs_rangeset_name",str(i.name))