📄 simulatevariablewind.cpp
字号:
/*******************************************************************************
SimulateVariableWind.cpp
Copyright (C) Victor Olaya
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*******************************************************************************/
#include "../../Terrain_Analysis/Terrain_Analysis_Morphometry/Morphometry.h"
//#include "../../GRID/Grid_Shapes/Grid2Contour.h"
#include "SimulateVariableWind.h"
#include <string>
#include <vector>
#include <fstream>
#include <locale>
#include <time.h>
#define NODATA -9999;
#define KMH2FTMIN (1000. / 0.3048 / 60.)
#define FTMIN2MMIN 0.3048
#define BTU2KCAL 0.252164401
#define FT2M 0.3048
#define NO_TIME_LIMIT -1
#define WINDOW_WIDTH 5
//#define TIME_INTERVAL_IN_CURVES 10.
//#define TIME_LIMIT 240
//#define MAX_FIRES_IN_CONTOURS 2000
//#define MAX_CONTOUR_VALUE 1500
CSimulateVariableWind::CSimulateVariableWind(void){
Parameters.Set_Name("Simulaci髇 (Viento variable)");
Parameters.Set_Description(
"(c) 2004 by Victor Olaya. Simulaci髇 con viento variable.");
Parameters.Add_Grid(NULL,
"DEM",
"MDE",
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid(NULL,
"FUEL",
"Modelo de combustible",
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid_List(NULL,
"WINDSPD",
"Velocidad del viento",
"Velocidad del viento (km/h)"
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid_List(NULL,
"WINDDIR",
"Direcci髇 del viento",
"Direcci髇 del viento (grados desde el norte en sentido antihorario)",
PARAMETER_INPUT);
Parameters.Add_Grid(NULL,
"M1H",
"Humedad del combustible muerto en 1-hora",
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid(NULL,
"M10H",
"Humedad del combustible muerto en 10-horas",
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid(NULL,
"M100H",
"Humedad del combustible muerto en 100-horas",
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid(NULL,
"MHERB",
"Humedad del combustible herb醕eo vivo",
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid(NULL,
"MWOOD",
"Humedad del combustible le駉so vivo",
_TL(""),
PARAMETER_INPUT);
Parameters.Add_Grid(NULL,
"TIME",
"Tiempo",
_TL(""),
PARAMETER_OUTPUT);
Parameters.Add_Grid(NULL,
"FLAME",
"Altura de llama",
"Altura de llama (m)",
PARAMETER_OUTPUT);
Parameters.Add_Grid(NULL,
"INTENSITY",
"Intensidad",
"Intensidad (Kcal/m)",
PARAMETER_OUTPUT);
Parameters.Add_Value(NULL,
"IGNTIME",
"Tiempo de inicio (min)",
_TL(""),
PARAMETER_TYPE_Double,
0,
0,
true);
Parameters.Add_Value(NULL,
"INTERVAL",
"Intervalo de tiempo entre capas (min)",
_TL(""),
PARAMETER_TYPE_Double,
30,
1,
true);
Parameters.Add_Value(NULL,
"SIMULATIONTIME",
"Tiempo de simulacion (min)",
_TL(""),
PARAMETER_TYPE_Double,
180,
1,
true);
Parameters.Add_Value(NULL,
"DEFAULTWINDDIR",
"Direcci髇 del viento",
"Direcci髇 del viento (grados desde el norte)",
PARAMETER_TYPE_Double,
0);
Parameters.Add_Value(NULL,
"DEFAULTWINDSPD",
"Velocidad del viento",
"Velocidad del viento (km/h)",
PARAMETER_TYPE_Double,
0);
Parameters.Add_Value(NULL,
"COORDX",
"Coordenada X",
"Coordenada X del punto de ignici髇 (s髄o si no se usa grid de puntos de ignici髇)",
PARAMETER_TYPE_Double,
0);
Parameters.Add_Value(NULL,
"COORDY",
"Coordenada Y",
"Coordenada Y del punto de ignici髇 (s髄o si no se usa grid de puntos de ignici髇)",
PARAMETER_TYPE_Double,
0);
Parameters.Add_FilePath(NULL,
"REPORTFILE",
"Informe",
"Informe",
_TL(""),
_TL(""),
true);
}//constructor
CSimulateVariableWind::~CSimulateVariableWind(void){}
bool CSimulateVariableWind::On_Execute(void){
AssignParameters();
CalculateFire();
DeleteObjects();
return true;
}//method
void CSimulateVariableWind::DeleteObjects(){
delete m_pAspectGrid;
delete m_pSlopeGrid;
delete m_pReactionIntensityGrid;
delete m_pEffectiveWindGrid;
delete m_pHeatPerUnitAreaGrid;
delete m_CentralPoints;
delete m_AdjPoints;
if (m_bDeleteWindSpdGrid){
delete m_pWindSpdGrids[0];
}//if
if (m_bDeleteWindDirGrid){
delete m_pWindDirGrids[0];
}//if
}//method
bool CSimulateVariableWind::AssignParameters(){
int x,y;
m_pDEM = Parameters("DEM")->asGrid();
m_pFuelGrid = Parameters("FUEL")->asGrid();
m_iWindDirGrids = Parameters("WINDDIR")->asInt();
m_pWindDirGrids =(CSG_Grid **)Parameters("WINDDIR")->asPointer();
m_iWindSpdGrids = Parameters("WINDSPD")->asInt();
m_pWindSpdGrids =(CSG_Grid **)Parameters("WINDSPD")->asPointer();
m_pM1Grid = Parameters("M1H")->asGrid();
m_pM10Grid = Parameters("M10H")->asGrid();
m_pM100Grid = Parameters("M100H")->asGrid();
m_pMHerbGrid = Parameters("MHERB")->asGrid();
m_pMWoodGrid = Parameters("MWOOD")->asGrid();
m_pTimeGrid = Parameters("TIME")->asGrid();
m_pFlameGrid = Parameters("FLAME")->asGrid();
m_pIntensityGrid = Parameters("INTENSITY")->asGrid();
m_fTimeLimit = Parameters("SIMULATIONTIME")->asDouble();
m_fIgnTime = Parameters("IGNTIME")->asDouble();
m_fInterval = Parameters("INTERVAL")->asDouble();
m_fWorldX = Parameters("COORDX")->asDouble();
m_fWorldY = Parameters("COORDY")->asDouble();
m_iGridX = (int) ((m_fWorldX - m_pDEM->Get_XMin()) / m_pDEM->Get_Cellsize());
m_iGridY = (int) ((m_fWorldY - m_pDEM->Get_YMin()) / m_pDEM->Get_Cellsize());
m_Catalog = Fire_FuelCatalogCreateStandard("Standard", 13);
Fire_FlameLengthTable(m_Catalog, 500, 0.1);
if (!m_iWindDirGrids){
m_pWindDirGrids = new CSG_Grid*[1];
m_pWindDirGrids[0] = SG_Create_Grid(m_pDEM);
m_pWindDirGrids[0]->Assign(Parameters("DEFAULTWINDDIR")->asDouble());
m_bDeleteWindDirGrid = true;
}//if
else{
m_bDeleteWindDirGrid = false;
}//else
if (!m_iWindSpdGrids){
m_pWindSpdGrids = new CSG_Grid*[1];
m_pWindSpdGrids[0] = SG_Create_Grid(m_pDEM);
m_pWindSpdGrids[0]->Assign(Parameters("DEFAULTWINDSPD")->asDouble());
m_bDeleteWindSpdGrid = true;
}//if
else{
m_bDeleteWindSpdGrid = false;
}//else
//substitute no-data values
for(y=0; y<Get_NY() && Set_Progress(y); y++){
for(x=0; x<Get_NX(); x++){
/*if (m_pWindSpdGrid->is_NoData(x, y)){
m_pWindSpdGrid->Set_Value(x, y, 0.);
}//if
if (m_pWindDirGrid->is_NoData(x, y)){
m_pWindDirGrid->Set_Value(x, y, 0.);
}//if*/
if (m_pM1Grid->is_NoData(x, y)){
m_pM1Grid->Set_Value(x, y, 0.);
}//if
if (m_pM10Grid->is_NoData(x, y)){
m_pM10Grid->Set_Value(x, y, 0.);
}//if
if (m_pM100Grid->is_NoData(x, y)){
m_pM100Grid->Set_Value(x, y, 0.);
}//if
if (m_pMHerbGrid->is_NoData(x, y)){
m_pMHerbGrid->Set_Value(x, y, 0.);
}//if
if (m_pMWoodGrid->is_NoData(x, y)){
m_pMWoodGrid->Set_Value(x, y, 0.);
}//if
}//for
}//for
m_pReactionIntensityGrid = SG_Create_Grid(m_pDEM, GRID_TYPE_Double);
m_pEffectiveWindGrid = SG_Create_Grid(m_pDEM, GRID_TYPE_Double);
m_pHeatPerUnitAreaGrid = SG_Create_Grid(m_pDEM, GRID_TYPE_Double);
m_pSlopeGrid = SG_Create_Grid(m_pDEM, GRID_TYPE_Double);
m_pAspectGrid = SG_Create_Grid(m_pDEM, GRID_TYPE_Double);
CMorphometry Morphometry;
if( !Morphometry.Get_Parameters()->Set_Parameter("ELEVATION", PARAMETER_TYPE_Grid, m_pDEM)
|| !Morphometry.Get_Parameters()->Set_Parameter("SLOPE", PARAMETER_TYPE_Grid, m_pSlopeGrid)
|| !Morphometry.Get_Parameters()->Set_Parameter("ASPECT", PARAMETER_TYPE_Grid, m_pAspectGrid)
|| !Morphometry.Execute() )
{
return( false );
}
m_pTimeGrid->Assign((double)0);
return true;
}//method
void CSimulateVariableWind::CalculateFire(){
Process_Set_Text("Simulando...");
m_CentralPoints .Clear();
m_AdjPoints .Clear();
m_CentralPoints.Clear();
if (m_pDEM->is_InGrid(m_iGridX, m_iGridY,false)){
m_CentralPoints.Add(m_iGridX, m_iGridY);
m_pTimeGrid->Set_Value(m_iGridX, m_iGridY,0.0);
}//if
if (CalculateFireSpreading(m_fTimeLimit)){
m_pTimeGrid->Set_NoData_Value(0.);
CreateReport();
}//if
}//method
int CSimulateVariableWind::CalculateFireSpreading(float fTimeLimit){
int x,y;
int x2,y2;
int i,j;
bool bReturn = false;
/* neighbor's address*/ /* N NE E SE S SW W NW */
static int nX[8] = { 0, 1, 1, 1, 0, -1, -1, -1};
static int nY[8] = { 1, 1, 0, -1, -1, -1, 0, 1};
float fDist; /* distance to neighbor */
float fAz; /* compass azimuth to neighbor (0=N) */
size_t modelNumber; /* fuel model number at current cell */
double moisture[6]; /* fuel moisture content at current cell */
double dSpreadRate; /* spread rate in direction of neighbor */
double dSpreadTime; /* time to spread from cell to neighbor */
double dIgnTime; /* time neighbor is ignited by current cell */
double dWindSpd;
double dWindDir;
int iBurntCells = 0;
while (m_CentralPoints.Get_Count()!=0){
for (int iPt=0; iPt<m_CentralPoints.Get_Count();iPt++){
x = m_CentralPoints.Get_X(iPt);
y = m_CentralPoints.Get_Y(iPt);
if (!m_pDEM->is_NoData(x,y) && !m_pFuelGrid->is_NoData(x,y)){
modelNumber = (size_t) m_pFuelGrid->asInt(x, y);
moisture[0] = m_pM1Grid->asFloat(x, y) / 100.;
moisture[1] = m_pM10Grid->asFloat(x, y) / 100.;
moisture[2] = m_pM100Grid->asFloat(x, y) / 100.;
moisture[3] = m_pM100Grid->asFloat(x, y) / 100.;
moisture[4] = m_pMHerbGrid->asFloat(x, y) / 100.;
moisture[5] = m_pMWoodGrid->asFloat(x, y) / 100.;
dWindSpd = getWindSpeed(x, y, m_pTimeGrid->asFloat(x,y)) * KMH2FTMIN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -