📄 grid_cross_profiles.cpp
字号:
///////////////////////////////////////////////////////////
// //
// SAGA //
// //
// System for Automated Geoscientific Analyses //
// //
// Module Library: //
// ta_profiles //
// //
//-------------------------------------------------------//
// //
// Grid_Cross_Profiles.cpp //
// //
// Copyright (C) 2006 by //
// Olaf Conrad //
// //
//-------------------------------------------------------//
// //
// This file is part of 'SAGA - System for Automated //
// Geoscientific Analyses'. SAGA 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; version 2 of the License. //
// //
// SAGA 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. //
// //
//-------------------------------------------------------//
// //
// e-mail: oconrad@saga-gis.org //
// //
// contact: Olaf Conrad //
// Institute of Geography //
// University of Goettingen //
// Goldschmidtstr. 5 //
// 37077 Goettingen //
// Germany //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#include <saga_api/doc_pdf.h>
#include "Grid_Cross_Profiles.h"
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define OFFSET 3
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CGrid_Cross_Profiles::CGrid_Cross_Profiles(void)
{
Set_Name(_TL("Cross Profiles"));
Set_Author(_TL("Copyrights (c) 2006 by Olaf Conrad"));
Set_Description (_TW(
"Create cross profiles from a grid based DEM for given lines.\n"
));
Parameters.Add_Grid(
NULL, "DEM" , _TL("DEM"),
_TL(""),
PARAMETER_INPUT
);
Parameters.Add_Shapes(
NULL, "LINES" , _TL("Lines"),
_TL(""),
PARAMETER_INPUT , SHAPE_TYPE_Line
);
Parameters.Add_Shapes(
NULL, "PROFILES" , _TL("Cross Profiles"),
_TL(""),
PARAMETER_OUTPUT , SHAPE_TYPE_Line
);
Parameters.Add_Value(
NULL, "DIST_LINE" , _TL("Profile Distance"),
_TL(""),
PARAMETER_TYPE_Double, 10.0, 0.0, true
);
Parameters.Add_Value(
NULL, "DIST_PROFILE", _TL("Profile Length"),
_TL(""),
PARAMETER_TYPE_Double, 10.0, 0.0, true
);
Parameters.Add_Value(
NULL, "NUM_PROFILE" , _TL("Profile Samples"),
_TL(""),
PARAMETER_TYPE_Int , 10.0, 3.0, true
);
Parameters.Add_FilePath(
NULL, "DOCUMENT" , _TL("Report"),
_TL(""),
_TL("Portable Document Format (*.pdf)|*.pdf|All Files|*.*"), NULL, true
);
}
//---------------------------------------------------------
CGrid_Cross_Profiles::~CGrid_Cross_Profiles(void)
{}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CGrid_Cross_Profiles::On_Execute(void)
{
int iLine, iPart, iPoint, nSamples;
double Distance, Length, dLine, dist, dx, dy;
TSG_Point iPt, jPt, dPt, aPt, bPt;
CSG_Shapes *pLines, *pProfiles;
CSG_Shape *pLine, *pProfile;
//-----------------------------------------------------
m_pDEM = Parameters("DEM") ->asGrid();
pProfiles = Parameters("PROFILES") ->asShapes();
pLines = Parameters("LINES") ->asShapes();
Distance = Parameters("DIST_LINE") ->asDouble();
Length = Parameters("DIST_PROFILE")->asDouble();
nSamples = Parameters("NUM_PROFILE") ->asInt();
//-----------------------------------------------------
pProfiles->Create(SHAPE_TYPE_Line, _TL("Profiles"));
pProfiles->Get_Table().Add_Field("ID" , TABLE_FIELDTYPE_Int);
pProfiles->Get_Table().Add_Field("LINE" , TABLE_FIELDTYPE_Int);
pProfiles->Get_Table().Add_Field("PART" , TABLE_FIELDTYPE_Int);
for(iPoint=0; iPoint<nSamples; iPoint++)
{
pProfiles->Get_Table().Add_Field(CSG_String::Format(SG_T("X%03d"), iPoint), TABLE_FIELDTYPE_Double);
}
//-----------------------------------------------------
for(iLine=0; iLine<pLines->Get_Count() && Set_Progress(iLine, pLines->Get_Count()); iLine++)
{
pLine = pLines->Get_Shape(iLine);
for(iPart=0; iPart<pLine->Get_Part_Count(); iPart++)
{
if( pLine->Get_Point_Count(iPart) > 1 )
{
dist = 0.0;
iPt = pLine->Get_Point(0, iPart);
for(iPoint=1; iPoint<pLine->Get_Point_Count(iPart); iPoint++)
{
jPt = iPt;
iPt = pLine->Get_Point(iPoint, iPart);
dx = iPt.x - jPt.x;
dy = iPt.y - jPt.y;
dLine = sqrt(dx*dx + dy*dy);
dx /= dLine;
dy /= dLine;
while( dist < dLine )
{
dPt.x = jPt.x + dist * dx;
dPt.y = jPt.y + dist * dy;
if( m_pDEM->is_InGrid_byPos(dPt) )
{
aPt.x = dPt.x + dy * Length;
aPt.y = dPt.y - dx * Length;
bPt.x = dPt.x - dy * Length;
bPt.y = dPt.y + dx * Length;
pProfile = pProfiles->Add_Shape();
pProfile->Add_Point(aPt);
pProfile->Add_Point(bPt);
pProfile->Get_Record()->Set_Value(0, pProfiles->Get_Count());
pProfile->Get_Record()->Set_Value(1, iLine);
pProfile->Get_Record()->Set_Value(2, iPart);
Get_Profile(pProfile, aPt, bPt, nSamples);
}
dist += Distance;
}
dist -= dLine;
}
}
}
}
//-----------------------------------------------------
if( pProfiles->Get_Count() > 0 )
{
if( Parameters("DOCUMENT")->asString() )
{
Make_Report(Parameters("DOCUMENT")->asString(), m_pDEM, pLines, pProfiles, Distance);
}
return( true );
}
return( false );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CGrid_Cross_Profiles::Get_Profile(CSG_Shape *pProfile, TSG_Point A, TSG_Point B, int nSamples)
{
if( 1 )
{
double d, dx, dy, z;
dx = B.x - A.x;
dy = B.y - A.y;
// d = sqrt(dx*dx + dy*dy) / (nSamples - 1);
d = (nSamples - 1);
dx /= d;
dy /= d;
for(int i=0; i<nSamples; i++)
{
if( m_pDEM->Get_Value(A, z) )
{
pProfile->Get_Record()->Set_Value (OFFSET + i, z);
}
else
{
pProfile->Get_Record()->Set_NoData (OFFSET + i);
}
A.x += dx;
A.y += dy;
}
return( true );
}
return( false );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define NBOXES 4
//---------------------------------------------------------
void CGrid_Cross_Profiles::Make_Report(const SG_Char *FileName, CSG_Grid *pDEM, CSG_Shapes *pLines, CSG_Shapes *pProfiles, double Distance)
{
if( FileName )
{
int iProfile, iPoint, nSamples, iBox;
CSG_Rect r;
CSG_Shape *pProfile, *pLine;
CSG_Shapes Profile;
CSG_Doc_PDF pdf;
pdf.Open(PDF_PAGE_SIZE_A4, PDF_PAGE_ORIENTATION_PORTRAIT, _TL("Cross Profiles"));
pdf.Layout_Add_Box(5, 5, 95, 20);
pdf.Layout_Add_Box(5, 25, 95, 45);
pdf.Layout_Add_Box(5, 50, 95, 70);
pdf.Layout_Add_Box(5, 75, 95, 90);
nSamples = pProfiles->Get_Table().Get_Field_Count() - OFFSET;
Distance = Distance / (nSamples - 1);
iBox = 0;
for(iProfile=0; iProfile<pProfiles->Get_Count() && Set_Progress(iProfile, pProfiles->Get_Count()); iProfile++)
{
pProfile = pProfiles->Get_Shape(iProfile);
Profile.Create(SHAPE_TYPE_Line);
pLine = Profile.Add_Shape();
for(iPoint=0; iPoint<nSamples; iPoint++)
{
if( !pProfile->Get_Record()->is_NoData(OFFSET + iPoint) )
{
pLine->Add_Point(
(iPoint - nSamples / 2) * Distance,
pProfile->Get_Record()->asDouble(OFFSET + iPoint)
);
}
}
if( pLine->Get_Point_Count(0) > 1 )
{
if( iBox >= NBOXES )
{
pdf.Add_Page();
iBox = 0;
}
// pdf.Draw_Graticule (pdf.Layout_Get_Box(iBox), Profile.Get_Extent(), 20);
// pdf.Draw_Shapes (pdf.Layout_Get_Box(iBox), &Profile);
r = pLine->Get_Extent(); r.Inflate(10);
pdf.Draw_Graticule (pdf.Layout_Get_Box(iBox), r, 15);
pdf.Draw_Shape (pdf.Layout_Get_Box(iBox), pLine, PDF_STYLE_POLYGON_FILLSTROKE, SG_COLOR_GREEN, SG_COLOR_BLACK, 1, &r);
iBox++;
}
}
pdf.Save(Parameters("DOCUMENT")->asString());
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -