00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "toolkits/util/dem.h"
00024 #include "lista.cc"
00025 #include <string.h>
00026 #include <stdlib.h>
00027
00028
00029
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
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
00077
00078
00079
00080
00081 fseek(fd, pos, SEEK_SET);
00082
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
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 )
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
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;
00198 LOCAL_DEM *Vecino = NULL;
00199
00200
00201
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
00278 int x = 0, y = 0;
00279
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
00330 for ( x = 0; x < x_tam; x++ ) {
00331
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
00342
00343
00344
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
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
00524
00525