__init__.py 6.0 KB

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