www.gusucode.com > VC++开源的SHP格式GIS地图查看软件源程序源码程序 > VC++开源的SHP格式GIS地图查看软件源程序源码程序\code\MapPolygon.cpp

    //Download by http://www.NewXing.com
#include "stdafx.h"
#include "global.h"
#include "MapPolygon.h"

IMPLEMENT_DYNAMIC(CMapPolygon,CObject)

CMapPolygon::CMapPolygon()
{


}

CMapPolygon::CMapPolygon(CMapPolygon& mappolygon )
{

   int i,iCount;
   CMapParts *pParts;
   
   iCount = m_Polygon.GetSize() - 1;
   for ( i = 0 ; i <= iCount ; i++ )
   { 
		pParts = new CMapParts(*mappolygon.GetParts(i));
		m_Polygon.Add(pParts); 	
   }
}

CMapPolygon::~CMapPolygon()
{

     Clear();
}

long CMapPolygon::GetCount()
{

	return m_Polygon.GetSize(); 
}

CMapRectangle CMapPolygon::GetExtent()
{

    return m_Extent;
}

void CMapPolygon::SetExtent(CMapRectangle& extent)
{
	m_Extent.SetLeft( extent.GetLeft());
	m_Extent.SetRight( extent.GetRight());
	m_Extent.SetTop(extent.GetTop());
    m_Extent.SetBottom(extent.GetBottom());
}

CMapParts* CMapPolygon::GetParts(long lIndex)
{

	int iCount;
    CMapParts  *pParts;

	iCount = m_Polygon.GetSize()-1;
	if ( lIndex < 0 || lIndex > iCount )
		return NULL;
    pParts = m_Polygon.GetAt(lIndex);
	return pParts;
}

double CMapPolygon::GetArea()
{

	return 0;
}

void CMapPolygon::Add(CMapParts* pParts)
{

    if ( pParts == NULL )
		return;
	m_Polygon.Add( pParts );

}

void CMapPolygon::Set(long lIndex , CMapParts* pParts)
{
	
	int iCount;
	CMapParts *pOldParts;

	if ( pParts == NULL )
		return;

	iCount = m_Polygon.GetSize()-1;
	if ( lIndex < 0 || lIndex > iCount )
		return ;
    pOldParts = m_Polygon.GetAt( lIndex );
    m_Polygon.SetAt(lIndex,pParts);
    delete pOldParts; 
}

void CMapPolygon::Remove(long lIndex)
{
	int iCount;
	CMapParts *pParts;
	
	iCount = m_Polygon.GetSize()-1;
	if ( lIndex < 0 || lIndex > iCount )
		return ;
	pParts = m_Polygon.GetAt( lIndex );  
    m_Polygon.RemoveAt(lIndex,1);   
	delete pParts; 
}

void CMapPolygon::Insert(long lIndex , CMapParts* pParts)
{
	int iCount;
	
	iCount = m_Polygon.GetSize()-1;
	if ( lIndex < 0 || lIndex > iCount )
		return ;
	m_Polygon.InsertAt(lIndex,pParts);
}

void CMapPolygon::Clear()
{

   int i,iCount;
   CMapParts *pParts;
   
   iCount = m_Polygon.GetSize() - 1;
   for ( i = iCount ; i >= 0   ; i-- )
   {
		pParts = m_Polygon.GetAt(i);
		delete pParts;
   } 
   m_Polygon.RemoveAll(); 
}

/*************************************************
  描述:         判断点是否在多边形内 
  输入:         点对象
  输出:        在返回TRUE 不在返回FALSE
*************************************************/
BOOL CMapPolygon::IsPointIn(CMapPoint& pt )
{
    int i,j,k,iNumber;
	double dblTemp;
	CMapParts*  pParts;
	CMapPoints* pPoints;
	CMapPoint  *ptFirst,*ptSecond;
	CMapPoint	ptInfint;
	
	iNumber = 0;
	//不在矩形范围内直接返回 
	if ( !m_Extent.IsPointIn(pt) ) 
		  return FALSE;
	//做一条通过pt点的射线
	dblTemp = pt.GetY();
	ptInfint.SetY( dblTemp );
	dblTemp = infinity;
	ptInfint.SetX(dblTemp);
	//获得复合多边形的每一个多边形
	for ( i = 0 ; i < m_Polygon.GetSize() ; i++ )
    {
		pParts = (CMapParts*)m_Polygon.GetAt(i); 
		//获得一个多边形的点集合
		for ( j = 0 ; j < pParts->GetCount() ; j++ )
		{	
			pPoints = (CMapPoints*)pParts->Get(j);
			//获得每个点集合的顶点坐标
			for ( k = 0 ; k < pPoints->GetCount() - 1 ; k++ )
			{
				ptFirst  = (CMapPoint*)pPoints->Get(k);
				ptSecond = (CMapPoint*)pPoints->Get(k+1);
				if (pt.IsPointInLine(*ptFirst,*ptSecond) )
					return TRUE; //该点在多边形边上
                if ( ptSecond->GetY() == ptFirst->GetY() )
					continue;  //略过水平边
				
				if ( ptFirst->IsPointInLine(  pt , ptInfint ))
				{
					//边与射线相交于边第一个顶点
					if ( ptFirst->GetY() > ptSecond->GetY() )
						iNumber++;	
				}
				else if( ptSecond->IsPointInLine( pt , ptInfint ))
				{
					//边与射线相交于边的第二个顶点
					if ( ptFirst->GetY() > ptSecond->GetY() )
					    iNumber++;	
	
				} //判断是否有公共交点
				else if ( isIntersect(pt,ptInfint,*ptFirst,*ptSecond) )
						iNumber++ ; 
			} 
		} 
		
	} 
	if ( iNumber % 2 )
		return TRUE;
    else
	    return FALSE;
}

/*****************************************************************************
  描述:  判断两条直线是否相交 且交点不是顶点
  参数: p1 --- 线段起点 p2 ---线段终点  p3 --- 线段起点 p4 --- 线段终点
  返回值  在直线上 返回TRUE 否则返回FALSE
******************************************************************************/

BOOL CMapPolygon::isIntersect(CMapPoint& p1 , CMapPoint& p2 , CMapPoint& p3 , CMapPoint& p4 )
{
	double dblMulti,dblTmp1,dblTmp2;
	//顶点相交
	if ( p1.IsEqual(p3) || p1.IsEqual(p4) || p2.IsEqual(p3) || p2.IsEqual(p4) )
		return FALSE;
    //判断两条线段外接矩形是否相交
	if ( min(p1.GetX(),p2.GetX()) > max(p3.GetX(),p4.GetX()) || max(p1.GetX(),p2.GetX())
		< min(p3.GetX(),p4.GetX()) || min(p1.GetY(),p2.GetY()) > max(p3.GetY(),p4.GetY())
		|| max(p1.GetY(),p2.GetY()) < min(p3.GetY(),p4.GetY()))
		return FALSE;
    //计算叉积  
	dblTmp1 = (double)((p1.GetX() - p3.GetX())*(p4.GetY()-p3.GetY()) - (p4.GetX()-p3.GetX())*(p1.GetY() - p3.GetY()));
	dblTmp2 = (double)((p4.GetX() -p3.GetX())*(p2.GetY() - p3.GetY()) - (p2.GetX()-p3.GetX())*(p4.GetY()-p3.GetY()));        ;
	dblMulti = dblTmp1 * dblTmp2;
	
	if ( dblMulti >= 0 )
		return TRUE;
	else
		return FALSE;

}