//***************************************************************************** // METHOD: ossimRpcProjection::worldToLineSample() // // Overrides base class implementation. Directly computes line-sample from // the polynomials. //***************************************************************************** void ossimRpcProjection::worldToLineSample(const ossimGpt& ground_point, ossimDpt& imgPt) const { if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::worldToLineSample(): entering..." << std::endl; if(ground_point.isLatNan() || ground_point.isLonNan() ) { imgPt.makeNan(); return; } //* // Normalize the lat, lon, hgt: //* double nlat = (ground_point.lat - theLatOffset) / theLatScale; double nlon = (ground_point.lon - theLonOffset) / theLonScale; double nhgt; if(ossim::isnan(ground_point.hgt)) { nhgt = (theHgtScale - theHgtOffset) / theHgtScale; } else { nhgt = (ground_point.hgt - theHgtOffset) / theHgtScale; } //*** // Compute the adjusted, normalized line (U) and sample (V): //*** double Pu = polynomial(nlat, nlon, nhgt, theLineNumCoef); double Qu = polynomial(nlat, nlon, nhgt, theLineDenCoef); double Pv = polynomial(nlat, nlon, nhgt, theSampNumCoef); double Qv = polynomial(nlat, nlon, nhgt, theSampDenCoef); double U_rot = Pu / Qu; double V_rot = Pv / Qv; //*** // U, V are normalized quantities. Need now to establish the image file // line and sample. First, back out the adjustable parameter effects // starting with rotation: //*** double U = U_rot*theCosMapRot + V_rot*theSinMapRot; double V = V_rot*theCosMapRot - U_rot*theSinMapRot; //*** // Now back out skew, scale, and offset adjustments: //*** imgPt.line = U*(theLineScale+theIntrackScale) + theLineOffset + theIntrackOffset; imgPt.samp = V*(theSampScale+theCrtrackScale) + theSampOffset + theCrtrackOffset; if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::worldToLineSample(): returning..." << std::endl; return; }
void ossimTileMapModel::worldToLineSample(const ossimGpt& ground_point, ossimDpt& img_pt) const { // if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::worldToLineSample(): entering..." << std::endl; if(ground_point.isLatNan() || ground_point.isLonNan() ) { img_pt.makeNan(); return; } double x = (180.0 + ground_point.lon) / 360.0; double y = - ground_point.lat * M_PI / 180; // convert to radians y = 0.5 * log((1+sin(y)) / (1 - sin(y))); y *= 1.0/(2 * M_PI); // scale factor from radians to normalized y += 0.5; // and make y range from 0 - 1 img_pt.samp = floor(x*pow(2.,static_cast<double>(qDepth))*256); img_pt.line = floor(y*pow(2.,static_cast<double>(qDepth))*256); return; }
//***************************************************************************** // METHOD: ossimRpcModel::worldToLineSample() // // Overrides base class implementation. Directly computes line-sample from // the polynomials. //***************************************************************************** void ossimRpcModel::worldToLineSample(const ossimGpt& ground_point, ossimDpt& img_pt) const { // if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::worldToLineSample(): entering..." << std::endl; if(ground_point.isLatNan() || ground_point.isLonNan() ) { img_pt.makeNan(); return; } //*** // First check if the world point is inside bounding rectangle: //*** //ossimDpt wdp (ground_point); //if (!(theBoundGndPolygon.pointWithin(ground_point))) // { //img_pt = extrapolate(ground_point); //if (traceExec()) CLOG << "returning..." << endl; // img_pt.makeNan(); // return; // } //*** // Normalize the lat, lon, hgt: //*** double nlat = (ground_point.lat - theLatOffset) / theLatScale; double nlon = (ground_point.lon - theLonOffset) / theLonScale; double nhgt; if( ground_point.isHgtNan() ) { // nhgt = (theHgtScale - theHgtOffset) / theHgtScale; nhgt = ( - theHgtOffset) / theHgtScale; } else { nhgt = (ground_point.hgt - theHgtOffset) / theHgtScale; } //*** // Compute the adjusted, normalized line (U) and sample (V): //*** double Pu = polynomial(nlat, nlon, nhgt, theLineNumCoef); double Qu = polynomial(nlat, nlon, nhgt, theLineDenCoef); double Pv = polynomial(nlat, nlon, nhgt, theSampNumCoef); double Qv = polynomial(nlat, nlon, nhgt, theSampDenCoef); double U_rot = Pu / Qu; double V_rot = Pv / Qv; //*** // U, V are normalized quantities. Need now to establish the image file // line and sample. First, back out the adjustable parameter effects // starting with rotation: //*** double U = U_rot*theCosMapRot + V_rot*theSinMapRot; double V = V_rot*theCosMapRot - U_rot*theSinMapRot; //*** // Now back out skew, scale, and offset adjustments: //*** img_pt.line = U*(theLineScale+theIntrackScale) + theLineOffset + theIntrackOffset; img_pt.samp = V*(theSampScale+theCrtrackScale) + theSampOffset + theCrtrackOffset; // if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::worldToLineSample(): returning..." << std::endl; return; }
//---------------------------------------------------------------------------** // METHOD: ossimSensorModel::worldToLineSample() // // Performs forward projection of ground point to image space. // //---------------------------------------------------------------------------** void ossimH5GridModel::worldToLineSample(const ossimGpt& worldPoint, ossimDpt& ip) const { static const double PIXEL_THRESHOLD = .1; // acceptable pixel error static const int MAX_NUM_ITERATIONS = 20; if(worldPoint.isLatNan() || worldPoint.isLonNan()) { ip.makeNan(); return; } //--- // First check if the world point is inside bounding rectangle: //--- int iters = 0; ossimDpt wdp (worldPoint); if ( m_crossesDateline && (wdp.x < 0.0) ) { // Longitude points stored between 0 and 360. wdp.x += 360.0; } if( (m_boundGndPolygon.getNumberOfVertices() > 0) && (!m_boundGndPolygon.hasNans()) ) { if (!(m_boundGndPolygon.pointWithin(wdp))) { // if(theSeedFunction.valid()) // { // theSeedFunction->worldToLineSample(worldPoint, ip); // } // else if(!theExtrapolateGroundFlag) // if I am not already in the extrapolation routine // { // ip = extrapolate(worldPoint); // } ip.makeNan(); return; } } //--- // Substitute zero for null elevation if present: //--- double height = worldPoint.hgt; if ( ossim::isnan(height) ) { height = 0.0; } //--- // Utilize iterative scheme for arriving at image point. Begin with guess // at image center: //--- if(theSeedFunction.valid()) { theSeedFunction->worldToLineSample(worldPoint, ip); } else { ip.u = theRefImgPt.u; ip.v = theRefImgPt.v; } ossimDpt ip_du; ossimDpt ip_dv; ossimGpt gp, gp_du, gp_dv; double dlat_du, dlat_dv, dlon_du, dlon_dv; double delta_lat, delta_lon, delta_u, delta_v; double inverse_norm; bool done = false; //--- // Begin iterations: //--- do { //--- // establish perturbed image points about the guessed point: //--- ip_du.u = ip.u + 1.0; ip_du.v = ip.v; ip_dv.u = ip.u; ip_dv.v = ip.v + 1.0; //--- // Compute numerical partials at current guessed point: //--- lineSampleHeightToWorld(ip, height, gp); lineSampleHeightToWorld(ip_du, height, gp_du); lineSampleHeightToWorld(ip_dv, height, gp_dv); if(gp.isLatNan() || gp.isLonNan()) { gp = ossimCoarseGridModel::extrapolate(ip); } if(gp_du.isLatNan() || gp_du.isLonNan()) { gp_du = ossimCoarseGridModel::extrapolate(ip_du); } if(gp_dv.isLatNan() || gp_dv.isLonNan()) { gp_dv = ossimCoarseGridModel::extrapolate(ip_dv); } if ( m_crossesDateline ) { // Longitude set to between 0 and 360. if ( gp.lon < 0.0 ) gp.lon += 360.0; if ( gp_du.lon < 0.0 ) gp_du.lon += 360.0; if ( gp_dv.lon < 0.0 ) gp_dv.lon += 360.0; } dlat_du = gp_du.lat - gp.lat; //e dlon_du = gp_du.lon - gp.lon; //g dlat_dv = gp_dv.lat - gp.lat; //f dlon_dv = gp_dv.lon - gp.lon; //h //--- // Test for convergence: // Use the wdp as it was corrected if there was a date line cross. // delta_lat = wdp.lat - gp.lat; delta_lon = wdp.lon - gp.lon; // Compute linearized estimate of image point given gp delta: inverse_norm = dlat_dv*dlon_du - dlat_du*dlon_dv; // fg-eh if (!ossim::almostEqual(inverse_norm, 0.0, DBL_EPSILON)) { delta_u = (-dlon_dv*delta_lat + dlat_dv*delta_lon)/inverse_norm; delta_v = ( dlon_du*delta_lat - dlat_du*delta_lon)/inverse_norm; ip.u += delta_u; ip.v += delta_v; } else { delta_u = 0; delta_v = 0; } #if 0 cout << "gp: " << gp << "\ngp_du: " << gp_du << "\ngp_dv: " << gp_dv << "\ndelta_lat: " << delta_lat << "\ndelta_lon: " << delta_lon << "\ndelta_u: " << delta_u << "\ndelta_v: " << delta_v << endl; #endif done = ((fabs(delta_u) < PIXEL_THRESHOLD)&& (fabs(delta_v) < PIXEL_THRESHOLD)); ++iters; } while ( (!done) && (iters < MAX_NUM_ITERATIONS)); //--- // Note that this error mesage appears only if max count was reached while // iterating. A linear (no iteration) solution would finish with iters = // MAX_NUM_ITERATIONS + 1: //--- #if 0 /* please leave for debug: */ if (iters >= MAX_NUM_ITERATIONS) { std::cout << "MAX ITERATION!!!" << std::endl; std::cout << "delta_u = " << delta_u << "\ndelta_v = " << delta_v << "\n"; } else { std::cout << "ITERS === " << iters << std::endl; } std::cout << "iters = " << iters << "\n"; #endif //--- // The image point computed this way corresponds to full image space. // Apply image offset in the case this is a sub-image rectangle: //--- ip -= theSubImageOffset; } // End: worldToLineSample( ... )
void ossimEquDistCylProjection::worldToLineSample(const ossimGpt &worldPoint, ossimDpt& lineSample)const { if(theModelTransformUnitType != OSSIM_UNIT_UNKNOWN) { ossimMapProjection::worldToLineSample(worldPoint, lineSample); return; } else { // make sure our tie point is good and world point // is good. // if(theUlEastingNorthing.isNan()|| worldPoint.isLatNan() || worldPoint.isLonNan()) { lineSample.makeNan(); return; } // initialize line sample // lineSample = ossimDpt(0,0); // I am commenting this code out because I am going to // move it to the ossimImageViewProjectionTransform. // // see if we have a datum set and if so // shift the world to our datum. If not then // find the easting northing value for the world // point. if(theDatum) { ossimGpt gpt = worldPoint; gpt.changeDatum(theDatum); // lineSample is currently in easting northing // and will need to be converted to line sample. lineSample = forward(gpt); } else { // lineSample is currently in easting northing // and will need to be converted to line sample. lineSample = forward(worldPoint); } // check the final result to make sure there were no // problems. // if(!lineSample.isNan()) { // if(!isIdentityMatrix()) // { // ossimDpt temp = lineSample; // lineSample.x = theInverseTrans[0][0]*temp.x+ // theInverseTrans[0][1]*temp.y+ // theInverseTrans[0][2]; // lineSample.y = theInverseTrans[1][0]*temp.x+ // theInverseTrans[1][1]*temp.y+ // theInverseTrans[1][2]; // } // else { lineSample.x = ((lineSample.x - theUlEastingNorthing.x)/theMetersPerPixel.x); // We must remember that the Northing is negative since the positive // axis for an image is assumed to go down since it's image space. lineSample.y = (-(lineSample.y - theUlEastingNorthing.y)/theMetersPerPixel.y); } } } }
void ossimEquDistCylProjection::lineSampleHeightToWorld(const ossimDpt &lineSample, const double& hgtEllipsoid, ossimGpt& gpt)const { // // make sure that the passed in lineSample is good and // check to make sure our easting northing is good so // we can compute the line sample. // // if(lineSample.hasNans()) { gpt.makeNan(); return; } if(theModelTransformUnitType != OSSIM_UNIT_UNKNOWN) { ossimMapProjection::lineSampleHeightToWorld(lineSample, hgtEllipsoid, gpt); return; } else { if(theUlEastingNorthing.hasNans()) { gpt.makeNan(); return; } ossimDpt eastingNorthing; eastingNorthing = (theUlEastingNorthing); eastingNorthing.x += (lineSample.x*theMetersPerPixel.x); // // Note: the Northing is positive up. In image space // the positive axis is down so we must multiply by // -1 // eastingNorthing.y += (-lineSample.y*theMetersPerPixel.y); // // now invert the meters into a ground point. // gpt = inverse(eastingNorthing); gpt.datum(theDatum); if(gpt.isLatNan() && gpt.isLonNan()) { gpt.makeNan(); } else { // Finally assign the specified height: gpt.hgt = hgtEllipsoid; } } if(theElevationLookupFlag) { gpt.hgt = ossimElevManager::instance()->getHeightAboveEllipsoid(gpt); } }