📄 shapes.cpp
字号:
///////////////////////////////////////////////////////////
// //
// SAGA //
// //
// System for Automated Geoscientific Analyses //
// //
// Application Programming Interface //
// //
// Library: SAGA_API //
// //
//-------------------------------------------------------//
// //
// shapes.cpp //
// //
// Copyright (C) 2005 by Olaf Conrad //
// //
//-------------------------------------------------------//
// //
// This file is part of 'SAGA - System for Automated //
// Geoscientific Analyses'. //
// //
// This library is free software; you can redistribute //
// it and/or modify it under the terms of the GNU Lesser //
// General Public License as published by the Free //
// Software Foundation, version 2.1 of the License. //
// //
// This library 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 Lesser General Public //
// License for more details. //
// //
// You should have received a copy of the GNU Lesser //
// 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 "shapes.h"
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
const SG_Char * SG_Get_ShapeType_Name(TSG_Shape_Type Type)
{
switch( Type )
{
case SHAPE_TYPE_Point: return( LNG("[DAT] Point") );
case SHAPE_TYPE_Points: return( LNG("[DAT] Points") );
case SHAPE_TYPE_Line: return( LNG("[DAT] Line") );
case SHAPE_TYPE_Polygon: return( LNG("[DAT] Polygon") );
default:
case SHAPE_TYPE_Undefined: return( LNG("[DAT] Undefined") );
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CSG_Shapes * SG_Create_Shapes(void)
{
return( new CSG_Shapes );
}
//---------------------------------------------------------
CSG_Shapes * SG_Create_Shapes(const CSG_Shapes &Shapes)
{
return( new CSG_Shapes(Shapes) );
}
//---------------------------------------------------------
CSG_Shapes * SG_Create_Shapes(const SG_Char *File_Name)
{
return( new CSG_Shapes(File_Name) );
}
//---------------------------------------------------------
CSG_Shapes * SG_Create_Shapes(TSG_Shape_Type Type, const SG_Char *Name, CSG_Table *pStructure)
{
return( new CSG_Shapes(Type, Name, pStructure) );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CSG_Shapes::CSG_Shapes(void)
: CSG_Data_Object()
{
_On_Construction();
}
//---------------------------------------------------------
CSG_Shapes::CSG_Shapes(const CSG_Shapes &Shapes)
: CSG_Data_Object()
{
_On_Construction();
Create(Shapes);
}
//---------------------------------------------------------
CSG_Shapes::CSG_Shapes(const SG_Char *File_Name)
: CSG_Data_Object()
{
_On_Construction();
Create(File_Name);
}
//---------------------------------------------------------
CSG_Shapes::CSG_Shapes(TSG_Shape_Type Type, const SG_Char *Name, CSG_Table *pStructure)
: CSG_Data_Object()
{
_On_Construction();
Create(Type, Name, pStructure);
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CSG_Shapes::_On_Construction(void)
{
m_Type = SHAPE_TYPE_Undefined;
m_Shapes = NULL;
m_nShapes = 0;
m_bUpdate = true;
m_Table.m_pOwner = this;
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CSG_Shapes::Create(const CSG_Shapes &Shapes)
{
return( Assign((CSG_Data_Object *)&Shapes) );
}
//---------------------------------------------------------
bool CSG_Shapes::Create(const SG_Char *File_Name)
{
int iShape;
Destroy();
if( _Load_ESRI(File_Name) )
{
if( Get_Count() < m_Table.Get_Record_Count() )
{
for(iShape=m_Table.Get_Record_Count()-1; iShape >= Get_Count(); iShape--)
{
m_Table._Del_Record(iShape);
}
}
for(iShape=Get_Count()-1; iShape >= 0; iShape--)
{
if( !Get_Shape(iShape)->is_Valid() )
{
Del_Shape(iShape);
}
}
Set_File_Name(File_Name);
if( !Get_History().Load(File_Name, HISTORY_EXT_SHAPES) )
{
Get_History().Add_Entry(LNG("[HST] Loaded from file"), File_Name);
}
return( true );
}
Destroy(); // loading failure...
return( false );
}
//---------------------------------------------------------
bool CSG_Shapes::Create(TSG_Shape_Type Type, const SG_Char *Name, CSG_Table *pStructure)
{
Destroy();
m_Table._Create(pStructure);
m_Table.Set_Name(Name);
Set_Name(Name);
m_Type = Type;
return( true );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CSG_Shapes::~CSG_Shapes(void)
{
Destroy();
}
//---------------------------------------------------------
bool CSG_Shapes::Destroy(void)
{
if( m_nShapes > 0 )
{
for(int i=0; i<m_nShapes; i++)
{
delete(m_Shapes[i]);
}
SG_Free(m_Shapes);
m_Shapes = NULL;
m_nShapes = 0;
}
m_Table._Destroy();
CSG_Data_Object::Destroy();
return( true );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CSG_Shapes::Assign(CSG_Data_Object *pObject)
{
int iShape;
CSG_Shape *pShape;
CSG_Shapes *pShapes;
//-----------------------------------------------------
if( pObject && pObject->is_Valid() && pObject->Get_ObjectType() == Get_ObjectType() )
{
pShapes = (CSG_Shapes *)pObject;
Create(pShapes->Get_Type(), pShapes->Get_Name(), &pShapes->Get_Table());
for(iShape=0; iShape<pShapes->Get_Count() && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++)
{
pShape = Add_Shape();
pShape->Assign(pShapes->Get_Shape(iShape));
}
SG_UI_Process_Set_Ready();
_Extent_Update();
Get_History().Assign(pObject->Get_History());
return( true );
}
return( false );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CSG_Shapes::Save(const SG_Char *File_Name, int Format)
{
bool bResult = false;
CSG_String sFile_Name = SG_File_Make_Path(NULL, File_Name, SG_T("shp"));
switch( Format )
{
case 0: default:
bResult = _Save_ESRI(sFile_Name);
break;
}
if( bResult )
{
Set_Modified(false);
Set_File_Name(sFile_Name);
Get_History().Save(File_Name, HISTORY_EXT_SHAPES);
}
return( bResult );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define GET_GROW_SIZE(n) (n < 256 ? 1 : (n < 8192 ? 64 : 1024))
//---------------------------------------------------------
CSG_Shape * CSG_Shapes::_Add_Shape(CSG_Table_Record *pRecord)
{
CSG_Shape *pShape = NULL;
if( pRecord )
{
switch( m_Type )
{
default:
break;
case SHAPE_TYPE_Point:
pShape = new CSG_Shape_Point (this, pRecord);
break;
case SHAPE_TYPE_Points:
pShape = new CSG_Shape_Points (this, pRecord);
break;
case SHAPE_TYPE_Line:
pShape = new CSG_Shape_Line (this, pRecord);
break;
case SHAPE_TYPE_Polygon:
pShape = new CSG_Shape_Polygon (this, pRecord);
break;
}
if( pShape )
{
if( (m_nShapes % GET_GROW_SIZE(m_nShapes)) == 0 )
{
CSG_Shape **pShapes = (CSG_Shape **)SG_Realloc(m_Shapes, (m_nShapes + GET_GROW_SIZE(m_nShapes)) * sizeof(CSG_Shape *));
if( pShapes == NULL )
{
delete(pShape);
return( NULL );
}
m_Shapes = pShapes;
}
m_Shapes[m_nShapes++] = pShape;
m_bUpdate = true;
Set_Modified();
}
}
return( pShape );
}
//---------------------------------------------------------
CSG_Shape * CSG_Shapes::Add_Shape(void)
{
if( m_Type != SHAPE_TYPE_Undefined )
{
return( _Add_Shape(m_Table._Add_Record(NULL)) );
}
return( NULL );
}
CSG_Shape * CSG_Shapes::Add_Shape(CSG_Table_Record *pValues)
{
if( m_Type != SHAPE_TYPE_Undefined )
{
return( _Add_Shape(m_Table._Add_Record(pValues)) );
}
return( NULL );
}
CSG_Shape * CSG_Shapes::Add_Shape(CSG_Shape *pShape, bool bCopyAttributes)
{
if( pShape && pShape->Get_Type() == m_Type )
{
CSG_Shape *_pShape;
if( (_pShape = _Add_Shape(m_Table._Add_Record(bCopyAttributes ? pShape->Get_Record() : NULL))) != NULL )
{
for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
{
for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
{
_pShape->Add_Point(pShape->Get_Point(iPoint, iPart), iPart);
}
}
return( _pShape );
}
}
return( NULL );
}
//---------------------------------------------------------
bool CSG_Shapes::Del_Shape(CSG_Shape *pShape)
{
return( Del_Shape(pShape->Get_Record()->Get_Index()) );
}
bool CSG_Shapes::Del_Shape(int iShape)
{
int i;
if( iShape >= 0 && iShape < m_nShapes )
{
if( m_Shapes[iShape]->is_Selected() )
{
Select(m_Shapes[iShape], true);
}
delete(m_Shapes[iShape]);
m_nShapes--;
for(i=iShape; i<m_nShapes; i++)
{
m_Shapes[i] = m_Shapes[i + 1];
}
m_Shapes = (CSG_Shape **)SG_Realloc(m_Shapes, m_nShapes * sizeof(CSG_Shape *));
m_Table._Del_Record(iShape);
m_bUpdate = true;
Set_Modified();
return( true );
}
return( false );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CSG_Shapes::_Extent_Update(void)
{
int i;
if( m_bUpdate )
{
if( m_nShapes > 0 )
{
m_Extent = m_Shapes[0]->Get_Extent();
for(i=1; i<m_nShapes; i++)
{
m_Extent.Union(m_Shapes[i]->Get_Extent());
}
}
else
{
m_Extent.Assign(0.0, 0.0, 0.0, 0.0);
}
m_bUpdate = false;
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CSG_Shape * CSG_Shapes::Get_Shape(TSG_Point Point, double Epsilon)
{
int iShape;
double d, dNearest;
CSG_Rect r(Point.x - Epsilon, Point.y - Epsilon, Point.x + Epsilon, Point.y + Epsilon);
CSG_Shape *pShape, *pNearest;
pNearest = NULL;
if( r.Intersects(Get_Extent()) != INTERSECTION_None )
{
for(iShape=0, dNearest=-1.0; iShape<m_nShapes; iShape++)
{
pShape = m_Shapes[iShape];
if( pShape->Intersects(r) )
{
d = pShape->Get_Distance(Point);
if( d == 0.0 )
{
return( pShape );
}
if( d > 0.0 && d <= Epsilon && (pNearest == NULL || d < dNearest) )
{
dNearest = d;
pNearest = pShape;
}
}
}
}
return( pNearest );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -