OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimCosmoSkymedModel.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // "Copyright Centre National d'Etudes Spatiales"
4 //
5 // License: LGPL
6 //
7 // See LICENSE.txt file in the top level directory for more details.
8 //
9 //----------------------------------------------------------------------------
10 // $Id$
11 
12 #include <cmath>
13 #include <cstdio>
14 
15 #include <ossimCosmoSkymedModel.h>
16 
17 #include <otb/GalileanEphemeris.h>
19 #include <otb/GMSTDateTime.h>
20 
21 #include <otb/PlatformPosition.h>
22 #include <otb/SensorParams.h>
23 #include <otb/RefPoint.h>
24 #include <otb/SarSensor.h>
25 
26 namespace ossimplugins
27 {
28 
29 RTTI_DEF1(ossimCosmoSkymedModel, "ossimCosmoSkymedModel", ossimGeometricSarSensorModel);
30 
32  _nbCol(0),
33  _SrGr_R0(0),
34  _sceneCenterRangeTime(0),
35  _pixel_spacing(0)
36 {
37 }
38 
40 {
41 }
42 
44 {
45  // in the case of Georeferenced images, _refPoint->get_distance() contains the ground range
46  double relativeGroundRange = _refPoint->get_distance() + _sensor->get_col_direction() * (col-_refPoint->get_pix_col())* _pixel_spacing ;
47 
48  double slantRange = _SrGr_coeffs[0]
49  + _SrGr_coeffs[1]*(relativeGroundRange-_SrGr_R0)
50  + _SrGr_coeffs[2]*(pow(relativeGroundRange,2)-_SrGr_R0)
51  + _SrGr_coeffs[3]*(pow(relativeGroundRange,3)-_SrGr_R0)
52  + _SrGr_coeffs[4]*(pow(relativeGroundRange,4)-_SrGr_R0)
53  + _SrGr_coeffs[5]*(pow(relativeGroundRange,5)-_SrGr_R0);
54 
55  return slantRange ;
56 }
57 
58 bool ossimCosmoSkymedModel::InitSensorParams(const ossimKeywordlist &kwl, const char *prefix)
59 {
60  const char* central_freq_str = kwl.find(prefix,"central_freq");
61  double central_freq = atof(central_freq_str);
62  const char* fr_str = kwl.find(prefix,"fr");
63  double fr = atof(fr_str);
64  const char* fa_str = kwl.find(prefix,"fa");
65  double fa = atof(fa_str);
66 
67  //number of different looks
68  const char* n_azilok_str = kwl.find(prefix,"n_azilok");
69  double n_azilok = atof(n_azilok_str);
70  const char* n_rnglok_str = kwl.find(prefix,"n_rnglok");
71  double n_rnglok = atof(n_rnglok_str);
72 
73  //ellipsoid parameters
74  const char* ellip_maj_str = kwl.find(prefix,"ellip_maj");
75  double ellip_maj = atof(ellip_maj_str) * 1000.0; // km -> m
76  const char* ellip_min_str = kwl.find(prefix,"ellip_min");
77  double ellip_min = atof(ellip_min_str) * 1000.0; // km -> m
78 
79  if(_sensor != NULL)
80  {
81  delete _sensor;
82  }
83 
84  _sensor = new SensorParams();
85 
86 
90  const char* orbitDirection_str = kwl.find(prefix,"orbitDirection");
91  std::string orbitDirection(orbitDirection_str) ;
92  int orbitDirectionSign ;
93  if (orbitDirection=="DESCENDING") orbitDirectionSign = 1 ;
94  else orbitDirectionSign = - 1 ;
95 
96  const char* lookDirection_str = kwl.find(prefix,"lookDirection");
97  std::string lookDirection(lookDirection_str) ;
98  if ((lookDirection == "Right")||(lookDirection == "RIGHT")) _sensor->set_sightDirection(SensorParams::Right) ;
100 
101  const char* colsOrder_str = kwl.find(prefix,"colsOrder");
102  std::string colsOrder(colsOrder_str) ;
103  const char* linsOrder_str = kwl.find(prefix,"linsOrder");
104  std::string linsOrder(linsOrder_str) ;
105  if (colsOrder=="NEAR-FAR")
106  _sensor->set_col_direction(orbitDirectionSign);
107  else _sensor->set_col_direction(-orbitDirectionSign);
108  if (linsOrder=="NEAR-FAR")
109  _sensor->set_lin_direction(orbitDirectionSign);
110  else _sensor->set_lin_direction(-orbitDirectionSign);
111 
112  _sensor->set_sf(fr);
113  const double CLUM = 2.99792458e+8 ;
114  double wave_length = CLUM / central_freq ;
115  _sensor->set_rwl(wave_length);
116  _sensor->set_nAzimuthLook(n_azilok);
117  _sensor->set_nRangeLook(n_rnglok);
118 
119  // fa is the processing PRF
120  _sensor->set_prf(fa * n_azilok);
121 
122  _sensor->set_semiMajorAxis(ellip_maj) ;
123  _sensor->set_semiMinorAxis(ellip_min) ;
124 
125  return true;
126 }
127 
129 {
130  /*
131  * Retrieval of ephemerisis number
132  */
133  const char* neph_str = kwl.find(prefix,"neph");
134  int neph = atoi(neph_str);
135 
136  /*
137  * Retrieval of reference date
138  */
139  const char* referenceUTC_str = kwl.find(prefix,"referenceUTC");
140  std::string referenceUTC(referenceUTC_str) ;
141  CivilDateTime ref_civil_date;
142  if (! UtcDateTimeStringToCivilDate(referenceUTC, ref_civil_date)) return false;
143 
144  /*
145  * Retrieval of ephemerisis
146  */
147  Ephemeris** ephemeris = new Ephemeris*[neph];
148  for (int i = 0; i < neph; ++i)
149  {
150  double pos[3];
151  double vit[3];
152  char name[64];
153 
154  sprintf(name,"eph%i_date",i);
155  const char* date_str = kwl.find(prefix,name);
156  float relative_date = atof(date_str);
157 
158  sprintf(name,"eph%i_posX",i);
159  const char* px_str = kwl.find(prefix,name);
160  pos[0] = atof(px_str);
161 
162  sprintf(name,"eph%i_posY",i);
163  const char* py_str = kwl.find(prefix,name);
164  pos[1] = atof(py_str);
165 
166  sprintf(name,"eph%i_posZ",i);
167  const char* pz_str = kwl.find(prefix,name);
168  pos[2] = atof(pz_str);
169 
170  sprintf(name,"eph%i_velX",i);
171  const char* vx_str = kwl.find(prefix,name);
172  vit[0] = atof(vx_str) ;
173 
174  sprintf(name,"eph%i_velY",i);
175  const char* vy_str = kwl.find(prefix,name);
176  vit[1] = atof(vy_str) ;
177 
178  sprintf(name,"eph%i_velZ",i);
179  const char* vz_str = kwl.find(prefix,name);
180  vit[2] = atof(vz_str) ;
181  /*
182  * Conversion to JSD Date
183  */
184  int second = (int) relative_date ;
185  double decimal = relative_date - second ;
186  CivilDateTime eph_civil_date(ref_civil_date.get_year(), ref_civil_date.get_month(), ref_civil_date.get_day(), second, decimal);
187  JSDDateTime eph_jsd_date(eph_civil_date);
188 
189  GeographicEphemeris* eph = new GeographicEphemeris(eph_jsd_date,pos,vit);
190 
191  ephemeris[i] = eph;
192  }
193 
194  /*
195  * Creation of the platform position interpolator
196  */
197  if (_platformPosition != NULL)
198  {
199  delete _platformPosition;
200  }
201  _platformPosition = new PlatformPosition(ephemeris,neph);
202 
203  /*
204  * Free of memory used by ephemerisis list : the constructor copies the ephemerisis
205  */
206  for (int i=0;i<neph;i++)
207  {
208  delete ephemeris[i];
209  }
210  delete[] ephemeris;
211 
212  return true;
213 }
214 
215 bool ossimCosmoSkymedModel::InitRefPoint(const ossimKeywordlist &kwl, const char *prefix)
216 {
217  const char* sc_lin_str = kwl.find(prefix,"sc_lin");
218  double sc_lin = atof(sc_lin_str);
219 
220  const char* sc_pix_str = kwl.find(prefix,"sc_pix");
221  double sc_pix = atof(sc_pix_str);
222 
223  // const char* pixel_spacing_str = kwl.find(prefix,"pixel_spacing");
224  // double pixel_spacing = atof(pixel_spacing_str);
225 
226  const char* azimuthStartTime_str = kwl.find(prefix,"azimuthStartTime");
227  double azimuthStartTime = atof(azimuthStartTime_str);
228 
229  const char* rng_gate_str = kwl.find(prefix,"rng_gate");
230  double rng_gate = atof(rng_gate_str);
231 
232  const char* referenceUTC_str = kwl.find(prefix,"referenceUTC");
233  std::string referenceUTC(referenceUTC_str) ;
234  CivilDateTime ref_civil_date;
235  if (! UtcDateTimeStringToCivilDate(referenceUTC, ref_civil_date)) return false;
236 
237  if(_refPoint == NULL)
238  {
239  _refPoint = new RefPoint();
240  }
241 
242  _refPoint->set_pix_col(sc_pix);
243  _refPoint->set_pix_line(sc_lin);
244 
245  double relative_date = (azimuthStartTime + sc_lin/_sensor->get_prf());
246  int second = (int) relative_date ;
247  double decimal = relative_date - second ;
248 
249  if(_platformPosition != NULL)
250  {
251  CivilDateTime * date = new CivilDateTime(
252  ref_civil_date.get_year(), ref_civil_date.get_month(),
253  ref_civil_date.get_day(), second, decimal);
254 
255  Ephemeris * ephemeris = _platformPosition->Interpolate((JSDDateTime)*date);
256  if (ephemeris == NULL) return false ;
257 
258  _refPoint->set_ephemeris(ephemeris);
259 
260  delete date;
261  date = 0;
262  delete ephemeris;
263  ephemeris = 0;
264  }
265  else
266  {
267  return false;
268  }
269 
270  double c = 2.99792458e+8;
271  double distance = (rng_gate + sc_pix*_sensor->get_nRangeLook()/_sensor->get_sf()) * (c/2.0);
272 
273  // in the case of Georeferenced images, the "relative" ground range is stored in place of the slant range
274  // (used for SlantRange computation relative to reference point, necessary for optimization)
275  // here, the pixelDirection is ignored since the CSKS reference point is always at the scene centre
278  }
279 
281 
282 
283  // in order to use ossimSensorModel::lineSampleToWorld
284  const char* nbCol_str = kwl.find(prefix,"nbCol");
285  const char* nbLin_str = kwl.find(prefix,"nbLin");
286  theImageSize.x = atoi(nbCol_str);
287  theImageSize.y = atoi(nbLin_str);
289 
290 
291  // Ground Control Points extracted from the model : scene center and corners
292  std::list<ossimGpt> groundGcpCoordinates ;
293  std::list<ossimDpt> imageGcpCoordinates ;
294  char name[64];
295  for (int k=0 ; k<5 ; k++) {
296  sprintf(name,"cornersCol%i",k);
297  const char* i_str = kwl.find(name);
298  int i = atoi(i_str);
299  sprintf(name,"cornersLin%i",k);
300  const char* j_str = kwl.find(name);
301  int j = atoi(j_str);
302  sprintf(name,"cornersLon%i",k);
303  const char* lon_str = kwl.find(name);
304  double lon = atof(lon_str);
305  sprintf(name,"cornersLat%i",k);
306  const char* lat_str = kwl.find(name);
307  double lat = atof(lat_str);
308  sprintf(name,"cornersHeight%i",k);
309  const char* height_str = kwl.find(name);
310  double height = atof(height_str) ;
311 
312  ossimDpt imageGCP(i,j);
313  ossimGpt groundGCP(lat, lon, height);
314  groundGcpCoordinates.push_back(groundGCP) ;
315  imageGcpCoordinates.push_back(imageGCP) ;
316  }
317 
318  // Default optimization
319  optimizeModel(groundGcpCoordinates, imageGcpCoordinates) ;
320 
321  return true;
322 }
323 
324 bool ossimCosmoSkymedModel::InitSRGR(const ossimKeywordlist &kwl, const char *prefix)
325 {
326  const char* rangeProjectionType_str = kwl.find(prefix,"rangeProjectionType");
327  std::string rangeProjectionType(rangeProjectionType_str);
328 
329  const char* pixel_spacing_str = kwl.find(prefix,"pixel_spacing");
330  _pixel_spacing= atof(pixel_spacing_str);
331 
332  _isProductGeoreferenced = (rangeProjectionType=="GROUNDRANGE") ;
333 
334  // Number of columns
335  const char* nbCol_str = kwl.find(prefix,"nbCol");
336  _nbCol = atoi(nbCol_str);
337 
338  // SRGR polynomial reference
339  const char* SrGr_R0_str = kwl.find(prefix,"SrGr_R0");
340  _SrGr_R0 = atof(SrGr_R0_str);
341 
342  // SRGR coefficients
343  char name[64];
344  double coeff ;
345  for(int i=0;i<6;i++)
346  {
347  sprintf(name,"SrToGr_coeffs_%i",i);
348  const char* coeff_str = kwl.find(prefix,name);
349  coeff = atof(coeff_str);
350  _SrGr_coeffs.push_back(coeff);
351  }
352 
353  return true;
354 }
355 
356 
357 bool ossimCosmoSkymedModel::UtcDateTimeStringToCivilDate(const std::string &utcString, CivilDateTime &outputDate) {
358  // conversion :
359  // try with date format yyyymmdd
360 
361  if (utcString.size() < 8) return false ;
362  const char* stringUTCDate = utcString.c_str() ;
363 
364  char year_str[5];
365  for (int i=0;i<4;i++)
366  {
367  year_str[i] = stringUTCDate[i];
368  }
369  year_str[4] = '\0';
370 
371  char month_str[3];
372  for (int i=4;i<6;i++)
373  {
374  month_str[i-4] = stringUTCDate[i];
375  }
376  month_str[2] = '\0';
377 
378  char day_str[3];
379  for (int i=6;i<8;i++)
380  {
381  day_str[i-6] = stringUTCDate[i];
382  }
383  day_str[2] = '\0';
384 
385  outputDate.set_year(atoi(year_str));
386  outputDate.set_month(atoi(month_str));
387  outputDate.set_day(atoi(day_str));
388  outputDate.set_second(0);
389  outputDate.set_decimal(0.0);
390 
391  return true ;
392 }
393 
394 
395 }
396 
397 
This class represent an ephemeris in Geographic coordinates system.
double _SrGr_R0
Slant Range for each Ground Range Projection reference point.
void set_sightDirection(SightDirection sight)
Definition: SensorParams.h:93
This class represents a date and time in the civil format.
Definition: CivilDateTime.h:30
void set_rwl(double rwl)
Definition: SensorParams.h:83
virtual bool InitSensorParams(const ossimKeywordlist &kwl, const char *prefix)
Initializes the Sensor Params from a projection keywordlist.
This class handles the platform position.
RTTI_DEF1(ossimAlosPalsarModel, "ossimAlosPalsarModel", ossimGeometricSarSensorModel)
Represents serializable keyword/value map.
const char * find(const char *key) const
This class handles the referential point.
Definition: RefPoint.h:29
double get_distance() const
Definition: RefPoint.cpp:95
void set_lin_direction(int dir)
Definition: SensorParams.h:128
void set_second(int second)
double get_nRangeLook() const
Definition: SensorParams.h:118
This class handles the sensor parameters.
Definition: SensorParams.h:29
virtual bool InitPlatformPosition(const ossimKeywordlist &kwl, const char *prefix)
Initializes the Platform Position from a projection keywordlist.
Ephemeris * Interpolate(JSDDateTime date) const
This function interpolates its ephemeris to create a new ephemeris at the given date and time...
void set_pix_line(double pix_line)
Definition: RefPoint.cpp:80
void set_pix_col(double pix_col)
Definition: RefPoint.cpp:85
bool _isProductGeoreferenced
True iff the product is ground range.
void set_semiMinorAxis(double value)
Definition: SensorParams.h:158
virtual bool InitRefPoint(const ossimKeywordlist &kwl, const char *prefix)
Initializes the Reference Point from a projection keywordlist.
This class represents an ephemeris.
Definition: Ephemeris.h:28
virtual double getSlantRangeFromGeoreferenced(double col) const
This function associates an image column number to a slant range when the image is georeferenced (gro...
void set_decimal(double decimal)
std::vector< double > _SrGr_coeffs
Slant Range for each Ground Range Projection coefficients.
void set_semiMajorAxis(double value)
Definition: SensorParams.h:153
double get_pix_col() const
Definition: RefPoint.cpp:105
void set_nRangeLook(double look)
Definition: SensorParams.h:138
bool UtcDateTimeStringToCivilDate(const std::string &utcString, CivilDateTime &outputDate)
virtual bool InitSRGR(const ossimKeywordlist &kwl, const char *prefix)
Initializes the Slant Range to Ground Range data sets : _SrToGr_R0,_SrToGr_coeffs_number,_SrToGr_exponent,_SrToGr_coeffs,_nbCol.
ossimDrect theImageClipRect
PlatformPosition * _platformPosition
Handle the position of the platform.
ossim_int32 y
Definition: ossimIpt.h:142
void set_nAzimuthLook(double look)
Definition: SensorParams.h:133
ossim_int32 x
Definition: ossimIpt.h:141
virtual bool optimizeModel(const std::list< ossimGpt > &groundCoordinates, const std::list< ossimDpt > &imageCoordinates)
This function optimizes the model according to a list of Ground Control Points.
void set_prf(double prf)
Definition: SensorParams.h:73
void set_ephemeris(Ephemeris *ephemeris)
Definition: RefPoint.cpp:65
void set_col_direction(int dir)
Definition: SensorParams.h:123
This class represents a date.
Definition: JSDDateTime.h:30
float distance(double lat1, double lon1, double lat2, double lon2, int units)
void set_distance(double distance)
Definition: RefPoint.cpp:75
void set_sf(double sf)
Definition: SensorParams.h:78