void ossimNitfProjectionFactory::computeScaleInMeters( const ossimNitfImageHeader* hdr, const std::vector<ossimDpt>& dpts, ossimDpt& scale) const { if ( !hdr || isSkewed(dpts)) { scale.makeNan(); return; } ossimIrect imageRect = hdr->getImageRect(); //--- // Calculate the scale. This assumes that the corner points are for the // edge of the corner pixels, not the center of the corner pixels. //--- double eastingSize = 0.0; double northingSize = 0.0; eastingSize = fabs(dpts[1].x - dpts[0].x); northingSize = fabs(dpts[0].y - dpts[3].y); double rows = imageRect.height();//hdr->getNumberOfRows(); double cols = imageRect.width();//hdr->getNumberOfCols(); if (!rows || !cols) { scale.makeNan(); return; } scale.y = northingSize / rows; scale.x = eastingSize / cols; }
void ossimNitfProjectionFactory::computeScaleInDecimalDegrees( const ossimNitfImageHeader* hdr, const std::vector<ossimGpt>& gpts, ossimDpt& scale) const { if ( !hdr || isSkewed(gpts)) { scale.makeNan(); return; } ossimIrect imageRect = hdr->getImageRect(); //--- // Calculate the scale. This assumes that the corner points are for the // edge of the corner pixels, not the center of the corner pixels. //--- double longitudeSize = 0.0; double latitudeSize = 0.0; if ( (gpts[1].lond() < 0.0) && (gpts[0].lond() >= 0) ) { //--- // Upper right negative(Western), upper left positive (Eastern). // Crossing date line maybe??? //--- longitudeSize = (gpts[1].lond() + 360.0) - gpts[0].lond(); } else { longitudeSize = gpts[1].lond() - gpts[0].lond(); } latitudeSize = gpts[0].latd() - gpts[2].latd(); double rows = imageRect.height(); double cols = imageRect.width(); // double rows = hdr->getNumberOfRows(); // double cols = hdr->getNumberOfCols(); if (!rows || !cols) { scale.makeNan(); return; } scale.y = latitudeSize / rows; scale.x = longitudeSize / cols; }
ossimProjection* ossimNitfProjectionFactory::makeGeographic( const ossimNitfImageHeader* hdr, const ossimString& coordinateSysetm) const { ossimProjection* proj = 0; if (!hdr) { return proj; } // To hold corner points. std::vector<ossimGpt> gpts; //--- // Get the corner points. // // Look for points from the BLOCKA tag. This may or may not be present. // If present since it has six digit precision use it for the points. //--- if ( getBlockaPoints(hdr, gpts) == false ) { ossimString geographicLocation = hdr->getGeographicLocation(); if (traceDebug()) { ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeGeographic DEBUG:" << "\ngeographicLocation: " << geographicLocation << std::endl; } if (coordinateSysetm == "G") { //--- // If coord system is G then format is: // Lat = ddmmssX // where d is degrees and m is minutes // and s is seconds and X is either N (North) or S (South). // Lon = dddmmssX // where d is degrees and m is minutes // and s is seconds and X is either N (North) or S (South). //--- parseGeographicString(geographicLocation, gpts); } else if (coordinateSysetm == "D") { //--- // If coor system is D then format is: // +-dd.ddd +-dd.ddd four times where + is northern hemispher and // - is souther hemisphere for lat and longitude // + is easting and - is westing. //--- parseDecimalDegreesString(geographicLocation, gpts); } } if (gpts.size() != 4) { return 0; } if (!isSkewed(gpts)) { proj = makeEuiDistant(hdr, gpts); } else { // Image is rotated. Make a Bilinear. proj = makeBilinear(hdr, gpts); } if (traceDebug() && proj) { ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeGeographic DEBUG:" << "\nUpper left corner: " << gpts[0] << "\nUpper right corner: " << gpts[1] << "\nLower right corner: " << gpts[2] << "\nLower left corner: " << gpts[3] << endl << proj->print(ossimNotify(ossimNotifyLevel_DEBUG)) << std::endl; } return proj; }
ossimProjection* ossimNitfProjectionFactory::makeUtm( const ossimNitfImageHeader* hdr, const ossimString& coordinateSystem) const { ossimUtmProjection* proj = 0; if (!hdr) { return proj; } ossimString geographicLocation = hdr->getGeographicLocation(); std::vector<ossimDpt> utmPoints; ossim_uint32 zone; ossimDpt scale; parseUtmString(geographicLocation, zone, utmPoints); if (traceDebug()) { ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeUtm DEBUG" << "\ngeo string: " << geographicLocation << std::endl; for (ossim_uint32 i=0; i<utmPoints.size(); ++i) { ossimNotify(ossimNotifyLevel_DEBUG) << "utmPoints[" << utmPoints[i] << std::endl; } } proj = new ossimUtmProjection; if(coordinateSystem == "S") { proj->setHemisphere('S'); } else { proj->setHemisphere('N'); } proj->setZone(zone); if(isSkewed(utmPoints)) { std::vector<ossimGpt> gpts; // Try blocka points first as they are more accurate. if ( getBlockaPoints(hdr, gpts) == false ) { ossimGpt ul = proj->inverse(utmPoints[0]); ossimGpt ur = proj->inverse(utmPoints[1]); ossimGpt lr = proj->inverse(utmPoints[2]); ossimGpt ll = proj->inverse(utmPoints[3]); gpts.push_back(ul); gpts.push_back(ur); gpts.push_back(lr); gpts.push_back(ll); } delete proj; proj = 0; return makeBilinear(hdr, gpts); } else { computeScaleInMeters(hdr, utmPoints, scale); } ossimProjection* result = 0; if(!scale.hasNans()) { //--- // Get the tie point. // // Look for the the BLOCKA tag which may or may not be present. // This has six digit precision in decimal degrees which equates to // about 0.11 meters (at equator) as compared to 1.0 accuaracy of the // IGEOLO field. //--- ossimDpt tie; std::vector<ossimGpt> gpts; if ( getBlockaPoints(hdr, gpts) ) { if (traceDebug()) { ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeUtm DEBUG:" << "\nTie point from blocka: " << gpts[0] << endl; } tie = proj->forward(gpts[0]); tie.x += scale.x/2.0; tie.y -= scale.y/2.0; } else { tie.x = utmPoints[0].x + scale.x/2.0; tie.y = utmPoints[0].y - scale.y/2.0; } if (traceDebug()) { ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeUtm DEBUG:" << "\nTie point: " << tie << "\nScale: " << scale << endl; } proj->setUlEastingNorthing(tie); proj->setMetersPerPixel(scale); result = proj; } else { delete proj; proj = 0; } return result; }
ossimProjection* ossimNitfProjectionFactory::makeUtm( const ossimNitfImageHeader* hdr, const ossimString& coordinateSystem) const { ossimProjection* proj = 0; if (hdr) { ossimString geographicLocation = hdr->getGeographicLocation(); if ( geographicLocation.size() ) { std::vector<ossimDpt> utmPoints; ossim_uint32 zone; ossimDpt scale; char hemisphere = 'N'; bool status = true; if ( coordinateSystem == "U") { // Sets zone, hemisphere and utmPoints. Returns true on success. status = parseMgrsString(geographicLocation, zone, hemisphere, utmPoints); } else { // Sets zone and utmPoints. Void return... parseUtmString(geographicLocation, zone, utmPoints); if(coordinateSystem == "S") { hemisphere = 'S'; } } if ( status ) { if ( traceDebug() ) { std::string s; s.push_back(hemisphere); ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeUtm DEBUG" << "\ngeo string: " << geographicLocation << "\nutm zone: " << zone << "\nhemisphere: " << hemisphere << std::endl; for (ossim_uint32 i=0; i<utmPoints.size(); ++i) { ossimNotify(ossimNotifyLevel_DEBUG) << "utmPoints[" << utmPoints[i] << std::endl; } } ossimRefPtr<ossimUtmProjection> uproj = new ossimUtmProjection; uproj->setHemisphere(hemisphere); uproj->setZone(zone); if(isSkewed(utmPoints)) { std::vector<ossimGpt> gpts; // Try blocka points first as they are more accurate. if ( getBlockaPoints(hdr, gpts) == false ) { ossimGpt ul = uproj->inverse(utmPoints[0]); ossimGpt ur = uproj->inverse(utmPoints[1]); ossimGpt lr = uproj->inverse(utmPoints[2]); ossimGpt ll = uproj->inverse(utmPoints[3]); gpts.push_back(ul); gpts.push_back(ur); gpts.push_back(lr); gpts.push_back(ll); } //--- // Make a bilinear either from our skewed utm points or the points from the blocka // tag. //--- proj = makeBilinear(hdr, gpts); uproj = 0; // Done with utm projeciton } else { computeScaleInMeters(hdr, utmPoints, scale); //--- // Assign our projection to the return "proj". // Use ossimRefPtr::release the so we don't delete proj when uproj // goes out of scope. //--- proj = uproj.release(); } if( scale.hasNans() == false ) { //--- // Get the tie point. // // Look for the the BLOCKA tag which may or may not be present. // This has six digit precision in decimal degrees which equates to // about 0.11 meters (at equator) as compared to 1.0 accuaracy of the // IGEOLO field. //--- ossimDpt tie; std::vector<ossimGpt> gpts; if ( getBlockaPoints(hdr, gpts) ) { if (traceDebug()) { ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeUtm DEBUG:" << "\nTie point from blocka: " << gpts[0] << endl; } tie = proj->forward(gpts[0]); tie.x += scale.x/2.0; tie.y -= scale.y/2.0; } else { tie.x = utmPoints[0].x + scale.x/2.0; tie.y = utmPoints[0].y - scale.y/2.0; } if (traceDebug()) { ossimNotify(ossimNotifyLevel_DEBUG) << "ossimNitfProjectionFactory::makeUtm DEBUG:" << "\nTie point: " << tie << "\nScale: " << scale << endl; } // Set the tie and scale. ossimMapProjection* mproj = dynamic_cast<ossimMapProjection*>(proj); if ( mproj ) { mproj->setUlEastingNorthing(tie); mproj->setMetersPerPixel(scale); } else // cannot cast { if ( proj ) { delete proj; proj = 0; } } } else // Scale has nans { if ( proj ) { delete proj; proj = 0; } } } // matches: if (status) } // matches: if ( geographicLocation.size() ) } // matches: if (hdr) return proj; }