/* init.c */ #undef TRACE #undef DEBUG #include #include #include #include #include #include #undef MAIN #include "ransurf.h" #include "local_proto.h" /* function prototypes */ static void IsLegal(char *Name); void Init(int argc, char **argv) { struct Option *Output; /* struct Option *TheoryS; */ struct Option *range_high_stuff; struct Option *SeedStuff; struct Cell_head Region; int row, col, i, j, NumWeight, NumDist, NumExp; char *Name, *Number, String[80]; double MinRes; FUNCTION(Init); Output = G_define_option() ; Output->key = "output"; Output->type = TYPE_STRING; Output->required = YES; Output->multiple = YES; Output->description = "Names of the resulting maps"; Output->gisprompt = "new,cell,raster" ; /* TheoryS = G_define_option() ; TheoryS->key = "theoretical_correlogram"; TheoryS->type = TYPE_STRING; TheoryS->required = NO; TheoryS->multiple = NO; TheoryS->description = "Name of the resulting theoretical correlogram map"; TheoryS->gisprompt = "new,cell,raster" ; */ Distance = G_define_option() ; Distance->key = "distance"; Distance->type = TYPE_DOUBLE; Distance->required = NO; Distance->multiple = NO; Distance->description= "Input value: max. distance of spatial correlation (value >= 0.0, default [0.0])"; Exponent = G_define_option() ; Exponent->key = "exponent"; Exponent->type = TYPE_DOUBLE; Exponent->multiple = NO; Exponent->required = NO; Exponent->description= "Input value: distance decay exponent (value > 0.0), default [1.0])"; Weight = G_define_option() ; Weight->key = "flat"; Weight->type = TYPE_DOUBLE; Weight->multiple = NO; Weight->required = NO; Weight->description= "Input value: distance filter remains flat before beginning exponent, default [0.0]"; SeedStuff = G_define_option() ; SeedStuff->key = "seed"; SeedStuff->type = TYPE_INTEGER; SeedStuff->required = NO; SeedStuff->description= "Input value: random seed (SEED_MIN >= value >= SEED_MAX), default [random]"; range_high_stuff = G_define_option() ; range_high_stuff->key = "high"; range_high_stuff->type = TYPE_INTEGER; range_high_stuff->required = NO; range_high_stuff->description= "Input value: maximum cell value of distribution, default [255]"; Uniform = G_define_flag() ; Uniform->key = 'u' ; Uniform->description = "Uniformly distributed cell values" ; Verbose = G_define_flag() ; Verbose->key = 'q' ; Verbose->description = "No (quiet) description during run" ; if (G_parser(argc, argv)) exit(EXIT_FAILURE); Rs = G_window_rows(); Cs = G_window_cols(); Surface = (double **) G_malloc( Rs * sizeof( double *)); for( row = 0; row < Rs; row++) Surface[ row] = (double *) G_malloc( Cs * sizeof( double)); G_get_set_window(&Region); EW = Region.ew_res; NS = Region.ns_res; if( EW < NS) MinRes = EW; else MinRes = NS; if (NULL == G_find_file( "cell", "MASK", G_mapset())) { MapCount = Rs * Cs; FDM = -1; } else { if ((FDM = G_open_cell_old( "MASK", G_mapset())) < 0) { G_fatal_error(" unable to open MASK"); } else { MapCount = 0; CellBuffer = G_allocate_cell_buf(); for (row = 0; row < Rs; row++) { G_get_map_row_nomask( FDM, CellBuffer, row); for( col = 0; col < Cs; col++) { if( CellBuffer[ col]) MapCount++; } } } } if( Uniform->answer) sprintf( Buf, "Uni. R. S."); else sprintf( Buf, "Dist. R. S."); if( ! range_high_stuff->answer) High = 255; else { High = atoi(range_high_stuff->answer); sprintf( String, " high=%d", High); strcat( Buf, String); } if (1 >= High) G_fatal_error("high [%d] must be greater than 1", High); CatInfo.NumCat = High; NumMaps = 0; OutNames = (char **) G_malloc( sizeof(char *)); for (i = 0; (Name = Output->answers[i]); i++) { IsLegal( Name); for( j = i - 1; j >= 0; j--) { if (strcmp(OutNames[j], Name) == 0) G_fatal_error("%s: Random map [%s] repeated, maps must be unique", G_program_name(), Name); } OutNames = (char **) G_realloc (OutNames, (i+1) * sizeof(char *)); OutNames[i] = (char *) G_malloc( sizeof(char) * (strlen(Name)+1)); strcpy( OutNames[i], Name); NumMaps++; } if (NumMaps == 0) G_fatal_error("%s: requires an output map", G_program_name()); Theory = 0; /* TheoryName = TheoryS->answer; if (G_legal_filename (TheoryName) != -1) { Theory++; } */ NumSeeds = 0; Seeds = (int *) G_malloc( NumMaps * sizeof( int)); if(! SeedStuff->answers){ for( i = 0; i < NumMaps; i++) { Seeds[ i] = SEED_MIN - 1; Seed = (int) getpid(); } } else { for( i = 0; (Number = SeedStuff->answers[i]) && i < NumMaps; i++) { sscanf( Number, "%d", &(Seeds[i])); if (Seeds[i] > SEED_MAX){ if(! Verbose->answer) printf( "Warning: seed [%d] larger than maximum [%d]\n", Seeds[i], SEED_MAX); Seeds[i] = Seeds[i] % SEED_MAX; if(! Verbose->answer) printf( " seed is set to %d\n", Seeds[i]); } else if (Seeds[i] < SEED_MIN){ if(! Verbose->answer) printf("Warning: seed [%d] smaller than minimum [%d]\n", Seeds[i], SEED_MIN); while( Seeds[i] < SEED_MIN) Seeds[i] += SEED_MAX - SEED_MIN; if(! Verbose->answer) printf( " seed is set to %d\n", Seeds[i]); } } } CellBuffer = G_allocate_cell_buf(); CatInfo.NumValue = (int *) G_malloc( CatInfo.NumCat * sizeof( int)); CatInfo.Average = (double *) G_malloc( CatInfo.NumCat * sizeof( double)); CatInfo.Min = (double *) G_malloc( CatInfo.NumCat * sizeof( double)); CatInfo.Max = (double *) G_malloc( CatInfo.NumCat * sizeof( double)); NumFilters = 1; AllFilters = (FILTER *) G_malloc( sizeof( FILTER)); /* if( ! Distance->answers) { NumDist = 1; AllFilters[ 0].MaxDist = MinRes / 2.0; } else { NumDist = 0; for (i = 0; Number = Distance->answers[i]; i++) { if(NumDist == NumFilters) { AllFilters = (FILTER *) G_realloc( AllFilters, ++NumFilters * sizeof( FILTER)); } sscanf( Number, "%lf", &(AllFilters[NumDist].MaxDist)); if (AllFilters[NumDist].MaxDist < 0.0) G_fatal_error("%s: distance value[%d]: [%lf] must be >= 0.0", G_program_name(), NumDist, AllFilters[NumDist].MaxDist); NumDist++; } } */ NumDist = 0; if( Distance->answer) { sscanf( Distance->answer, "%lf", &(AllFilters[NumDist].MaxDist)); if (AllFilters[NumDist].MaxDist < 0.0) G_fatal_error("%s: distance value[%d]: [%lf] must be >= 0.0", G_program_name(), NumDist, AllFilters[NumDist].MaxDist); NumDist++; } /* NumExp = 0; if( Exponent->answers) { for (i = 0; Number = Exponent->answers[i]; i++) { if(NumExp == NumFilters) AllFilters = (FILTER *) G_realloc( AllFilters, ++NumFilters * sizeof( FILTER)); sscanf( Number, "%lf", &(AllFilters[NumExp].Exp)); DOUBLE(AllFilters[NumExp].Exp); if (AllFilters[NumExp].Exp <= 0.0) G_fatal_error("%s: exponent value [%lf] must be > 0.0", G_program_name(), AllFilters[NumExp].Exp); AllFilters[ NumExp].Exp = 1.0 / AllFilters[ NumExp].Exp; NumExp++; } } INT(NumExp); */ NumExp = 0; if( Exponent->answer) { sscanf( Exponent->answer, "%lf", &(AllFilters[NumExp].Exp)); if (AllFilters[NumExp].Exp <= 0.0) G_fatal_error("%s: exponent value [%lf] must be > 0.0", G_program_name(), AllFilters[NumExp].Exp); NumExp++; } NumWeight = 0; /* if( Weight->answers) { for (i = 0; Number = Weight->answers[i]; i++) { if(NumWeight == NumFilters) AllFilters = (FILTER *) G_realloc( AllFilters, ++NumFilters * sizeof( FILTER)); sscanf( Numbers, "%lf", &(AllFilters[NumWeight].Mult)); if (AllFilters[NumWeight].Mult == 0.0) G_fatal_error("%s: weight value [%lf] must not be 0.0", G_program_name(), AllFilters[NumWeight].Mult); NumWeight++; } } */ if( Weight->answer) { sscanf( Weight->answer, "%lf", &(AllFilters[NumWeight].Mult)); if (AllFilters[NumWeight].Mult > AllFilters[NumWeight].MaxDist) G_fatal_error("%s: flat value [%lf] must be less than distance value [%lf]", G_program_name(), AllFilters[NumWeight].Mult, AllFilters[NumWeight].MaxDist); NumWeight++; } if( NumDist > 0) { sprintf( String, " dist="); strcat( Buf, String); for( i = 0; i < NumDist - 1; i++) { sprintf( String, "%.*lf,", Digits( AllFilters[i].MaxDist, 6), AllFilters[i].MaxDist); strcat( Buf, String); } sprintf( String, "%.*lf", Digits( AllFilters[i].MaxDist, 6), AllFilters[i].MaxDist); strcat( Buf, String); } if (NumDist > 1 && NumDist < NumFilters) G_fatal_error("%s: must have a distance value for each filter", G_program_name()); if( NumDist == 0) { AllFilters[0].MaxDist = MinRes / 4.0; } if( NumDist < NumFilters) { for( NumDist = 1; NumDist < NumFilters; NumDist++) AllFilters[NumDist].MaxDist = AllFilters[ 0].MaxDist; } for( NumDist = 0; NumDist < NumFilters; NumDist++) { if( AllFilters[NumDist].MaxDist < MinRes) AllFilters[NumDist].MaxDist = MinRes * 0.5; else AllFilters[NumDist].MaxDist *= 0.5 ; } if( NumExp > 0) { sprintf( String, " exp="); strcat( Buf, String); for( i = 0; i < NumExp - 1; i++) { sprintf( String, "%.*lf,", Digits( AllFilters[i].Exp, 6), AllFilters[i].Exp); strcat( Buf, String); } sprintf( String, "%.*lf", Digits( AllFilters[i].Exp, 6), AllFilters[i].Exp); strcat( Buf, String); } if (NumExp > 1 && NumExp < NumFilters) G_fatal_error("%s: must have a exponent value for each filter", G_program_name()); if( NumWeight > 0) { sprintf( String, " flat="); strcat( Buf, String); for( i = 0; i < NumWeight - 1; i++) { sprintf( String, "%.*lf,", Digits( AllFilters[i].Mult, 6), AllFilters[i].Mult); strcat( Buf, String); DOUBLE(AllFilters[i].Mult); } sprintf( String, "%.*lf", Digits( AllFilters[i].Mult, 6), AllFilters[i].Mult); strcat( Buf, String); } if (NumWeight > 1 && NumWeight < NumFilters) G_fatal_error("%s: must have a weight value for each filter", G_program_name()); if( NumExp == 1) { for( NumExp = 1; NumExp < NumFilters; NumExp++) AllFilters[NumExp].Exp = AllFilters[ 0].Exp; } if( NumExp == 0) { for( NumExp = 0; NumExp < NumFilters; NumExp++) AllFilters[NumExp].Exp = 1.0; } if( NumWeight == 0) { for( NumWeight = 0; NumWeight < NumFilters; NumWeight++) AllFilters[NumWeight].Mult = 0.0; } RETURN; AllMaxDist = 0.0; for( i = 0; i < NumFilters; i++) { if( AllMaxDist < AllFilters[i].MaxDist) AllMaxDist = AllFilters[i].MaxDist; AllFilters[ i].MaxSq = AllFilters[ i].MaxDist * AllFilters[ i].MaxDist; INT(i); DOUBLE(AllFilters[i].Mult); DOUBLE(AllFilters[i].MaxDist); RETURN; DOUBLE(AllFilters[i].MaxSq); DOUBLE(AllFilters[i].Exp); RETURN; } BigF.RowPlus = AllMaxDist / NS; BigF.ColPlus = AllMaxDist / EW; BigF.NumR = BigF.RowPlus * 2 + 1; BigF.NumC = BigF.ColPlus * 2 + 1; BigF.LowBF = (int *) G_malloc( BigF.NumR * sizeof( int)); BigF.HihBF = (int *) G_malloc( BigF.NumR * sizeof( int)); BigF.F = (double **) G_malloc( BigF.NumR * sizeof( double *)); for( i = 0; i < BigF.NumR; i++) BigF.F[ i] = (double *) G_malloc( BigF.NumC * sizeof( double)); AllMaxDist *= 2.0; } static void IsLegal(char *Name) { if (G_legal_filename (Name) == -1) G_fatal_error("%s: map name [%s] not legal for GRASS", G_program_name(), Name); }