int main(int argc, char **argv) { FILE *demfile,*outfile,*outfile2; char demfilename[255],outfilename[255],outfilename2[255]; int nRows; /* Number of rows */ int nCols; /* Number of columns */ float *temp; float **elev,**slope,**aspect,**hillshade; unsigned char **outputgrid; int i; int ny,nx; float lx,ly; double max_angle,angle; float saz,sal; double theta; float dx; float x,y,sx,sy,dz,dist; float mx,my; float start_elev; float max_elev,min_elev; float target_row,target_col; int stop_flag; float a,b,c,d,e,f,g,h,j; float dzdx,dzdy,rr; float safe_distance; int month,day,year,jday; float hour; int ihour; float dt; int count; float outstep; int stepsperday; int daylight; int sunlight; float standardmeridian,latitude,longitude; float noon_hour, declination, halfdaylength, solar_hour; float sunrise, sunset, timeadjustment, sunearthdistance; float sinesolaraltitude, solartimestep, sunmax, solarazimuth; float beam,diffuse; if(argc<13) { printf("usage is: make_dhsvm_shade_maps: \n"); printf("demfilename \n"); printf("outfilename \n"); printf("nrows, ncols \n"); printf("cellsize (in the same units as the dem elevation)\n"); printf("longitude and latitude of the site (dd)\n"); printf("longitude of location for met file time stamp\n"); printf("year month day output_time_step (hours)\n"); exit(-1); } /* note: this program will loop over all time, starting at 0 and advancing */ /* every hour */ /* output images ranging from 0 to 255 are made at every output_time_step */ /* these are in the proper format for DHSVM */ strcpy(demfilename, argv[1]); /* name of the binary flo at dem input file - no header */ strcpy(outfilename, argv[2]); /* name of the binary float hillshade output file */ nRows = GetNumber(argv[3]); nCols = GetNumber(argv[4]); dx = GetFloat(argv[5]); /* the cellsize of the dem */ longitude=GetFloat(argv[6])*RADPDEG; latitude=GetFloat(argv[7])*RADPDEG; standardmeridian=GetFloat(argv[8])*RADPDEG; year = GetNumber(argv[9]); month = GetNumber(argv[10]); day = GetNumber(argv[11]); outstep = GetFloat(argv[12]); printf("calculating shade map for %d / %d / %d \n",month,day,year); temp = calloc(nRows*nCols, sizeof(float)); if (temp == NULL) exit(-1); if (!(demfile = fopen(demfilename, "rb"))){ printf("dem file not found \n"); exit(-1); } if (!(outfile = fopen(outfilename, "wb"))){ printf("output file not opened \n"); exit(-1); } /* sprintf(outfilename2,"%s.float",outfilename); if (!(outfile2 = fopen(outfilename2, "wb"))){ printf("output file not opened \n"); exit(-1); } */ fread(temp, sizeof(float), nCols*nRows, demfile); if (!((elev) = (float**) calloc(nRows, sizeof(float*)))) exit(-1); for (ny = 0; ny < nRows; ny++) { if (!((elev)[ny] = (float*) calloc(nCols, sizeof(float)))) exit(-1); } if (!((slope) = (float**) calloc(nRows, sizeof(float*)))) exit(-1); for (ny = 0; ny < nRows; ny++) { if (!((slope)[ny] = (float*) calloc(nCols, sizeof(float)))) exit(-1); } if (!((aspect) = (float**) calloc(nRows, sizeof(float*)))) exit(-1); for (ny = 0; ny < nRows; ny++) { if (!((aspect)[ny] = (float*) calloc(nCols, sizeof(float)))) exit(-1); } if (!((hillshade) = (float**) calloc(nRows, sizeof(float*)))) exit(-1); for (ny = 0; ny < nRows; ny++) { if (!((hillshade)[ny] = (float*) calloc(nCols, sizeof(float)))) exit(-1); } if (!((outputgrid) = (unsigned char**) calloc(nRows, sizeof(unsigned char*)))) exit(-1); for (ny = 0; ny < nRows; ny++) { if (!((outputgrid)[ny] = (unsigned char*) calloc(nCols, sizeof(unsigned char)))) exit(-1); } max_elev = 0.0; for (ny = 0; ny < nRows; ny++) { for (nx = 0; nx < nCols; nx++) { elev[ny][nx] = temp[ny*nCols + nx]; if(elev[ny][nx]>max_elev) max_elev = elev[ny][nx]; } } CalcSlopeAspect(nRows,nCols,dx,elev,&slope,&aspect); dt=outstep; stepsperday=(int)(24/outstep); for(i=0;i<stepsperday;i++){ hour=(float)i*outstep; printf("working on hour %f \n",hour); jday=DayOfYear(year,month,day); SolarDay(jday, longitude, latitude, standardmeridian, &noon_hour, &declination, &halfdaylength, &sunrise, &sunset, &timeadjustment, &sunearthdistance); SolarHour(latitude, hour+dt, dt, noon_hour, &solar_hour, declination,sunrise, sunset, timeadjustment, sunearthdistance, &sinesolaraltitude, &daylight, &solartimestep, &sunmax, &solarazimuth); sal=asin(sinesolaraltitude); saz=solarazimuth; /* printf("for %2d/%2d/%4d at met-file-time %5.2f and solar hour %5.2f \n", month,day,year,hour+0.5*dt,solar_hour); printf(" sunrise is at %5.2f with sunset at %5.2f and solar alt: %f with azimuth %f \n", sunrise,sunset,sal*DEGPRAD,saz*DEGPRAD);*/ CalcHillShadeWithTerrainBlocking(nRows,nCols,dx,max_elev,elev, sal,saz,slope,aspect,&hillshade); /* at this point hillshade is between 0 and 255 */ /* which is the standard arc-info for the hillshade command */ /* we need to translate this to the proper dhsvm format */ /* and output it as an unsigned char */ for (ny = 0; ny < nRows; ny++) { for (nx = 0; nx < nCols; nx++) { if(sinesolaraltitude>0) if(hillshade[ny][nx]/255/sinesolaraltitude>11.47) outputgrid[ny][nx]=255; else outputgrid[ny][nx]=(unsigned char)(hillshade[ny][nx]/sinesolaraltitude/11.47); else outputgrid[ny][nx]=0; } } /* for (ny = 0; ny < nRows; ny++) { fwrite(hillshade[ny],sizeof(float),nCols,outfile2); }*/ for (ny = 0; ny < nRows; ny++) { fwrite(outputgrid[ny],sizeof(unsigned char),nCols,outfile); } } }
/***************************************************************************** Function name: InitNewStep() Purpose : Initialize Earth-Sun geometry and meteorological data at the beginning of each timestep Required : MAPSIZE Map - Structure with information about location TIMESTRUCT Time - Structure with time information int PrecipType - Type of precipitation input, RADAR, STATION or OROGRAPHIC int FlowGradient - Type of FlowGradient calculation int NStats - Number of meteorological stations METLOCATION *Stat - Structure with information about the meteorological stations in or near the study area char *RadarFileName - Name of file with radar images MAPSIZE Radar - Structure with information about the precipitation radar coverage RADCLASSPIX **RadMap - Structure with radiation data for each pixel RADARPIX **RadarMap - Structure with precipitation information for each radar pixel SOLARGEOMETRY *SolarGeo - structure with information about Earth-Sun geometry SOILPIX **SoilMap - structure with soil information float ***MM5Input - MM5 input maps float ***WindModel - Wind model maps Returns : void Modifies : Comments : To be executed at the beginning of each time step *****************************************************************************/ void InitNewStep(INPUTFILES *InFiles, MAPSIZE *Map, TIMESTRUCT *Time, int NSoilLayers, OPTIONSTRUCT *Options, int NStats, METLOCATION *Stat, char *RadarFileName, MAPSIZE *Radar, RADARPIX **RadarMap, SOLARGEOMETRY *SolarGeo, TOPOPIX **TopoMap, RADCLASSPIX **RadMap, SOILPIX **SoilMap, float ***MM5Input, float ***WindModel, MAPSIZE *MM5Map) { const char *Routine = "InitNewStep"; int i; /* counter */ int j; /* counter */ int x; /* counter */ int y; /* counter */ int NumberType; /* number type in MM5 input */ int Step; /* Step in the MM5 Input */ float *Array = NULL; int MM5Y, MM5X; /* Calculate variables related to the position of the sun above the horizon, this is only necessary if shading is TRUE */ SolarHour(SolarGeo->Latitude, (Time->DayStep + 1) * ((float) Time->Dt) / SECPHOUR, ((float) Time->Dt) / SECPHOUR, SolarGeo->NoonHour, SolarGeo->Declination, SolarGeo->Sunrise, SolarGeo->Sunset, SolarGeo->TimeAdjustment, SolarGeo->SunEarthDistance, &(SolarGeo->SineSolarAltitude), &(SolarGeo->DayLight), &(SolarGeo->SolarTimeStep), &(SolarGeo->SunMax), &(SolarGeo->SolarAzimuth)); /*printf("SunMax is %f\n",SolarGeo->SunMax);*/ if (Options->MM5 == TRUE) { /* Read the data from the MM5 files */ if (!(Array = (float *) calloc(MM5Map->NY * MM5Map->NX, sizeof(float)))) ReportError((char *) Routine, 1); NumberType = NC_FLOAT; Step = NumberOfSteps(&(Time->StartMM5), &(Time->Current), Time->Dt); Read2DMatrix(InFiles->MM5Temp, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_temperature - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } Read2DMatrix(InFiles->MM5Humidity, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_humidity - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } Read2DMatrix(InFiles->MM5Wind, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_wind - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } Read2DMatrix(InFiles->MM5ShortWave, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_shortwave - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } Read2DMatrix(InFiles->MM5LongWave, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_longwave - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } Read2DMatrix(InFiles->MM5Precipitation, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_precip - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; if (MM5Input[MM5_precip - 1][y][x] < 0.0) { printf("Warning: MM5 precip is less than zero %f\n", MM5Input[MM5_precip - 1][y][x]); MM5Input[MM5_precip - 1][y][x] = 0.0; } } Read2DMatrix(InFiles->MM5Terrain, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_terrain - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } Read2DMatrix(InFiles->MM5Lapse, Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[MM5_lapse - 1][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } if (Options->HeatFlux == TRUE) { for (i = 0, j = MM5_lapse; i < NSoilLayers; i++, j++) { Read2DMatrix(InFiles->MM5SoilTemp[i], Array, NumberType, MM5Map->NY, MM5Map->NX, Step); for (y = 0; y < Map->NY; y++) for (x = 0; x < Map->NX; x++) { MM5Y = (int) ((y + MM5Map->OffsetY) * Map->DY / MM5Map->DY); MM5X = (int) ((x - MM5Map->OffsetX) * Map->DX / MM5Map->DY); MM5Input[j][y][x] = Array[MM5Y * MM5Map->NX + MM5X]; } } } free(Array); } /*end if MM5*/ /* if the flow gradient is based on the water table, recalculate the water table gradients. Flow directions are now calculated in RouteSubSurface*/ if (Options->FlowGradient == WATERTABLE) { /* Calculate the WaterLevel, i.e. the height of the water table above some datum */ for (y = 0; y < Map->NY; y++) { for (x = 0; x < Map->NX; x++) { if (INBASIN(TopoMap[y][x].Mask)) { SoilMap[y][x].WaterLevel = TopoMap[y][x].Dem - SoilMap[y][x].TableDepth; } } } /* HeadSlopeAspect(Map, TopoMap, SoilMap); */ } if ((Options->MM5 == TRUE && Options->QPF == TRUE) || Options->MM5 == FALSE) GetMetData(Options, Time, NSoilLayers, NStats, SolarGeo->SunMax, Stat, Radar, RadarMap, RadarFileName); }