def createXML_WCSt11Ack( context ) : 
    """ create WCSt 1.1 Acknowledgement XML document """ 

    xml = [] 
    xml.append( u'<?xml version="1.0" encoding="utf-8"?>\n' ) 
    xml.append( u'<Acknowledgement xmlns="http://www.opengis.net/wcs/1.1/wcst"' )
    xml.append( u' xmlns:ows="http://www.opengis.net/ows/1.1"' )
    xml.append( u' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' )
    xml.append( u' xsi:schemaLocation="http://www.opengis.net/wcs/1.1/wcst ' ) 
    xml.append( u' http://schemas.opengis.net/wcst/1.1/wcstTransaction.xsd">\n' ) 
    xml.append( u'<TimeStamp>%s</TimeStamp>\n' % timeStampUTC() )
    xml.append( u'<RequestId>%s</RequestId>\n' % context['requestId'] )
    xml.append( u'</Acknowledgement>\n' ) 

    return ( u"".join(xml) ).encode("UTF-8")
def createXML_WCSt11Ack(context):
    """ create WCSt 1.1 Acknowledgement XML document """

    xml = []
    xml.append(u'<?xml version="1.0" encoding="utf-8"?>\n')
    xml.append(u'<Acknowledgement xmlns="http://www.opengis.net/wcs/1.1/wcst"')
    xml.append(u' xmlns:ows="http://www.opengis.net/ows/1.1"')
    xml.append(u' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
    xml.append(u' xsi:schemaLocation="http://www.opengis.net/wcs/1.1/wcst ')
    xml.append(u' http://schemas.opengis.net/wcst/1.1/wcstTransaction.xsd">\n')
    xml.append(u'<TimeStamp>%s</TimeStamp>\n' % timeStampUTC())
    xml.append(u'<RequestId>%s</RequestId>\n' % context['requestId'])
    xml.append(u'</Acknowledgement>\n')

    return (u"".join(xml)).encode("UTF-8")
Example #3
0
def wcst11ActionAdd(action, context, maxAttempts=3):
    """ WCS-T 1.1 Transaction - Add action handler """

    aname = action["Action"]
    logger.debug("WCSt11:%s: START" % aname)

    # create coverage Id manager
    covIdManager = CoverageIdManager()

    # generate internal coverage Id (CID)
    for i in xrange(maxAttempts):
        cid = getNewCoverageID()
        # try to reserve the ID
        if reserveCoverageId(covIdManager, cid, context['requestId']): break
    else:
        msg = "WCSt11:%s: Failed to generate an unique coverage ID!" % aname
        logger.error(msg)
        raise Exception, msg

    # extract user provided CID
    coverageId = action["Identifier"]

    # if the user provided coverage id cannot be used -> fall-back to the internal CID
    if (coverageId is None) or (not reserveCoverageId(covIdManager, coverageId,
                                                      context['requestId'])):
        coverageId = cid

    if coverageId != cid:
        logger.info("WCSt11:%s: Inserting new coverage: %s (%s) " %
                    (aname, coverageId, cid))
    else:
        logger.info("WCSt11:%s: Inserting new coverage: %s " %
                    (aname, coverageId))

    try:

        # ------------------------------------------------------------------------------

        pixelData = []
        covDescript = []
        geoTransform = []
        eopXML = None

        prefix = "WCSt11:%s" % aname

        # download references
        for i, r in enumerate(action["Reference"]):

            logger.info("WCSt11:%s: Reference: role: %s \t href: %s " %
                        (aname, r['role'], r['href']))

            basename = os.path.join(context['pathTemp'],
                                    "%s_ref_%3.3i" % (cid, i))

            if r['role'] == "urn:ogc:def:role:WCS:1.1:Pixels":
                pixelData.append(
                    wcst11DownloadReference(r['href'], basename, prefix))
            elif r['role'] == "urn:ogc:def:role:WCS:1.1:CoverageDescription":
                covDescript.append(
                    wcst11DownloadReference(r['href'], basename, prefix))
            elif r['role'] == "urn:ogc:def:role:WCS:1.1:GeoreferencingTransformation":
                geoTransform.append(
                    wcst11DownloadReference(r['href'], basename, prefix))

        # -MP- NOTE:
        # I REALLY do not know what to do with the CoverageDescription and GeoreferencingTransformation.
        # They are required by the WCS-T standard (mandatory references which are always supposed to be present)
        # but not by the EOxServer API at all. Therefore I decided to silently ignore their absence.
        # When provided it is fine, but not I do not need them at all.

        # ------------------------------------------------------------------------------
        # download metadata
        for i, r in enumerate(action["Metadata"]):

            logger.info("WCSt11:%s: Metadata: role: %s \t href: %s " %
                        (aname, r['role'], r['href']))

            basename = os.path.join(context['pathTemp'],
                                    "%s_md_%3.3i" % (cid, i))

            if r['role'] == "http://www.opengis.net/eop/2.0/EarthObservation":
                eopXML = wcst11DownloadReference(r['href'], basename, prefix)

        # ------------------------------------------------------------------------------
        # get information about the pixel data

        srcTIFfile = pixelData[0][0]

        try:
            info = GDalInfo(srcTIFfile)
        except Exception as e:
            raise ExActionFailed, "WCSt11:%s: Failed to check the input pixel data! Reason: %s" % (
                aname, str(e))

        # check that the input data is geotiff
        if info.driverName != "GeoTIFF":
            raise ExActionFailed, "WCSt11:%s: Input pixel data not in required GeoTIFF format! Format: %s " % (
                aname, info.driverName)

        # check geocoding
        if bool(info.isReferenceable) == bool(info.isRectified):
            raise ExActionFailed, "WCSt11:%s: Input GeoTIFF pixel data not properly geocoded!" % aname

        logger.debug("WCSt11:%s: Coverage Type: %s " %
                     (aname, ("REFERENCEABLE", "RECTIFIED")[info.isRectified]))

        # ------------------------------------------------------------------------------
        # eopXML check

        srcXMLfile = os.path.join(context['pathTemp'], "%s_md.xml" % cid)

        isEODataset = False

        if eopXML is not None:

            logger.info("WCSt11:%s: Parsing the input EOP2.0 XML file: %s  " %
                        (aname, eopXML[0]))

            # The following commands extract the EOP profile from the provided XML document
            # and changes the EOP ID  to coverageId.
            # The input can be either EOP2.0 XML document or an arbirary XML having EOP2.0 XML as
            # sub-element. In the latter case, the first instance of EOP2.0 XML element is extracted.

            f0 = file(eopXML[0])
            f1 = file(srcXMLfile, "w")

            try:
                eop20SetID(f0, f1, coverageId)
            except Exception as e:
                f0.close()
                f1.close()
                raise ExActionFailed, "WCSt11:%s: Failed to parse the input EOP2.0 XML Document! Reason: %s" % (
                    aname, str(e))

            f0.close()
            f1.close()

            isEODataset = True

        # ------------------------------------------------------------------------------
        # in case of missing EO profile extract footprint
        # temporary workarround - shall be removed in future
        # the XML metadata generation should be performed by the coverage manager only

        if (not isEODataset) and info.isRectified:

            # prepare coverage insert
            md_start = timeStampUTC()
            md_stop = md_start

            md_footprint = getFootprint(info, repeatFirst=True)

            logger.debug(str(info))
            logger.debug(md_footprint)

            logger.info(
                "WCSt11:%s: EOP2.0 XML not provided! Trying to extract information from the GeoTIFF image."
                % aname)
            logger.debug("WCSt11:%s: Generating EOP2.0 XML file: %s" %
                         (aname, srcXMLfile))

            fid = file(srcXMLfile, "w")
            fid.write(
                createXML_EOP20(coverageId, md_footprint, md_start, md_stop))
            fid.close()

            isEODataset = True

        # ------------------------------------------------------------------------------

        dstXMLfile = os.path.join(context['pathPerm'], "%s.xml" % cid)
        dstTIFfile = os.path.join(context['pathPerm'], "%s.tif" % cid)
        dstMDfile = dstTIFfile

        # move the pixel data to the final destination

        logger.info("WCSt11:%s: Coverage data location:      %s " %
                    (aname, dstTIFfile))
        shutil.move(srcTIFfile, dstTIFfile)

        if isEODataset:
            logger.info("WCSt11:%s: Coverage metadata location:  %s " %
                        (aname, dstXMLfile))
            shutil.move(srcXMLfile, dstXMLfile)
            dstMDfile = dstXMLfile

        # ------------------------------------------------------------------------------
        # rectified dataset
        if info.isRectified:

            logger.info(
                "WCSt11:%s: Inserting instance of RectifiedDataset ..." %
                aname)

            rdm = RectifiedDatasetManager()

            rdm.create(
                coverageId,
                context['requestId'],
                local_path=os.path.abspath(dstTIFfile),
                md_local_path=os.path.abspath(dstMDfile),
                range_type_name="RGB")  # TODO: proper Range Type selection

        # referencable dataset
        elif info.isReferenceable:

            logger.info(
                "WCSt11:%s: Inserting instance of ReferenceableDataset ..." %
                aname)

            rdm = ReferenceableDatasetManager()

            rdm.create(
                coverageId,
                context['requestId'],
                local_path=os.path.abspath(dstTIFfile),
                md_local_path=os.path.abspath(dstMDfile),
                range_type_name="ASAR")  # TODO: proper Range Type selection

        # ------------------------------------------------------------------------------

    except:
        releaseCoverageIds(covIdManager, (cid, coverageId))
        raise

    # release reserved coverage ids
    releaseCoverageIds(covIdManager, (cid, coverageId))

    return coverageId
Example #4
0
def wcst11ActionAdd( action , context , maxAttempts = 3 ) : 
    """ WCS-T 1.1 Transaction - Add action handler """ 

    aname = action["Action"]
    logger.debug( "WCSt11:%s: START" % aname ) 

    # create coverage Id manager 
    covIdManager = CoverageIdManager()

    # generate internal coverage Id (CID) 
    for i in xrange( maxAttempts ) :
        cid = getNewCoverageID()
        # try to reserve the ID 
        if reserveCoverageId( covIdManager , cid , context['requestId'] ) : break  
    else : 
        msg = "WCSt11:%s: Failed to generate an unique coverage ID!" % aname 
        logger.error( msg ) 
        raise Exception , msg 

    # extract user provided CID 
    coverageId = action["Identifier"] 

    # if the user provided coverage id cannot be used -> fall-back to the internal CID
    if ( coverageId is None ) or ( not reserveCoverageId( covIdManager , coverageId , context['requestId'] ) ):
        coverageId = cid 

    if coverageId != cid :
        logger.info( "WCSt11:%s: Inserting new coverage: %s (%s) " % ( aname , coverageId , cid ) ) 
    else :
        logger.info( "WCSt11:%s: Inserting new coverage: %s " % ( aname , coverageId ) ) 

    try : 

        # ------------------------------------------------------------------------------

        pixelData    = [] 
        covDescript  = [] 
        geoTransform = []  
        eopXML       = None 

        prefix = "WCSt11:%s" % aname 

        # download references 
        for i,r in enumerate(action["Reference"]): 

            logger.info( "WCSt11:%s: Reference: role: %s \t href: %s " % ( aname , r['role'] , r['href'] ) ) 

            basename = os.path.join( context['pathTemp'] , "%s_ref_%3.3i" % ( cid , i ) ) 

            if r['role'] == "urn:ogc:def:role:WCS:1.1:Pixels" : 
                pixelData.append( wcst11DownloadReference( r['href'] , basename , prefix ) ) 
            elif r['role'] == "urn:ogc:def:role:WCS:1.1:CoverageDescription" : 
                covDescript.append( wcst11DownloadReference( r['href'] , basename , prefix ) )
            elif r['role'] == "urn:ogc:def:role:WCS:1.1:GeoreferencingTransformation" : 
                geoTransform.append( wcst11DownloadReference( r['href'] , basename , prefix ) )

        # -MP- NOTE: 
        # I REALLY do not know what to do with the CoverageDescription and GeoreferencingTransformation.
        # They are required by the WCS-T standard (mandatory references which are always supposed to be present)
        # but not by the EOxServer API at all. Therefore I decided to silently ignore their absence. 
        # When provided it is fine, but not I do not need them at all.   

        # ------------------------------------------------------------------------------
        # download metadata 
        for i,r in enumerate(action["Metadata"]): 

            logger.info( "WCSt11:%s: Metadata: role: %s \t href: %s " % ( aname , r['role'] , r['href'] ) ) 

            basename = os.path.join( context['pathTemp'] , "%s_md_%3.3i" % ( cid , i ) ) 

            if r['role'] == "http://www.opengis.net/eop/2.0/EarthObservation" : 
                eopXML = wcst11DownloadReference( r['href'] , basename , prefix ) 

        # ------------------------------------------------------------------------------
        # get information about the pixel data 

        srcTIFfile = pixelData[0][0]

        try: 
            info = GDalInfo( srcTIFfile ) 
        except Exception as e : 
            raise ExActionFailed , "WCSt11:%s: Failed to check the input pixel data! Reason: %s" % ( aname , str(e) ) 

        # check that the input data is geotiff 
        if info.driverName != "GeoTIFF" : 
            raise ExActionFailed , "WCSt11:%s: Input pixel data not in required GeoTIFF format! Format: %s " % ( aname , info.driverName ) 

        # check geocoding 
        if bool( info.isReferenceable ) == bool( info.isRectified ) :   
            raise ExActionFailed , "WCSt11:%s: Input GeoTIFF pixel data not properly geocoded!" % aname 
       
        logger.debug( "WCSt11:%s: Coverage Type: %s " % ( aname , ("REFERENCEABLE","RECTIFIED")[info.isRectified] ) ) 

        # ------------------------------------------------------------------------------
        # eopXML check 

        srcXMLfile = os.path.join( context['pathTemp'] , "%s_md.xml" % cid ) 

        isEODataset = False 

        if eopXML is not None :

            logger.info( "WCSt11:%s: Parsing the input EOP2.0 XML file: %s  " % ( aname , eopXML[0] ) )

            # The following commands extract the EOP profile from the provided XML document 
            # and changes the EOP ID  to coverageId.
            # The input can be either EOP2.0 XML document or an arbirary XML having EOP2.0 XML as 
            # sub-element. In the latter case, the first instance of EOP2.0 XML element is extracted. 

            f0 = file(eopXML[0]) ; f1 = file( srcXMLfile , "w" ) 

            try : 
                eop20SetID( f0 , f1 , coverageId ) 
            except Exception as e : 
                f0.close() ; f1.close() 
                raise ExActionFailed , "WCSt11:%s: Failed to parse the input EOP2.0 XML Document! Reason: %s" % ( aname , str(e) ) 

            f0.close() ; f1.close() 
        
            isEODataset = True 

        # ------------------------------------------------------------------------------
        # in case of missing EO profile extract footprint 
        # temporary workarround - shall be removed in future 
        # the XML metadata generation should be performed by the coverage manager only 

        if ( not isEODataset ) and info.isRectified : 

            # prepare coverage insert 
            md_start     = timeStampUTC()
            md_stop      = md_start

            md_footprint = getFootprint( info , repeatFirst = True )

            logger.debug( str(info) ) 
            logger.debug( md_footprint ) 

            logger.info( "WCSt11:%s: EOP2.0 XML not provided! Trying to extract information from the GeoTIFF image." % aname ) 
            logger.debug( "WCSt11:%s: Generating EOP2.0 XML file: %s" % ( aname , srcXMLfile ) )

            fid = file( srcXMLfile , "w" ) 
            fid.write( createXML_EOP20( coverageId , md_footprint , md_start , md_stop ) ) 
            fid.close() 

            isEODataset = True 

        # ------------------------------------------------------------------------------
            
        dstXMLfile = os.path.join( context['pathPerm'] , "%s.xml" % cid )
        dstTIFfile = os.path.join( context['pathPerm'] , "%s.tif" % cid )
        dstMDfile  = dstTIFfile 

        # move the pixel data to the final destination 

        logger.info( "WCSt11:%s: Coverage data location:      %s " % ( aname , dstTIFfile ) ) 
        shutil.move( srcTIFfile , dstTIFfile )                          

        if isEODataset : 
            logger.info( "WCSt11:%s: Coverage metadata location:  %s " % ( aname , dstXMLfile ) ) 
            shutil.move( srcXMLfile , dstXMLfile )
            dstMDfile = dstXMLfile 

        # ------------------------------------------------------------------------------
        # rectified dataset 
        if info.isRectified : 

            logger.info( "WCSt11:%s: Inserting instance of RectifiedDataset ..." % aname ) 

            rdm = RectifiedDatasetManager() 
        
            rdm.create( coverageId , context['requestId'] , 
                local_path = os.path.abspath( dstTIFfile ) , 
                md_local_path = os.path.abspath( dstMDfile ) , 
                range_type_name = "RGB" )  # TODO: proper Range Type selection
            
            
        # referencable dataset 
        elif info.isReferenceable : 

            logger.info( "WCSt11:%s: Inserting instance of ReferenceableDataset ..." % aname ) 

            rdm = ReferenceableDatasetManager() 

            rdm.create( coverageId , context['requestId'] , 
                local_path = os.path.abspath( dstTIFfile ) , 
                md_local_path = os.path.abspath( dstMDfile ) , 
                range_type_name = "ASAR" )  # TODO: proper Range Type selection

        # ------------------------------------------------------------------------------

    except : 
        releaseCoverageIds( covIdManager , ( cid , coverageId ) ) 
        raise 

    # release reserved coverage ids 
    releaseCoverageIds( covIdManager , ( cid , coverageId ) ) 

    return coverageId