OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimRangeDomeTileSource.cpp
Go to the documentation of this file.
1 /*
2  * ossimRangeDomeTileSource.cpp
3  *
4  * Created on: Aug 3, 2015
5  * Author: okramer
6  */
7 
10 #include <ossim/base/ossimCommon.h>
13 #include <ossim/base/ossimIpt.h>
14 #include <ossim/base/ossimDpt.h>
16 #include <ossim/base/ossimNotify.h>
20 #include <iostream>
21 
22 using namespace std;
23 
24 RTTI_DEF1(ossimRangeDomeTileSource, "ossimRangeDomeTileSource", ossimImageHandler);
25 
27 
28 ossimRangeDome::ossimRangeDome(vector<ossimString>& tokens)
29 : valid (false),
30  id (0),
31  radiusMeters (0),
32  radiusPixelsSq (0),
33  classification (UNASSIGNED),
34  startAz (0),
35  endAz (0)
36 {
37  if ((tokens.size() < 6) || (tokens[0].size() && (tokens[0].chars()[0] == '#')))
38  return;
39 
40  ossim_uint32 i = 0;
41  id = tokens[i++].toUInt32();
42  centerGpt.lat = tokens[i++].toDouble();
43  centerGpt.lon = tokens[i++].toDouble();
44  centerGpt.hgt = tokens[i++].toDouble();
45  radiusMeters = tokens[i++].toDouble();
46  classification = (Classification) tokens[i++].toInt32();
47  valid = true;
48 
49  if (tokens.size() >= 8)
50  {
51  startAz = tokens[i++].toDouble();
52  endAz = tokens[i++].toDouble();
53  if (endAz == 360.0)
54  endAz = 0.0;
55  }
56 
57  if ( tokens.size()-i )
58  {
59  description = tokens[i];
60  description.trim();
61  }
62 }
63 
65 {
67  double dlat = radiusMeters/scale.y;
68  double dlon = radiusMeters/scale.x;
69  return ossimGrect(centerGpt.lat+dlat, centerGpt.lon-dlon,
70  centerGpt.lat-dlat, centerGpt.lon+dlon);
71 }
72 
74 : m_gsd(1.0, 1.0) // default GSD
75 {
76 }
77 
78 
80 {
81  close();
82 }
83 
84 
86 {
87 #if 0 /* Please wrap with traceDebug(). drb */
88  if (!theImageFile.isReadable())
89  {
90  ossimNotify(ossimNotifyLevel_WARN)<<"ossimRangeDomeTileSource::open() -- Error. Coould not"
91  " open CSV file at <"<<theImageFile<<">" << endl;
92  return false;
93  }
94 #endif
95 
96  ossimString dome_spec;
98  char* magic_number = new char [ sizeOfMagic ];
99 
100  // Open the CSV and check proper file type:
101  ifstream indata (theImageFile.chars());
102  if (indata.fail())
103  return false;
104  indata.read(magic_number, sizeOfMagic);
105 
106  if (indata.eof() || indata.fail() || (OSSIM_RANGE_DOME_SPEC_MAGIC_NUMBER != magic_number))
107  return false;
108 
109  // loop over each record/dome spec:
110  vector<ossimString> tokens;
111  while (indata.good())
112  {
113  tokens.clear();
114  getline(indata, dome_spec);
115  dome_spec.split(tokens, ",", true);
116  ossimRangeDome dome (tokens);
117  if (dome.valid)
118  m_rangeDomes.push_back(dome);
119  }
120 
121  // The GSD may be incorrect, but init anyway then redo whe GSD is set:
122  initialize();
123 
124  return isOpen();
125 }
126 
128 {
129  if (!isOpen())
130  return;
131 
132  // Establish bounding rect:
133  ossimGrect boundingRect;
134  boundingRect.makeNan();
135  vector<ossimRangeDome>::iterator dome = m_rangeDomes.begin();
136  while (dome != m_rangeDomes.end())
137  {
138  boundingRect.expandToInclude(dome->boundingRect());
139  ++dome;
140  }
141 
142  // Set up the geometry:
144  mapProj->setOrigin(boundingRect.midPoint());
145  mapProj->setMetersPerPixel(m_gsd);
146  ossimDpt degPerPixel (mapProj->getDecimalDegreesPerPixel());
147  mapProj->setElevationLookupFlag(false);
148  mapProj->setUlTiePoints(boundingRect.ul());
149  ossimIpt image_size(boundingRect.width()/degPerPixel.x, boundingRect.height()/degPerPixel.y);
150  theGeometry = new ossimImageGeometry(0, mapProj.get());
151  theGeometry->setImageSize(image_size);
152 
153  // Transform the domes to image space coordinates:
154  dome = m_rangeDomes.begin();
155  double r;
156  while (dome != m_rangeDomes.end())
157  {
158  theGeometry->worldToLocal(dome->centerGpt, dome->centerIpt);
159  r = dome->radiusMeters/m_gsd.x;
160  dome->radiusPixelsSq = r*r;
161  ++dome;
162  }
163 }
164 
165 
167 {
168  return (!m_rangeDomes.empty());
169 }
170 
171 
173 {
174  m_rangeDomes.clear();
175  theGeometry = 0;
176 }
177 
178 
180  ossim_uint32 resLevel)
181 {
183 
184  tile->setImageRectangle(rect);
185  tile->initialize();
186 
187  getTile(tile.get(), resLevel);
188 
189  return tile;
190 }
191 
192 
194 {
195  if (!result || !theGeometry.valid())
196  return false;
197 
198  // Start with null fill:
199  result->fill(getNullPixelValue());
200 
201  // Verify intersection with dataset. Everything done in R0 space:
202  ossimIrect tile_rect (result->getImageRectangle());
203  ossim_uint32 coord_scale = resLevel + 1;
204  ossimIrect tile_rect_r0 (coord_scale*tile_rect);
205  ossimIrect boundingImgRect;
206  theGeometry->getBoundingRect(boundingImgRect);
207 
208  if (!tile_rect_r0.intersects(boundingImgRect))
209  {
211  return true;
212  }
213 
214  vector<ossimRangeDome>::iterator dome;
215  double d2, x0, y0, dx, dy, az;
216 
217  // Nested loop over all pixels in tile:
218  for (ossim_int32 yn=tile_rect.ul().y; yn<=tile_rect.lr().y; ++yn)
219  {
220  y0 = yn * coord_scale;
221 
222  for (ossim_int32 xn=tile_rect.ul().x; xn<=tile_rect.lr().x; ++xn)
223  {
224  x0 = xn * coord_scale;
225 
226  // Loop over each dome in the list to see if this pixel is affected:
227  dome = m_rangeDomes.begin();
228  while (dome != m_rangeDomes.end())
229  {
230  // Check distance to center:
231  dx = x0 - dome->centerIpt.x;
232  dy = y0 - dome->centerIpt.y;
233  d2 = dx*dx + dy*dy;
234 
235  if (d2 > dome->radiusPixelsSq)
236  {
237  ++dome;
238  continue;
239  }
240 
241  // Passed range test, do azimuth test. First check for simple 360 dome:
242  if (dome->startAz == dome->endAz)
243  {
244  result->setValue(xn, yn, (ossim_uint8) dome->classification);
245  ++dome;
246  continue;
247  }
248 
249  // Need full azimuth test:
250  az = ossim::atan2d(dx, -dy);
251  if (az < 0)
252  az += 360;
253  if (((dome->startAz < dome->endAz) && (az >= dome->startAz) && (az <= dome->endAz)) ||
254  ((dome->startAz > dome->endAz) && (
255  ((az >= dome->startAz) && (az > dome->endAz)) ||
256  ((az < dome->startAz) && (az <= dome->endAz)))))
257  {
258  result->setValue(xn, yn, (ossim_uint8) dome->classification);
259  }
260  ++dome;
261  }
262  }
263  }
264 
265  result->validate();
266  return true;
267 }
268 
269 
271 {
272  return 1;
273 }
274 
275 
277 {
278  if (theGeometry.valid())
279  return ( theGeometry->getImageSize().y / (resLevel+1) );
280  return 0;
281 }
282 
283 
285 {
286  if (theGeometry.valid())
287  return ( theGeometry->getImageSize().x / (resLevel+1) );
288  return 0;
289 }
290 
291 
292 bool ossimRangeDomeTileSource::saveState(ossimKeywordlist& kwl, const char* prefix) const
293 {
294  static const char MODULE[] = "ossimRangeDomeTileSource::saveState()";
295 
296  ossimImageHandler::saveState(kwl, prefix);
298  {
300  << " ERROR detected in keyword list! State not saved." << std::endl;
301  return false;
302  }
303 
305 
306  return true;
307 }
308 
309 
310 bool ossimRangeDomeTileSource::loadState(const ossimKeywordlist& kwl, const char* prefix)
311 {
312  static const char MODULE[] = "ossimRangeDomeTileSource::loadState()";
313  theDecimationFactors.clear();
314 
315  ossimImageHandler::loadState(kwl, prefix);
317  {
319  << "WARNING: error detected in keyword list! State not load." << std::endl;
320  return false;
321  }
322 
323  ossimDpt gsd;
325  if (!value.empty())
326  gsd.x = value.toDouble();
327 
328  value = kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_Y_KW);
329  if (!value.empty())
330  setGSD(value.toDouble());
331 
332  // The rest of the state is established by opening the file:
333  bool good_open = open();
334  return good_open;
335 }
336 
337 
339 {
340  if (!property.valid())
341  return;
342 
343  ossimString s;
344  property->valueToString(s);
345  if (s.empty())
346  return;
347 
348  // The user should select either explicit GSD or relative GSD factor, never both:
349  if ( property->getName() == ossimKeywordNames::METERS_PER_PIXEL_KW )
350  {
351  ossim_float64 gsd = s.toFloat64();
352  if (!ossim::isnan(gsd))
353  setGSD(gsd);
354  }
355  else
356  {
358  }
359 }
360 
361 
363 {
366  {
368  prop = new ossimStringProperty(name, value);
369  }
370  else
371  {
372  prop = ossimImageHandler::getProperty(name);
373  }
374  return prop;
375 }
376 
377 
378 
380 {
381  gsd.x =(1.0/(resLevel+1)) * m_gsd.x;
382  gsd.y =(1.0/(resLevel+1)) * m_gsd.y;
383 }
384 
385 
387 {
388  if (gsd == m_gsd.x)
389  return;
390 
391  m_gsd.x = gsd;
392  m_gsd.y = gsd;
393 
394  initialize();
395 }
396 
397 
398 
virtual const ossimDpt & getDecimalDegreesPerPixel() const
Returns decimal degrees per pixel as an ossimDpt with "x" representing longitude and "y" representing...
void fill(ossim_uint32 band, ossim_float64 value)
will fill the entire band with the value.
ossimGrect boundingRect() const
ossimRefPtr< ossimImageGeometry > theGeometry
static const ossimString OSSIM_RANGE_DOME_SPEC_MAGIC_NUMBER
virtual void setValue(ossim_int32 x, ossim_int32 y, ossim_float64 color)
ossimFilename theImageFile
virtual void setImageRectangle(const ossimIrect &rect)
const ossimIpt & getImageSize() const
virtual void setGSD(const ossim_float64 &gsd)
Represents serializable keyword/value map.
RTTI_DEF1(ossimRangeDomeTileSource, "ossimRangeDomeTileSource", ossimImageHandler)
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
std::vector< ossimDpt > theDecimationFactors
void makeNan()
Definition: ossimGrect.h:284
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual bool isOpen() const
Derived classes must implement this method to be concrete.
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
void getBoundingRect(ossimIrect &bounding_rect) const
Get the bounding rect of (0, 0) to (imageSize.x-1, imageSize.y-1).
ossim_float64 width() const
Returns the width of a rectangle in deg.
Definition: ossimGrect.h:247
double y
Definition: ossimDpt.h:165
virtual void setOrigin(const ossimGpt &origin)
Sets theOrigin to origin.
static ossimString toString(bool aValue)
Numeric to string methods.
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const
Pure virtual, derived classes must implement.
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
static const ossimErrorCode OSSIM_ERROR
std::istream & getline(std::istream &is, ossimString &str, char delim)
Definition: ossimString.h:916
Classification classification
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
virtual void setProperty(ossimRefPtr< ossimProperty > property)
void setImageSize(const ossimIpt &size)
static const char * METERS_PER_PIXEL_Y_KW
virtual void initialize()
Initialize the data buffer.
virtual void setMetersPerPixel(const ossimDpt &gsd)
void expandToInclude(const ossimGpt &gpt)
Expands existing rect to accommodate argument point.
Definition: ossimGrect.cpp:299
std::vector< ossimRangeDome > m_rangeDomes
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
static ossimImageDataFactory * instance()
ossimRangeDome(std::vector< ossimString > &tokens)
yy_size_t size
virtual ossimDataObjectStatus validate() const
ossim_float64 lon
Definition: ossimGpt.h:266
std::string::size_type size() const
Definition: ossimString.h:405
virtual void setProperty(ossimRefPtr< ossimProperty > property)
The reader properties are: – the GSD ("meters_per_pixel")
unsigned int ossim_uint32
const char * chars() const
For backward compatibility.
Definition: ossimString.h:77
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
double toDouble() const
ossim_float64 toFloat64() const
const ossimGpt & ul() const
Definition: ossimGrect.h:252
virtual ossimIrect getImageRectangle() const
double atan2d(double y, double x)
Definition: ossimCommon.h:267
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const
Pure virtual, derived classes must implement.
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
ossimGpt midPoint() const
Definition: ossimGrect.h:178
bool isReadable() const
virtual void close()
Deletes the overview and clears the valid image vertices.
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
virtual void initialize()
initialize Does nothing in this class.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual ossimErrorCode getErrorStatus() const
ossim_int32 y
Definition: ossimIpt.h:142
static const char * METERS_PER_PIXEL_KW
double x
Definition: ossimDpt.h:164
bool empty() const
Definition: ossimString.h:411
virtual void getGSD(ossimDpt &gsd, ossim_uint32 resLevel) const
virtual void setDataObjectStatus(ossimDataObjectStatus status) const
Full list found in ossimConstants.h.
virtual void setUlTiePoints(const ossimGpt &gpt)
bool worldToLocal(const ossimGpt &world_pt, ossimDpt &local_pt) const
Exposes the 3D world-to-local image coordinate reverse projection.
ossimDpt metersPerDegree() const
Definition: ossimGpt.cpp:498
virtual ossim_uint32 getNumberOfInputBands() const
ossim_int32 x
Definition: ossimIpt.h:141
ossim_float64 lat
Definition: ossimGpt.h:265
ossim_float64 height() const
Returns the height of a rectangle in deg.
Definition: ossimGrect.h:242
Class used for rendering range domes (a.k.a.
void setElevationLookupFlag(bool flag)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual bool open()
Reads CSV file representing range domes.
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
unsigned char ossim_uint8
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
const ossimString & getName() const
int ossim_int32
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91