예제 #1
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
예제 #2
0
def wcst11ActionDelete(action, context):

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

    # extract permanet storage
    pathPerm = os.path.abspath("%s/.." % context['pathPerm'])

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

    if not coverageId:
        raise ExActionFailed, "WCSt11:%s: Missing the required coverage identifier!" % aname

    # check the covergae type
    coverageType = CoverageIdManager().getCoverageType(coverageId)

    if not coverageType:
        raise ExActionFailed, "WCSt11:%s: Invalid coverage identifier! Identifier=%s" % (
            aname, repr(coverageId))

    # process the supproted coverage types

    if coverageType == "RectifiedDataset":
        cls = RectifiedDatasetRecord
        mng = RectifiedDatasetManager()

    elif coverageType == "ReferenceableDataset":
        cls = ReferenceableDatasetRecord
        mng = ReferenceableDatasetManager()

    else:  # unsupproted coverage types
        raise ExActionFailed, "WCSt11:%s: Unsupported coverage type! Type=%s ; Identifier=%s" % (
            aname, repr(coverageType), repr(coverageId))

    # check the location

    obj = cls.objects.get(coverage_id=coverageId)
    pck = obj.data_package

    if pck.data_package_type == 'local':

        logger.debug(dir(pck.localdatapackage))

        lpath = pck.localdatapackage.data_location.path
        mpath = pck.localdatapackage.metadata_location.path

        # let only the covergas inserted via the WCS-T to be deletable via this interface
        if not (lpath.startswith(pathPerm) and mpath.startswith(pathPerm)):
            raise ExActionFailed, "WCSt11:%s: No permission to remove the coverage! Identifier=%s" % (
                aname, repr(coverageId))

        # delete the coverage
        logger.info("WCSt11:%s: Removing coverage: %s " % (aname, coverageId))
        mng.delete(coverageId)

        # delete the coverage data
        for f in (lpath, mpath):
            try:
                logger.info("WCSt11:%s: Removing file: %s " % (aname, f))
                os.remove(f)
            except Exception as e:
                logger.warn("WCSt11:%s: Failed to remove file! path=%s " %
                            (aname, f))
                logger.warn("WCSt11:%s: Reason: %s %s" %
                            (aname, str(type(e)), str(e)))

        # delete directories if empty
        for d in set((os.path.dirname(lpath), os.path.dirname(mpath))):
            try:
                logger.info("WCSt11:%s: Removing directory: %s " % (aname, d))
                os.rmdir(d)
            except Exception as e:
                logger.warn("WCSt11:%s: Failed to remove directory! path=%s " %
                            (aname, d))
                logger.warn("WCSt11:%s: Reason: %s %s" %
                            (aname, str(type(e)), str(e)))

    return coverageId