00001 #include "ImageInterface.h" 00002 00003 00004 00005 bool ImageInterface::instanceFlag = false; 00006 ImageInterface* ImageInterface::instance = NULL; 00007 00008 ImageInterface* ImageInterface::getInterface(GLIMSProject *proj){ 00009 //return new ImageInterface(proj) ; 00010 00011 if(! instanceFlag) { 00012 instance = new ImageInterface(proj); 00013 instanceFlag = true; 00014 return instance; 00015 } 00016 else 00017 { 00018 return instance; 00019 } 00020 00021 } 00022 00023 void ImageInterface::destroyInterface(){ 00024 if(instanceFlag && instance != NULL) { 00025 delete instance; 00026 instanceFlag = false; 00027 } 00028 } 00029 00030 ImageInterface::~ImageInterface(){ 00031 //instanceFlag = false; 00032 } 00033 00034 ImageInterface::ImageInterface( GLIMSProject *proj ){ 00035 mProj = proj; 00036 } 00037 00038 Image* ImageInterface::getImage(){ 00039 return mProj->getImage(); 00040 } 00041 00042 ImageFormat* ImageInterface::getImageFormat(){ 00043 return (mProj->getImage())->getFormat(); 00044 } 00045 00046 00047 std::vector<double>* ImageInterface::getCubeLatLong(double lat1, double lon1, int z1, double lat2, double lon2, int z2){ 00048 int highz, lowz; 00049 00050 //find which z is smaller and which is larger 00051 if(z1>z2) { 00052 highz = z1; 00053 lowz = z2; 00054 }else{ 00055 lowz = z1; 00056 highz = z2; 00057 } 00058 00059 std::vector<double>* vals = NULL ; 00060 00061 //create doubles for translating from Lat/Lon to XY 00062 double x11 = lat1; 00063 double x21 = lat2; 00064 double y11 = lon1; 00065 double y21 = lon2; 00066 00067 getImageFormat()->getXY(lowz, x11, y11); 00068 getImageFormat()->getXY(lowz, x21, y21); 00069 00070 int lowx; 00071 int lowy; 00072 int highy; 00073 int highx; 00074 00075 //find which x is smaller and which is larger 00076 if(x11>x21) { 00077 highx = (int)(x11+0.5); 00078 lowx = (int)x21; 00079 } 00080 else{ 00081 lowx = (int)x11; 00082 highx = (int)(x21+0.5); 00083 } 00084 00085 //find which y is smaller and which is larger 00086 if(y11>y21) { 00087 highy = (int)(y11+0.5); 00088 lowy = (int)y21; 00089 }else{ 00090 lowy = (int)y11; 00091 highy = (int)(y21+0.5); 00092 } 00093 00094 00095 for(int i = lowz; i<=highz; i++){//for each band 00096 00097 //create doubles for translating from Lat/Lon to XY 00098 double x1 = lat1; 00099 double x2 = lat2; 00100 double y1 = lon1; 00101 double y2 = lon2; 00102 00103 //translate corners to XY 00104 getImageFormat()->getXY(i, x1, y1); 00105 getImageFormat()->getXY(i, x2, y2); 00106 00107 int nlowx; 00108 int nlowy; 00109 int nhighy; 00110 int nhighx; 00111 00112 //find which x is smaller and which is larger 00113 if(x1>x2) { 00114 nhighx = (int)(x1+0.5); 00115 nlowx = (int)x2; 00116 }else{ 00117 nlowx = (int)x1; 00118 nhighx = (int)(x2+0.5); 00119 } 00120 00121 //find which y is smaller and which is larger 00122 if(y1>y2) { 00123 nhighy = (int)(y1+0.5); 00124 nlowy = (int)y2; 00125 } 00126 else{ 00127 nlowy = (int)y1; 00128 nhighy = (int)(y2+0.5); 00129 } 00130 00131 //get the values requested 00132 void * newline = getImageFormat()->getBand(i, nlowx, nlowy, (nhighx-nlowx), (nhighy-nlowy), (highx-lowx)+1, (highy-lowy)+1, ImageFormat::SCALE_NN) ; 00133 std::vector<double>* temp = NULL ; 00134 00135 //get the values requested 00136 if (newline != NULL) { 00137 temp = (getValueAsDouble(newline, i, ((highx-lowx)+1)*((highy-lowy)+1))) ; 00138 } 00139 00140 //get the values requested 00141 if(i==lowz && temp != NULL) vals = temp; 00142 00143 else if (temp != NULL){ 00144 //put the values into the vector...at the end 00145 vals->insert(vals->end(), temp->begin(), temp->end()); 00146 delete temp; 00147 } 00148 } 00149 00150 return vals; 00151 } 00152 00153 std::vector<double>* ImageInterface::getCube(int x1, int y1, int z1, int x2, int y2, int z2){ 00154 00155 int lowx; 00156 int lowy; 00157 int lowz; 00158 int highx; 00159 int highy; 00160 int highz; 00161 00162 //find which x is smaller and which is larger 00163 if(x1>x2) { 00164 highx = x1; 00165 lowx = x2; 00166 } 00167 else { 00168 lowx = x1; 00169 highx = x2; 00170 } 00171 00172 //find which y is smaller and which is larger 00173 if(y1>y2) { 00174 highy = y1; 00175 lowy = y2; 00176 } 00177 else { 00178 lowy = y1; 00179 highy = y2; 00180 } 00181 00182 //find which z is smaller and which is larger 00183 if(z1>z2) { 00184 highz = z1; 00185 lowz = z2; 00186 } 00187 else { 00188 lowz = z1; 00189 highz = z2; 00190 } 00191 00192 00193 //create a vector, go ahead and assign it to the first (lowest) band 00194 std::vector<double>* vals = (getValueAsDouble(getImageFormat()->getBand(lowz, lowx, lowy, (highx-lowx)+1, (highy-lowy)+1, (highx-lowx)+1, (highy-lowy)+1, ImageFormat::SCALE_NN), lowz, ((highx-lowx)+1)*((highy-lowy)+1))); 00195 00196 00197 //create double values of corners, so they can be translated 00198 double templx = lowx; 00199 double temply = lowy; 00200 double temphx = highx; 00201 double temphy = highy; 00202 00203 //translate corners to Lat/Lon 00204 getImageFormat()->getLL(lowz, templx, temply); 00205 getImageFormat()->getLL(lowz, temphx, temphy); 00206 00207 //QMessageBox::information( 0, "Application name", "before loop" ); 00208 00209 00210 for(int i = lowz+1; i<=highz; i++){//for each band 00211 00212 //create doubles for translating from Lat/Lon to XY 00213 double nhighx = temphx; 00214 double nlowx = templx; 00215 double nhighy = temphy; 00216 double nlowy = temply; 00217 00218 //translate corners to XY 00219 getImageFormat()->getXY(i, nlowx, nlowy); 00220 getImageFormat()->getXY(i, nhighx, nhighy); 00221 00222 //get the values requested 00223 std::vector<double>* temp = (getValueAsDouble(getImageFormat()->getBand(i, (int)nlowx, (int)nlowy, (int)(nhighx-nlowx)+1, (int)(nhighy-nlowy)+1, (highx-lowx)+1, (highy-lowy)+1, ImageFormat::SCALE_NN), i, ((highx-lowx)+1)*((highy-lowy)+1))); 00224 00225 //put the values into the vector...at the end 00226 vals->insert(vals->end(), temp->begin(), temp->end()); 00227 delete temp; 00228 } 00229 00230 return vals;//return vector 00231 } 00232 00233 std::vector<double>* ImageInterface::getCubeAllBands(int x1, int y1, int x2, int y2){ 00234 return getCube(x1, y1, 0, x2, y2, getImageFormat()->getNumBands()-1); 00235 } 00236 00237 std::vector<double>* ImageInterface::getSlice(int x1, int y1, int z1, int x2, int y2, int z2){ 00238 int lowx; 00239 int lowy; 00240 int highx; 00241 int highy; 00242 00243 //figure out which x is larger and smaller 00244 if(x1>x2) { 00245 highx = x1; 00246 lowx = x2; 00247 } 00248 else{ 00249 lowx = x1; 00250 highx = x2; 00251 } 00252 00253 //figure out which y is larger and smaller 00254 if(y1>y2) { 00255 highy = y1; 00256 lowy = y2; 00257 }else{ 00258 lowy = y1; 00259 highy = y2; 00260 } 00261 00262 00263 //if the slice is all in one layer 00264 if(z1 == z2){ 00265 //return the vector from this layer 00266 return getValueAsDouble(getImageFormat()->getBand(z1, lowx, lowy, (highx-lowx)+1, (highy-lowy)+1, (highx-lowx)+1, (highy-lowy)+1, ImageFormat::SCALE_NN), z1, ((highx-lowx)+1)*((highy-lowy)+1)); 00267 } 00268 else {//if the vector is accross layers 00269 if(x1 == x2 || y1 == y2){//one of these must be the same 00270 00271 return getCube(highx, highy, z1, lowx, lowy, z2); 00272 /* @TODO so, yeah. This works and does the stretching 00273 * all well in the x direction, but not the y direction 00274 * ideally, this problem would be fixed in the 00275 * ImageFormat::getBand(), but if not we can hack it here 00276 */ 00277 00278 } 00279 return NULL;//if something wasn't right, return NULL 00280 } 00281 00282 } 00283 00284 00285 std::vector<double>* ImageInterface::getSliceScaled(int x1, int y1, int z1, int x2, int y2, int z2){ 00286 int lowx; 00287 int lowy; 00288 int highx; 00289 int highy; 00290 00291 00292 //figure out which x is larger and smaller 00293 if(x1>x2) { 00294 highx = x1; 00295 lowx = x2; 00296 }else{ 00297 lowx = x1; 00298 highx = x2; 00299 } 00300 00301 //figure out which y is larger and smaller 00302 if(y1>y2) { 00303 highy = y1; 00304 lowy = y2; 00305 }else{ 00306 lowy = y1; 00307 highy = y2; 00308 } 00309 00310 //if the slice is all in one layer 00311 if(z1 == z2){ 00312 //return the vector from this layer 00313 00314 //get the size of the first layer, for scaling 00315 int scaledh = (highy - lowy)+1; 00316 int scaledw = (highx - lowx)+1; 00317 00318 double nhx = highx+1; 00319 double nlx = lowx; 00320 double nhy = highy+1; 00321 double nly = lowy; 00322 00323 if(z1 > 0){//if this isn't the only layer, we may need to scale 00324 00325 //get the vector of BandInf 00326 std::vector<ImageFormat::BandInf> &binf = getImage()->getBandInfSet(); 00327 00328 //get the size of the type from the proper BandInf 00329 int baseh = binf[0].height; 00330 int basew = binf[0].width; 00331 int thish = binf[z1].height; 00332 int thisw = binf[z1].width; 00333 00334 if( (baseh != thish) || (basew != thisw) ){ 00335 //translate corners to Lat/Lon 00336 getImageFormat()->getLL(0, nlx, nly); 00337 getImageFormat()->getLL(0, nhx, nhy); 00338 00339 //translate back to XY relative to z1 00340 getImageFormat()->getXY(z1, nlx, nly); 00341 getImageFormat()->getXY(z1, nhx, nhy); 00342 00343 //was getting strange negatives sometimes, so we make this 0 00344 if(nlx < 0) nlx = 0; 00345 if(nly < 0) nly = 0; 00346 00347 //translate back to ints 00348 lowx = (int)nlx; 00349 lowy = (int)nly; 00350 highx = (int)(nhx+0.5); 00351 highy = (int)(nhy+0.5); 00352 00353 } 00354 return getValueAsDouble(getImageFormat()->getBand(z1, lowx, lowy, (highx-lowx), (highy-lowy), scaledw, scaledh, ImageFormat::SCALE_NN), z1, scaledw*scaledh); 00355 } 00356 else 00357 return getValueAsDouble(getImageFormat()->getBand(z1, lowx, lowy, (highx-lowx)+1, (highy-lowy)+1, (highx-lowx)+1, (highy-lowy)+1, ImageFormat::SCALE_NN), z1, ((highx-lowx)+1)*((highy-lowy)+1)); 00358 00359 } else {//if the vector is accross layers 00360 00361 00362 if(x1 == x2 || y1 == y2){//one of these must be the same 00363 /* @TODO so, yeah. This works and does the stretching 00364 * all well in the x direction, but not the y direction 00365 * ideally, this problem would be fixed in the 00366 * ImageFormat::getBand(), but if not we can hack it here 00367 */ 00368 return getCube(highx, highy, z1, lowx, lowy, z2); 00369 } 00370 return NULL;//if something wasn't right, return NULL 00371 } 00372 00373 } 00374 00375 std::vector<double>* ImageInterface::getPoint(int x1, int y1, int z1){ 00376 return getValueAsDouble(getImageFormat()->getBand(z1, x1, y1, 1, 1, 0, 0), z1, 1); 00377 } 00378 00379 int ImageInterface::getBands(){ 00380 return getImageFormat()->getNumBands(); 00381 } 00382 int ImageInterface::getHeight(){ 00383 return getImage()->height(); 00384 } 00385 int ImageInterface::getWidth(){ 00386 return getImage()->width(); 00387 } 00388 char* ImageInterface::getPath(){ 00389 return NULL;//this needs to be fixed...but I don't know how 00390 } 00391 00392 QImage* ImageInterface::getQImage(int neww, int newh){ 00393 return getImage()->getRect(0, 0, getWidth(), getHeight(), neww, newh); 00394 } 00395 00396 QImage* ImageInterface::getQImageArea(int x, int y, int w, int h, int neww, int newh){ 00397 return getImage()->getRect(x, y, w, h, neww, newh); 00398 } 00399 00400 std::vector<double>* ImageInterface::getValueAsDouble(void* line, int bandnum, int width){ 00401 //create a vector to hold the values 00402 std::vector<double> *theValues = new std::vector<double>(width); 00403 00404 //get the vector of BandInf 00405 std::vector<ImageFormat::BandInf> &binf = getImage()->getBandInfSet(); 00406 00407 //get the size of the type from the proper BandInf 00408 //int dtsz = ImageFormat::dtypeSize( binf[bandnum].type ); 00409 00410 for( int x=0; x < width; x++ ) { 00411 int dx = x ; //* dtsz;//dx is now the byte of the next value 00412 00413 // based on type, do the proper cast to double 00414 switch( binf[bandnum].type ) { 00415 case ImageFormat::INT8: 00416 (*theValues)[x] = (double)(((char*)line)[dx]); 00417 break; 00418 00419 case ImageFormat::UINT8: 00420 (*theValues)[x] = (double)(((unsigned char*)line)[dx]); 00421 break; 00422 00423 case ImageFormat::INT16: 00424 (*theValues)[x] = (double)(((short*)line)[dx]); 00425 break; 00426 00427 case ImageFormat::UINT16: 00428 (*theValues)[x] = (double)(((unsigned short*)line)[dx]); 00429 break; 00430 00431 case ImageFormat::INT32: 00432 (*theValues)[x] = (double)(((int*)line)[dx]); 00433 break; 00434 00435 case ImageFormat::UINT32: 00436 (*theValues)[x] = (double)(((unsigned int*)line)[dx]); 00437 break; 00438 00439 case ImageFormat::INT64: 00440 (*theValues)[x] = (double)(((long*)line)[dx]); 00441 break; 00442 00443 case ImageFormat::UINT64: 00444 (*theValues)[x] = (double)(((unsigned long*)line)[dx]); 00445 break; 00446 00447 default: 00448 break; 00449 } 00450 } 00451 00452 return theValues; 00453 } 00454 00455 std::vector<std::string> ImageInterface::getBandNames(){ 00456 //get the vector of BandInf 00457 std::vector<ImageFormat::BandInf> &binf = getImage()->getBandInfSet(); 00458 00459 std::vector<std::string> temp; 00460 00461 for(int i=0; i<getBands(); i++){ 00462 temp.push_back(binf[i].name); 00463 } 00464 00465 return temp; 00466 } 00467 00468 void ImageInterface::getLL( int band, double &x, double &y){ 00469 getImageFormat()->getLL(band, x, y); 00470 } 00471 00472 void ImageInterface::getXY( int band, double &lat, double &lon){ 00473 getImageFormat()->getXY(band, lat, lon); 00474 } 00475 00476 std::string ImageInterface::runDriverTest() { 00477 string test = ""; 00478 stringstream ss; 00479 std::vector<double> temp = *(getSlice(1000, 1000, 2, 1000, 1010, 5)); 00480 //std::vector<double> temp = getCube(1000, 1000, 2, 1010, 1010, 5); 00481 for(unsigned int i = 0; i < temp.size(); i++){ 00482 if(i%11 == 0) ss << "\n"; 00483 //int dec, sign; 00484 //translate double values to string values 00485 ss << temp[i] << "; "; 00486 // std::string str2 = fcvt(temp[i], 0, &dec, &sign); 00487 //std::string str2 = "2.0"; 00488 //test.append(str2+"; "); 00489 00490 } 00491 00492 test = ss.str(); 00493 return test; 00494 00495 } 00496
Home |
Search |
Disclaimers & Privacy |
Contact Us GLIMSView Maintainer: dsoltesz@usgs.gov |