DS9FileReader.h

Go to the documentation of this file.
00001 //# DS9FileReader.h: Implementation for DS9 region file reader etc.
00002 //# Copyright (C) 2008
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id$
00027 #ifndef DS9FILEREADER_H_
00028 #define DS9FILEREADER_H_
00029 
00030 #include <QStringList>
00031 
00032 #include <display/RegionShapes/RSFileReaderWriter.h>
00033 #include <coordinates/Coordinates/Coordinate.h>
00034 #include <display/DisplayDatas/DrawingDisplayData.h>
00035 
00036 #include <casa/namespace.h>
00037 
00038 namespace casa {
00039 
00040 // Contains common enums, constants, and methods for DS9 files.
00041         class DS9 {
00042         public:
00043                 // Units.
00044                 // <group>
00045                 enum CoordinateUnit {
00046                     Degrees, Radians, PhysicalPixels, ImagePixels, HMS, DMS, ArcSec,
00047                     ArcMin, UNSET
00048                 };
00049 
00050                 static const String FILE_ARCMIN;
00051                 static const String FILE_ARCSEC;
00052                 static const String FILE_DEGREES;
00053                 static const String FILE_DELIMITER;
00054                 static const String FILE_DMS_D;
00055                 static const String FILE_DMS_M;
00056                 static const String FILE_DMS_S;
00057                 static const String FILE_HMS_H;
00058                 static const String FILE_HMS_M;
00059                 static const String FILE_HMS_S;
00060                 static const String FILE_IMAGE_PIXELS;
00061                 static const String FILE_PHYSICAL_PIXELS;
00062                 static const String FILE_RADIANS;
00063 
00064                 static CoordinateUnit coordinateUnit(const String& unit) {
00065                         if(unit == FILE_ARCMIN) return ArcMin;
00066                         else if(unit == FILE_ARCSEC) return ArcSec;
00067                         else if(unit == FILE_DEGREES) return Degrees;
00068                         else if(unit == FILE_IMAGE_PIXELS) return ImagePixels;
00069                         else if(unit == FILE_PHYSICAL_PIXELS) return PhysicalPixels;
00070                         else if(unit == FILE_RADIANS) return Radians;
00071 
00072                         else return UNSET;
00073                 }
00074 
00075                 static const QRegExp REGEXP_HDMS;
00076                 static const QRegExp REGEXP_HMS;
00077                 static const QRegExp REGEXP_DMS;
00078                 static const QRegExp REGEXP_NUMSYS;
00079                 // </group>
00080 
00081 
00082                 // Coordinate systems.
00083                 // <group>
00084                 enum CoordinateSystem {
00085                     Physical, Image, FK4, FK5, Galactic, Ecliptic, Linear, Amplifier,
00086                     Detector
00087                 };
00088 
00089                 static CoordinateSystem defaultCoordinateSystem() {
00090                         return Physical;
00091                 }
00092 
00093                 static const QString FILE_AMPLIFIER;
00094                 static const QString FILE_B1950;
00095                 static const QString FILE_DETECTOR;
00096                 static const QString FILE_ECLIPTIC;
00097                 static const QString FILE_FK4;
00098                 static const QString FILE_FK5;
00099                 static const QString FILE_GALACTIC;
00100                 static const QString FILE_ICRS;
00101                 static const QString FILE_IMAGE;
00102                 static const QString FILE_J2000;
00103                 static const QString FILE_LINEAR;
00104                 static const QString FILE_PHYSICAL;
00105 
00106                 static QStringList coordinateSystemFirstWords() {
00107                         QStringList list;
00108                         list << FILE_AMPLIFIER << FILE_B1950 << FILE_DETECTOR;
00109                         list << FILE_ECLIPTIC << FILE_FK4 << FILE_FK5 << FILE_GALACTIC;
00110                         list << FILE_ICRS << FILE_IMAGE << FILE_J2000 << FILE_LINEAR;
00111                         list << FILE_PHYSICAL;
00112                         return list;
00113                 }
00114 
00115                 static CoordinateSystem coordinateSystem(const QString& cs) {
00116                         QString c = cs.toLower();
00117                         if(c == FILE_AMPLIFIER) return Amplifier;
00118                         else if(c == FILE_B1950 || c == FILE_FK4) return FK4;
00119                         else if(c == FILE_DETECTOR) return Detector;
00120                         else if(c == FILE_ECLIPTIC) return Ecliptic;
00121                         else if(c == FILE_FK5 || c == FILE_J2000 || c == FILE_ICRS) return FK5;
00122                         else if(c == FILE_GALACTIC) return Galactic;
00123                         else if(c == FILE_IMAGE) return Image;
00124                         else if(c == FILE_LINEAR) return Linear;
00125                         else if(c == FILE_PHYSICAL) return Physical;
00126 
00127                         else return defaultCoordinateSystem();
00128                 }
00129 
00130                 static QString coordinateSystem(CoordinateSystem c) {
00131                         switch(c) {
00132                         case Physical:
00133                                 return FILE_PHYSICAL;
00134                         case Image:
00135                                 return FILE_IMAGE;
00136                         case FK4:
00137                                 return FILE_FK4;
00138                         case FK5:
00139                                 return FILE_FK5;
00140                         case Galactic:
00141                                 return FILE_GALACTIC;
00142                         case Ecliptic:
00143                                 return FILE_ECLIPTIC;
00144                         case Linear:
00145                                 return FILE_LINEAR;
00146                         case Amplifier:
00147                                 return FILE_AMPLIFIER;
00148                         case Detector:
00149                                 return FILE_DETECTOR;
00150 
00151                         default:
00152                                 return "";
00153                         }
00154                 }
00155                 // </group>
00156 
00157 
00158                 // Regions.
00159                 // <group>
00160                 enum RegionType {
00161                     Circle, Annulus, Ellipse, EllipseAnnulus, Box, BoxAnnulus, Polygon,
00162                     Line, Vector, Text, Ruler, CirclePoint, BoxPoint, DiamondPoint,
00163                     CrossPoint, XPoint, ArrowPoint, BoxCirclePoint, Compass, Projection,
00164                     Panda, EllipticalPanda, BoxPanda, Composite
00165                 };
00166 
00167                 // region types, first word
00168                 static const QString FILE_ANNULUS;
00169                 static const QString FILE_ARROW;     // only for "arrow point"
00170                 static const QString FILE_BOX;
00171                 static const QString FILE_BOXCIRCLE; // only for "boxcircle point"
00172                 static const QString FILE_BPANDA;
00173                 static const QString FILE_CIRCLE;
00174                 static const QString FILE_COMPASS;
00175                 static const QString FILE_COMPOSITE;
00176                 static const QString FILE_CROSS;     // only for "cross point"
00177                 static const QString FILE_DIAMOND;   // only for "diamond point"
00178                 static const QString FILE_ELLIPSE;
00179                 static const QString FILE_EPANDA;
00180                 static const QString FILE_LINE;
00181                 static const QString FILE_PANDA;
00182                 static const QString FILE_POINT;
00183                 static const QString FILE_POLYGON;
00184                 static const QString FILE_PROJECTION;
00185                 static const QString FILE_RULER;
00186                 static const QString FILE_TEXT;
00187                 static const QString FILE_VECTOR;
00188                 static const QString FILE_X;         // only for "x point"
00189 
00190                 static QStringList regionFirstWords() {
00191                         QStringList list;
00192                         list << FILE_ANNULUS << FILE_ARROW << FILE_BOX << FILE_BOXCIRCLE;
00193                         list << FILE_BPANDA << FILE_CIRCLE << FILE_COMPASS << FILE_COMPOSITE;
00194                         list << FILE_CROSS << FILE_DIAMOND << FILE_ELLIPSE << FILE_EPANDA;
00195                         list << FILE_LINE << FILE_PANDA << FILE_POINT << FILE_POLYGON;
00196                         list << FILE_PROJECTION << FILE_RULER << FILE_TEXT << FILE_VECTOR;
00197                         list << FILE_X;
00198                         return list;
00199                 }
00200 
00201                 static QString regionType(RegionType type) {
00202                         switch(type) {
00203                         case Circle:
00204                                 return FILE_CIRCLE;
00205                         case Annulus:
00206                                 return FILE_ANNULUS;
00207                         case Ellipse:
00208                         case EllipseAnnulus:
00209                                 return FILE_ELLIPSE;
00210                         case Box:
00211                         case BoxAnnulus:
00212                                 return FILE_BOX;
00213                         case Polygon:
00214                                 return FILE_POLYGON;
00215                         case Line:
00216                                 return FILE_LINE;
00217                         case Vector:
00218                                 return FILE_VECTOR;
00219                         case Text:
00220                                 return FILE_TEXT;
00221                         case Ruler:
00222                                 return FILE_RULER;
00223                         case CirclePoint:
00224                                 return FILE_CIRCLE + " " + FILE_POINT;
00225                         case BoxPoint:
00226                                 return FILE_BOX + " " + FILE_POINT;
00227                         case DiamondPoint:
00228                                 return FILE_DIAMOND + " " + FILE_POINT;
00229                         case CrossPoint:
00230                                 return FILE_CROSS + " " + FILE_POINT;
00231                         case XPoint:
00232                                 return FILE_X + " " + FILE_POINT;
00233                         case ArrowPoint:
00234                                 return FILE_ARROW + " " + FILE_POINT;
00235                         case BoxCirclePoint:
00236                                 return FILE_BOXCIRCLE+ " " +FILE_POINT;
00237                         case Compass:
00238                                 return FILE_COMPASS;
00239                         case Projection:
00240                                 return FILE_PROJECTION;
00241                         case Panda:
00242                                 return FILE_PANDA;
00243                         case EllipticalPanda:
00244                                 return FILE_EPANDA;
00245                         case BoxPanda:
00246                                 return FILE_BPANDA;
00247                         case Composite:
00248                                 return FILE_COMPOSITE;
00249 
00250                         default:
00251                                 return "";
00252                         }
00253                 }
00254 
00255                 static QString pointType(RegionType type) {
00256                         switch(type) {
00257                         case CirclePoint:
00258                                 return FILE_CIRCLE;
00259                         case BoxPoint:
00260                                 return FILE_BOX;
00261                         case DiamondPoint:
00262                                 return FILE_DIAMOND;
00263                         case CrossPoint:
00264                                 return FILE_CROSS;
00265                         case XPoint:
00266                                 return FILE_X;
00267                         case ArrowPoint:
00268                                 return FILE_ARROW;
00269                         case BoxCirclePoint:
00270                                 return FILE_BOXCIRCLE;
00271 
00272                         default:
00273                                 return "";
00274                         }
00275                 }
00276                 // </group>
00277 
00278                 // DS9 defaults.
00279                 // <group>
00280                 static const int MARKER_SIZE;
00281                 static const int ARROW_SIZE;
00282                 // </group>
00283 
00284                 // Miscellaneous.
00285                 // <group>
00286                 static const QString FILE_COMMENT;
00287                 static const QString FILE_COMPOSITE_OR;
00288                 static const QString FILE_EQUAL;
00289                 static const QString FILE_GLOBAL;
00290                 static const QString FILE_LINESEP;
00291                 static const QString FILE_MINUS;
00292                 static const QString FILE_PLUS;
00293                 static const QString FILE_TEXT_END1;
00294                 static const QString FILE_TEXT_END2;
00295                 static const QString FILE_TEXT_END3;
00296                 static const QString FILE_TEXT_START1;
00297                 static const QString FILE_TEXT_START2;
00298                 static const QString FILE_TEXT_START3;
00299                 // </group>
00300         };
00301 
00302 
00303 // Class to represent a single coordinate (value + unit).
00304         class DS9Coordinate {
00305         public:
00306                 // Constructor which takes a system and a unit.
00307                 DS9Coordinate(DS9::CoordinateSystem s, DS9::CoordinateUnit u = DS9::UNSET);
00308 
00309                 // Destructor.
00310                 ~DS9Coordinate();
00311 
00312 
00313                 // Sets the coordinate system to the given.
00314                 void set(DS9::CoordinateSystem system);
00315 
00316                 // Sets the coordinate unit to the given.
00317                 void set(DS9::CoordinateUnit unit);
00318 
00319                 // Sets the single value to the given.
00320                 void set(double value);
00321 
00322                 // Sets the HMS/DMS value to the given.  minusZero is used when the first
00323                 // value is zero, but the whole value is negative.
00324                 void set(double val1, double val2, double val3, bool minusZero = false);
00325 
00326                 // Returns the coordinate system.
00327                 DS9::CoordinateSystem system() const;
00328 
00329                 // Returns the unit.
00330                 DS9::CoordinateUnit unit() const;
00331 
00332                 // Returns the first value.  No conversion is used.
00333                 double value() const;
00334 
00335                 // Returns the value(s).  Size will be 1 for normal coordinates, 3 for
00336                 // HMS/DMS.  No conversion is used.
00337                 vector<double> values() const;
00338 
00339                 // Returns 1 for normal coordinates or 3 for HMS/DMS.
00340                 unsigned int size() const;
00341 
00342                 // Returns true if this coordinate is valid, false otherwise.  If the
00343                 // coordinate is invalid (such as an unset unit), the method will attempt
00344                 // to fix it.
00345                 bool isValid() const;
00346 
00347                 // Returns a String version for use with DS9Region::toPrintString.
00348                 String toPrintString() const;
00349 
00350                 // Returns the value in degrees.
00351                 double toDegrees() const;
00352 
00353         private:
00354                 DS9::CoordinateSystem m_system; // coordinate system
00355                 DS9::CoordinateUnit m_unit;     // coordinate unit
00356                 vector<double> m_values;        // values
00357                 bool m_minusZero;               // minusZero flag for HMS/DMS
00358         };
00359 
00360 
00361 // Holds information for read DS9 regions.  A DS9Region consists of a type,
00362 // a list of coordinates, a coordinate system, and a set of properties.
00363 // Composite regions also have a list of children regions.  For simplicity,
00364 // properties are either bool properties or String properties.  All properties
00365 // have defaults which are set during construction.
00366         class DS9Region { /*: public RFRegion*/
00367                 //friend class DS9RegionFileReader;
00368 
00369         public:
00370                 // Public Static Members/Methods //
00371 
00372                 // Properties.
00373                 // <group>
00374                 static const String PROP_BACKGROUND;
00375                 static const String PROP_COLOR;
00376                 static const String PROP_COMPASS;
00377                 static const String PROP_COMPASS_ELABEL;
00378                 static const String PROP_COMPASS_NLABEL;
00379                 static const String PROP_COMPOSITE;
00380                 static const String PROP_DASH;
00381                 static const String PROP_DASHLIST;
00382                 static const String PROP_DELETE;
00383                 static const String PROP_EDIT;
00384                 static const String PROP_FIXED;
00385                 static const String PROP_FONT;
00386                 static const String PROP_HIGHLITE;
00387                 static const String PROP_INCLUDE;
00388                 static const String PROP_LINE;
00389                 static const String PROP_MARKER_SIZE;
00390                 static const String PROP_MOVE;
00391                 static const String PROP_ROTATE;
00392                 static const String PROP_RULER;
00393                 static const String PROP_SELECT;
00394                 static const String PROP_SOURCE;
00395                 static const String PROP_TAG;
00396                 static const String PROP_TEXT;
00397                 static const String PROP_TEXTANGLE;
00398                 static const String PROP_VECTOR;
00399                 static const String PROP_WIDTH;
00400                 // </group>
00401 
00402                 // Note: when adding new properties:
00403                 // 1) add to properties(), DS9RegionFileWriter::globalProperties() (if
00404                 //    necessary)
00405                 // 2) add to isBoolProperty()
00406                 // 3) for strings, add to valueIsValid
00407                 // 4) add to defaultBoolValue() or defaultStringValue()
00408                 // 5) if special printing is required, edit toPrintString,
00409                 //    DS9RegionFileWriter::writeGlobals()
00410                 // 6) if special input is required, edit
00411                 //    DS9RegionFileReader::readProperties()
00412 
00413                 // Returns all valid properties.
00414                 static vector<String> properties() {
00415                         static vector<String> v(26);
00416                         v[0] = PROP_INCLUDE;
00417                         v[1] = PROP_TEXT;
00418                         v[2] = PROP_COLOR;
00419                         v[3] = PROP_FONT;
00420                         v[4] = PROP_SELECT;
00421                         v[5] = PROP_EDIT;
00422                         v[6] = PROP_MOVE;
00423                         v[7] = PROP_ROTATE;
00424                         v[8] = PROP_DELETE;
00425                         v[9] = PROP_FIXED;
00426                         v[10] = PROP_LINE;
00427                         v[11] = PROP_RULER;
00428                         v[12] = PROP_SOURCE;
00429                         v[13] = PROP_BACKGROUND;
00430                         v[14] = PROP_TEXTANGLE;
00431                         v[15] = PROP_WIDTH;
00432                         v[16] = PROP_MARKER_SIZE;
00433                         v[17] = PROP_HIGHLITE;
00434                         v[18] = PROP_TAG;
00435                         v[19] = PROP_VECTOR;
00436                         v[20] = PROP_COMPASS;
00437                         v[21] = PROP_COMPASS_NLABEL;
00438                         v[22] = PROP_COMPASS_ELABEL;
00439                         v[23] = PROP_COMPOSITE;
00440                         v[24] = PROP_DASH;
00441                         v[25] = PROP_DASHLIST;
00442                         return v;
00443                 }
00444 
00445                 // Returns true if the given String is a valid property, false otherwise.
00446                 static bool isProperty(const String& prp) {
00447                         static vector<String> v = properties();
00448                         for(unsigned int i = 0; i < v.size(); i++) if(v[i] == prp) return true;
00449                         return false;
00450                 }
00451 
00452                 // Returns true if the given String is a valid bool property, false
00453                 // otherwise.
00454                 static bool isBoolProperty(const String& property) {
00455                         if(!isProperty(property)) return false;
00456                         else return property != PROP_TEXT && property != PROP_COLOR &&
00457                                             property != PROP_FONT && property != PROP_LINE &&
00458                                             property != PROP_RULER && property != PROP_TEXTANGLE &&
00459                                             property != PROP_WIDTH && property != PROP_MARKER_SIZE &&
00460                                             property != PROP_TAG && property != PROP_COMPASS &&
00461                                             property != PROP_COMPASS_NLABEL &&
00462                                             property != PROP_COMPASS_ELABEL &&
00463                                             property != PROP_DASHLIST;
00464                 }
00465 
00466                 // Returns true if the given value is valid for the given String property
00467                 // and region type, false otherwise.
00468                 static bool valueIsValid(const String& property, const String& value,
00469                                          DS9::RegionType type) {
00470                         if(property == PROP_COLOR) {
00471                                 if(value == "white"   || value == "black" || value == "red" ||
00472                                         value == "green"   || value == "blue"  || value == "cyan" ||
00473                                         value == "magenta" || value == "yellow" || value == "gray" ||
00474                                         value == "grey") return true;
00475                                 QString v(value.c_str());
00476                                 return (v.size() == 7 &&
00477                                         v.indexOf(QRegExp("#(?:\\d|[A-F]|[a-f]){6}")) == 0) ||
00478                                        (v.size() == 6 &&
00479                                         v.indexOf(QRegExp("(?:\\d|[A-F]|[a-f]){6}")) == 0);
00480                         } else if(property == PROP_FONT) {
00481                                 QStringList split = QString(value.c_str()).split(QRegExp("\\s+"));
00482                                 if(split.size() < 3) return false;
00483                                 bool valid;
00484                                 split[1].toInt(&valid);
00485                                 if(!valid) return false;
00486                                 return split[2] == "bold" || split[2] == "normal" ||
00487                                        split[2] == "italic" || split[2] == "italics";
00488                         } else if(property == PROP_LINE) {
00489                                 QStringList split = QString(value.c_str()).split(QRegExp("\\s+"));
00490                                 if(split.size() < 2) return false;
00491                                 return (split[0] == "0" || split[0] == "1") &&
00492                                        (split[1] == "0" || split[1] == "1");
00493                         } else if(property == PROP_DASHLIST) {
00494                                 QStringList split = QString(value.c_str()).split(QRegExp("\\s+"));
00495                                 if(split.size() < 2) return false;
00496                                 bool valid;
00497                                 split[0].toUInt(&valid);
00498                                 if(!valid) return false;
00499                                 split[1].toUInt(&valid);
00500                                 return valid;
00501                         } else if(property == PROP_RULER) {
00502                                 QStringList split = QString(value.c_str()).split(QRegExp("\\s+"));
00503                                 if(split.size() < 2) return false;
00504                                 split[0] = split[0].toLower();
00505                                 split[1] = split[1].toLower();
00506                                 return DS9::coordinateSystemFirstWords().contains(split[0]) &&
00507                                        (split[1] == "image"   || split[1] == "physical" ||
00508                                         split[1] == "degrees" || split[1] == "arcmin" ||
00509                                         split[1] == "arcsec");
00510                         } else if(property == PROP_TEXTANGLE) {
00511                                 bool valid;
00512                                 QString(value.c_str()).toDouble(&valid);
00513                                 return type == DS9::Text && valid;
00514                         } else if(property == PROP_WIDTH) {
00515                                 bool valid;
00516                                 QString(value.c_str()).toDouble(&valid);
00517                                 return valid;
00518                         } else if(property == PROP_MARKER_SIZE) {
00519                                 bool valid;
00520                                 QString(value.c_str()).toInt(&valid);
00521                                 return valid;
00522                         } else if(property == PROP_COMPASS) {
00523                                 return DS9::coordinateSystemFirstWords().contains(value.c_str(),
00524                                         Qt::CaseInsensitive);
00525                         } else return !isBoolProperty(property);
00526                 }
00527 
00528                 // Returns the default value for the given bool property.
00529                 static bool defaultBoolValue(const String& property) {
00530                         if(property == PROP_INCLUDE)         return true;
00531                         else if(property == PROP_SELECT)     return true;
00532                         else if(property == PROP_EDIT)       return true;
00533                         else if(property == PROP_MOVE)       return true;
00534                         else if(property == PROP_ROTATE)     return true;
00535                         else if(property == PROP_DELETE)     return true;
00536                         else if(property == PROP_FIXED)      return false;
00537                         else if(property == PROP_SOURCE)     return true;
00538                         else if(property == PROP_BACKGROUND) return false;
00539                         else if(property == PROP_HIGHLITE)   return true;
00540                         else if(property == PROP_VECTOR)     return true;
00541                         else if(property == PROP_COMPOSITE)  return false;
00542                         else if(property == PROP_DASH)       return false;
00543                         else return false;
00544                 }
00545 
00546                 // Returns the default value for the given String property.
00547                 static String defaultStringValue(const String& property) {
00548                         if(property == PROP_TEXT)                return "";
00549                         else if(property == PROP_COLOR)          return "green";
00550                         else if(property == PROP_FONT)           return "helvetica 10 normal";
00551                         else if(property == PROP_LINE)           return "0 0";
00552                         else if(property == PROP_RULER)          return "pixels";
00553                         else if(property == PROP_TEXTANGLE)      return "0";
00554                         else if(property == PROP_WIDTH)          return "1";
00555                         else if(property == PROP_MARKER_SIZE)
00556                                 return String::toString(DS9::MARKER_SIZE);
00557                         else if(property == PROP_TAG)            return "";
00558                         else if(property == PROP_COMPASS)        return "image";
00559                         else if(property == PROP_COMPASS_NLABEL) return "N";
00560                         else if(property == PROP_COMPASS_ELABEL) return "E";
00561                         else if(property == PROP_DASHLIST)       return "8 3";
00562                         else return "";
00563                 }
00564 
00565 
00566                 // Non-Static //
00567 
00568                 // Constructor, which types a type and a coordinate system.
00569                 DS9Region(DS9::RegionType type, DS9::CoordinateSystem coordSys);
00570 
00571                 // Destructor.
00572                 ~DS9Region();
00573 
00574 
00575                 // Returns a human-readable representation of this region.
00576                 String toPrintString() const;
00577 
00578                 // Returns a name.
00579                 String name() const;
00580 
00581                 // Converts this region to a RegionShape.  Not all DS9 region types are
00582                 // supported and thus this may return NULL.  For unsupported regions, see
00583                 // cookbook documentation.
00584                 RegionShape* toRegionShape() const;
00585 
00586 
00587                 // Returns the region type.
00588                 DS9::RegionType type() const;
00589 
00590                 // Sets/adds the given properties to this region's.  Returns false if an
00591                 // error occured.
00592                 bool setProperties(const RecordInterface& properties);
00593 
00594                 // Defines the given bool property with the given value.  Returns false if
00595                 // the given property is invalid.
00596                 bool define(const String& property, bool value);
00597 
00598                 // Defines the given String property with the given value.  Returns false
00599                 // if the given property or value is invalid.
00600                 bool define(const String& property, const String& value);
00601 
00602                 // Returns true if the given property is defined, false otherwise.
00603                 bool isDefined(const String& property);
00604 
00605                 // Returns the value for the given bool property.
00606                 bool boolValue(const String& property);
00607 
00608                 // Returns the String value for the given String property.
00609                 String stringValue(const String& property);
00610 
00611                 // Adds the given coordinate to the region.
00612                 void pushCoordinate(const DS9Coordinate& coord);
00613 
00614                 // Adds the given region to this composite region (does nothing for non-
00615                 // composite regions).
00616                 void pushCompositeRegion(const DS9Region& region);
00617 
00618                 // Returns true if this region's coordinates are valid, false otherwise.
00619                 // If the coordinates are invalid, this method will attempt to fix them
00620                 // first.
00621                 bool checkCoordinates();
00622 
00623                 // Returns true if this region's properties are valid, false otherwise.
00624                 // If the properties are invalid, this method will attempt to fix them
00625                 // first.
00626                 bool checkProperties();
00627 
00628                 // Returns the last error found during toRegionShape().  This error is only
00629                 // valid if toRegionShape() returns NULL which indicates an error was
00630                 // encountered.
00631                 const RFError& lastError() const;
00632 
00633         private:
00634                 DS9::RegionType m_type;               // Region type.
00635                 DS9::CoordinateSystem m_system;       // Region coordinate system.
00636                 vector<DS9Coordinate> m_coords;       // Region coordinates.
00637                 Record m_props;                       // Region properties.
00638                 vector<DS9Region> m_compositeRegions; // Composite children.
00639 
00640                 // Last encountered error during toRegionShape.
00641                 RFError m_lastError;
00642 
00643                 // Convenience method for setting the last error during toRegionShape.
00644                 void setError(const String& error, bool isFatal = false) const;
00645         };
00646 
00647 
00648 // Implementation of RSFileReader for DS9 regions.
00649         class DS9FileReader : public RSFileReader {
00650         public:
00651                 // Constructor.
00652                 DS9FileReader();
00653 
00654                 // Destructor.
00655                 ~DS9FileReader();
00656 
00657 
00658                 // RSFileReader methods //
00659 
00660                 // Implements RSFileReader::read.
00661                 bool read(vector<RegionShape*>& shapes);
00662 
00663         private:
00664                 // Whether a coordinate system has been set in the file, and what it is.
00665                 pair<DS9::CoordinateSystem, bool> m_nextSystem;
00666 
00667                 // Read regions.
00668                 vector<DS9Region> m_regions;
00669 
00670                 // Current read global properties.
00671                 Record m_globals;
00672 
00673 
00674                 // Processes the given line and returns whether an error occurred or not.
00675                 // If an error occurred, the details are appended to invalid.
00676                 bool processLine(const QString& line, stringstream& invalid);
00677 
00678                 // Processes the given region and returns whether an error occurred or not.
00679                 // If an error occurred, the details are appended to invalid.  line should
00680                 // contain the comma-, parentheses-, or whitespace-separated text before
00681                 // the comment symbol, while "comment" should contain all text after the
00682                 // comment symbol.  The include flag is used to set the include property.
00683                 bool processRegion(QStringList& line, QString& comment,
00684                                    stringstream& invalid, bool include = true);
00685 
00686                 // Processes the given coordinate system and returns whether an error
00687                 // occurred or not.  If an error occurred, the details are appended to
00688                 // invalid.
00689                 bool processCoordSys(QString& line, stringstream& invalid);
00690 
00691                 // Processes the given global line and returns whether an error occurred or
00692                 // not.  If an error occurred, the details are appended to invalid.
00693                 bool processGlobal(QString& line, stringstream& invalid);
00694 
00695                 // Processes the given comment into properties for the given region, and
00696                 // returns whether an error occurred or not.  If an error occurred, the
00697                 // details are appended to invalid.
00698                 bool processComment(DS9Region& region, QString& comment,
00699                                     stringstream& invalid);
00700 
00701                 // For "point" regions.  Parses the given comment for a point=type property
00702                 // and places the correct type into "type".  Returns whether the operation
00703                 // succeeded or not.
00704                 bool readPointType(QString& comment, DS9::RegionType& type);
00705 
00706                 // Reads properties in the given line into the given record.
00707                 bool readProperties(Record& record, QString& line);
00708         };
00709 
00710 }
00711 
00712 #endif /*DS9FILEREADER_H_*/
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1