1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
|
// red drenaje 3D.cpp : define los comportamientos de las clases para la aplicación.
//
#include "Resource.h"
#include "stdafx.h"
#include "estructuras.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <iostream>
//#include <windows.h>
#include <math.h>
#define BUFSIZE 80
// rutina que libera la memoria de los arreglos globales usados en el proceso
void libera_memoria()
{
int i, j;
struct punto *p_actual, *p_anterior;
// se libera la memoria de las imagenes del modelo de alturas y de direcciones de flujo
for(i = 0; i < num_lineas; i++)
{
free(ima_alturas[i]);
free(ima_dflujo[i]);
}
free(ima_alturas);
free(ima_dflujo);
// se libera la memoria ocupada para los nodos
free(nodos);
// se libera la memoria ocupada por la topologia de la red
for(i = 0; i < num_tramos; i++)
{
free(red[i].lista_tramos_aguas_arriba); // se libera la memoria de las listas aguas arriba
}
// se libera la memoria del arreglo red
free(red);
// se libera la memoria ocupada por los tramos de la red
// primero se liberan los puntos de los tramos
for(i = 0; i < num_tramos; i++)
{
p_actual = tramos[i].ultimo_punto;
// se recorre la lista para liberar los puntos de atras hacia adelante
for(j = 0; j < tramos[i].numero_puntos; j++)
{
p_anterior = p_actual->anterior;
delete p_actual;
p_actual = p_anterior;
}
}
// se libera la memoria ocupada por las listas de nodos aguas arriba
for(i = 0; i < num_tramos; i++)
{
free(tramos[i].nodos_aguas_arriba); // se libera la memoria de las listas aguas arriba
}
// se libera la memoria del arreglo de tramos
free(tramos);
}
// rutina que lee el modelo de elevaciones generado por Physitel
void lee_modelo_de_elevaciones(LPCTSTR archivo)
{
FILE *a_elev;
char encabezado[513], mensaje[80];
int t_fichero, t_proyeccion, zona, i;
// se abre el la imagen de elevaciones
if( (fopen_s( &a_elev, archivo, "rb" )) !=0 )
{
AfxMessageBox("Error al abrir la imagen de elevaciones\n\ncheque que el archivo exista",
MB_OK|MB_ICONSTOP);
exit(0);
}
//se lee el encabezado de la imagen de elevaciones
if ((fread(encabezado, sizeof(char), 512, a_elev)) != 512)
{
AfxMessageBox("Error al leer el encabezado de la imagen de elevaciones",
MB_OK|MB_ICONSTOP);
exit(0);
}
// se le agrega el fin de cadena al encabezado
encabezado[512] = '\0';
// se lee la información del encabezado
sscanf_s(encabezado, "%d %d %d %d %d %d %d %d %d", &t_fichero, &t_proyeccion, &zona,
&num_lineas, &num_pixels, &coord_SD_X, &coord_SD_Y, &res_X, &res_Y);
// para calculos de distancias o longitudes de tramos se calcula la distancia diagonal entre dos pixels
distancia_diagonal = (float) sqrt((double)((res_X*res_X)+(res_Y*res_Y)));
//se obtienen de manera dinámica memoria para almacenar la imagen de elevaciones
// se supone que una variable int es de 4 bytes 32 bits y es signed
ima_alturas= (int**) malloc(sizeof(int *) * num_lineas);
for(i = 0; i < num_lineas; i++)
ima_alturas[i] = (int *) malloc(sizeof(int) * num_pixels);
// se lee la imagen de elevaciones
for( i = 0; i < num_lineas; i++)
{
if((fread(ima_alturas[i], sizeof(int), num_pixels, a_elev)) != num_pixels)
{
sprintf_s(mensaje, "Error al leer la línea %d de la imagen de direcciones de flujo\0", i);
AfxMessageBox(mensaje, MB_OK|MB_ICONSTOP);
exit(0);
}
}
// se cierra el archivo de elevaciones
fclose(a_elev);
}
// rutina que lee la imagen de direcciones de flujo producida por Physitel, esta rutina
// considera que la imagen original perdió los bordes debido a la convolución con una ventana
// de 3x3, por lo que restaura la imagen original asignando un valor de -1 a los bordes
void lee_direcciones_de_flujo(LPCTSTR archivo)
{
FILE *a_dir;
char encabezado[513], mensaje[80];
int i;
// se abre el la imagen de direcciones de flujo
if( (fopen_s( &a_dir, archivo, "rb" )) !=0 )
{
AfxMessageBox("Error al abrir la imagen de direcciones de flujo\n\ncheque que el archivo exista",
MB_OK|MB_ICONSTOP);
exit(0);
}
//se lee la información de encabezado de la imagen de direcciones de flujo para desecharla
if ((fread(encabezado, sizeof(char), 512, a_dir)) != 512)
{
AfxMessageBox("Error al leer el encabezado de la imagen de direcciones de flujo",
MB_OK|MB_ICONSTOP);
exit(0);
}
// se le agrega el fin de cadena al encabezado
encabezado[512] = '\0';
//se obtienen de manera dinámica memoria para almacenar la imagen de direcciones de flujo
// se supone que una variable int es de 4 bytes 32 bits y es signed
ima_dflujo= (int**) malloc(sizeof(int *) * num_lineas);
for(i = 0; i < num_lineas; i++)
ima_dflujo[i] = (int *) malloc(sizeof(int) * num_pixels);
// se asigna un valor de -1 a los bordes que se pierden por la convolución de la ventana
// de 3x3, esto es a la primera y última línea y al primer y último pixel de cada linea
for(i = 0; i < num_pixels; i++)
{
ima_dflujo[0][i] = -1;
ima_dflujo[num_lineas-1][i] = -1;
}
for(i = 0; i < num_lineas; i++)
{
ima_dflujo[i][0] = -1;
ima_dflujo[i][num_pixels-1] = -1;
}
// se lee la imagen de direcciones de flujo
for( i = 1; i < (num_lineas-1); i++)
{
if((fread(&ima_dflujo[i][1], sizeof(int), (num_pixels-2), a_dir)) != (num_pixels-2))
{
sprintf_s(mensaje, "Error al leer la línea %d de la imagen de direcciones de flujo\0", i);
AfxMessageBox(mensaje, MB_OK|MB_ICONSTOP);
exit(0);
}
}
// se cierra el archivo de direcciones de flujo
fclose(a_dir);
}
// rutina que lee el archivo de nodos
// OJO: esta rutina considera una corrección de +1 metro en X y de -1 metro en Y dado que
// las coordenadas en los archivos de nodos de Physitel vienen con este error. si se deseara
// usar esta rutina en algún otro programa esta corrección debe ser suprimida.
// además la posición de las coordenadas se desplaza de la esquina superior izquierda del
//pixel al centro del mismo
void lee_archivo_de_nodos(LPCTSTR archivo)
{
FILE *a_nodos;
char comentario[513];
int t_fichero, i;
float ancho_rio;
// se abre el archivo de nodos
if( (fopen_s( &a_nodos, archivo, "rt" )) !=0 )
{
AfxMessageBox("Error al abrir el archivo de nodos\n\ncheque que el archivo exista",
MB_OK|MB_ICONSTOP);
exit(0);
}
//se lee el encabezado del archivo de nodos
if ((fscanf_s(a_nodos, "%d %d",&t_fichero, &num_nodos)) != 2)
{
AfxMessageBox("error al leer el tipo de fichero y el número de nodos en el archivo de nodos",
MB_OK|MB_ICONSTOP);
exit(0);
}
// se lee la linea de comentario y se desecha.
// Como el fscanf deja el line feed se hacen dos lecturas con el fgets
if((fgets(comentario, 513, a_nodos))== NULL)
{
AfxMessageBox("error al leer el line feed en el archivo de nodos", MB_OK|MB_ICONSTOP);
exit(0);
}
if((fgets(comentario, 513, a_nodos))== NULL)
{
AfxMessageBox("error al leer el comentario en el archivo de nodos", MB_OK|MB_ICONSTOP);
exit(0);
}
// se obtienen memoria dinámica para el arreglo de nodos
nodos = (struct punto *) malloc(sizeof(struct punto) * num_nodos);
// se leen los nodos del archivo
for(i=0; i < num_nodos; i++)
{
fscanf_s(a_nodos, "%d %d %d %d %f", &nodos[i].ident, &nodos[i].coord_X, &nodos[i].coord_Y,
&nodos[i].altura, &ancho_rio);
// se asigna el valor nulo a los apuntadores anterior y siguiente para establecer que
// es un solo punto
nodos[i].anterior = NULL;
nodos[i].siguiente = NULL;
// se corrigen los valores leidos de Physitel con un -1 en X y un -1 en Y
nodos[i].coord_X = nodos[i].coord_X - 1;
nodos[i].coord_Y = nodos[i].coord_Y - 1;
// estas coordenadas establecen la esquina superior derecha del pixel en lugar de su
// su punto central se suma res_X/2 a X y se resta res_Y/2 a Y para trasladar el punto
// al centro del pixel
nodos[i].coord_X = nodos[i].coord_X + (int)((float)res_X/2);
nodos[i].coord_Y = nodos[i].coord_Y - (int)((float)res_Y/2);
// se asigna temporalmente el valor cero al número de línea y pixel en lo que son calculados
nodos[i].linea = 0;
nodos[i].pixel = 0;
}
// se cierra el archivo de nodos
fclose(a_nodos);
} |
Partager