#include "grass/gis.h" #include "grass/Vect.h" #include "grass/display.h" #include "grass/raster.h" #include "grass/colors.h" #include #include #include "libreria.h" int main(int argc,char *argv[]){ struct GModule *module; //Definición del módulo struct Map_info map,map2; //Mapas struct Option *input, *output; //Opciones de usuario struct line_pnts *linea,*linea1,*linea2; //Secuencias de puntos; struct line_cats *cats,*refcats; dbDriver *driver; dbHandle handle; dbTable *tabla; dbColumn *columna; dbValue *valor; dbCursor cursor; dbString orden_sql,valores; char *db_nombre, *driver_nombre,*name,*name2,*mapset,err_msg[200],*ordenc; int i,j,lev,n_lines,n_nodes,n_rows,p,pp; int ltype=0; int col,ncols,more; int *mapacat,dbcat,*dborden; double *dblong; int *tocado,*norden,no_orden,*previo,*sigue2,maxo,u,k,h,eti,n1,n2,l11,l12,l21,l22,l13,l23,divo,*signo; int *n_lineas,prev[2]; double *recta,*sinuosidad,*longit,lonref; char *colorin; ordenc=(char *) malloc(200); colorin=(char *) malloc(11); G_gisinit (argv[0]); // Gestión de la linea de comandos module = G_define_module(); module->description ="Reordena una red de drenaje de Strhaler a Horton"; input = G_define_option(); input->key = "input"; input->type = TYPE_STRING; input->required = YES; input->description = "Nombre del mapa vectorial que vas a abrir"; input->gisprompt = "viejo,vectorial,mapa vectorial"; output = G_define_option(); output->key = "output"; output->type = TYPE_STRING; output->required = YES; output->description = "Nombre del mapa vectorial que vas a crear"; output->gisprompt = "nuevo,vectorial,mapa vectorial"; if (G_parser(argc,argv)) exit(1); linea=Vect_new_line_struct(); cats=Vect_new_cats_struct(); // Abre el mapa vectorial de entrada name = input->answer; mapset = G_find_file ("vector", name, ""); if (mapset == NULL) { sprintf (err_msg, "Could not find vector file [%s]", name); G_fatal_error (err_msg); } lev=Vect_open_old (&map, name, mapset); if (0 > lev) { sprintf (err_msg, "Could not open vector file [%s]\n", name); G_fatal_error (err_msg); } n_lines=Vect_get_num_lines(&map); n_nodes=Vect_get_num_nodes(&map); printf("Mapa %s abierto en nivel %d.\n",name,lev); printf("%d areas, %d lineas, %d nodos %d islas %d atts\n",Vect_get_num_areas(&map),n_lines,n_nodes,Vect_get_num_islands(&map)); //Lee categorías mapacat=(int *) G_calloc(n_lines+1,sizeof(int)); dborden=(int *) G_calloc(n_lines+2,sizeof(int)); dblong=(double *) G_calloc(n_lines+1,sizeof(double)); for (i=1;i<=n_lines;i++){ ltype=Vect_read_line(&map,linea,cats,i); if(ltype>=0){*(mapacat+i)=cats->cat[0];printf("%d %d\n",i,*(mapacat+i));} } // Reserva de memoria signo=G_calloc(n_lines+1,sizeof(int)); tocado=G_calloc(n_lines+1,sizeof(int)); norden=G_calloc(n_lines+1,sizeof(int)); previo=G_calloc(n_lines+1,sizeof(int)); sigue2=G_calloc(n_lines,sizeof(int)); longit=G_calloc(n_lines+1,sizeof(double)); sinuosidad=G_calloc(n_lines,sizeof(double)); n_lineas=G_calloc(n_nodes,sizeof(int)); printf("HOLA\n"); linea=Vect_new_line_struct(); linea1=Vect_new_line_struct(); linea2=Vect_new_line_struct(); printf("HOLA\n"); //TRABAJO CON LA BASE DE DATOS //Establecer parámetros de la conexión driver_nombre=db_get_default_driver_name(); db_nombre=db_get_default_database_name(); driver=db_start_driver_open_database(driver_nombre,db_nombre); //Abrimos driver=db_start_driver(driver_nombre); db_init_handle(&handle); db_set_handle(&handle,db_nombre,NULL); if(db_open_database(driver,&handle)!=DB_OK){exit(ERROR);} //Generar, comprobar y ejecutar la orden SQL de consulta db_init_string(&orden_sql); db_zero_string (&orden_sql); db_init_string(&valores); sprintf(ordenc,"select cat,orden,longitud from %s;",input->answer); db_append_string(&orden_sql,ordenc); ordenc=db_get_string(&orden_sql); printf("%s\n",ordenc); printf("conexión: %s %s\n",driver_nombre,db_nombre); if(db_open_select_cursor(driver,&orden_sql,&cursor,DB_SEQUENTIAL)!=DB_OK) return ERROR; //Procesar resultados tabla=db_get_cursor_table(&cursor); ncols=db_get_table_number_of_columns(tabla); while(1){ if(db_fetch(&cursor,DB_NEXT,&more)!=DB_OK) return ERROR; if(!more) break; columna=db_get_table_column(tabla,0); db_convert_column_value_to_string(columna,&valores); dbcat=atoi(db_get_string(&valores)); for (i=1;i<=n_lines;i++){ if(dbcat==mapacat[i]){ columna=db_get_table_column(tabla,1); db_convert_column_value_to_string(columna,&valores); *(dborden+i)=atoi(db_get_string(&valores)); columna=db_get_table_column(tabla,2); db_convert_column_value_to_string(columna,&valores); *(dblong+i)=atof(db_get_string(&valores)); printf("%d %d %d %f\n",i,*(mapacat+i),*(dborden+i),*(dblong+i)); if(*(dborden+i)>maxo) maxo=*(dborden+i); } } };n_rows=i;printf("%d filas max(o)=%d\n",n_rows,maxo); //Cerramos db_close_database(driver); db_shutdown_driver(driver); //COMIENZA LA TOPOLOGIA // Calcular la topología for (u=2;u<=maxo;u++){ for (i=1;i<=n_lines;i++){ if (dborden[i]==u){ previo[i]=0;prev[0]=0;prev[1]=0; eti=*(mapacat+i); h=0;lonref=0; n1=(map.plus.Line[i])->N1; n2=(map.plus.Line[i])->N2; printf("i=%d cat=%d o=%d n1=%d n2=%d\n",i,eti,dborden[i],n1,n2); for(k=0;k<(map.plus.Node[n1])->n_lines;k++){ l11=abs(*(((map.plus.Node[n1])->lines)+k)); if(dborden[l11]==u-1 && dblong[l11]>lonref){ prev[0]=l11;lonref=dblong[l11]; } if(dborden[l11]>u){lonref=0;prev[0]=0;break;} } for(k=0;k<(map.plus.Node[n2])->n_lines;k++){ l21=abs(*(((map.plus.Node[n2])->lines)+k)); if(dborden[l21]==u-1 && dblong[l21]>lonref){ prev[1]=l21;lonref=dblong[l21]; } if(norden[l21]>u){lonref=0;prev[1]=0;break;} } if (prev[0]==0 && prev[1]!=0)previo[i]=prev[1]; if (prev[1]==0 && prev[0]!=0)previo[i]=prev[0]; if (prev[1]!=0 && prev[0]!=0){ if(dblong[prev[0]]>dblong[prev[1]]) previo[i]=prev[0]; else previo[i]=prev[1]; } *(dblong+i)=*(dblong+i)+*(dblong+previo[i]); printf("long=%f o=%d pre=%d cat=%d\n\n",*(dblong+i),dborden[i],previo[i],mapacat[previo[i]]); } } } // Preparar el fichero de salida name2 = output->answer; printf("hola\n"); lev=Vect_open_new (&map2, name2,0); printf("hola\n"); if (0 > lev) {sprintf (err_msg, "No se abre [%s]\n", name2); G_fatal_error (err_msg);} printf("Mapa %s abierto en nivel %d.\n",name2,lev); //COMENZAR LA CREACION DE LA NUEVA BASE DE DATOS //Establecer parámetros de la conexión driver_nombre=db_get_default_driver_name(); db_nombre=db_get_default_database_name(); //Abrimos driver=db_start_driver(driver_nombre); db_init_handle(&handle); db_set_handle(&handle,db_nombre,NULL); if(db_open_database(driver,&handle)!=DB_OK){exit(ERROR);} //Generar y comprobar la orden SQL de creación de tabla db_init_string(&orden_sql); db_zero_string (&orden_sql); sprintf(ordenc,"create table %s ( cat integer, ",output->answer); db_append_string(&orden_sql,ordenc); db_append_string(&orden_sql,"orden integer, longitud double precision, GRASSRGB varchar(11) );"); ordenc=db_get_string(&orden_sql); printf("%s\n",ordenc); //Ejecutar (crear la tabla, hacer un índice y dar permisos) printf("conexión: %s %s\n",driver_nombre,db_nombre); printf("Ejecuta: %d\n",db_execute_immediate (driver, &orden_sql)); printf("Indice: %d\n",db_create_index2(driver, output->answer, "cat" )); printf("GRANT: %d\n",db_grant_on_table (driver, output->answer, DB_PRIV_SELECT , DB_GROUP|DB_PUBLIC )); for (u=maxo;u>=2;u--){ for (i=1;i<=n_lines;i++){ printf("test %d %d\n",i,dborden[i]); if (dborden[i]==u && tocado[i]==0){ p=i;pp=previo[p]; linea1=Vect_new_line_struct(); Vect_read_line(&map,linea1,cats,p); printf("o=%d l=%d cat=%d %d \n",u,i,mapacat[i],cats->cat[0]); while(pp!=0){ tocado[p]=1; printf("o=%d l=%d cat=%d l2=%d cat2=%d o2=%d\n",u,p,mapacat[p],pp,mapacat[pp],dborden[pp]); linea2=Vect_new_line_struct();Vect_read_line(&map,linea2,cats,pp); linea=Vect_new_line_struct();une_tramos(linea1,linea2,linea); copia_tramos(linea,linea1); Vect_destroy_line_struct(linea); p=pp;pp=previo[p];tocado[p]=1; } printf("hola1 %d %d %d\n",i,dborden[i],mapacat[i]); refcats=Vect_new_cats_struct(); Vect_cat_set(refcats,1,*(mapacat+i)); Vect_write_line(&map2,2,linea1,refcats); Vect_destroy_cats_struct(refcats); printf("hola2 %d %d %d\n",i,dborden[i],mapacat[i]); //Añadir la correspondiente linea a la base de datos if(dborden[i]==1) strcpy(colorin,"0:0:255"); if(dborden[i]==2) strcpy(colorin,"255:255:0"); if(dborden[i]==3) strcpy(colorin,"0:255:0"); if(dborden[i]==4) strcpy(colorin,"255:0:0"); if(dborden[i]==5) strcpy(colorin,"0:255:255"); if(dborden[i]==6) strcpy(colorin,"255:0:255"); if(dborden[i]>6) strcpy(colorin,"0:0:0"); printf("hola3 %d %d %d \n",i,mapacat[i],dborden[i]); sprintf(ordenc,"insert into %s values(%d,%d,%f,'%s');",name2,mapacat[i],dborden[i],dblong[i],colorin); printf("%s\n",ordenc); db_set_string(&orden_sql,ordenc); printf("Ejecuta: %d\n",db_execute_immediate(driver, &orden_sql)); Vect_destroy_line_struct(linea1); } } } for (i=1;i<=n_lines;i++){ if (tocado[i]==0){ linea=Vect_new_line_struct(); Vect_read_line(&map,linea,cats,i); refcats=Vect_new_cats_struct();printf("hola\n"); Vect_cat_set(refcats,1,*(mapacat+i));printf("hola\n"); Vect_write_line(&map2,2,linea,refcats); Vect_destroy_cats_struct(refcats); //Añadir la correspondiente linea a la base de datos if(dborden[i]==1) strcpy(colorin,"0:0:255"); if(dborden[i]==2) strcpy(colorin,"255:255:0"); if(dborden[i]==3) strcpy(colorin,"0:255:0"); if(dborden[i]==4) strcpy(colorin,"255:0:0"); if(dborden[i]==5) strcpy(colorin,"0:255:255"); if(dborden[i]==6) strcpy(colorin,"255:0:255"); if(dborden[i]>6) strcpy(colorin,"0:0:0"); sprintf(ordenc,"insert into %s values(%d,%d,%f,'%s');",name2,mapacat[i],dborden[i],dblong[i],colorin); printf("%s\n",ordenc); db_set_string(&orden_sql,ordenc); printf("Ejecuta: %d\n",db_execute_immediate(driver, &orden_sql)); Vect_destroy_line_struct(linea); } } //Enlace mapa-tabla. build y copia de cabeceras Vect_copy_head_data(&map,&map2); Vect_map_add_dblink(&map2,1,NULL,name2,"cat",db_nombre,driver_nombre); Vect_build(&map2, stdout); Vect_close(&map); Vect_close(&map2); }