Generación automática del Modelo Digital del Terreno. Hind Taud Resumen Para generar el Modelo Digital del Terreno MDT de una manera automática, se investigó las metodologías reportadas en la literatura. Se eligió la técnica de creación a partir de curvas de nivel. Las curvas se encuentran en base de datos como los elaborados por INEGI. Se desarrollo el proyecto según lo establecido en programación de Actividades. Se desarrollo un algoritmo para la transformación de datos del formato DXF al formato raster o matricial. Se elaboro también un código para agrupamiento de datos cuado estos provienen de diferentes zonas. 1. Introducción La generación de la superficie es una herramienta que se usa en diversos campos de investigación. Esta generación o creación se logra mediante el proceso de interpolación espacial. La interpolación consiste en la estimación de los valores que alcanza una variable Z en un conjunto de puntos en un espacio bi-dimensional a partir de una base de datos como medidas puntuales. El objetivo principal en esta investigación es precisamente la creación del Modelo Digital del Terreno MDT o de elevación. Existen diferentes definiciones en la literatura sobre el MDT, la más sencilla, es considerar el modelo como una imagen digital del terreno donde en cada punto espacial de esta imagen corresponde su altura en el terreno. En cualquier análisis o estudios geo-espaciales, la importancia de usar estos modelos crece considerablemente y la información que proporciona enriquece la base de datos. 2. Estudio bibliográfico Como se ha elaborado en el proyecto, la primera etapa fue un estudio bibliográfico sobre la generación del modelo digital del terreno. Diferentes datos de diversas fuentes como las curvas de nivel, fotogrametría y datos del campo pueden ser datos de entrada para la creación del modelo. Las curvas de nivel en formato digital pueden ser obtenidas a partir de mapas mediante la digitalización manual, o a partir de técnicas automáticas de escaneo. La hipsometría es obtenida también mediante fotografía aérea o a partir de imágenes de satélite incluyendo fuente de radar [1, 2 y 3]. Diferentes estructuras han sido utilizadas. Las más frecuentes estructuras son las de malla rectangular o la estructura matricial de elevación y la malla triangular. A partir de métodos de interpolación se pueden generar superficies. Las más conocidas están descritas y explicadas por Watson [4]. La evaluación de la calidad del modelo generado es profundamente explicada en diferentes trabajos [5,6,7,8 y 9]. Un metodología de evaluación basada en la visualización se 1 propuso en el trabajo de Taud et al. [10]. La visualización, efectivamente proporciona un mecanismo poderoso para la identificación de distribuciones espaciales e la incertidumbre en los modelos. En el trabajo de watson, los métodos de interpolación se pueden clasificar como métodos de ajuste de función (lagrange, colocación, minimum curvature splines, kriging, relajación), métodos basados en distancia (inverse-distance weight gradients), métodos de triangulación, métodos rectangulares (bilinear patches, Hermite patches, Bezier patches, B-spline patches, etc.) y métodos de vecinos. Generalmente, se pueden clasificar en dos clases. La primera predetermina parámetros de una función analítica que se evalúa en una posición dada para obtener la elevación de superficie representativa. La secunda clase se hace una adición de influencia de datos en cada punto. A pesar de la existencia de múltiples técnicas de interpolación, la mas usada al nivel mundial para generar un MDT es la que se basa en las curvas de nivel dado que permiten obtener un modelo con un costo bajo que sea computacional o económico. Por estas razones se eligió la utilización de este acercamiento. Muy pocos trabajos se han desarrollado en los últimos años [10, 11, 12, 13, 14 y 15]. Algunas generan contornos de manera iterativa, aplicando o no técnicas de la morfología matemática (dilatación, erosión, esqueletización), otros, aplican información en diferentes direcciones alrededor de un punto. Evidentemente, otros tratan de mejorar técnicas ya existentes. Se propone en esta investigación, mejorar la metodología desarrollada por los autores [10] mediante cambios en algunas partes de la metodología e integración de otros datos geomorfológicos. 3. Formato de datos Las curvas de nivel son datos geo-espaciales que se puede tener en diferentes formatos. Por ejemplo en formato de texto (*.txt) donde hay los datos de los puntos en X,Y,Z y su altura correspondiente. El formato usado por algún software de Sistemas de información geográfica es el formato DXF (Drawing Interchange file format). Los archivos DXF son archivos ASCII simples con extensión .DXF donde hay toda la información sobre los puntos que forman las curvas, zona de estudio, proyecciones, etc. De forma general los archivos DXF son una secuencia de valores ASCII escritos de manera secuencial. Se escriben por parejas de datos correspondientes a un identificador y en la línea siguiente un valor correspondiente al identificador que lo precede. Esta secuencia de datos esta dividida en secciones. El conocimiento de la estructura de estos archivos hace posible la creación de un programa para leer o escribir este tipo de archivos y poder aprovechar al máximo la posibilidad de generar proceso automático que ahorran tiempo y dinero. El acceso a estos datos podría ser gratuito como en algunos sitios de Internet o por compra de base de datos de las instituciones especializadas. El INEGI, Instituto Nacional de Estadística Geografía e Informática esta poniendo a los múltiples y diversos usuarios, una base de datos, digital y vectorial las curvas de nivel en formatos DXF de AutoCad en diferentes 2 escalas de todo México. La información en este formato se presta a edición y manipulación con mucha facilidad por lo que es relativamente sencillo adaptarla a necesidades particulares con el uso de software tipo GIS. La información producida por INEGI se proporciona en capas como altimetría (puntos correspondientes a curvas de nivel), datos de hidrografía (redes hidrológicas), etc. Una descripción del formato DXF se encuentra en el capitulo 18 del libro escrito por el autor Ransen [16]. Se eligió el uso de estos dos formatos (txt y DXF) para poder tener una gran apertura a diferentes usuarios, de diferentes campos, interesados en el uso de la metodología de generación del modelo digital del terreno que se esta desarrollando en este proyecto. 4. Proyección de vector a Raster (anexo A) La base de datos vectorial es obtenida a partir de una escala dada. Una aproximación es necesaria para pasar del espacio real al espacio discreto. Su proyección en el espacio discreto depende mucho de la resolución requerida. En baja resolución se yuxtaponen las curvas, lo que implica perdida de información, y también en la interpolación. En alta resolución, se genera una imagen grande lo que implica el crecimiento del tiempo de la interpolación. En este caso, la proyección en las zonas montañosas donde las curvas de nivel son muy cercanas proporciona un resultado satisfactorio mientras en zonas planas donde hay pocas curvas se generan muchos puntos para interpolar. Se elaboró el código desarrollado en el lenguaje C del algoritmo que permite tener la imagen de la curvas de nivel a partir del formato de INEGI DXF. Los datos utilizados corresponden a cartas topográficas con las siguientes características: una escala de 1:50 000, una proyección cartográfica de Universal Transversa de Mercator (U.T.M.) e intervalo de curvas de nivel de 20 metros. 5. Agrupación de datos (anexo B). Se elaboró otro código en lenguaje C para responder a otra problemática que puede encontrar un usuario. Cuando es necesario trabajar en una zona que se encuentra entre dos cartas topográficas, el código nos permite juntar según el formato DXF dos datos de altimetría separados para poder generar un mapa de curvas de nivel con el primer código. 6. Conclusión Se cumplió con el avance programado en la programación de Actividades de Investigación descrito en el protocolo de proyecto: Revisión del estado del arte- estudio bibliográfico (Juniojulio 2006), Codificación de los base de datos de INEGI (julio-septiembre 2006). Extracción de la imagen de contornos: cambio del espacio vectorial al espacio raster (septiembre- diciembre 2006). 3 7. Impacto Este proyecto, en su fin, permitiría tener un gran impacto en el sector productivo y también un gran beneficio social y/o educativo. La generación del modelo digital del terreno a partir de datos vectoriales de INEGI permitiría, a diversos sectores de diversos campos, de integrar el modelo digital en sus trabajos. 8. Bibliografía [1] Taud H., Parrot J.-F.,1995. - Quantitative Digital Elevation Model from SAR data, Proceedings EUROPTO series.''Synthetic aperture radar and passive microwave sensing'', Vol 2584, 226-233. [2] Kobler A. , Pfeifer N., Ogrinc P., Todorovski L. ,Oštir K., Džeroski, S., 2006, Repetitive interpolation: A robust algorithm for DTM generation from Aerial Laser Scanner Data in forested terrain, Remote Sensing of Environment, doi:10.1016/j.rse.2006.10.013. [3] Mora, O., Arbiol, R., Palà, V., Adell, A., Torre, M., 2006. Generation of accurate DEMs using DInSAR methodology (TopoDInSAR), IEEE Geoscience and Remote Sensing Letters 3 (4), 55154. [4] Watson, D.F., 1992. Contouring: a Guide to the Analysis and Display of Spatial Data. Pergamon, Oxford, p. 340. [5] Burrough, P.A., 1986. Principles of Geographical Information. Systems for Land Resources Assessment. University Press, Oxford, p. 193. [6] Aronoff, S. 1991. Geographical Information Systems: a Management Perspective. WDl Publications, Ottawa, p. 294. [7] Wood, J.D., Fisher, P.F., 1993. Assessing interpolation accuracy in elevation models. IEEE Computer Graphics & Applications, 48-56. [8] Li, Z., 1994. A comparative study of the accuracy of digital terrain models (DTMs) based on various data models, Journal of Photogrammetry and Remote Sensing, 49, 2-11. [9] Carrara, A., Bitelli, G., Carla, R., 1997. Comparison of techniques for generating digital terrain models from contour lines, International Journal of Geographical Information Sciences, 11 (5), 451-473. [10] Taud H., Parrot J.-F., Alvarez R.,1999. DEM generation by contour line dilation, Computers and Geosciences, 25 (7), pp. 775-783. [11] Wang, J.-J., Teng, S.-Q., 2002. The method of making DEM based on contour line, Computer Applications, 22 (8), pp. 34-35. [12] Ardiansyah, P.O.D., Yokoyama, R., 2002. DEM generation method from contour lines based on the steepest slope segment chain and a monotone interpolation function, ISPRS Journal of Photogrammetry and Remote Sensing, 57 (1-2), pp. 86-101. 4 [13] Gold, C., Dakowicz, M., 2003. Digital elevation models from contour lines: Improving Accuracy by incorporating skeleton points and slope information, GIM International, 17 (2), pp. 56-59. [14] Gousie, M.B., Franklin, Wm.R., 2003. Constructing a DEM from grid-based data by computing intermediate contours, GIS: Proceedings of the ACM International Symposium on Advances in Geographic Information Systems, pp. 71-77. [15] Liu, P.-J., Zhao, R.-L., Zhu, J.-Z., Zhu, Q.-K., Tang, X.-M. 2006. Method for generating DEM Geomorphologic feature, Journal of China University of Mining and Technology 35 (4), pp. 521525. [16] Ransen O., 1997. AutoCad programming in C and C++, Chichester; New York: Wiley, 492p. Anexo A /*======================================================*/ /* version 1 noviembre 2006 */ /*======================================================*/ #include <stdio.h> #include <string.h> #include <errno.h> #include <math.h> #include <time.h> #include <stdlib.h> #include <values.h> #include <limits.h> #include <io.h> #include <conio.h> #include "c:\prog\lib\nrutil.cpp" #include "c:\prog\lib\nrutil.h" #define ival -999.0 void opening(); void treatment(); void rotation(double angle,int sentido,double i_in,double j_in); void save(); void extraction(); void trace_droite(int ideb,int jdeb,int ifin,int jfin,double alti); unsigned char **tab,**tab2,**tab3; int nb_lig,nb_col; int nb_lig3,nb_col3; int val_minimo,val_maximo; double min_x,min_y,min_alt; double max_x,max_y,max_alt; double pix_size,id2,jd2,size_pix; double **dtab; FILE *f1,*f2,*f2d,*f3d; /***************************************************/ /* main */ 5 /***************************************************/ main() { opening(); printf("\n\n tamano del pixel ? "); scanf("%lf",&pix_size); size_pix=pix_size; treatment(); extraction(); save(); } /***************************************************/ /* trace droite */ /***************************************************/ void trace_droite(int ideb,int jdeb,int ifin,int jfin,double alti) { double a,b,rmax,icrrnt_d,jcrrnt_d,dinext,djnext; int icrrnt,jcrrnt,ilast,jlast; int ico=1; a=(double)(jfin-jdeb); b=(double)(ifin-ideb); icrrnt=ideb; jcrrnt=jdeb; icrrnt_d=(double)icrrnt; jcrrnt_d=(double)jcrrnt; ilast=icrrnt; jlast=jcrrnt; dtab[ideb][jdeb]=alti; rmax=max(fabs(a),fabs(b)); if(rmax == 0.) return; dinext=b/rmax; djnext=a/rmax; while (ilast!=ifin || jlast!=jfin) { icrrnt_d=icrrnt_d+dinext;jcrrnt_d=jcrrnt_d+djnext; icrrnt=(int)(icrrnt_d+.5); jcrrnt=(int)(jcrrnt_d+.5); dtab[icrrnt][jcrrnt]=alti; ilast=icrrnt; jlast=jcrrnt; } } /***************************************************/ /* treatment */ /***************************************************/ void treatment() { int i,j,k,val,jval,check; int segm=0,point,ico,rep; int reg; int intervalo,val_deb,num_segment; int flag,ideb,jdeb,ifin,jfin; int flag_sect,line; int jco,lco,n,valprov,difmin; 6 int tabval[260],tabord[260]; int sentido; double angulo; double f_ideb,f_jdeb,f_ideb2,f_jdeb2; double f_ifin,f_jfin,f_ifin2,f_jfin2; double min_dyn=10000.,max_dyn=0.; double miny=4000000.,maxy=0.,minx=4000000.,maxx=0.; double dif_x,dif_y,hypo; double dval1,dval2,dval3; double pix_size_def,dif_j; double S,C,T,CT,TA,TA2; double cote,d_col,angle; double pi=4*atan(1.),api=pi/180.; char texte[80]; char *SECTION="SECTION",*POLYLINE="POLYLINE",*VERTEX="VERTEX",*ENDSEC="ENDSEC"; // enter = 0 char *TABLE="TABLE"; char *AC1006="AC1006"; // enter = 1 char *HEADER="HEADER",*ENTITIES="ENTITIES",*TABLES="TABLES"; // enter = 2 char *INSBASE="$INSBASE",*EXTMIN="$EXTMIN",*EXTMAX="$EXTMAX",*ACADVER="$ACADVER"; // enter = 9 char *CECOLOR="$CECOLOR",*CELTYPE="$CELTYPE"; // enter = 9 for(i=0; i<260; i++) tabval[i]=0; printf("\n treatment\n"); printf("\n numero de registros anteriores en Vertex ? "); scanf("%d",&reg); flag_sect=0; while (!feof(f1)) { fscanf(f1,"%s",texte); check=strcoll(SECTION,texte); if(check == 0) { flag_sect++; } check=strcoll(ENDSEC,texte); if(check == 0) { } check=strcoll(HEADER,texte); if(check == 0) { } check=strcoll(TABLES,texte); if(check == 0) { } check=strcoll(EXTMIN,texte); if(check == 0) { fscanf(f1,"%d",&val); label2: 7 if(val == 10) { fscanf(f1,"%lf",&min_x); fscanf(f1,"%d",&val); goto label2; } if(val == 20) { fscanf(f1,"%lf",&min_y); fscanf(f1,"%d",&val); goto label2; } if(val == 30) { fscanf(f1,"%lf",&min_alt); fscanf(f1,"%d",&val); goto label2; } } check=strcoll(EXTMAX,texte); if(check == 0) { fscanf(f1,"%d",&val); label3: if(val == 10) { fscanf(f1,"%lf",&max_x); fscanf(f1,"%d",&val); goto label3; } if(val == 20) { fscanf(f1,"%lf",&max_y); fscanf(f1,"%d",&val); dif_x=max_x-min_x; nb_col=(int)((dif_x/pix_size)+0.5); dif_y=max_y-min_y; nb_lig=(int)((dif_y/pix_size)+0.5); ///////////////////////////////////// printf("\n\n Primera aproximacion : "); printf("\n\n lineas = %d columnas = %d \n\n",nb_lig,nb_col); goto label3; } if(val == 30) { fscanf(f1,"%lf",&max_alt); fscanf(f1,"%d",&val); goto label3; } } check=strcoll(POLYLINE,texte); if(check == 0) { segm++; printf("\tsegment %d \r ",segm); flag=0; } check=strcoll(VERTEX,texte); 8 if(check == 0) { for(j=1; j<=reg; j++) { fscanf(f1,"%s",texte); } fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval1); // columnas = x fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval2); // lineas = y fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval3); // altitudes fscanf(f1,"%d",&val); if(min_dyn > dval3) min_dyn=dval3; if(max_dyn < dval3) max_dyn=dval3; if(dval2 == max_y) { if(minx > dval1) minx=dval1; } if(dval1 == max_x) { if(maxy < dval2) maxy=dval2; } } } ///////////////////////////////////////////// printf("\n\n angulo de rotacion (decimal) ? "); scanf("%lf",&angle); do { printf("\n rotacion: sentido :\n\t0 ====> izquierdo\n\t1 ====> derecho\n\t"); scanf("%d",&sentido); } while(sentido != 0 && sentido != 1); T=angle*api; S=sin(T); C=cos(T); cote=(double)nb_col*S; d_col=(double)nb_col-cote; hypo=sqrt((cote*cote)+(d_col*d_col)); pix_size_def=(pix_size*hypo)/(double)nb_col; label36: printf("\n Numero total de segmentos = %d ",segm); printf("\n\n Dyn. Min = %lf Max = %lf ",min_dyn,max_dyn); printf("\n\n Min Y = %lf Max Y = %lf ",min_y,max_y); printf("\n Min X = %lf Max X = %lf ",min_x,max_x); rewind(f1); flag_sect=0; segm=0; pix_size=pix_size_def; while (!feof(f1)) { fscanf(f1,"%s",texte); check=strcoll(SECTION,texte); if(check == 0) { 9 flag_sect++; } check=strcoll(ENDSEC,texte); if(check == 0) { } check=strcoll(HEADER,texte); if(check == 0) { } check=strcoll(TABLES,texte); if(check == 0) { } check=strcoll(EXTMIN,texte); if(check == 0) { fscanf(f1,"%d",&val); label21: if(val == 10) { fscanf(f1,"%lf",&min_x); fscanf(f1,"%d",&val); goto label21; } if(val == 20) { fscanf(f1,"%lf",&min_y); fscanf(f1,"%d",&val); goto label21; } if(val == 30) { fscanf(f1,"%lf",&min_alt); fscanf(f1,"%d",&val); goto label21; } } check=strcoll(EXTMAX,texte); if(check == 0) { fscanf(f1,"%d",&val); label31: if(val == 10) { fscanf(f1,"%lf",&max_x); fscanf(f1,"%d",&val); goto label31; } if(val == 20) { fscanf(f1,"%lf",&max_y); fscanf(f1,"%d",&val); dif_x=max_x-min_x; nb_col=(int)((dif_x/pix_size)+0.5); dif_y=max_y-min_y; nb_lig=(int)((dif_y/pix_size)+0.5); printf("\n\n Segunda aproximacion : "); printf("\n\n pix_size %lf lineas = %d columnas = %d \n\n",pix_size,nb_lig,nb_col); 10 // /* // /* /* getch(); fprintf(f2d,"%d\n%d\n%d\n%d\n",nb_lig,nb_col,1,(int)min_alt); */ dtab=dmatrice(nb_col+2,nb_lig+2); tab=ucmatrice(nb_col,nb_lig); tab2=ucmatrice(nb_col,nb_lig); for(i=0; i<nb_lig+1; i++) for(j=0; j<nb_col+1; j++) dtab[i][j]=ival; for(i=0; i<nb_lig; i++) for(j=0; j<nb_col; j++) tab[i][j]=(unsigned char)255; goto label31; } if(val == 30) { fscanf(f1,"%lf",&max_alt); fscanf(f1,"%d",&val); fprintf(f2d,"%d\n%lf\n",(int)max_alt,pix_size); goto label31; } } check=strcoll(POLYLINE,texte); if(check == 0) { segm++; printf("\tsegment %d \r ",segm); flag=0; ico=0; } check=strcoll(VERTEX,texte); if(check == 0) { ico++; for(j=1; j<=reg; j++) { fscanf(f1,"%s",texte); } fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval1); // columnas = x fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval2); // lineas = y fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval3); // altitudes fscanf(f1,"%d",&val); if(segm > 400) { printf("\n vertex %d dval1 %lf dval2 %lf dval3 %lf ",ico,dval1,dval2,dval3); } */ if(min_dyn > dval3) min_dyn=dval3; if(max_dyn < dval3) max_dyn=dval3; if(dval2 == max_y) { if(minx > dval1) minx=dval1; } if(dval1 == max_x) { if(maxy < dval2) maxy=dval2; } if(miny > dval2) miny=dval2; 11 // // // if(maxy < dval2) maxy=dval2; if(minx > dval1) minx=dval1; if(maxx < dval1) maxx=dval1; */ if(flag == 0) { f_ideb=(dval2-min_y)/pix_size; f_ideb=(double)nb_lig-f_ideb; f_jdeb=(dval1-min_x)/pix_size; printf("\n rotation angle %lf sentido %d ideb %lf jdeb %lf ",angle,sentido,f_ideb,f_jdeb); rotation(angle,sentido,f_ideb,f_jdeb); printf("\n sortie rota f_ideb %lf f_jdeb %lf id2 %lf jd2 %lf ",f_ideb,f_jdeb,id2,jd2); getch(); ideb=(int)(id2+.5); jdeb=(int)(jd2+.5); flag++; point=1; } else { f_ifin=(dval2-min_y)/pix_size; f_ifin=(double)nb_lig-f_ifin; f_jfin=(dval1-min_x)/pix_size; rotation(angle,sentido,f_ifin,f_jfin); printf("\n f_ifin %lf f_jfin %lf id2 %lf jd2 %lf ",f_ifin,f_jfin,id2,jd2); getch(); ifin=(int)(id2+.5); jfin=(int)(jd2+.5); trace_droite(ideb,jdeb,ifin,jfin,dval3); ideb=ifin; jdeb=jfin; } } } /////////////////////////////////////////////////////// // fprintf(f2d,"%d\n%d\n%d\n%d\n",nb_lig,nb_col,1,(int)min_alt); ico=jco=0; flag=0; for(i=0; i<nb_lig; i++) { for(j=0; j<nb_col; j++) { val=(int)dtab[i][j]; ico++; if(val != (int)ival) { if(flag == 0) { flag=1; jco++; tabval[jco]=val; } else { lco=0; for(n=1; n<=jco; n++) { if(val == tabval[n]) 12 { lco++; } } if(lco == 0) { jco++; tabval[jco]=val; } } } } } valprov=(int)min_dyn; tabord[1]=(int)min_dyn; intervalo=tabval[10]-tabval[9]; intervalo=abs(intervalo); printf("\n\n Intervalo altimetrico = %d ",intervalo); do { printf("\n\n 0 ====> tomar en cuenta este intervalo\n 1 ====> elegir otro\n "); scanf("%d",&rep); } while(rep != 0 && rep != 1); if(rep == 1) { printf("\n valor del intervalo ? "); scanf("%d",&intervalo); } // printf("\n\n Definicion de los valores de la tabla de correspondencia :"); printf("\n\n\tValor minimo ? "); scanf("%d",&val_minimo); printf("\n\tValor maximo ? "); scanf("%d",&val_maximo); num_segment=((val_maximo-val_minimo)/intervalo); if(num_segment > 253) { printf("\n\n El numero total de intervalos (%d) es demasiado grande ",num_segment+1); getch(); exit(0); } val_deb=val_minimo-intervalo; for(i=1; i<=num_segment+1; i++) { val_deb=val_deb+intervalo; tabord[i]=val_deb; } for(k=1; k<=num_segment+1; k++) { fprintf(f3d," %d %d \n",k,tabord[k]); } fprintf(f2d,"%d\n%d\n%d\n%d\n%lf\n\n",nb_lig,nb_col,1,val_minimo,val_maximo,pix_size); printf("\n\n Guardando \n\n"); for(i=0; i<nb_lig; i++) { if (((i+1)%200)==0) printf("\tlinea %d \r ",i+1); for(j=0; j<nb_col; j++) 13 { // for(k=1; k<jco; k++) for(k=1; k<num_segment+1; k++) { if((int)dtab[i][j] == tabord[k]) tab[i][j]=(unsigned char)k; } } } for(i=1; i<nb_lig-1; i++) { for(j=1; j<nb_col-1; j++) { if((int)tab[i][j] != 255) { val=(int)tab[i][j]; jval=0; if((int)tab[i-1][j-1] == val) jval=1; if((int)tab[i-1][j] == val) jval=jval+2; if((int)tab[i-1][j+1] == val) jval=jval+4; if((int)tab[i][j+1] == val) jval=jval+8; if((int)tab[i+1][j+1] == val) jval=jval+16; if((int)tab[i+1][j] == val) jval=jval+32; if((int)tab[i+1][j-1] == val) jval=jval+64; if((int)tab[i][j-1] == val) jval=jval+128; if(jval == 130 || jval == 10 || jval == 40 || jval == 160) { tab[i][j]=(unsigned char)255; } } } } } /***************************************************/ /* extraction */ /***************************************************/ void extraction() { int i,j; int i3,j3; int min_i=10000,max_i=0; int min_j=10000,max_j=0; for(i=0; i<nb_lig; i++) { for(j=0; j<nb_col; j++) { if((int)tab[i][j] != 255) { if(min_i > i) min_i=i; if(max_i < i) max_i=i; if(min_j > j) min_j=j; if(max_j < j) max_j=j; } } } /* printf("\n min_i %d max_i %d ",min_i,max_i); 14 printf("\n min_j %d max_j %d ",min_j,max_j); getch(); */ nb_lig3=(max_i-min_i)+1; nb_col3=(max_j-min_j)+1; tab3=ucmatrice(nb_col3,nb_lig3); i3=0; for(i=min_i; i<=max_i; i++) { j3=0; for(j=min_j; j<=max_j; j++) { tab3[i3][j3]=tab[i][j]; j3++; } i3++; } fprintf(f2d,"%d\n%d\n%d\n%d\n%d\n%lf\n\n",nb_lig3,nb_col3,1,val_minimo,val_maximo,size_pix); fprintf(f2d,"\n\n\n Coordenadas UTM :"); fprintf(f2d,"\n\tX min : %lf Y min : %lf ",min_x,min_y); fprintf(f2d,"\n\tX max : %lf Y max : %lf ",max_x,max_y); fprintf(f2d,"\n\n\t\t\t\tCopyright J.F. Parrot"); fclose(f2d); } /***************************************************/ /* rotation */ /***************************************************/ void rotation(double angle,int sens,double i_in,double j_in) { int i,j,val; int i2,j2; int sentido; double desv,ic,jc; double dif_i,dif_j; double hypo,base,altura; double id,jd,T; double S,C; double pi=4*atan(1.),api=pi/180.; desv=angle; sentido=sens; /* // printf("\n\n angulo de convergencia de cuadricula : %lf ",desv); if(sentido == 0) printf("\n sentido de la desviacion : izquierda"); else printf("\n sentido de la desviacion : derecha\n"); */ ic=(double)nb_lig/2.; jc=(double)nb_col/2.; printf("\n ic %lf jc %lf ",ic,jc); id=i_in; jd=j_in; dif_i=ic-id; dif_j=jd-jc; hypo=sqrt((dif_i*dif_i)+(dif_j*dif_j)); S=(double)dif_i/hypo; C=(double)dif_j/hypo; 15 T=atan2(S,C); T=T/api; if(T < 0.) T=T+360; // printf("\n angle entree = %lf desv %lf ",T,desv); if(sentido == 0) { T=T+desv; if(T > 360.) T=T-360.; } else { T=T-desv; if(T < 0.) T=T+360.; } // printf("\n angle sortie = %lf desv %lf ",T,desv); T=T*api; S=sin(T); C=cos(T); dif_i=S*hypo; dif_j=C*hypo; id2=ic-dif_i; jd2=jc+dif_j; // printf("\n id %lf jd %lf id2 %lf jd2 %lf \n\n",id,jd,id2,jd2); // getch(); } /***************************************************/ /* save */ /***************************************************/ void save() { int i; for(i=0; i<nb_lig3; i++) fwrite(tab3[i],nb_col3,sizeof(unsigned char),f2); fclose(f2); } /***************************************************/ /* opening */ /***************************************************/ void opening() { char nomim1[128],nomim2[128],nomdir[128],nomfic1[128]; char nomdescr2[128],nomdescr3[128]; printf("\n\t***********************************************************"); printf("\n\t* *"); printf("\n\t* DXF_V2 *"); printf("\n\t* Proyección de vector a Raster *"); printf("\n\t* *"); printf("\n\t* *"); printf("\n\t* HIND TAUD *"); printf("\n\t* (noviembre de 2006) *"); printf("\n\t***********************************************************"); 16 strcpy(nomim1,"c:\\images\\"); printf("\n\n Nombre del archivo : "); scanf("%s",nomdir); strcat(nomim1,nomdir); strcat(nomim1,"\\"); strcpy(nomim2,nomim1); printf("\n\n Nombre de la Fila .dxf (sin extension .dxf) ? "); scanf("%s",nomfic1); strcat(nomim1,nomfic1); strcat(nomim1,".dxf"); if ((f1=fopen(nomim1,"r")) == NULL) { printf("\n No hay Fila %s \n",nomim1); getch(); exit(0); } printf("\n\n Nombre de la imagen resultante (sin extension _trdxf.raw) ? "); scanf("%s",nomfic1); strcat(nomim2,nomfic1); strcpy(nomdescr2,nomim2); strcpy(nomdescr3,nomim2); strcat(nomim2,"_trdxf.raw"); strcat(nomdescr2,"_trdxf.txt"); strcat(nomdescr3,"_trdxf_tab.txt"); f2=fopen(nomim2,"wb"); f2d=fopen(nomdescr2,"w"); f3d=fopen(nomdescr3,"w"); } Anexo B /*======================================================*/ /* programa agrupacion version 1 noviembre 2006 */ /*======================================================*/ #include <stdio.h> #include <string.h> #include <errno.h> #include <math.h> #include <time.h> #include <stdlib.h> #include <values.h> #include <limits.h> #include <io.h> #include <conio.h> #include "c:\prog\lib\nrutil.cpp" #include "c:\prog\lib\nrutil.h" 17 #define ival -999.0 void opening(); void treatment(); struct imagen { unsigned char nombre[128]; unsigned char tipodato[64]; int min_etiq[100]; double media_etiq[100]; double mediana_etiq[100]; int max_etiq[100]; double desv[100]; }capas[100]; char nomgen[128]; unsigned char **tab,**tab2,**tab3; int nb_lig,nb_col; int nb_lig3,nb_col3; int val_minimo,val_maximo; int num_arch; double min_x,min_y,min_alt; double max_x,max_y,max_alt; double pix_size,id2,jd2,size_pix; double **dtab; FILE *f1,*f2,*f2d,*f3d; /***************************************************/ /* main */ /***************************************************/ main() { opening(); treatment(); } /***************************************************/ /* treatment */ /***************************************************/ void treatment() { int i,j,k,val,jval,check; int segm=0,point,ico,rep; int intervalo,val_deb,num_segment; 18 int flag,ideb,jdeb,ifin,jfin; int flag_sect,line; int jco,lco,n,valprov,difmin; int tabval[260],tabord[260]; int sentido; char nomim3[128],Buff[128]; double angulo; double f_ideb,f_jdeb,f_ideb2,f_jdeb2; double f_ifin,f_jfin,f_ifin2,f_jfin2; double min_dyn=10000.,max_dyn=0.; double miny=4000000.,maxy=0.,minx=4000000.,maxx=0.; double minalt=100000.,maxalt=0.; double dif_x,dif_y,hypo; double dval,dval1,dval2,dval3; double pix_size_def,dif_j; double S,C,T,CT,TA,TA2; double cote,d_col,angle; double pi=4*atan(1.),api=pi/180.; char texte[80]; char *SECTION="SECTION",*POLYLINE="POLYLINE",*VERTEX="VERTEX",*ENDSEC="ENDSEC"; // enter = 0 char *TABLE="TABLE",*SEQEND="SEQEND",*TEXTSTYLE="$TEXTSTYLE"; char *AC1006="AC1006"; // char *HEADER="HEADER",*ENTITIES="ENTITIES",*TABLES="TABLES"; // enter = 1 enter = 2 char *INSBASE="$INSBASE",*EXTMIN="$EXTMIN",*EXTMAX="$EXTMAX",*ACADVER="$ACADVER"; // enter =9 char *CECOLOR="$CECOLOR",*CELTYPE="$CELTYPE"; // // enter = 9 char *EOF="EOF"; for(i=0; i<260; i++) tabval[i]=0; printf("\n treatment\n"); for(i=1; i<=num_arch; i++) { strcpy(nomim3,capas[i].nombre); printf("\n\n Archivo %d Nombre : %s \n\n",i,nomim3); f1=fopen(nomim3,"r"); // printf("\n open OK "); flag_sect=0; segm=0; while (!feof(f1)) 19 { fscanf(f1,"%s",texte); check=strcoll(SECTION,texte); if(check == 0) { flag_sect++; } check=strcoll(ENDSEC,texte); if(check == 0) { } check=strcoll(HEADER,texte); if(check == 0) { } check=strcoll(TABLES,texte); if(check == 0) { } check=strcoll(EXTMIN,texte); if(check == 0) { fscanf(f1,"%d",&val); label2: if(val == 10) { fscanf(f1,"%lf",&min_x); fscanf(f1,"%d",&val); // printf("\n min_x %lf ",min_x); if(minx > min_x) minx=min_x; goto label2; } if(val == 20) { fscanf(f1,"%lf",&min_y); fscanf(f1,"%d",&val); // printf("\n min_y %lf ",min_y); if(miny > min_y) miny=min_y; goto label2; } if(val == 30) { fscanf(f1,"%lf",&min_alt); fscanf(f1,"%d",&val); 20 // printf("\n min_alt %lf ",min_alt); if(minalt > min_alt) minalt=min_alt; goto label2; } } check=strcoll(EXTMAX,texte); if(check == 0) { fscanf(f1,"%d",&val); label3: if(val == 10) { fscanf(f1,"%lf",&max_x); fscanf(f1,"%d",&val); // printf("\n max_x %lf ",max_x); if(maxx < max_x) maxx=max_x; goto label3; } if(val == 20) { fscanf(f1,"%lf",&max_y); fscanf(f1,"%d",&val); // printf("\n max_y %lf ",max_y); if(maxy < max_y) maxy=max_y; goto label3; } if(val == 30) { fscanf(f1,"%lf",&max_alt); fscanf(f1,"%d",&val); // printf("\n max_alt %lf ",max_alt); if(maxalt < max_alt) maxalt=max_alt; goto label3; } } check=strcoll(POLYLINE,texte); if(check == 0) { segm++; printf("\tsegment %d \r ",segm); flag=0; } check=strcoll(VERTEX,texte); if(check == 0) 21 { for(j=1; j<=4; j++) { fscanf(f1,"%s",texte); } fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval1); // columnas = x fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval2); // lineas = y fscanf(f1,"%d",&val); fscanf(f1,"%lf",&dval3); // altitudes fscanf(f1,"%d",&val); if(min_dyn > dval3) min_dyn=dval3; if(max_dyn < dval3) max_dyn=dval3; } label4: } fclose(f1); } printf("\n\n min x = %lf min y = %lf ",minx,miny); printf("\n max x = %lf max y = %lf ",maxx,maxy); printf("\n min a = %lf max a = %lf \n\n",minalt,maxalt); // rewind(f1); fprintf(f2," 0\n"); fprintf(f2,"SECTION\n"); fprintf(f2," 2\n"); fprintf(f2,"HEADER\n"); fprintf(f2," 9\n"); fprintf(f2,"$EXTMIN\n"); fprintf(f2," 10\n"); fprintf(f2,"%d\n %d\n",(int)minx,20); fprintf(f2,"%d\n %d\n",(int)miny,30); fprintf(f2,"%d\n %d\n",(int)minalt,9); fprintf(f2,"$EXTMAX\n"); fprintf(f2," 10\n"); fprintf(f2,"%d\n %d\n",(int)maxx,20); fprintf(f2,"%d\n %d\n",(int)maxy,30); fprintf(f2,"%d\n %d\n",(int)maxalt,0); // copier hasta polyline fprintf(f2,"ENDSEC\n %d\n",0); // fprintf(f2,"SECTION\n %d\n",2); // fprintf(f2,"ENTITIES\n %d\n",0); // for(i=1; i<=num_arch; i++) { 22 strcpy(nomim3,capas[i].nombre); printf("\n\n Archivo %d Nombre : %s ",i,nomim3); f1=fopen(nomim3,"r"); // printf("\n open OK "); flag=0; segm=0; printf("\n\n"); while (!feof(f1)) { fscanf(f1,"%s",texte); check=strcoll(POLYLINE,texte); if(check == 0) { flag=1; segm++; printf("\t segmento %d \r ",segm); fprintf(f2,"POLYLINE\n"); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%s",texte); fprintf(f2,"%s\n",texte); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%s",texte); fprintf(f2,"%s\n",texte); fscanf(f1,"%d",&val); fprintf(f2,"% d\n",val); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%d",&val); fprintf(f2,"%d\n",val); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); } check=strcoll(VERTEX,texte); if(check == 0) { 23 fprintf(f2,"VERTEX\n"); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%s",texte); // CN_3301 fprintf(f2,"%s\n",texte); fscanf(f1,"%d",&val); // 62 // 9 fprintf(f2," %d\n",val); fscanf(f1,"%d",&val); fprintf(f2," %d\n",val); fscanf(f1,"%d",&val); // 10 fprintf(f2," %d\n",val); fscanf(f1,"%lf",&dval); // 338959 fprintf(f2,"%d\n",(int)(dval+0.5)); fscanf(f1,"%d",&val); // 20 fprintf(f2," %d\n",val); fscanf(f1,"%lf",&dval); // 2793430 fprintf(f2,"%d\n",(int)(dval+0.5)); fscanf(f1,"%d",&val); // 30 fprintf(f2," %d\n",val); fscanf(f1,"%lf",&dval); // 2090 fprintf(f2,"%d\n",(int)(dval+0.5)); fscanf(f1,"%d",&val); // 0 fprintf(f2," %d\n",val); } check=strcoll(SEQEND,texte); if(check == 0) { fprintf(f2,"SEQEND\n"); fprintf(f2,"%d\n",0); } check=strcoll(ENDSEC,texte); if(check == 0) { if(flag == 1) { fprintf(f2,"ENDSEC\n"); fprintf(f2,"%d\n",0); } } } fclose(f1); } fprintf(f2,"EOF\n"); fclose(f2); 24 } /***************************************************/ /* opening */ /*************************************************/ void opening() { char nomim1[128],nomim2[128],nomdir[128],nomfic1[128]; char nomdescr2[128],nomdescr3[128],nomfic[128]; int i; printf("\n\t***********************************************************"); printf("\n\t* *"); printf("\n\t* SUM_DXF *"); printf("\n\t* *"); printf("\n\t* Hind Taud printf("\n\t* (noviembre de 2006) printf("\n\t* *"); *"); *"); printf("\n\t***********************************************************"); strcpy(nomim1,"c:\\images\\"); printf("\n\n Nombre del archivo : "); scanf("%s",nomdir); strcat(nomim1,nomdir); strcat(nomim1,"\\"); strcpy(nomgen,nomim1); printf("\n\n Numero de archivos a pegar ? "); scanf("%d",&num_arch); for(i=1; i<=num_arch; i++) { printf("\n\n Name of the file .dxf numero %d (sin extension .dxf) ? ",i); scanf("%s",nomfic); strcpy(nomim2,nomgen); strcat(nomim2,nomfic); strcat(nomim2,".dxf"); strcpy(capas[i].nombre,nomim2); } printf("\n\n Nombre del archivo .dxf (sin extension .dxf) ? "); scanf("%s",nomfic1); strcat(nomim1,nomfic1); strcat(nomim1,".dxf"); f2=fopen(nomim1,"w"); } /*-----------------------------------------*/ 25