📄 view_map_3d_image.cpp
字号:
///////////////////////////////////////////////////////////
// //
// SAGA //
// //
// System for Automated Geoscientific Analyses //
// //
// User Interface //
// //
// Program: SAGA //
// //
//-------------------------------------------------------//
// //
// VIEW_Map_3D_Image.cpp //
// //
// Copyright (C) 2005 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. //
// //
//-------------------------------------------------------//
// //
// contact: Olaf Conrad //
// Institute of Geography //
// University of Goettingen //
// Goldschmidtstr. 5 //
// 37077 Goettingen //
// Germany //
// //
// e-mail: oconrad@saga-gis.org //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#include <wx/wx.h>
#include <wx/window.h>
#include "res_dialogs.h"
#include "helper.h"
#include "wksp_map.h"
#include "view_map_3d.h"
#include "view_map_3d_image.h"
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define FLAG_COLOR 0x01
#define FLAG_DATA 0x02
#define FLAG_PROJECTION 0x04
#define FLAG_ALL (FLAG_COLOR|FLAG_DATA|FLAG_PROJECTION)
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CVIEW_Map_3D_Image::CVIEW_Map_3D_Image(CVIEW_Map_3D *pParent, CWKSP_Map *pMap)
{
m_pParent = pParent;
m_pMap = pMap;
m_pDEM = NULL;
m_img_z = NULL;
m_img_nx = 0;
m_img_ny = 0;
m_Points = NULL;
m_nxPoints = 0;
m_nyPoints = 0;
m_Resolution = 200;
m_xyRatio = 1.0;
m_bInterpol = false;
//-----------------------------------------------------
((BYTE *)&m_Missing)[3] = 0xff;
((BYTE *)&m_Missing)[2] = 0x7f;
((BYTE *)&m_Missing)[1] = 0xff;
((BYTE *)&m_Missing)[0] = 0xff;
}
//---------------------------------------------------------
CVIEW_Map_3D_Image::~CVIEW_Map_3D_Image(void)
{
if( m_img_z )
{
SG_Free(m_img_z[0]);
SG_Free(m_img_z);
}
if( m_Points )
{
SG_Free(m_Points[0]);
SG_Free(m_Points);
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CVIEW_Map_3D_Image::Save(void)
{
int type;
wxString file;
CSG_Parameters Parameters;
//-----------------------------------------------------
Parameters.Create(NULL, LNG("Save 3D Image Options"), LNG(""));
Parameters.Add_Node(NULL, "NODE_RES", LNG("Image Resolution"), LNG(""));
Parameters.Add_Value(
Parameters("NODE_RES") , "WIDTH" , LNG("Width"),
wxT(""),
PARAMETER_TYPE_Int , m_img_nx, 1, true
);
Parameters.Add_Value(
Parameters("NODE_RES") , "HEIGHT" , LNG("Height"),
wxT(""),
PARAMETER_TYPE_Int , m_img_ny, 1, true
);
//-----------------------------------------------------
if( m_img.Ok() && DLG_Image_Save(file, type) && DLG_Parameters(&Parameters) )
{
Set_Buisy_Cursor(true);
if( m_pParent && (m_img_nx != Parameters("WIDTH")->asInt() || m_img_ny != Parameters("HEIGHT")->asInt()) )
{
CVIEW_Map_3D_Image Image(NULL, m_pMap);
m_pParent->_Parms_Update(true, &Image);
Image.Set_Image(Parameters("WIDTH")->asInt(), Parameters("HEIGHT")->asInt());
Image.Save(file, type);
}
else
{
Save(file, type);
}
Set_Buisy_Cursor(false);
}
}
//---------------------------------------------------------
void CVIEW_Map_3D_Image::Save(const wxChar *file, int type)
{
if( m_img.Ok() && file != NULL )
{
m_img.SaveFile(file, type);
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CVIEW_Map_3D_Image::Set_Source(int Resolution)
{
BYTE *Color, Mask[3];
int x, y;
double z, xPos, yPos, dx, dy, zMin, zMax, xyRatio;
CSG_Rect rSource(m_pMap->Get_Extent());
wxImage img;
//-----------------------------------------------------
xyRatio = rSource.Get_XRange() / rSource.Get_YRange();
if( !m_Points || (Resolution > 0 && Resolution != m_Resolution) || xyRatio != m_xyRatio )
{
TPoint *pPoint;
if( Resolution > 0 )
m_Resolution = Resolution;
m_xyRatio = xyRatio;
if( m_xyRatio > 1.0 )
{
m_nxPoints = m_Resolution;
m_nyPoints = (int)(m_Resolution / m_xyRatio);
}
else
{
m_nxPoints = (int)(m_Resolution * m_xyRatio);
m_nyPoints = m_Resolution;
}
pPoint = m_Points ? m_Points[0] : NULL;
pPoint = (TPoint *)SG_Realloc( pPoint , m_nxPoints * m_nyPoints * sizeof(TPoint ));
m_Points = (TPoint **)SG_Realloc(m_Points, m_nyPoints * sizeof(TPoint *));
for(int n=0; n<m_nyPoints; n++, pPoint+=m_nxPoints)
{
m_Points[n] = pPoint;
}
m_Src_bUpdate = true;
}
//-----------------------------------------------------
if( m_Src_bUpdate && m_Points && m_pDEM )
{
m_Src_bUpdate = false;
if( m_bInterpol )
img.Create(m_nxPoints , m_nyPoints);
else
img.Create(m_nxPoints - 1, m_nyPoints - 1);
m_pMap->Get_Image(img, rSource);
m_Range = rSource.Get_XRange() > rSource.Get_YRange() ? rSource.Get_XRange() : rSource.Get_YRange();
//-------------------------------------------------
dx = rSource.Get_XRange() / (double)m_nxPoints;
dy = rSource.Get_YRange() / (double)m_nyPoints;
zMin = 1.0;
zMax = 0.0;
for(y=0, yPos=rSource.Get_YMin(); y<m_nyPoints && PROGRESSBAR_Set_Position(y, m_nyPoints); y++, yPos+=dy)
{
for(x=0, xPos=rSource.Get_XMin(); x<m_nxPoints; x++, xPos+=dx)
{
if( m_pDEM->Get_Value(xPos, yPos, z) )
{
m_Points[y][x].zDEM = z;
m_Points[y][x].Flags = FLAG_DATA;
if( zMin > zMax )
zMin = zMax = z;
else if( z < zMin )
zMin = z;
else if( z > zMax )
zMax = z;
}
else
{
m_Points[y][x].Flags = 0;
}
}
}
//-------------------------------------------------
z = zMin + (zMax - zMin) / 2.0;
for(y=0; y<m_nyPoints && PROGRESSBAR_Set_Position(y, m_nyPoints); y++)
{
for(x=0; x<m_nxPoints; x++)
{
if( (m_Points[y][x].Flags & FLAG_DATA) != 0 )
{
m_Points[y][x].zDEM -= z;
}
}
}
//-----------------------------------------------------
Mask[0] = img.GetMaskRed();
Mask[1] = img.GetMaskGreen();
Mask[2] = img.GetMaskBlue();
for(y=0; y<img.GetHeight(); y++)
{
Color = img.GetData() + (img.GetHeight() - 1 - y) * 3 * img.GetWidth();
for(x=0; x<img.GetWidth(); x++, Color+=3)
{
if( memcmp(Color, Mask, 3 * sizeof(BYTE)) )
{
m_Points[y][x].r = Color[0];
m_Points[y][x].g = Color[1];
m_Points[y][x].b = Color[2];
m_Points[y][x].Flags |= FLAG_COLOR;
}
}
}
//-------------------------------------------------
PROCESS_Set_Okay(true);
Set_Image();
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CVIEW_Map_3D_Image::Set_Image(int NX, int NY)
{
int y;
float *pz;
if( !m_img_z || NX != m_img_nx || NY != m_img_ny )
{
m_img.Create(NX, NY);
m_img_nx = m_img.GetWidth();
m_img_ny = m_img.GetHeight();
pz = m_img_z ? m_img_z[0] : NULL;
pz = (float *)SG_Realloc(pz , NY * NX * sizeof(float ));
m_img_z = (float **)SG_Realloc(m_img_z, NY * sizeof(float *));
for(y=0; y<NY; y++, pz+=NX)
{
m_img_z[y] = pz;
}
Set_Image();
}
}
//---------------------------------------------------------
void CVIEW_Map_3D_Image::Set_Image(void)
{
BYTE BkStereo, *r, *p;
int i, n;
//-----------------------------------------------------
if( m_Points && m_img_z )
{
n = m_img_nx * m_img_ny;
if( !m_bStereo )
{
for(i=0, p=m_img.GetData(); i<n; i++, p+=3)
{
memcpy(p, &m_BkColor, 3);
}
_Rotate_Matrix(m_xRotate, m_yRotate, m_zRotate);
_Draw_Image();
}
//-------------------------------------------------
else
{
BkStereo = (BYTE)((SG_GET_R(m_BkColor) + SG_GET_G(m_BkColor) + SG_GET_B(m_BkColor)) / 3.0);
//---------------------------------------------
// 1. Right View...
memset(m_img.GetData(), BkStereo, 3 * n);
_Rotate_Matrix(m_xRotate, m_yRotate + 0.5 * m_Stereo, m_zRotate);
_Draw_Image();
r = (BYTE *)SG_Malloc(n * sizeof(BYTE));
for(i=0, p=m_img.GetData(); i<n; i++, p+=3)
{
r[i] = (p[0] + p[1] + p[2]) / 3;
}
//---------------------------------------------
// 2. Left View...
memset(m_img.GetData(), BkStereo, 3 * n);
_Rotate_Matrix(m_xRotate, m_yRotate - 0.5 * m_Stereo, m_zRotate);
_Draw_Image();
for(i=0, p=m_img.GetData(); i<n; i++, p+=3)
{
p[0] = (p[0] + p[1] + p[2]) / 3;
p[1] = r[i];
p[2] = BkStereo;
}
SG_Free(r);
}
if( m_pParent )
{
m_pParent->_Paint();
}
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define RANGE 200.0
//---------------------------------------------------------
void CVIEW_Map_3D_Image::_Rotate_Matrix(double xRotate, double yRotate, double zRotate)
{
int x, y;
double px, py, pz, ix, iy, dx, dy, dz, xRange, yRange;
TPoint *p;
if( m_xyRatio > 1.0 )
{
xRange = RANGE;
yRange = RANGE / m_xyRatio;
}
else
{
xRange = RANGE * m_xyRatio;
yRange = RANGE;
}
//-----------------------------------------------------
r_fig = sqrt(2.0) * m_Figure_Weight * RANGE;
dx = xRange / m_nxPoints;
dy = yRange / m_nyPoints;
dz = -RANGE * m_Exaggeration / m_Range;
r_sin_x = sin(xRotate);
r_sin_y = sin(yRotate);
r_sin_z = sin(zRotate);
r_cos_x = cos(xRotate);
r_cos_y = cos(yRotate);
r_cos_z = cos(zRotate);
r_ext = RANGE;
if( m_img_ny > m_img_nx )
{
r_m = m_img_nx / r_ext;
r_kx = 0.0f;
r_ky = m_img_ny - (m_img_ny - r_m * r_ext) / 2.0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -