1 //**************************************************************************************************
2 //
3 // OSSIM (http://trac.osgeo.org/ossim/)
4 //
5 // License:  MIT -- See LICENSE.txt file in the top level directory for more details.
6 //
7 //**************************************************************************************************
8 // $Id$
9 
10 #ifndef ossimPointCloudImageSource_HEADER
11 #define ossimPointCloudImageSource_HEADER
12 
13 #include <ossim/base/ossimConstants.h>
14 #include <ossim/base/ossimString.h>
15 #include <ossim/imaging/ossimImageHandler.h>
16 #include <ossim/base/ossimIrect.h>
17 #include <ossim/point_cloud/ossimPointCloudHandler.h>
18 #include <vector>
19 #include <mutex>
20 
21 class ossimImageData;
22 class ossimTiffOverviewTileSource;
23 class ossimPoinCloudHandler;
24 
25 /**
26  * Class used for rendering point cloud data into a raster tile. It is derived from
27  * ossimImageHandler so that it can be included in the available file formats for reading as
28  * maintained by the ossimImageHandlerRegistry. This base class implementation exposes the data
29  * elements represented by the base-class ossimPointCloudSource and the individual point base-class
30  * ossimPointCloudRecord, namely, intensity, RGB color, elevation, and number of returns.
31  *
32  * For sensor systems providing additional renderable data items, a derived class will be required
33  * to expose those components.
34  */
35 class OSSIMDLLEXPORT ossimPointCloudImageHandler : public ossimImageHandler
36 {
37 public:
main(String[] args)38    enum Components { INTENSITY=0, HIGHEST, LOWEST, RETURNS, RGB, NUM_COMPONENTS /*not a component*/ };
39 
40    ossimPointCloudImageHandler();
41    virtual ~ossimPointCloudImageHandler();
42 
43    /**
44     *  @brief open method.
45     *  Satisfies ossimImageHandler::open pure virtual.
46     *  @return Returns true on success, false on error.
47     *  @note This method relies on the data member ossimImageData::theImageFile
48     *  being set.  Callers should do a "setFilename" prior to calling this
49     *  method or use the ossimImageHandler::open that takes a file name and an
50     *  entry index.
51     */
52    virtual bool open() override;
53 
54    /**
55     *  @brief is open method.
56     *  Satisfies ossimImageHandler::isOpen pure virtual.
57     *  @return true if open, false if not.
58     */
59    virtual bool isOpen() const override { return m_pch.valid(); }
60 
61 
62    /**
63     * @brief Close method.
64     */
65    virtual void close() override;
66 
67    /**
68     *  Returns a pointer to a tile given an origin representing the upper left
69     *  corner of the tile to grab from the image.
70     *  Satisfies pure virtual from TileSource class.
71     */
72    ossimRefPtr<ossimImageData> getTile(const  ossimIrect& rect,
73                                        ossim_uint32 resLevel=0) override;
74 
75    /**
76     * Method to get a tile.
77     * @param result The tile to stuff.  Note The requested rectangle in full
78     * image space and bands should be set in the result tile prior to
79     * passing.  It will be an error if:
80     * result.getNumberOfBands() != this->getNumberOfOutputBands()
81     * @return true on success false on error.  If return is false, result
82     *  is undefined so caller should handle appropriately with makeBlank or
checkSize(int actual, int expected, String prop)83     * whatever.
84     */
85    bool getTile(ossimImageData* result, ossim_uint32 resLevel=0) override;
86 
87    /**
88     * @brief Gets bands.
89     * Satisfies ossimImageSource::getNumberOfInputBands pure virtual.
90     * @retrun Number of bands.
91     */
92    ossim_uint32 getNumberOfInputBands() const override;
93 
94    /**
95     * @brief Gets lines.
96     * Satisfies ossimImageHandler::getNumberOfLines pure virtual.
97     * @param resLevel Reduced resolution level to return lines of.
98     * Default = 0
99     * @return The number of lines for specified reduced resolution level.
100     */
101    ossim_uint32 getNumberOfLines(ossim_uint32 resLevel = 0) const override;
102 
103    /**
104     * @brief Gets samples.
105     * Satisfies ossimImageHandler::getNumberOfSamples
106     * @param resLevel Reduced resolution level to return samples of.
107     * Default = 0
108     * @return The number of samples for specified reduced resolution level.
109     */
110    ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel = 0) const override;
111 
112    /**
113     * @brief Gets tile width.
114     * Satisfies ossimImageHandler::getImageTileWidth pure virtual.
115     * @return The tile width of the image or 0 if the image is not tiled.
116     * Note: this is not the same as the ossimImageSource::getTileWidth which
117     * returns the output tile width which can be different than the internal
118     * image tile width on disk.
119     */
120    ossim_uint32 getImageTileWidth() const  override;
121 
122    /**
123     * @brief Gets tile height.
124     * Satisfies ossimImageHandler::getImageTileHeight pure virtual.
125     * @return The tile width of the image or 0 if the image is not tiled.
126     * Note: this is not the same as the ossimImageSource::getTileWidth which
127     * returns the output tile width which can be different than the internal
128     * image tile width on disk.
129     */
130    ossim_uint32 getImageTileHeight() const override;
131 
132    /** @return The width of the output tile. */
133    ossim_uint32 getTileWidth() const override;
134 
135    /** @returns The height of the output tile. */
136    ossim_uint32 getTileHeight() const override;
137 
138    /** @return The output pixel type of the tile source. */
139    ossimScalarType getOutputScalarType() const override;
140 
141    /**
142     * @brief Gets entry list.
143     * This list reflects the data component entry list provided by the derived point-cloud handler.
144     * This base class understands the basic (LIDAR-biased) entries: "Intensity", "RGB",
145     * "Elevation", and "Return". If a sensor provides other components, then a derived image handler
146     * will be needed to rasterize that data channel as well.
147     * @param entryList This is the list to initialize with entry indexes.
148     */
149    void getEntryList(std::vector<ossim_uint32>& entryList) const override;
150 
151    void getEntryNames(std::vector<ossimString>& entryNames) const override;
152 
153    /** @return The current entry number. */
154    ossim_uint32 getCurrentEntry() const override;
155 
156    /**
157     * @param entryIdx Entry number to select.
158     * @return true if it was able to set the current entry and false otherwise.
159     */
160    bool setCurrentEntry(ossim_uint32 entryIdx) override;
161 
162    /** @return "point-cloud" */
163    ossimString getShortName() const override;
164 
165    /** @return "ossim point cloud to image renderer" */
166    ossimString getLongName()  const override;
167 
168    /**
169     * Returns the image geometry object associated with this tile source or
170     * NULL if non defined.  The geometry contains full-to-local image
171     * transform as well as projection (image-to-world).
172     */
173    ossimRefPtr<ossimImageGeometry> getImageGeometry() override;
174 
175    /** @return Min pixel value. */
176    double getMinPixelValue(ossim_uint32 band) const override;
177 
178    /** @return Min pixel value. */
179    double getMaxPixelValue(ossim_uint32 band) const override;
180 
181    /** @return Min pixel value. */
182    double getNullPixelValue(ossim_uint32 band) const override;
183 
184    /** @return The total number of decimation levels. */
185    ossim_uint32 getNumberOfDecimationLevels() const override;
186 
187    bool saveState(ossimKeywordlist& kwl, const char* prefix) const override;
188 
189    bool loadState(const ossimKeywordlist& kwl, const char* prefix) override;
190 
191    void getValidImageVertices(std::vector<ossimIpt>& validVertices,
192                               ossimVertexOrdering ordering,
193                               ossim_uint32 resLevel) const override;
194 
195    /**
196     * The reader properties are:
197     * -- the GSD ("meters_per_pixel") which overrides computed nominal GSD
198     * -- the GSD factor ("gsd_factor") scales the computed nominal GSD, defaults to 1.0.
199     * -- the active component as entry number ("entry") with possible values [0 - 4] corresponding
200     *    to "component" property (listed below)
201     * -- the active component ("component") as string with possible values
202     *    "intensity", "highest", "lowest", "returns", or "rgb", respectively (case insensitive)
203     */
204    void setProperty(ossimRefPtr<ossimProperty> property) override;
205    ossimRefPtr<ossimProperty> getProperty(const ossimString& name) const override;
206 
207    /**
208     * Permits backdoor for setting the input point cloud handler object. Useful for debug
209     */
210    bool setPointCloudHandler(ossimPointCloudHandler* pch);
211 
212    /** @brief Get the GSD for resLevel. */
213    void getGSD(ossimDpt& gsd, ossim_uint32 resLevel) const;
214 
215    /** @brief Sets m_gsd data member and projection if projection is set. */
216    void setGSD( const ossim_float64& gsd );
217 
218 
219 protected:
220    class PcrBucket
221    {
222    public:
223       PcrBucket() : m_bucket(0), m_numSamples(0) {}
224       PcrBucket(const ossim_float32* init_value, ossim_uint32 numBands);
225       PcrBucket(const ossim_float32& R, const ossim_float32& G, const ossim_float32& B);
226 
227       explicit PcrBucket(const ossim_float32& init_value);
228 
229       ~PcrBucket();
230       ossim_float32* m_bucket;
231       int m_numSamples;
232    };
233 
234    void initTile();
235 
236    void addSample(std::map<ossim_int32, PcrBucket*>& accumulator,
237                   ossim_int32 index,
238                   const ossimPointRecord* sample);
239 
240    void normalize(std::map<ossim_int32, PcrBucket*>& accumulator);
241 
242    ossim_uint32 componentToFieldCode() const;
243 
244    ossimRefPtr<ossimPointCloudHandler> m_pch;
245    ossim_float32                m_maxPixel;
246    ossim_float32                m_minPixel;
247    ossimDpt                     m_gsd;
248    ossim_float64                m_gsdFactor;
249    ossimRefPtr<ossimImageData>  m_tile;
250    std::mutex                   m_mutex;
251    Components                   m_activeComponent;
252    std::vector<ossimString>     m_componentNames;
253 };
254 
255 #endif /* ossimPointCloudRenderer_HEADER */
256