39 static ossimTrace traceExec (
"ossimRpcProjection:exec");
40 static ossimTrace traceDebug (
"ossimRpcProjection:debug");
43 static const int NUM_COEFFS = 20;
44 static const char* MODEL_TYPE =
"ossimRpcModel";
45 static const char* POLY_TYPE_KW =
"polynomial_format";
46 static const char* LINE_SCALE_KW =
"line_scale";
47 static const char* SAMP_SCALE_KW =
"samp_scale";
48 static const char* LAT_SCALE_KW =
"lat_scale";
49 static const char* LON_SCALE_KW =
"long_scale";
50 static const char* HGT_SCALE_KW =
"height_scale";
51 static const char* LINE_OFFSET_KW =
"line_off";
52 static const char* SAMP_OFFSET_KW =
"samp_off";
53 static const char* LAT_OFFSET_KW =
"lat_off";
54 static const char* LON_OFFSET_KW =
"long_off";
55 static const char* HGT_OFFSET_KW =
"height_off";
56 static const char* LINE_NUM_COEF_KW =
"line_num_coeff_";
57 static const char* LINE_DEN_COEF_KW =
"line_den_coeff_";
58 static const char* SAMP_NUM_COEF_KW =
"samp_num_coeff_";
59 static const char* SAMP_DEN_COEF_KW =
"samp_den_coeff_";
69 static const ossimString PARAM_NAMES[] ={
"intrack_offset",
113 thePolyType (model.thePolyType),
115 theSampScale (model.theSampScale),
116 theLatScale (model.theLatScale),
117 theLonScale (model.theLonScale),
118 theHgtScale (model.theHgtScale),
120 theSampOffset (model.theSampOffset),
121 theLatOffset (model.theLatOffset),
122 theLonOffset (model.theLonOffset),
123 theHgtOffset (model.theHgtOffset),
124 theIntrackOffset(model.theIntrackOffset),
125 theCrtrackOffset(model.theCrtrackOffset),
126 theIntrackScale(model.theIntrackScale),
127 theCrtrackScale(model.theCrtrackScale),
128 theYawSkew (model.theYawSkew),
129 theCosMapRot (model.theCosMapRot),
130 theSinMapRot (model.theSinMapRot)
134 for (
int i=0; i<20; i++)
184 for (
int i=0; i<20; i++)
205 const std::vector<double>& xNumeratorCoeffs,
206 const std::vector<double>& xDenominatorCoeffs,
207 const std::vector<double>& yNumeratorCoeffs,
208 const std::vector<double>& yDenominatorCoeffs,
224 if(xNumeratorCoeffs.size() == 20)
226 std::copy(xNumeratorCoeffs.begin(),
227 xNumeratorCoeffs.end(),
230 if(xDenominatorCoeffs.size() == 20)
232 std::copy(xDenominatorCoeffs.begin(),
233 xDenominatorCoeffs.end(),
236 if(yNumeratorCoeffs.size() == 20)
238 std::copy(yNumeratorCoeffs.begin(),
239 yNumeratorCoeffs.end(),
242 if(yDenominatorCoeffs.size() == 20)
244 std::copy(yDenominatorCoeffs.begin(),
245 yDenominatorCoeffs.end(),
293 double U_rot = Pu / Qu;
294 double V_rot = Pv / Qv;
342 const double& ellHeight,
350 static const int MAX_NUM_ITERATIONS = 10;
351 static const double CONVERGENCE_EPSILON = 0.1;
368 U = U_rot; V = V_rot;
402 double Pu, Qu, Pv, Qv;
403 double dPu_dLat, dQu_dLat, dPv_dLat, dQv_dLat;
404 double dPu_dLon, dQu_dLon, dPv_dLon, dQv_dLon;
406 double deltaU, deltaV;
407 double dU_dLat, dU_dLon, dV_dLat, dV_dLon, W;
408 double deltaLat, deltaLon;
436 if ((fabs(deltaU) > epsilonU) || (fabs(deltaV) > epsilonV))
453 dU_dLat = (Qu*dPu_dLat - Pu*dQu_dLat)/(Qu*Qu);
454 dU_dLon = (Qu*dPu_dLon - Pu*dQu_dLon)/(Qu*Qu);
455 dV_dLat = (Qv*dPv_dLat - Pv*dQv_dLat)/(Qv*Qv);
456 dV_dLon = (Qv*dPv_dLon - Pv*dQv_dLon)/(Qv*Qv);
458 W = dU_dLon*dV_dLat - dU_dLat*dV_dLon;
463 deltaLat = (dU_dLon*deltaV - dV_dLon*deltaU) / W;
464 deltaLon = (dV_dLat*deltaU - dU_dLat*deltaV) / W;
471 }
while (((fabs(deltaU)>epsilonU) || (fabs(deltaV)>epsilonV))
472 && (iteration < MAX_NUM_ITERATIONS));
477 if (iteration == MAX_NUM_ITERATIONS)
480 <<
"solution. Results are inaccurate." << endl;
531 if(&projection ==
this)
return true;
545 const double& H,
const double* c)
const 551 r = c[ 0] + c[ 1]*L + c[ 2]*P + c[ 3]*H +
552 c[ 4]*L*P + c[ 5]*L*H + c[ 6]*P*H + c[ 7]*L*P*H +
553 c[ 8]*L*L + c[ 9]*P*P + c[10]*H*H + c[11]*L*L*L +
554 c[12]*L*L*P + c[13]*L*L*H + c[14]*L*P*P + c[15]*P*P*P +
555 c[16]*P*P*H + c[17]*L*H*H + c[18]*P*H*H + c[19]*H*H*H;
559 r = c[ 0] + c[ 1]*L + c[ 2]*P + c[ 3]*H +
560 c[ 4]*L*P + c[ 5]*L*H + c[ 6]*P*H + c[ 7]*L*L +
561 c[ 8]*P*P + c[ 9]*H*H + c[10]*L*P*H + c[11]*L*L*L +
562 c[12]*L*P*P + c[13]*L*H*H + c[14]*L*L*P + c[15]*P*P*P +
563 c[16]*P*H*H + c[17]*L*L*H + c[18]*P*P*H + c[19]*H*H*H;
576 const double& H,
const double* c)
const 582 dr = c[2] + c[4]*L + c[6]*H + c[7]*L*H + 2*c[9]*P + c[12]*L*L +
583 2*c[14]*L*P + 3*c[15]*P*P +2*c[16]*P*H + c[18]*H*H;
587 dr = c[2] + c[4]*L + c[6]*H + 2*c[8]*P + c[10]*L*H + 2*c[12]*L*P +
588 c[14]*L*L + 3*c[15]*P*P + c[16]*H*H + 2*c[18]*P*H;
601 const double& H,
const double* c)
const 607 dr = c[1] + c[4]*P + c[5]*H + c[7]*P*H + 2*c[8]*L + 3*c[11]*L*L +
608 2*c[12]*L*P + 2*c[13]*L*H + c[14]*P*P + c[17]*H*H;
612 dr = c[1] + c[4]*P + c[5]*H + 2*c[7]*L + c[10]*P*H + 3*c[11]*L*L +
613 c[12]*P*P + c[13]*H*H + 2*c[14]*P*L + 2*c[17]*L*H;
626 out <<
"\nDump of ossimRpcProjection object at " << hex <<
this <<
":\n" 639 for (
int i=0; i<NUM_COEFFS; i++)
640 out<<
" "<<LINE_NUM_COEF_KW<<
"["<<i<<
"]: "<<
theLineNumCoef[i]<<endl;
643 for (
int i=0; i<NUM_COEFFS; i++)
644 out<<
" "<<LINE_DEN_COEF_KW<<
"["<<i<<
"]: "<<
theLineDenCoef[i]<<endl;
647 for (
int i=0; i<NUM_COEFFS; i++)
648 out<<
" "<<SAMP_NUM_COEF_KW<<
"["<<i<<
"]: "<<
theSampNumCoef[i]<<endl;
651 for (
int i=0; i<NUM_COEFFS; i++)
652 out<<
" "<<SAMP_DEN_COEF_KW<<
"["<<i<<
"]: "<<
theSampDenCoef[i]<<endl;
666 const char* prefix)
const 694 for (
int i=0; i<NUM_COEFFS; i++)
737 keyword = POLY_TYPE_KW;
738 value = kwl.
find(prefix, keyword);
742 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 748 keyword = LINE_SCALE_KW;
749 value = kwl.
find(prefix, keyword);
753 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 759 keyword = SAMP_SCALE_KW;
760 value = kwl.
find(prefix, keyword);
764 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 770 keyword = LAT_SCALE_KW;
771 value = kwl.
find(prefix, keyword);
775 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 781 keyword = LON_SCALE_KW;
782 value = kwl.
find(prefix, keyword);
786 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 792 keyword = HGT_SCALE_KW;
793 value = kwl.
find(prefix, keyword);
797 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 803 keyword = LINE_OFFSET_KW;
804 value = kwl.
find(prefix, keyword);
808 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 814 keyword = SAMP_OFFSET_KW;
815 value = kwl.
find(prefix, keyword);
819 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 825 keyword = LAT_OFFSET_KW;
826 value = kwl.
find(prefix, keyword);
830 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 836 keyword = LON_OFFSET_KW;
837 value = kwl.
find(prefix, keyword);
841 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 847 keyword = HGT_OFFSET_KW;
848 value = kwl.
find(prefix, keyword);
852 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 858 for (
int i=0; i<NUM_COEFFS; i++)
864 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 874 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 884 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 894 <<
"<" << keyword <<
">. Check the keywordlist for proper syntax." 910 for (
int i=0; i<numParams; i++)
965 for(idx = 0; idx < numAdj; ++idx)
979 double den = 0.5/hdelta;
993 res.
lon = den*(res.
lon - gd.
lon) * 100000.0;
1004 static double den = 0.5/hdelta;
1029 std::vector<ossimDpt> imagePoints;
1030 std::vector<ossimGpt> groundPoints;
1051 NEWMAT::SymmetricMatrix&
A,
1052 NEWMAT::ColumnVector& residue,
1053 NEWMAT::ColumnVector& projResidue,
1073 int no = dimObs * tieSet.
size();
1077 projResidue.ReSize(np);
1082 const vector<ossimRefPtr<ossimTieGpt> >& theTPV = tieSet.
getTiePoints();
1083 vector<ossimRefPtr<ossimTieGpt> >::const_iterator tit;
1092 for (tit = theTPV.begin() ; tit != theTPV.end() ; ++tit)
1095 resIm = (*tit)->tie -
forward(*(*tit));
1096 residue(c++) = resIm.
x;
1097 residue(c++) = resIm.
y;
1100 for(
int p=0;p<np;++p)
1106 for(
int p1=0;p1<np;++p1)
1109 projResidue.element(p1) += imDerp[p1].
x * resIm.
x + imDerp[p1].
y * resIm.
y;
1112 for(
int p2=p1;p2<np;++p2)
1114 A.element(p1,p2) += imDerp[p1].
x * imDerp[p2].
x + imDerp[p1].
y * imDerp[p2].
y;
1123 std::vector<ossimGpt> gdDerp(np);
1126 for (tit = theTPV.begin() ; tit != theTPV.end() ; ++tit)
1130 residue(c++) = resGd.
lon = ((*tit)->lon - gd.
lon) * 100000.0;
1131 residue(c++) = resGd.
lat = ((*tit)->lat - gd.
lat) * 100000.0 * cos(gd.
lat / 180.0 *
M_PI);
1132 residue(c++) = resGd.
hgt = (*tit)->hgt - gd.
hgt;
1135 for(
int p=0;p<np;++p)
1141 for(
int p1=0;p1<np;++p1)
1144 projResidue.element(p1) += gdDerp[p1].lon * resGd.
lon + gdDerp[p1].lat * resGd.
lat + gdDerp[p1].hgt * resGd.
hgt;
1147 for(
int p2=p1;p2<np;++p2)
1149 A.element(p1,p2) += gdDerp[p1].lon * gdDerp[p2].lon + gdDerp[p1].lat * gdDerp[p2].lat + gdDerp[p1].hgt * gdDerp[p2].hgt;
1156 NEWMAT::ColumnVector
1160 NEWMAT::ColumnVector residue;
1170 int no = dimObs * tieSet.
size();
1174 const vector<ossimRefPtr<ossimTieGpt> >& theTPV = tieSet.
getTiePoints();
1175 vector<ossimRefPtr<ossimTieGpt> >::const_iterator tit;
1183 for (tit = theTPV.begin() ; tit != theTPV.end() ; ++tit)
1186 resIm = (*tit)->tie -
forward(**tit);
1187 residue(c++) = resIm.
x;
1188 residue(c++) = resIm.
y;
1194 for (tit = theTPV.begin() ; tit != theTPV.end() ; ++tit)
1198 residue(c++) = ((*tit)->lon - gd.
lon) * 100000.0;
1199 residue(c++) = ((*tit)->lat - gd.
lat) * 100000.0 * cos(gd.
lat / 180.0 *
M_PI);
1200 residue(c++) = (*tit)->hgt - gd.
hgt;
1212 NEWMAT::ColumnVector
1215 NEWMAT::ColumnVector
x =
invert(
A)*r;
1226 NEWMAT::DiagonalMatrix d;
1242 d[idx] = 1.0/d[idx];
1249 cout<<
"warning: singular matrix in SVD"<<endl;
void setParameterDescription(ossim_uint32 idx, const ossimString &descrption)
double computeParameterOffset(ossim_uint32 idx) const
virtual ossimDpt getMetersPerPixel() const
unsigned int size() const
NEWMAT::Matrix invert(const NEWMAT::Matrix &m) const
stable invert stolen from ossimRpcSolver
bool saveAdjustments(ossimKeywordlist &kwl, const ossimString &prefix=ossimString("")) const
Save all adjustments to the KWL file.
void getSlaveMasterPoints(std::vector< ossimDpt > &imv, std::vector< ossimGpt > &gdv) const
double theSampDenCoef[20]
virtual void adjustableParametersChanged()
Represents serializable keyword/value map.
bool addFile(const char *file)
virtual bool setupOptimizer(const ossimString &setup)
setupFromString() Derived classes should implement as needed. Initialize parameters needed for optimi...
const char * find(const char *key) const
char theLineScale[LINE_SCALE_SIZE+1]
FIELD: LINE_SCALE.
virtual std::ostream & print(std::ostream &out) const
Outputs theErrorStatus as an ossimErrorCode and an ossimString.
virtual ossimOptimizableProjection & operator=(const ossimOptimizableProjection &source)
NEWMAT::ColumnVector getResidue(const ossimTieGptSet &tieSet)
ossimRpcProjection & operator=(const ossimRpcProjection &source)
virtual ossimGpt inverse(const ossimDpt &pp) const
static ossimString toString(bool aValue)
Numeric to string methods.
double theLineDenCoef[20]
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual void lineSampleHeightToWorld(const ossimDpt &image_point, const double &heightEllipsoid, ossimGpt &worldPoint) const
virtual ossimDpt getForwardDeriv(int parmIdx, const ossimGpt &gpos, double hdelta=1e-11)
ossim_float64 hgt
Height in meters above the ellipsiod.
virtual bool operator==(const ossimProjection &projection) const
ossim_uint32 getNumberOfAdjustableParameters() const
void solveCoefficients(const ossimDrect &imageBounds, ossimProjection *imageProj, ossim_uint32 xSamples=8, ossim_uint32 ySamples=8)
This will convert any projector to an RPC model.
static const char * TYPE_KW
const ossimRefPtr< ossimRpcModel > getRpcModel() const
Fetches the solved-for RPC model.
virtual std::ostream & print(std::ostream &out) const
double dPoly_dLat(const double &nlat, const double &nlon, const double &nhgt, const double *coeffs) const
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
double theSampNumCoef[20]
virtual class enabling projection optimization (can be used for outlier rejection - RANSAC) ...
ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
saveState Fulfills ossimObject base-class pure virtuals.
virtual ossimGpt origin() const
virtual void lineSampleToWorld(const ossimDpt &image_point, ossimGpt &world_point) const
unsigned int ossim_uint32
double getAdjustableParameter(ossim_uint32 idx) const
virtual bool useForward() const
bool isParameterLocked(ossim_uint32 idx) const
void SVD(const Matrix &, DiagonalMatrix &, Matrix &, Matrix &, bool=true, bool=true)
void setParameterUnit(ossim_uint32 idx, ossimUnitType unit)
const vector< ossimRefPtr< ossimTieGpt > > & getTiePoints() const
ossimErrorCode theErrorStatus
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
NEWMAT::ColumnVector solveLeastSquares(NEWMAT::SymmetricMatrix &A, NEWMAT::ColumnVector &r) const
void initAdjustableParameters()
double getRmsError() const
static ossimProjectionFactoryRegistry * instance()
virtual double optimizeFit(const ossimTieGptSet &tieSet, double *targetVariance=NULL)
virtual ossimObject * getBaseObject()
virtual ossimGpt getInverseDeriv(int parmIdx, const ossimDpt &ipos, double hdelta=1e-11)
PolynomialType thePolyType
double polynomial(const double &nlat, const double &nlon, const double &nhgt, const double *coeffs) const
virtual void worldToLineSample(const ossimGpt &world_point, ossimDpt &image_point) const
virtual ossim_uint32 degreesOfFreedom() const
virtual ossimDpt forward(const ossimGpt &wp) const
void buildNormalEquation(const ossimTieGptSet &tieSet, NEWMAT::SymmetricMatrix &A, NEWMAT::ColumnVector &residue, NEWMAT::ColumnVector &projResidue, double pstep_scale)
virtual void setAdjustableParameter(ossim_uint32 idx, double value, bool notify=false)
storage class for a set of geographic tie points, between master and slave images ...
double dPoly_dLon(const double &nlat, const double &nlon, const double &nhgt, const double *coeffs) const
void resizeAdjustableParameterArray(ossim_uint32 numberOfParameters)
This currently only support Rational poilynomial B format.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
RTTI_DEF3(ossimRpcProjection, "ossimRpcProjection", ossimProjection, ossimOptimizableProjection, ossimAdjustableParameterInterface)
char theLineOffset[LINE_OFFSET_SIZE+1]
FIELD: LINE_OFF.
void setAttributes(ossim_float64 theSampleOffset, ossim_float64 theLineOffset, ossim_float64 theSampleScale, ossim_float64 theLineScale, ossim_float64 theLatOffset, ossim_float64 theLonOffset, ossim_float64 theHeightOffset, ossim_float64 theLatScale, ossim_float64 theLonScale, ossim_float64 theHeightScale, const std::vector< double > &xNumeratorCoeffs, const std::vector< double > &xDenominatorCoeffs, const std::vector< double > &yNumeratorCoeffs, const std::vector< double > &yDenominatorCoeffs, PolynomialType polyType=B)
double theLineNumCoef[20]
void setParameterSigma(ossim_uint32 idx, double value, bool notify=false)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.