//******************************************************************* // Copyright (C) 2000 ImageLinks Inc. // // License: MIT // // See LICENSE.txt file in the top level directory for more details. // // Author: Garrett Potts // //************************************************************************* // $Id: ossimGrect.h 23664 2015-12-14 14:17:27Z dburken $ #ifndef ossimGrect_HEADER #define ossimGrect_HEADER 1 #include #include #include #include #include #include class OSSIM_DLL ossimGrect { public: friend OSSIM_DLL std::ostream& operator<<(std::ostream& os, const ossimGrect& rect); /** * Will default to 0,0,0,0. */ ossimGrect() : theUlCorner(0.0, 0.0, 0.0), theLrCorner(0.0, 0.0, 0.0) {} /** * Copies the passed in rectangle to this * object. */ ossimGrect(const ossimGrect& rect) : theUlCorner(rect.ul()), theLrCorner(rect.lr()) {} /** * WIll take two ground points and fill the * bounding rect appropriately. */ ossimGrect(const ossimGpt& p1, const ossimGpt& p2); /** * Takes the upper left and lower right ground * points */ ossimGrect(double ulLat, double ulLon, double lrLat, double lrLon, const ossimDatum* aDatum=ossimDatumFactory::instance()->wgs84()) : theUlCorner(ulLat, ulLon,0, aDatum), theLrCorner(lrLat, lrLon, 0, aDatum) {} ossimGrect(const ossimGpt& point, double latSpacingInDegrees, double lonSpacingInDegrees) : theUlCorner(point), theLrCorner(point) { std::vector v; computeEvenTiles(v, latSpacingInDegrees, lonSpacingInDegrees); if(v.size()) *this = v[0]; } ossimGrect(std::vector& points); ossimGrect(const ossimGpt& p1, const ossimGpt& p2, const ossimGpt& p3, const ossimGpt& p4); const ossimGrect& operator=(const ossimGrect& rect) { theUlCorner = rect.ul(); theLrCorner = rect.lr(); return *this; } inline ossimGpt midPoint()const; /** Returns the height of a rectangle in deg. */ inline ossim_float64 height() const; /** Returns the width of a rectangle in deg. */ inline ossim_float64 width() const; /** Returns the height of a rectangle in meters. */ ossim_float64 heightMeters() const; /** Returns the width of a rectangle in meters using the center lat for scaling EW direction. */ ossim_float64 widthMeters() const; inline const ossimGpt& ul()const; inline const ossimGpt& lr()const; inline ossimGpt ur() const; inline ossimGpt ll() const; inline ossimGpt& ul(); inline ossimGpt& lr(); inline void makeNan(); inline bool isLonLatNan()const; inline bool hasNans()const; inline bool isNan()const; /*! * Returns true if "this" rectangle is contained completely within the * input rectangle "rect". */ bool completely_within(const ossimGrect& rect) const; /*! * Returns true if any portion of an input rectangle "rect" intersects * "this" rectangle. */ bool intersects(const ossimGrect& rect) const; inline ossimGrect clipToRect(const ossimGrect& rect)const; inline ossimGrect combine(const ossimGrect& rect)const; /** * Expands existing rect to accomodate argument point. If this object contains NaNs * (uninitialized), then the rect is set to 0-area with the arg point as both UL and LR -- * convenient for establishing bounds in a loop over collection of points. This method does not * consider height. * @param gpt Argument point. */ void expandToInclude(const ossimGpt& gpt); void expandToInclude(const ossimGrect& rect); /** * METHOD: pointWithin(ossimGpt) * * @param gpt Point to test for withinness. * @param considerHgt true if the height is to be compared to be between ul.hgt and lr.hgt * @return true if argument is inside rectangle (or cuboid when hgt considered) * * @note There is no datum shift applied if * gpt is of a different datum than this datum. */ inline bool pointWithin(const ossimGpt& gpt, bool considerHgt=false) const; //inline below ossimGrect stretchToEvenBoundary(double latSpacingInDegrees, double lonSpacingInDegrees)const; void computeEvenTiles(std::vector& result, double latSpacingInDegrees, double lonSpacingInDegrees, bool clipToGeographicBounds = true)const; private: ossimGpt theUlCorner; // Contains max height as well ossimGpt theLrCorner; // Contains min height as well }; //==================== BEGIN INLINE DEFINITIONS =============================== //***************************************************************************** // INLINE METHOD: ossimGrect::midPoint() //***************************************************************************** inline ossimGpt ossimGrect::midPoint()const { return ossimGpt((ul().latd() + ur().latd() + ll().latd() + lr().latd())*.25, (ul().lond() + ur().lond() + ll().lond() + lr().lond())*.25, (ul().height()+ur().height()+ll().height()+ lr().height())*.25, ul().datum() ); } //***************************************************************************** // INLINE METHOD: ossimGrect::clipToRect() //***************************************************************************** inline ossimGrect ossimGrect::clipToRect(const ossimGrect& rect)const { double ulx, uly, lrx, lry; ulx = ossim::max(rect.ul().lond(),ul().lond()); uly = ossim::min(rect.ul().latd(),ul().latd()); lrx = ossim::min(rect.lr().lond(),lr().lond()); lry = ossim::max(rect.lr().latd(),lr().latd()); if( lrx < ulx || lry > uly ) { return ossimGrect(ossimGpt(0,0,0),ossimGpt(0,0,0)); } else { return ossimGrect(ossimGpt(uly, ulx, 0, rect.ul().datum()), ossimGpt(lry, lrx, 0, rect.ul().datum())); } } //******************************************************************* // Inline Method: ossimDrect::combine(const ossimDrect& rect) //******************************************************************* inline ossimGrect ossimGrect::combine(const ossimGrect& rect)const { if (isLonLatNan()) return rect; ossimGpt ulCombine; ossimGpt lrCombine; ulCombine.lon = ((ul().lon <= rect.ul().lon)?ul().lon:rect.ul().lon); ulCombine.lat = ((ul().lat >= rect.ul().lat)?ul().lat:rect.ul().lat); lrCombine.lon = ((lr().lon >= rect.lr().lon)?lr().lon:rect.lr().lon); lrCombine.lat = ((lr().lat <= rect.lr().lat)?lr().lat:rect.lr().lat); return ossimGrect(ulCombine, lrCombine); } //***************************************************************************** // INLINE METHOD: ossimGrect::pointWithin() //***************************************************************************** inline bool ossimGrect::pointWithin(const ossimGpt& gpt, bool considerHgt) const { bool within = (gpt.lat <= theUlCorner.lat) && (gpt.lat >= theLrCorner.lat) && (gpt.lon >= theUlCorner.lon) && (gpt.lon <= theLrCorner.lon); if (considerHgt) within &= (gpt.hgt <= theUlCorner.hgt) && (gpt.hgt >= theLrCorner.hgt); return within; } inline ossim_float64 ossimGrect::height() const { return (theUlCorner.latd() - theLrCorner.latd()); } inline ossim_float64 ossimGrect::width() const { return (theLrCorner.lond() - theUlCorner.lond()); } inline const ossimGpt& ossimGrect::ul() const { return theUlCorner; } inline ossimGpt ossimGrect::ur() const { ossimGpt gpt (theUlCorner.lat, theLrCorner.lon, theUlCorner.hgt, theUlCorner.datum()); return gpt; } inline ossimGpt ossimGrect::ll() const { ossimGpt gpt (theLrCorner.lat, theUlCorner.lon, theLrCorner.hgt, theLrCorner.datum()); return gpt; } inline const ossimGpt& ossimGrect::lr() const { return theLrCorner; } inline ossimGpt& ossimGrect::ul() { return theUlCorner; } inline ossimGpt& ossimGrect::lr() { return theLrCorner; } inline void ossimGrect::makeNan() { theUlCorner.makeNan(); theLrCorner.makeNan(); } inline bool ossimGrect::isLonLatNan() const { return ( ossim::isnan(theUlCorner.lat) || ossim::isnan(theUlCorner.lon) || ossim::isnan(theLrCorner.lat) || ossim::isnan(theLrCorner.lon) ); } inline bool ossimGrect::hasNans() const { return ( theUlCorner.hasNans() || theLrCorner.hasNans() ); } inline bool ossimGrect::isNan()const { return ( theUlCorner.hasNans() && theLrCorner.hasNans() ); } #endif /* End of "#ifndef ossimGrect_HEADER" */