Página principal | Jerarquía de la clase | Lista alfabética | Lista de componentes | Lista de archivos | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

dem.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= Dem.h                                                   Octubre de 1999 =
00003 //=-------------------------------------------------------------------------=
00004 //= Declaracion de la clase GLOBAL_DEM que contiene datos de altimetria a   =
00005 //= escala planetaria.                                                      =
00006 //=-------------------------------------------------------------------------=
00007 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00008 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00009 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00010 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00011 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00012 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00013 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00014 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00015 //=-------------------------------------------------------------------------=
00016 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00017 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00018 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00019 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00020 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00021 //===========================================================================
00022 
00023 #include "toolkits/util/dem.h"
00024 #include "lista.cc"
00025 #include <string.h>
00026 #include <stdlib.h>
00027 
00028 //===========================================================================
00029 //= Macros                                                                  =
00030 //===========================================================================
00031 
00032 #define ESPERO(tipo, msg) \
00033     if ( tipo_token != (tipo) ) { \
00034         fprintf(stderr, "<GLOBAL_DEM> ERROR: Esperaba %s y recibi [%s].\n", \
00035           (msg), cad); fflush(stderr);  return FALSE; \
00036     }
00037 
00038 //===========================================================================
00039 //= Clase LOCAL_DEM                                                         =
00040 //===========================================================================
00041 
00042 LOCAL_DEM::LOCAL_DEM(char *n)
00043 {
00044     nombre = new char[strlen(n)+1];
00045     strcpy(nombre, n);
00046     fd = NULL;
00047     revisado = FALSE;
00048 }
00049 
00050 LOCAL_DEM::~LOCAL_DEM()
00051 {
00052     if ( fd ) fclose(fd);
00053     delete nombre;
00054 }
00055 
00056 void
00057 LOCAL_DEM::leer_linea(BYTE *buffer, long int pos, long int num_elems, 
00058  char *path)
00059 {
00060     //-----------------------------------------------------------------------
00061     static char archivo[1024];
00062     int i;
00063 
00064     if ( !fd ) {
00065         sprintf(archivo, "%s/%s", path, nombre);
00066         fd = fopen(archivo, "rb");
00067         if ( !fd ) {
00068             for ( i = 0; i < num_elems; i++ ) {
00069                 buffer[2*i] = 10;
00070                 buffer[2*i+1] = 10;
00071             }
00072             return;
00073         }
00074     }
00075 
00076     //printf("[%c%c%c%c%c%c]", nombre[1], nombre[2], nombre[3],
00077     //                         nombre[4], nombre[5], nombre[6]); 
00078     //fflush(stdout);
00079 
00080     //-----------------------------------------------------------------------
00081     fseek(fd, pos, SEEK_SET);
00082     //fread(buffer, sizeof(WORD), num_elems, fd);
00083     for ( i = 0; i < num_elems; i++ ) {
00084         lea_WORD_BE(&(((WORD *)buffer)[i]), fd);
00085     }
00086 }
00087 
00088 BOOLEAN
00089 LOCAL_DEM::disponible(char *path)
00093 {
00094     if ( revisado && !fd ) return FALSE;
00095     if ( revisado && fd ) return TRUE;
00096 
00097     //-----------------------------------------------------------------------
00098     static char archivo[1024];
00099 
00100     if ( !fd ) {
00101         sprintf(archivo, "%s/%s", path, nombre);
00102         fd = fopen(archivo, "rb");
00103         revisado = TRUE;
00104         if ( !fd ) {
00105             return FALSE;
00106         }
00107     }
00108     return TRUE;
00109 }
00110 
00111 //===========================================================================
00112 //= Clase GLOBAL_DEM                                                        =
00113 //===========================================================================
00114 
00115 GLOBAL_DEM::GLOBAL_DEM()
00116 {
00117     _num_paralelos = 0;
00118     _num_meridianos = 0;
00119     menor_x = 0;
00120     menor_y = 0;
00121     buffer = NULL;
00122     path = NULL;
00123 }
00124 
00125 GLOBAL_DEM::~GLOBAL_DEM()
00126 {
00127     int i;
00128 
00129     for ( i = 0; i < parches.tam(); i++ ) {
00130         delete parches[i];
00131     }
00132     parches.elim();
00133     if ( path ) delete path;
00134 
00135     if ( buffer ) delete buffer;
00136 }
00137 
00138 long int
00139 GLOBAL_DEM::num_paralelos(void)
00140 {
00141     return _num_paralelos;
00142 }
00143 
00144 long int
00145 GLOBAL_DEM::num_meridianos(void)
00146 {
00147     return _num_meridianos;
00148 }
00149 
00150 long int
00151 GLOBAL_DEM::mayor_x(void)
00152 {
00153     return menor_x;
00154 }
00155 
00156 long int
00157 GLOBAL_DEM::mayor_y(void)
00158 {
00159     return menor_y;
00160 }
00161 
00162 static void
00163 calcular_color(WORD *data, BYTE *r, BYTE *g, BYTE *b, int /*x*/)
00167 {
00168     if ( (BYTE)(*data) != 0xD8 ) {
00169         (*b) = 0;
00170         (*r) = (BYTE)((BYTE)((*data)*5) + (BYTE)150);
00171         (*g) = (BYTE)((BYTE)((*data)*5) + (BYTE)150);
00172         if ( *r > 252 || *r < 150 ) {
00173             *r = *g = *b = 254;        
00174         }
00175         //*r = *g = (BYTE)((*data)*10) + (BYTE)100;
00176       }
00177       else {
00178         *r = *g = 0;
00179         *b = 200;
00180     }
00181 }
00182 
00183 BOOLEAN
00184 GLOBAL_DEM::exportar_imagen(IMAGEN_RGB *Imagen,long int x_pos,long int y_pos)
00195 {
00196     //-----------------------------------------------------------------------
00197     LOCAL_DEM *Parche = NULL; // Este es el area de donde se leen las lineas
00198     LOCAL_DEM *Vecino = NULL; // Esta es el area a la derecha de Parche, y se
00199                               // en caso de que las lineas sean muy anchas
00200 
00201     //- Exporte datos a la imagen -------------------------------------------
00202     int x = 0, y = 0;
00203     BYTE r, g, b;
00204     long int base_y, base_x;
00205     long int base2_y, base2_x;
00206     long int x_pos2, len;
00207 
00208     for ( y = 0; y < Imagen->ytam(); y++ ) {
00209         //-----------------------------------------------------------------
00210         for ( parches.principio(); parches.ventana(); ++parches ) {
00211             Parche = parches.ventana();
00212             if ( x_pos >= Parche->longitud &&
00213                  x_pos <  Parche->longitud+Parche->x_tam &&
00214                  y_pos-y + Imagen->ytam() < Parche->latitud &&
00215                  y_pos-y + Imagen->ytam() >= Parche->latitud+Parche->y_tam ) {
00216                 break;
00217             }
00218         }
00219         if ( !parches.ventana() ) continue;
00220 
00221         x_pos2 = x_pos + Parche->x_tam;
00222         if ( x_pos2 >= _num_meridianos ) x_pos2 = 0;
00223         for ( parches.principio(); parches.ventana(); ++parches ) {
00224             Vecino = parches.ventana();
00225             if ( x_pos2 >= Vecino->longitud &&
00226                  x_pos2 <  Vecino->longitud+Vecino->x_tam &&
00227                  y_pos-y + Imagen->ytam() <  Vecino->latitud &&
00228                  y_pos-y + Imagen->ytam() >= Vecino->latitud+Vecino->y_tam ) {
00229                 break;
00230             }
00231         }
00232 
00233         //-----------------------------------------------------------------
00234         base_x = x_pos - Parche->longitud;
00235         base_y = (y_pos-y+Imagen->ytam()) - (Parche->latitud+Parche->y_tam);
00236 
00237         if ( base_x + Imagen->xtam() <= Parche->x_tam ) {
00238             len = Imagen->xtam();
00239           }
00240           else {
00241             len = Vecino->x_tam - base_x;
00242             base2_x = 0;
00243             base2_y = (y_pos-y+Imagen->ytam())-(Vecino->latitud+Vecino->y_tam);
00244             Vecino->leer_linea(&buffer[len*2],
00245                 (base2_y)*(2*Vecino->x_tam) + 2*base2_x, 
00246                 base2_x+ Imagen->xtam() - len, path);
00247         }
00248         Parche->leer_linea(buffer, base_y*(2*Parche->x_tam) + 2*base_x, len,
00249             path);
00250 
00251         //-----------------------------------------------------------------
00252         for ( x = 0; x < Imagen->xtam(); x++ ) {
00253             calcular_color((WORD*)(&buffer[2*x]), &r, &g, &b, x);
00254             Imagen->putpixel(x, Imagen->ytam()-y-1, r, g, b);
00255         }
00256     }
00257 
00258     return TRUE;
00259 }
00260 
00261 BOOLEAN
00262 GLOBAL_DEM::exportar_vertices(VERTICE_GL *Vertices,
00263         long int x_pos,long int y_pos, long int x_tam, long int y_tam)
00276 {
00277     //- Exporte datos -------------------------------------------------------
00278     int x = 0, y = 0;
00279     //BYTE r, g, b;
00280     LOCAL_DEM *Parche = NULL, *Vecino = NULL;
00281     long int base_y, base_x;
00282     long int base2_y, base2_x;
00283     long int x_pos2, len;
00284     double vx, vy, vz;
00285 
00286     for ( y = 0; y < y_tam; y++ ) {
00287         //-----------------------------------------------------------------
00288         for ( parches.principio(); parches.ventana(); ++parches ) {
00289             Parche = parches.ventana();
00290             if ( x_pos >= Parche->longitud &&
00291                  x_pos <  Parche->longitud+Parche->x_tam &&
00292                  y_pos-y + y_tam <  Parche->latitud &&
00293                  y_pos-y + y_tam >= Parche->latitud+Parche->y_tam ) {
00294                 break;
00295             }
00296         }
00297         if ( !parches.ventana() ) continue;
00298 
00299         x_pos2 = x_pos + Parche->x_tam;
00300         if ( x_pos2 >= _num_meridianos ) x_pos2 = 0;
00301         for ( parches.principio(); parches.ventana(); ++parches ) {
00302             Vecino = parches.ventana();
00303             if ( x_pos2 >= Vecino->longitud &&
00304                  x_pos2 <  Vecino->longitud+Vecino->x_tam &&
00305                  y_pos-y + y_tam <  Vecino->latitud &&
00306                  y_pos-y + y_tam >= Vecino->latitud+Vecino->y_tam ) {
00307                 break;
00308             }
00309         }
00310 
00311         //-----------------------------------------------------------------
00312         base_x = x_pos - Parche->longitud;
00313         base_y = (y_pos-y+y_tam) - (Parche->latitud+Parche->y_tam);
00314 
00315         if ( base_x + x_tam <= Parche->x_tam ) {
00316             len = x_tam;
00317           }
00318           else {
00319             len = Vecino->x_tam - base_x;
00320             base2_x = 0;
00321             base2_y = (y_pos-y+y_tam)-(Vecino->latitud+Vecino->y_tam);
00322             Vecino->leer_linea(&buffer[len*2],
00323                 (base2_y)*(2*Vecino->x_tam) + 2*base2_x, 
00324                 base2_x+ x_tam - len, path);
00325         }
00326         Parche->leer_linea(buffer, base_y*(2*Parche->x_tam) + 2*base_x, len,
00327             path);
00328 
00329         //- Genere los datos correspondientes a la linea actual -----------
00330         for ( x = 0; x < x_tam; x++ ) {
00331             //calcular_color((WORD*)(&buffer[2*x]), &r, &g, &b, x);
00332             vx = x;
00333             vy = y;
00334           #ifdef AQZ_BIG_ENDIAN
00335             vz = (double)((char)buffer[2*x]) + (double)buffer[2*x+1]*256;
00336           #endif
00337           #ifdef AQZ_LITTLE_ENDIAN
00338             vz = (double)((char)buffer[2*x])*256 + (double)buffer[2*x+1];
00339           #endif
00340             if ( vz < 0 ) vz = -50;
00341             // El 1000 es porque GTOPO30 viene en unidades de metros, y
00342             // es una grilla donde cada muestra es de 1km^2. Por otro lado,
00343             // la altura no requiere conversion, porque ya va codificada en
00344             // metros.
00345             Vertices[(y) * x_tam + x].x = 1000*((float)vx);
00346             Vertices[(y) * x_tam + x].y = 1000*((float)(vy-y_tam+2));
00347             Vertices[(y) * x_tam + x].z = ((float)vz);  
00348         }
00349     }
00350 
00351     return TRUE;
00352 
00353 }
00354 
00355 //===========================================================================
00356 
00357 void
00358 GLOBAL_DEM::set_nombre(const char *n)
00359 {
00360     strcpy(_nombre, n);
00361 }
00362 
00363 char *
00364 GLOBAL_DEM::nombre(void)
00365 {
00366     return _nombre;
00367 }
00368 
00369 BOOLEAN
00370 GLOBAL_DEM::leer(TOKENIZADOR *Sabiondo)
00371 {
00372     char cad[1000];
00373     int tipo_token = TK_DESCONOCIDO, pos;
00374     LOCAL_DEM *Parche = NULL;
00375     long int tmp;
00376     double val;
00377     int i;
00378 
00379     //- Ejecute el parser especifico de la COSA_RIGIDA -----------------
00380     pos = 1;
00381     while ( tipo_token != TK_CERRAR) {
00382         tipo_token = Sabiondo->siguiente_token(cad);
00383         switch ( pos ) {
00384             case 1:
00385               ESPERO(TK_CADENA, "una cadena");
00386               if ( strlen(cad) > MAX_CAD-1 ) cad[MAX_CAD-1] = '\0'; 
00387               des_comille(cad);
00388               set_nombre(cad);
00389               pos++;
00390               break;
00391             case 2:  ESPERO(TK_ABRIR, "\"{\"");  pos++; break;
00392             default:
00393               if ( tipo_token == TK_CERRAR ) break;
00394               ESPERO(TK_IDENTIFICADOR, "un identificador (3)");
00395               if ( strcmp(cad, "num_meridianos") == 0 ) {
00396                   tipo_token = Sabiondo->siguiente_token(cad);
00397                   ESPERO(TK_NUMERO, "un numero");
00398                   _num_meridianos = atol(cad);
00399                 }
00400                 else if ( strcmp(cad, "num_paralelos") == 0 ) {
00401                   tipo_token = Sabiondo->siguiente_token(cad);
00402                   ESPERO(TK_NUMERO, "un numero");
00403                   _num_paralelos = atol(cad);
00404                 }
00405                 else if ( strcmp(cad, "directorio") == 0 ) {
00406                   tipo_token = Sabiondo->siguiente_token(cad);
00407                   ESPERO(TK_CADENA, "una cadena (path de directorio)");
00408                   des_comille(cad);
00409                   if ( path ) delete path;
00410                   path = new char[strlen(cad)+1];
00411                   strcpy(path, cad);
00412                 }
00413                 else if ( strcmp(cad, "area") == 0 ) {
00414                   tipo_token = Sabiondo->siguiente_token(cad);
00415                   ESPERO(TK_CADENA, "una cadena");
00416                   des_comille(cad);
00417                   Parche = new LOCAL_DEM(cad);
00418                   tipo_token = Sabiondo->siguiente_token(cad);
00419                   ESPERO(TK_VECTOR_INICIO, "el inicio de una coordenada(lat)");
00420                   val = 180 - (atof(&cad[1]) + 90);
00421                   Parche->latitud =(long int)((val*(double)_num_paralelos)/180);
00422 
00423                   tipo_token = Sabiondo->siguiente_token(cad);
00424                   ESPERO(TK_NUMERO, "el final de una coordenada (lon)");
00425                   Parche->longitud = (long int)(
00426                       ((atof(cad) + 180) * (double)_num_meridianos) / 360);
00427 
00428                   tipo_token = Sabiondo->siguiente_token(cad);
00429                   ESPERO(TK_NUMERO, "el inicio de la 2coordenada(lat)");
00430                   val = 180 - (atof(cad) + 90);
00431                   tmp = (long int)((val * (double)_num_paralelos) / 180);
00432                   Parche->y_tam = tmp - Parche->latitud;
00433 
00434                   tipo_token = Sabiondo->siguiente_token(cad);
00435                   ESPERO(TK_VECTOR_FIN, "el final de la 2coordenada (lon)");
00436                   cad[strlen(cad) - 1] = '\0';
00437                   tmp = (long int)(
00438                       ((atof(cad) + 180) * (double)_num_meridianos) / 360);
00439                   Parche->x_tam = tmp - Parche->longitud;
00440 
00441                   parches.anx(Parche);
00442                 }
00443               ;
00444               break;
00445         }
00446     }
00447 
00448     if ( !parches.tam() ) return FALSE;
00449 
00450     long int mayor_x = 0;
00451 
00452     menor_x = parches[0]->x_tam;
00453     menor_y = (long int)fabs((double)parches[0]->y_tam);
00454     for ( i = 0; i < parches.tam(); i++ ) {
00455         if ( parches[i]->x_tam < menor_x ) menor_x = parches[i]->x_tam;
00456         if ( parches[i]->x_tam > mayor_x ) mayor_x = parches[i]->x_tam;
00457         if ( fabs((double)parches[i]->y_tam) < menor_y )
00458             menor_y = (long int)fabs((double)parches[i]->y_tam);
00459     }
00460 
00461     buffer = new BYTE[mayor_x*2];
00462     if ( !buffer ) return FALSE;
00463 
00464     return TRUE;
00465 }
00466 
00467 //===========================================================================
00468 
00469 #ifdef GL_ENABLED
00470 void
00471 GLOBAL_DEM::pintar_gl(long int pos_x, long int pos_y, 
00472                       long int size_x, long int size_y)
00479 {
00480     int i;
00481     LOCAL_DEM *Parche;
00482     double x, y, dx, dy;
00483     double xP, yP, dxP, dyP;
00484     BOOLEAN soy_yo;
00485     double e = 0.0025;
00486 
00487     xP =  (double)pos_x / (double)_num_meridianos;
00488     yP =  (double)(_num_paralelos-pos_y) / (double)_num_paralelos;
00489     dxP = (double)size_x / (double)_num_meridianos;
00490     dyP = (double)size_y / (double)_num_paralelos;
00491 
00492     for ( i = 0; i < parches.tam(); i++ ) {
00493         Parche = parches[i];
00494         x =  (double)Parche->longitud / (double)_num_meridianos;
00495         y =  (double)(_num_paralelos-Parche->latitud) / (double)_num_paralelos;
00496         dx = (double)Parche->x_tam / (double)_num_meridianos;
00497         dy = (double)Parche->y_tam / (double)_num_paralelos;
00498         soy_yo = FALSE;
00499         if ( xP >= x && xP < x+dx && yP >= y && yP < y+dy ) {
00500             soy_yo = TRUE;
00501         }
00502         if ( Parche->disponible(path) ) glColor3f(0, 1, 0);
00503         else glColor3d(0, 0.4, 0);
00504         glBegin(soy_yo?GL_QUADS:GL_LINE_LOOP);
00505             glVertex2d(2*x-1+e,        2*y-1+e);
00506             glVertex2d(2*(x + dx)-1-e, 2*y-1+e); 
00507             glVertex2d(2*(x + dx)-1-e, 2*(y - dy)-1-e);
00508             glVertex2d(2*x-1+e,        2*(y - dy)-1-e);
00509         glEnd();
00510     }
00511 
00512     glColor3f(1, 1, 0);
00513     glBegin(GL_LINE_LOOP);
00514         glVertex2d(2*xP-1,        2*yP-1);
00515         glVertex2d(2*(xP + dxP)-1, 2*yP-1);
00516         glVertex2d(2*(xP + dxP)-1, 2*(yP - dyP)-1);
00517         glVertex2d(2*xP-1,        2*(yP - dyP)-1);
00518     glEnd();
00519 }
00520 #endif // GL_ENABLED
00521 
00522 //===========================================================================
00523 //= EOF                                                                     =
00524 //===========================================================================
00525 

Este archivo HTML ha sido generado automáticamente a partir del código fuente AQUYNZA. NO LO EDITE. Para mayor información contacte al autor.