OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimAdjMapModel.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 // Copyright (c) 2005, Oscar Kramer, all rights reserved.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Oscar Kramer
9 //
10 // Description:
11 //
12 // Special "sensor model" that provides a conventional map projection but
13 // with additional capability for adjusting the map x,y coordinates with
14 // offset, scale, and rotation transform. Funtions to control notifications,
15 // information and error output.
16 //
17 //----------------------------------------------------------------------------
18 // $Id: ossimAdjMapModel.cpp 15766 2009-10-20 12:37:09Z gpotts $
19 
20 #include <cstdlib> /* for atof */
26 
27 // Geometry File Keywords:
28 static const char* PARAMETER_KEYWORDS[] = {"map_offset_x",
29  "map_offset_y",
30  "map_rotation",
31  "map_scale_x",
32  "map_scale_y"};
33 static const char* MAP_PROJ_FILE_KW = "map_proj_filename";
34 
35 RTTI_DEF1(ossimAdjMapModel, "ossimAdjMapModel", ossimSensorModel);
36 
37 //----------------------------------------------------------------------------
39 //----------------------------------------------------------------------------
40 
42  :
44  theAdjParams(NUM_ADJ_PARAMS),
45  theMapProjection(),
46  theCosTheta(0.0),
47  theSinTheta(0.0)
48 {
49  theImageSize = ossimIpt(0,0);
52 }
53 
54 //----------------------------------------------------------------------------
56 //----------------------------------------------------------------------------
57 
59  const ossimIpt& image_size)
60  :
62  theAdjParams(NUM_ADJ_PARAMS),
63  theMapProjection(map_proj),
64  theCosTheta(0.0),
65  theSinTheta(0.0)
66 {
68  theImageSize = image_size;
70 }
71 
72 //----------------------------------------------------------------------------
74 //----------------------------------------------------------------------------
75 
77  :
78  ossimSensorModel(copy_this),
79  theAdjParams(NUM_ADJ_PARAMS),
80  theMapProjection(copy_this.theMapProjection),
81  theCosTheta(0.0),
82  theSinTheta(0.0)
83 {
84  theAdjParams = copy_this.theAdjParams;
85 }
86 
87 //----------------------------------------------------------------------------
89 //----------------------------------------------------------------------------
91  const char* prefix)
92  :
93  ossimSensorModel(kwl),
94  theAdjParams(NUM_ADJ_PARAMS),
95  theMapProjection(),
96  theCosTheta(0.0),
97  theSinTheta(0.0)
98 
99 {
101  loadState(kwl, prefix);
102 }
103 
104 //----------------------------------------------------------------------------
106 //----------------------------------------------------------------------------
107 
109  :
111  theAdjParams(NUM_ADJ_PARAMS),
112  theMapProjection(),
113  theCosTheta(0.0),
114  theSinTheta(0.0)
115 {
117  ossimKeywordlist kwl (kwl_filename);
118  loadState(kwl);
119 }
120 
121 //----------------------------------------------------------------------------
123 //----------------------------------------------------------------------------
125 {
126  if (!theMapProjection)
127  {
128  theErrorStatus++;
129  return false;
130  }
131  theSensorID = "AdjMapModel";
133  theMeanGSD = 0.5*(theGSD.x + theGSD.y);
135 
136  return true;
137 }
138 
139 //----------------------------------------------------------------------------
141 //----------------------------------------------------------------------------
143 {
145 }
146 
147 //----------------------------------------------------------------------------
150 //----------------------------------------------------------------------------
152 {
153  // Initialize this adjustment as the initial geometry "adjustment":
156  setAdjustmentDescription("Initial Geometry");
157 
158  // Initialize each adjustable parameter for this initial:
159  setAdjustableParameter (OFFSET_X, 0.0, 1.0);
160  setParameterDescription(OFFSET_X, "map_offset_x");
162 
163  setAdjustableParameter (OFFSET_Y, 0.0, 1.0);
164  setParameterDescription(OFFSET_Y, "map_offset_y");
166 
167  setAdjustableParameter (ROTATION, 0.0, 1.0);
168  setParameterDescription(ROTATION, "map_rotation");
170 
171  setAdjustableParameter (SCALE_X, 0.0, 1.0);
172  setParameterDescription(SCALE_X, "map_scale_x");
174 
175  setAdjustableParameter (SCALE_Y, 0.0, 1.0);
176  setParameterDescription(SCALE_Y, "map_scale_y");
178 
179  updateModel();
180 }
181 
182 //----------------------------------------------------------------------------
185 //----------------------------------------------------------------------------
187 {
188  for (int i=0; i<NUM_ADJ_PARAMS; i++)
190 
193 }
194 
195 //----------------------------------------------------------------------------
197 //----------------------------------------------------------------------------
199  const double& heightEllipsoid,
200  ossimGpt& worldPoint) const
201 {
202  // Just call other transform method
203  // Check for bad map projection pointer:
204  if (!theMapProjection)
205  {
206  worldPoint = ossimGpt(ossim::nan(), ossim::nan(), ossim::nan());
207  return;
208  }
209 
210  // Adjust image point by transform:
211  double x = theAdjParams[SCALE_X]*(image_point.x - theAdjParams[OFFSET_X]);
212  double y = theAdjParams[SCALE_Y]*(image_point.y - theAdjParams[OFFSET_Y]);
213  ossimDpt adjusted_point(x*theCosTheta + y*theSinTheta,
215 
216  // Obtain ground point given adjusted image point:
218  heightEllipsoid,
219  worldPoint);
220  worldPoint.height(heightEllipsoid);
221 }
222 
223 //----------------------------------------------------------------------------
225 //----------------------------------------------------------------------------
227  ossimGpt& worldPoint) const
228 {
229  lineSampleHeightToWorld(image_point, 0.0, worldPoint);
230  if (!worldPoint.hasNans())
231  {
232 // worldPoint.height(theElevation->getHeightAboveEllipsoid(worldPoint));
233  }
234 }
235 
236 //----------------------------------------------------------------------------
239 //----------------------------------------------------------------------------
241  ossimDpt& image_point) const
242 {
243  // Check for bad map projection pointer:
244  if (!theMapProjection)
245  {
246  image_point = ossimDpt(ossim::nan(), ossim::nan());
247  return;
248  }
249 
250  // Obtain non-adjusted image point given ground point:
251  ossimDpt p1;
252  theMapProjection->worldToLineSample(world_point, p1);
253 
254  // Adjust image point by transform:
255  ossimDpt p2 (p1.x*theCosTheta - p1.y*theSinTheta,
256  p1.y*theCosTheta + p1.x*theSinTheta);
257  image_point.x = p2.x/theAdjParams[SCALE_X] + theAdjParams[OFFSET_X];
258  image_point.y = p2.y/theAdjParams[SCALE_Y] + theAdjParams[OFFSET_Y];
259 }
260 
261 //----------------------------------------------------------------------------
264 //----------------------------------------------------------------------------
265 bool ossimAdjMapModel::saveState(ossimKeywordlist& kwl, const char* prefix) const
266 {
267  // Save off map projection info:
268  if (theMapProjection.valid())
269  {
270  ossimString map_prefix(prefix);
271  if (map_prefix.size() && (map_prefix[map_prefix.size()-1] != '.'))
272  map_prefix += ".";
273  map_prefix += "map_proj.";
274  theMapProjection->saveState(kwl, map_prefix.chars());
275  }
276 
277  // Hand off to base class for common stuff:
278  ossimSensorModel::saveState(kwl, prefix);
279 
280  // Save off data members:
281  kwl.add(prefix, ossimKeywordNames::TYPE_KW, "ossimAdjMapModel");
282  for (int i=0; i<NUM_ADJ_PARAMS; i++)
283  kwl.add(prefix, PARAMETER_KEYWORDS[i], theAdjParams[i]);
284 
285  return true;
286 }
287 
288 //----------------------------------------------------------------------------
291 //----------------------------------------------------------------------------
292 bool ossimAdjMapModel::loadState(const ossimKeywordlist& kwl, const char* prefix)
293 {
294  static const ossimString MODULE ("ossimAdjMapModel::loadState() -- ");
295  bool success = true;
296  const char* value_str;
297  double value;
298  ossimString error_msg (MODULE+"Error encountered reading keyword: ");
299 
300  try
301  {
302  // Verify correct model type:
303  value_str = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
304  if ((!value_str) || (strcmp(value_str, TYPE_NAME(this))))
305  {
306  throw (error_msg + ossimKeywordNames::TYPE_KW);
307  }
308 
309  ossimString map_prefix(prefix);
310  if (map_prefix.size() && (map_prefix[map_prefix.size()-1] != '.'))
311  map_prefix += ".";
312  map_prefix += "map_proj.";
313  theMapProjection = dynamic_cast<ossimMapProjection*>(
315 
316  //---
317  // Instantiate the map projection via the factory if one has not been
318  // initialized yet:
319  //---
320  if (!theMapProjection)
321  {
322  // should find the map projection filename in the KWL:
323  value_str = kwl.find(prefix, MAP_PROJ_FILE_KW);
324  if (!value_str)
325  {
326  throw (error_msg + MAP_PROJ_FILE_KW);
327  }
329  ossimMapProjectionFactory::instance()->createProjection(ossimKeywordlist(value_str)));
330  if (!theMapProjection)
331  {
332  throw "Error encountered instantiating map ";
333  }
334  }
335 
336  // Hand off to base class for common stuff:
337  ossimSensorModel::loadState(kwl, prefix);
338 
339  // Everything OK so far, just load in the adjustable parameters. This involves modifying the
340  // center value of the bsae class adjustable parameter:
341  for (int i=0; i<NUM_ADJ_PARAMS; i++)
342  {
343  value_str = kwl.find(prefix, PARAMETER_KEYWORDS[i]);
344  if (!value_str)
345  {
346  throw (error_msg + PARAMETER_KEYWORDS[i]).chars();
347  }
348  value = atof(value_str);
349  setParameterCenter(i, value);
350  }
351  }
352  catch (const char* /*message*/)
353  {
354  theErrorStatus++;
355  success = false;
356  }
357 
358  //---
359  // updateModel() reads the base class adjustable parameters and initializes
360  // theAdjParams
361  // with the unnormalized, biased (to the "center" set above) quantities
362  // used in the projection:
363  //---
364  if (success)
365  {
367  updateModel();
368  }
369 
370  return success;
371 }
372 
373 //----------------------------------------------------------------------------
376 //----------------------------------------------------------------------------
378 {
379  os <<
380  "//*****************************************************************\n"
381  "// Template for Adjustable Map Model keywordlist\n"
382  "//*****************************************************************\n"
383  << ossimKeywordNames::TYPE_KW << ": " << "ossimFcsiModel" << endl;
384 
386 
387  os << "//***\n"
388  << "// Derived-class AdjMapModel Keywords:\n"
389  << "//***\n"
390  << PARAMETER_KEYWORDS[OFFSET_X] << ": <east offset meters>\n"
391  << PARAMETER_KEYWORDS[OFFSET_Y] << ": <north offset meters>\n"
392  << PARAMETER_KEYWORDS[ROTATION] << ": <degrees CW>\n"
393  << PARAMETER_KEYWORDS[SCALE_X] << ": <ratio>\n"
394  << PARAMETER_KEYWORDS[SCALE_Y] << ": <ratio>\n"
395  << endl;
396 
397  return;
398 }
399 
400 //----------------------------------------------------------------------------
402 //----------------------------------------------------------------------------
404 {
406  for (int i=0; i<NUM_ADJ_PARAMS; i++)
407  out << PARAMETER_KEYWORDS[i] << ": " << theAdjParams[i] << endl;
408  out << endl;
409 
410  return out;
411 }
412 
413 //----------------------------------------------------------------------------
415 //----------------------------------------------------------------------------
417 {
418  if (theMapProjection.valid())
419  {
421  }
422 
423  return ossimDpt(0,0);
424 }
425 
427 {
428  return new ossimAdjMapModel(*this);
429 }
430 
ossimString theSensorID
virtual ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
takes a filename.
ossim_uint32 x
void setParameterDescription(ossim_uint32 idx, const ossimString &descrption)
virtual void initAdjustableParameters()
Initializes adjustable parameters to their default values.
#define TYPE_NAME(p)
Definition: ossimRtti.h:326
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual ossimDpt getMetersPerPixel() const
Fetches the GSD from the internal map projection.
Represents serializable keyword/value map.
ossim_uint32 y
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
virtual ossimDpt worldToLineSample(const ossimGpt &worldPoint) const
static ossimMapProjectionFactory * instance()
double y
Definition: ossimDpt.h:165
ColumnVector theAdjParams
This is the vector of UNNORMALIZED, BIASED parameters as used in the model.
virtual std::ostream & print(std::ostream &out) const
Extends base-class implementation. Dumps contents of object to ostream.
void setAdjustmentDescription(const ossimString &description)
double sind(double x)
Definition: ossimCommon.h:260
static const char * TYPE_KW
virtual void updateModel()
Following a change to the adjustable parameter set, this virtual is.
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
std::string::size_type size() const
Definition: ossimString.h:405
virtual ossimGpt origin() const
virtual ossimObject * dup() const
Returns pointer to a new instance, copy of this.
void newAdjustment(ossim_uint32 numberOfParameters=0)
const char * chars() const
For backward compatibility.
Definition: ossimString.h:77
double height() const
Definition: ossimGpt.h:107
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
bool initializeFromMap()
Initializes base class data members after map model established.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual std::ostream & print(std::ostream &out) const
double cosd(double x)
Definition: ossimCommon.h:259
static void writeGeomTemplate(ostream &os)
virtual void lineSampleToWorld(const ossimDpt &image_point, ossimGpt &worldPoint) const
Overrides base class virtual.
bool hasNans() const
Definition: ossimGpt.h:135
virtual void setAdjustableParameter(ossim_uint32 idx, double value, bool notify=false)
virtual void worldToLineSample(const ossimGpt &world_point, ossimDpt &image_point) const
Rigorous inverse transform implented, overrides base-class&#39; iterative.
double x
Definition: ossimDpt.h:164
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Fulfills ossimObject base-class pure virtuals.
ossimRefPtr< ossimMapProjection > theMapProjection
static void writeGeomTemplate(ostream &os)
Writes a template of geom keywords processed by loadState and saveState.
virtual void lineSampleHeightToWorld(const ossimDpt &image_point, const double &heightEllipsoid, ossimGpt &worldPoint) const
Overrides base class pure virtual.
Special "sensor model" that provides a conventional map projection but with.
ossimAdjMapModel()
Constructs to uninitialized state (needed by factory).
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Fulfills ossimObject base-class pure virtuals.
virtual ossimDpt getMetersPerPixel() const
void setParameterCenter(ossim_uint32 idx, double center, bool notify=false)
virtual void lineSampleHeightToWorld(const ossimDpt &lineSampPt, const double &heightAboveEllipsoid, ossimGpt &worldPt) const
This is the pure virtual that projects the image point to the given elevation above ellipsoid...
void CleanUp()
Definition: newmat4.cpp:895
virtual ~ossimAdjMapModel()
ground to image faster (you don&#39;t need DEM)
RTTI_DEF1(ossimAdjMapModel, "ossimAdjMapModel", ossimSensorModel)
ossim_float64 theMeanGSD
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23