casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Region.h
Go to the documentation of this file.
00001 //# Region.h: base class for statistical regions
00002 //# Copyright (C) 2011
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 
00028 
00029 #ifndef REGION_REGION_H_
00030 #define REGION_REGION_H_
00031 
00032 #include <set>
00033 #include <list>
00034 #include <string>
00035 #include <images/Images/ImageStatistics.h>
00036 #include <measures/Measures/MDirection.h>
00037 #include <display/region/RegionInfo.h>
00038 #include <display/Utilities/dtor.h>
00039 #include <display/Display/MouseToolState.h>
00040 #include <display/Utilities/VOID.h>
00041 #include <stdexcept>
00042 
00043 
00044 extern "C" void casa_viewer_pure_virtual( const char *file, int line, const char *func );
00045 #define DISPLAY_PURE_VIRTUAL(FUNCTION,RESULT) \
00046   { casa_viewer_pure_virtual( __FILE__, __LINE__, #FUNCTION ); return RESULT; }
00047 
00048 namespace casa {
00049 
00050     class WorldCanvas;
00051     class PrincipalAxesDD;
00052     template <class T> class ImageInterface;
00053     class ImageRegion;
00054         class DisplayData;
00055 
00056     namespace viewer {
00057 
00058         // convert linear coordinates to viewer screen coordinates...
00059         void linear_to_screen( WorldCanvas *wc_, double, double, int &, int & );
00060         void linear_to_screen( WorldCanvas *wc_, double, double, double, double, int &, int &, int &, int & );
00061         // convert linear coordinates to casa pixel coordinates...
00062         void linear_to_pixel( WorldCanvas *wc_, double, double, double &, double & );
00063         void linear_to_pixel( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00064         // convert viewer screen coordinates to linear coordinates...
00065         void screen_to_linear( WorldCanvas *wc_, int, int, double &, double & );
00066         void screen_to_linear( WorldCanvas *wc_, int, int, int, int, double &, double &, double &, double & );
00067         // convert linear coordinates to world coordinates...
00068         void linear_to_world( WorldCanvas *wc_, double, double, double &, double & );
00069         void linear_to_world( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00070         // convert world coordinates to linear coordinates...
00071         void world_to_linear( WorldCanvas *wc_, double, double, double &, double & );
00072         void world_to_linear( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double& );
00073         // convert casa pixel coordinates to world coordinates...
00074         void pixel_to_world( WorldCanvas *wc_, double, double, double &, double & );
00075         void pixel_to_world( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00076         // convert casa pixel coordinates to linear coordinates...
00077         void pixel_to_linear( WorldCanvas *wc_, double, double, double &, double & );
00078         void pixel_to_linear( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00079 
00080         // convert linear coordinates to specific coordinate systems...
00081         void linear_to_j2000( WorldCanvas *wc_, double, double, double &, double & );
00082         void linear_to_j2000( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00083         void linear_to_b1950( WorldCanvas *wc_, double, double, double &, double & );
00084         void linear_to_b1950( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00085         void linear_to_galactic( WorldCanvas *wc_, double, double, double &, double & );
00086         void linear_to_galactic( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00087         void linear_to_ecliptic( WorldCanvas *wc_, double, double, double &, double & );
00088         void linear_to_ecliptic( WorldCanvas *wc_, double, double, double, double, double &, double &, double &, double & );
00089 
00090         void to_linear( WorldCanvas *, MDirection::Types in_type, double, double, double &, double & );
00091         void to_linear( WorldCanvas *, MDirection::Types in_type, double, double, double, double, double &, double &, double &, double & );
00092         void to_linear_offset( WorldCanvas *, MDirection::Types in_type, double, double, double &, double & );
00093 
00094         void screen_offset_to_linear_offset( WorldCanvas *wc_, int, int, double &, double & );
00095         void pixel_offset_to_linear_offset( WorldCanvas *wc_, double, double, double &, double & );
00096         void linear_offset_to_pixel_offset( WorldCanvas *wc_, double, double, double &, double & );
00097 
00098         MDirection::Types get_coordinate_type( const CoordinateSystem &wc );
00099 
00100 
00101         class ImageRegion_state {
00102                 public:
00103                         ImageRegion_state( ImageRegion *ir, size_t region_count ) : imageregion(ir), count_(region_count) { }
00104                         ImageRegion_state( const ImageRegion_state &other ) : imageregion(other.imageregion), count_(other.count_) { }
00105                         operator ImageRegion *( ) { return imageregion; }
00106                         size_t regionCount( ) const { return count_; }
00107                 private:
00108                         void* operator new (std::size_t) throw (std::logic_error)
00109                                                 { throw std::logic_error("allocating an object not intended for dynamic allocation"); }
00110                         ImageRegion *imageregion;
00111                         size_t count_;
00112         };
00113 
00114         // All regions are specified in "linear coordinates", not "pixel coordinates". This is necessary
00115         // because "linear coordinates" scale with zooming whereas "pixel coordinates" do not. Unfortunately,
00116         // this means that coordinate transformation is required each time the region is drawn.
00117         class Region : public dtorNotifier {
00118             public:
00119                 typedef std::set<Region*> region_list_type;
00120 
00121                 /* enum states { undisplayed, inactive, highlighted, selected }; */
00122                 // LSDoubleDashed is only used to preserve state (it is a Display::LineStyle option)
00123                 enum LineStyle { SolidLine, DashLine, DotLine, LSDoubleDashed };
00124                 enum TextPosition { TopText, RightText, BottomText, LeftText };
00125                 enum TextFontStyle { ItalicText = 1 << 0, BoldText = 1 << 1 };
00126                 enum Coord { J2000, B1950, Galactic, SuperGalactic, Ecliptic, DefaultCoord };
00127                 enum Units { Degrees, Radians, Sexagesimal, Pixel, DefaultUnits };
00128 
00129                 // state returned from mouse functions for regions...
00130                 enum MouseState { MouseRefresh = 1 << 0, MouseSelected = 1 << 1, MouseHandle = 1 << 2 };
00131 
00132                 enum RegionTypes { RectRegion, PointRegion, EllipseRegion, PolyRegion };
00133 
00134                 enum PointLocation { PointInside = 1 << 0, PointHandle = 1 << 1, PointOutside = 1 << 2 };
00135 
00136                 enum RegionChanges { RegionChangeCreate, RegionChangeUpdate, RegionChangeReset, RegionChangeFocus, RegionChangeModified, RegionChangeLabel, RegionChangeDelete, RegionChangeStatsUpdate, RegionChangeNewChannel };
00137 
00138                 class PointInfo {
00139                     public:
00140                         PointInfo( double x, double y, unsigned int location, unsigned int handle=0 ) :
00141                                                         x_(x), y_(y), location_(location), handle_(handle) { }
00142                         PointInfo( const PointInfo &other) : x_(other.x_), y_(other.y_), location_(other.location_), handle_(other.handle_) { }
00143                         unsigned int handle( ) const { return handle_; }
00144                         unsigned int &handle( ) { return handle_; }
00145                         unsigned int location( ) const { return location_; }
00146                         unsigned int operator&( PointLocation mask ) const { return location_ & mask; }
00147                         const PointInfo &operator=( const PointInfo &other ) {
00148                             x_ = other.x_;
00149                             y_ = other.y_;
00150                             location_ = other.location_;
00151                             handle_ = other.handle_;
00152                             return *this;
00153                         }
00154                         double x( ) const { return x_; }
00155                         double y( ) const { return y_; }
00156                         double &x( ) { return x_; }
00157                         double &y( ) { return y_; }
00158                     private:
00159                         double x_, y_;
00160                         unsigned int location_;
00161                         unsigned int handle_;
00162                 };
00163 
00164                 // functions to query results from mouse functions...
00165                 static bool refreshNeeded( int v ) { return v & MouseRefresh ? true : false; }
00166                 static bool regionSelected( int v ) { return v & MouseSelected ? true : false; }
00167                 static bool handleSelected( int v ) { return v & MouseHandle ? true : false; }
00168 
00169                 // user specified name
00170                 virtual const std::string name( ) const DISPLAY_PURE_VIRTUAL(Region::name,"");
00171 
00172                 virtual std::string lineColor( ) const DISPLAY_PURE_VIRTUAL(Region::lineColor,"cyan");
00173                 virtual std::string centerColor( ) const DISPLAY_PURE_VIRTUAL(Region::centerColor,"cyan");
00174                 virtual int lineWidth( ) const DISPLAY_PURE_VIRTUAL(Region::lineWidth,1);
00175                 virtual LineStyle lineStyle( ) const DISPLAY_PURE_VIRTUAL(Region::lineStyle,SolidLine);
00176 
00177                 virtual std::string textColor( ) const DISPLAY_PURE_VIRTUAL(Region::textColor,"cyan");
00178                 virtual std::string textFont( ) const DISPLAY_PURE_VIRTUAL(Region::textFont,"Courier");
00179                 virtual int textFontSize( ) const DISPLAY_PURE_VIRTUAL(Region::textFontSize,12);
00180                 virtual int textFontStyle( ) const DISPLAY_PURE_VIRTUAL(Region::textFontStyle,0);
00181                 virtual std::string textValue( ) const DISPLAY_PURE_VIRTUAL(Region::textValue,"");
00182                 virtual TextPosition textPosition( ) const DISPLAY_PURE_VIRTUAL(Region::textPosition,BottomText);
00183                 virtual void textPositionDelta( int &/*x*/, int &/*y*/ ) const DISPLAY_PURE_VIRTUAL(Region::textPositionDelta,);
00184 
00185                 virtual void setLabel( const std::string &l ) = 0;
00186                 virtual void setLabelPosition( TextPosition ) = 0;
00187                 virtual void setLabelDelta( const std::vector<int> & ) = 0;
00188                 virtual void setFont( const std::string &font="", int font_size=-1, int font_style=0, const std::string &font_color="" ) = 0;
00189                 virtual void setLine( const std::string &line_color="", Region::LineStyle line_style=Region::SolidLine, unsigned int line_width=1 ) = 0;
00190                 virtual void setAnnotation(bool) = 0;
00191 
00192                 void getCoordinatesAndUnits( Region::Coord &c, Region::Units &x_units, Region::Units &y_units,
00193                                              std::string &width_height_units ) const;
00194                 void getPositionString( std::string &x, std::string &y, std::string &angle,
00195                                         double &bounding_width, double &bounding_height,
00196                                         Region::Coord coord = Region::DefaultCoord,
00197                                         Region::Units x_units = Region::DefaultUnits,
00198                                         Region::Units y_units = Region::DefaultUnits,
00199                                         const std::string &bounding_units = "rad" ) const;
00200 
00201                 bool translateX( const std::string &/*x*/, const std::string &/*x_units*/, const std::string &/*coordsys*/ );
00202                 bool translateY( const std::string &/*x*/, const std::string &/*y_units*/, const std::string &/*coordsys*/ );
00203                 bool resizeX( const std::string &/*x*/, const std::string &/*x_units*/, const std::string &/*coordsys*/ );
00204                 bool resizeY( const std::string &/*x*/, const std::string &/*y_units*/, const std::string &/*coordsys*/ );
00205 
00206                 // one would expect the "number of frames" in our composite cube (including
00207                 // multiple images) to be contained in the non-GUI portion of the viewer
00208                 // hierarchy, but rather it is within the Qt portion... thus this function
00209                 // to fetch it...   <drs>
00210                 virtual int numFrames( ) const DISPLAY_PURE_VIRTUAL(Region::numFrames,0);
00211                 virtual void zRange( int &/*min*/, int &/*max*/ ) const DISPLAY_PURE_VIRTUAL(Region::zRange,);
00212                 int zIndex( ) const;
00213                 bool regionVisible( ) const { return visible_; }
00214 
00215                 bool worldBoundingRectangle( double &, double &, const std::string & ) const;
00216 
00217                 virtual ~Region( ) { }
00218 
00219                 Region( ) : wc_(0), selected_(false), visible_(true), mouse_in_region(false) { }
00220                 Region( WorldCanvas *wc );
00221 
00222                 // is this region degenerate?
00223                 virtual bool degenerate( ) const;
00224 
00225                 void setDrawingEnv( );
00226                 void resetDrawingEnv( );
00227                 void setTextEnv( );
00228                 void resetTextEnv( );
00229                 void pushDrawingEnv( LineStyle ls, int thickness=-1 );
00230                 void popDrawingEnv( );
00231 
00232                 void setDrawCenter(bool draw_center){draw_center_=draw_center;};
00233                 bool getDrawCenter(){return draw_center_;};
00234 
00235                 // duplicate of MultiWCTool::refresh( )
00236                 void refresh( );
00237 
00238                 virtual PointInfo checkPoint( double x, double y ) const = 0;
00239 
00240                 // returns OR'ed set of MouseState...
00241                 virtual unsigned int mouseMovement( double /*x*/, double /*y*/, bool /*other_selected*/ )
00242                 DISPLAY_PURE_VIRTUAL(Region::mouseMovement,0);
00243 
00244                 virtual void draw( bool other_selected );
00245 
00246                 // indicates that region movement requires that the statistcs be updated...
00247                 virtual void updateStateInfo( bool /*region_modified*/, Region::RegionChanges /*change*/ ) DISPLAY_PURE_VIRTUAL(Region::updateStateInfo,);
00248 
00249                 // indicates that the center info is no longer valid
00250                 virtual void invalidateCenterInfo( ) DISPLAY_PURE_VIRTUAL(Region::invalidateCenterInfo,);
00251 
00252                 bool selected( ) const { return selected_; }
00253 
00254                 virtual bool weaklySelected( ) const = 0;
00255                 virtual void weaklySelect( ) = 0;
00256                 virtual void weaklyUnselect( ) = 0;
00257                 // indicates that the user has selected this rectangle...
00258                 // ...may need to scroll region dock
00259                 virtual void selectedInCanvas( ) DISPLAY_PURE_VIRTUAL(Region::selectedInCanvas,);
00260 
00261                 // blank out the statistics for this region
00262                 virtual void clearStatistics( ) DISPLAY_PURE_VIRTUAL(Region::clearStatistics,);
00263 
00264                 virtual bool clickWithin( double /*x*/, double /*y*/ ) const DISPLAY_PURE_VIRTUAL(Region::clickWithin,false);
00265                 virtual int clickHandle( double /*x*/, double /*y*/ ) const DISPLAY_PURE_VIRTUAL(Region::clickHandle,0);
00266                 // return value indicates if any data was flagged...
00267                 virtual bool doubleClick( double /*x*/, double /*y*/ );
00268                 // for rectangles, resizing can change the handle...
00269                 // for rectangles, moving a handle is resizing...
00270                 virtual int moveHandle( int handle, double /*x*/, double /*y*/ ) DISPLAY_PURE_VIRTUAL(Region::moveHandle,handle);
00271                 virtual void move( double /*dx*/, double /*dy*/ ) DISPLAY_PURE_VIRTUAL(Region::move,);
00272                 virtual void resize( double /*width_delta*/, double /*height_delta*/ ) = 0;
00273                 virtual bool valid_translation( double dx, double dy, double width_delta, double height_delta ) = 0;
00274 
00275                 // functions added with the introduction of RegionToolManager and the
00276                 // unified selection and manipulation of the various region types...
00277                 virtual void mark( bool set=true ) = 0;
00278                 virtual bool marked( ) const = 0;
00279                 // returns the new state...
00280                 virtual bool mark_toggle( ) = 0;
00281 
00282                 void clearMouseInRegion( ) { mouse_in_region = false; }
00283 
00284                 // update status information...
00285                 virtual void status( const std::string &msg, const std::string &type="info" ) = 0;
00286 
00287                 virtual bool markCenter( ) const DISPLAY_PURE_VIRTUAL(Region::markCenter,true);
00288 
00289                 virtual bool skyComponent( ) const DISPLAY_PURE_VIRTUAL(Region::skyComponent,true);
00290 
00291                 // in "linear" coordinates...
00292                 virtual void boundingRectangle (double &/*blc_x*/, double &/*blc_y*/, double &/*trc_x*/,
00293                                                 double &/*trc_y*/) const
00294                 DISPLAY_PURE_VIRTUAL(Region::boundingRectangle,);
00295 
00296                 virtual void emitUpdate( )
00297                         DISPLAY_PURE_VIRTUAL(Region::emitUpdate,);
00298             protected:
00299                 virtual std::list<RegionInfo> *generate_dds_statistics( );
00300                 // hook to allow generate_dds_statistics( ) to generate statistics
00301                 // for rectangular measurement set regions...
00302                 virtual void generate_nonimage_statistics( DisplayData*, std::list<RegionInfo> * ) { }
00303 
00304                 virtual ImageRegion *get_image_region( DisplayData* ) const
00305                         DISPLAY_PURE_VIRTUAL(Region::get_image_region,0);
00306                 virtual ImageRegion_state get_image_selected_region( DisplayData* );
00307 
00308                 virtual const std::list<Region*> &get_selected_regions( ) = 0;
00309                 virtual size_t selected_region_count( )
00310                         DISPLAY_PURE_VIRTUAL(Region::selected_region_count,0);
00311                 virtual size_t marked_region_count( ) = 0;
00312                         /* DISPLAY_PURE_VIRTUAL(Region::marked_region_count,0); */
00313 
00314                 virtual std::list<RegionInfo> *generate_dds_centers(bool )
00315                         DISPLAY_PURE_VIRTUAL(Region::generate_dds_centers, new std::list<RegionInfo>( ));
00316 
00317                 static Int getAxisIndex( ImageInterface<Float> *image, std::string axtype );
00318 
00319                 inline double linear_average( double a, double b ) const { return (a + b) / 2.0; }
00320                 RegionInfo::center_t *getLayerCenter( PrincipalAxesDD *padd, ImageInterface<Float> *image, ImageRegion& imgReg);
00321                 RegionInfo::stats_t  *getLayerStats( PrincipalAxesDD *padd, ImageInterface<Float> *image, ImageRegion& imgReg );
00322 
00323                 Units current_xunits( ) const;
00324                 Units current_yunits( ) const;
00325                 Coord current_region_coordsys( ) const;
00326                 MDirection::Types current_casa_coordsys( ) const;
00327 
00328                 virtual void drawRegion( bool /*selected*/ ) = 0; //DISPLAY_PURE_VIRTUAL(Region::drawRegion,);
00329                 virtual void drawText( );
00330 
00331                 virtual void setCenter(double &, double &, double &, double &) DISPLAY_PURE_VIRTUAL(Region::setCenter,);
00332 
00333                 virtual void drawCenter(double &x, double &y );
00334                 virtual void drawCenter(double &x, double &y, double &deltx, double &delty);
00335 
00336 
00337                 virtual bool within_drawing_area( );
00338 
00339                 LineStyle current_ls;
00340                 typedef std::pair<LineStyle,int> ls_ele;
00341                 std::list<ls_ele> ls_stack;
00342                 WorldCanvas *wc_;
00343 
00344                 int last_z_index;
00345                 bool selected_;
00346 
00347                 bool visible_;
00348 
00349                 // Should this region be considered complete?
00350                 // Set to true by derived classes...
00351                 bool complete;
00352 
00353                 // Derived classes set this to true and clear it when the mouse
00354                 // enters and exits this regions bounding box...
00355                 bool mouse_in_region;
00356 
00357             private:
00358                 void set_line_style(const ls_ele&);
00359                 bool draw_center_;
00360 
00361         };
00362 
00363         // used to pass point specific marker information (marker type and scaling)
00364         // to generic region creation routines RegionTool::create(...)
00365         class PointMarkerState : public VOID {
00366             public:
00367                 PointMarkerState( QtMouseToolNames::PointRegionSymbols t, int s ) : VOID("viewer.PointMarkerState"), type_(t), scale_(s) { }
00368                 QtMouseToolNames::PointRegionSymbols type( ) const { return type_; }
00369                 int scale( ) const { return scale_; }
00370             private:
00371                 QtMouseToolNames::PointRegionSymbols type_;
00372                 int scale_;
00373         };
00374     }
00375 }
00376 
00377 #endif