USGS

Isis 3.0 Developer's Reference (API)

Home

CubeAttribute.h

Go to the documentation of this file.
00001 #ifndef CubeAttribute_h
00002 #define CubeAttribute_h
00003 
00026 #include <typeinfo>
00027 
00028 #include <QDebug>
00029 #include <QStringList>
00030 
00031 #include "Cube.h"
00032 #include "Endian.h"
00033 #include "FileName.h"
00034 #include "IException.h"
00035 #include "PixelType.h"
00036 
00037 
00038 namespace Isis {
00047   enum LabelAttachment {
00048     AttachedLabel,  
00049     DetachedLabel,  
00050 
00056     ExternalLabel
00057   };
00058 
00059 
00068   inline QString LabelAttachmentName(LabelAttachment labelType) {
00069     if(labelType == AttachedLabel) return "Attached";
00070     if(labelType == DetachedLabel) return "Detached";
00071     if(labelType == ExternalLabel) return "External";
00072 
00073     QString msg = "Invalid label attachment type [" + QString(labelType) + "]";
00074     throw IException(IException::Programmer, msg, _FILEINFO_);
00075   }
00076 
00077 
00086   inline LabelAttachment LabelAttachmentEnumeration(const QString &labelType) {
00087     QString temp = labelType.toUpper();
00088     if(temp == "ATTACHED") return AttachedLabel;
00089     if(temp == "DETACHED") return DetachedLabel;
00090     if(temp == "External") return ExternalLabel;
00091 
00092     QString msg = "Invalid label attachment type string [" + labelType + "]";
00093     throw IException(IException::Unknown, msg, _FILEINFO_);
00094   }
00095 
00096 
00097 
00133   template<typename ChildClass> class CubeAttribute {
00134     public:
00135 
00137       CubeAttribute(QList< bool (ChildClass::*)(QString) const > testers) {
00138         m_attributeTypeTesters = testers;
00139       }
00140 
00141 
00153       CubeAttribute(QList< bool (ChildClass::*)(QString) const > testers,
00154                     const FileName &fileName) {
00155         m_attributeTypeTesters = testers;
00156         setAttributes(fileName);
00157       }
00158 
00159 
00161       virtual ~CubeAttribute() {
00162       }
00163 
00164 
00173       QString toString() const {
00174         QString result;
00175 
00176         if (!m_attributes.isEmpty())
00177           result = "+" + m_attributes.join("+");
00178 
00179         return result;
00180       }
00181 
00182 
00193       void addAttribute(QString attribute) {
00194         QString upcaseAtt = attribute.toUpper();
00195 
00196         if (attribute.contains("+")) {
00197           throw IException(IException::Unknown,
00198                            "Individual attributes (for example, BSQ) cannot contain the '+' "
00199                            "character because that is used to denote the separation of individual "
00200                            "attributes",
00201                            _FILEINFO_);
00202         }
00203 
00204         // Verify this attribute is legal
00205         bool legal = false;
00206         bool (ChildClass::*tester)(QString) const;
00207         foreach (tester, m_attributeTypeTesters) {
00208           if ( (static_cast<const ChildClass *>(this)->*tester)(upcaseAtt) ) {
00209             if (legal) {
00210               throw IException(IException::Unknown,
00211                                QObject::tr("Attribute [%1] is ambiguous").arg(attribute),
00212                                _FILEINFO_);
00213             }
00214 
00215             legal = true;
00216           }
00217         }
00218 
00219         if (!legal) {
00220           throw IException(IException::Unknown,
00221                            QObject::tr("Attribute [%1] is not recognized").arg(attribute),
00222                            _FILEINFO_);
00223         }
00224 
00225         m_attributes.append(attribute);
00226       }
00227 
00228 
00237       void addAttributes(const FileName &fileNameWithAtts) {
00238         addAttributes(fileNameWithAtts.attributes());
00239       }
00240 
00241 
00250       void addAttributes(const char *attributesString) {
00251         addAttributes(QString(attributesString));
00252       }
00253 
00254 
00263       void addAttributes(const QString &attributesString) {
00264         setAttributes(toString() + "+" + attributesString);
00265       }
00266 
00267 
00277       void setAttributes(const FileName &fileName) {
00278         QStringList attributes = fileName.attributes().split("+", QString::SkipEmptyParts);
00279 
00280         m_attributes.clear();
00281         foreach (QString attribute, attributes)
00282           addAttribute(attribute);
00283       }
00284 
00285 
00286     protected:
00295       QStringList attributeList(bool (ChildClass::*tester)(QString) const) const {
00296         QStringList relevantAttributes;
00297 
00298         foreach (QString attribute, m_attributes) {
00299           QString upcaseAtt = attribute.toUpper();
00300           if ( (static_cast<const ChildClass *>(this)->*tester)(upcaseAtt) ) {
00301             relevantAttributes.append(upcaseAtt);
00302           }
00303         }
00304 
00305         return relevantAttributes;
00306       }
00307 
00308 
00320       void setAttribute(QString newValue, bool (ChildClass::*tester)(QString) const) {
00321         QMutableListIterator<QString> it(m_attributes);
00322 
00323         bool found = false;
00324         while (it.hasNext()) {
00325           QString &attribute = it.next();
00326 
00327           QString upcaseAtt = attribute.toUpper();
00328           if ( (static_cast<const ChildClass *>(this)->*tester)(upcaseAtt) ) {
00329             if (found || newValue == "") {
00330               // already found one (remove the duplicate) or just deleting it
00331               it.remove();
00332             }
00333             else {
00334               // modify existing attribute value
00335               attribute = newValue;
00336             }
00337 
00338             found = true;
00339           }
00340         }
00341 
00342         // Attribute doesn't exist, add it
00343         if (!found && newValue != "") {
00344           m_attributes.append(newValue);
00345         }
00346       }
00347 
00348     private:
00354       QStringList m_attributes;
00355 
00363       QList< bool (ChildClass::*)(QString) const > m_attributeTypeTesters;
00364   };
00365 
00366 
00394   class CubeAttributeInput : public CubeAttribute<CubeAttributeInput> {
00395 
00396     public:
00397 
00399       CubeAttributeInput();
00400 
00401 
00411       CubeAttributeInput(const FileName &fileName);
00412 
00413 
00415       ~CubeAttributeInput();
00416 
00417 
00419       std::vector<QString> bands() const;
00420 
00432       QString bandsString() const;
00433 
00435       void setBands(const std::vector<QString> &bands);
00436 
00437       using CubeAttribute<CubeAttributeInput>::toString;
00438 
00439     private:
00440       bool isBandRange(QString attribute) const;
00441 
00442       static QString toString(const std::vector<QString> &bands);
00443       static QList<bool (CubeAttributeInput::*)(QString) const> testers();
00444 
00445     private:
00446       std::vector<QString> m_bands; 
00447   };
00448 
00449 
00484   class CubeAttributeOutput : public CubeAttribute<CubeAttributeOutput> {
00485 
00486     public:
00487 
00489       CubeAttributeOutput();
00490 
00503       CubeAttributeOutput(const FileName &fileName);
00504 
00505 
00507       ~CubeAttributeOutput();
00508 
00509 
00511       bool propagatePixelType() const;
00512 
00514       bool propagateMinimumMaximum() const;
00515 
00517       Cube::Format fileFormat() const;
00518 
00520       QString fileFormatString() const;
00521 
00523       void setFileFormat(Cube::Format fmt);
00524 
00526       ByteOrder byteOrder() const;
00527 
00529       QString byteOrderString() const;
00530 
00532       void setByteOrder(ByteOrder order);
00533 
00535       double minimum() const;
00536 
00538       double maximum() const;
00539 
00541       void setMinimum(double min);
00542 
00544       void setMaximum(double max);
00545 
00547       PixelType pixelType() const;
00548 
00550       void setPixelType(PixelType type);
00551 
00553       void setLabelAttachment(LabelAttachment attachment);
00554 
00555       LabelAttachment labelAttachment() const;
00556 
00557       using CubeAttribute<CubeAttributeOutput>::toString;
00558 
00559 
00560     private:
00561       bool isByteOrder(QString attribute) const;
00562       bool isFileFormat(QString attribute) const;
00563       bool isLabelAttachment(QString attribute) const;
00564       bool isPixelType(QString attribute) const;
00565       bool isRange(QString attribute) const;
00566 
00567       static QString toString(Cube::Format);
00568 
00575       enum RangeType {
00576         PropagateRange, 
00577         RangeSet,       
00578       };
00579 
00580       static QList<bool (CubeAttributeOutput::*)(QString) const> testers();
00581   };
00582 };
00583 
00584 #endif