MapPolygon.cpp
上传用户:bjslfz
上传日期:2022-07-25
资源大小:4430k
文件大小:5k
源码类别:

文件操作

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "MapPolygon.h"
  3. IMPLEMENT_DYNAMIC(CMapPolygon,CObject)
  4. CMapPolygon::CMapPolygon()
  5. {
  6. }
  7. CMapPolygon::CMapPolygon(CMapPolygon& mappolygon )
  8. {
  9.    int i,iCount;
  10.    CMapParts *pParts;
  11.    
  12.    iCount = m_Polygon.GetSize() - 1;
  13.    for ( i = 0 ; i <= iCount ; i++ )
  14.    { 
  15. pParts = new CMapParts(*mappolygon.GetParts(i));
  16. m_Polygon.Add(pParts); 
  17.    }
  18. }
  19. CMapPolygon::~CMapPolygon()
  20. {
  21.      Clear();
  22. }
  23. long CMapPolygon::GetCount()
  24. {
  25. return m_Polygon.GetSize(); 
  26. }
  27. CMapRectangle CMapPolygon::GetExtent()
  28. {
  29.     return m_Extent;
  30. }
  31. void CMapPolygon::SetExtent(CMapRectangle& extent)
  32. {
  33. m_Extent.SetLeft( extent.GetLeft());
  34. m_Extent.SetRight( extent.GetRight());
  35. m_Extent.SetTop(extent.GetTop());
  36.     m_Extent.SetBottom(extent.GetBottom());
  37. }
  38. CMapParts* CMapPolygon::GetParts(long lIndex)
  39. {
  40. int iCount;
  41.     CMapParts  *pParts;
  42. iCount = m_Polygon.GetSize()-1;
  43. if ( lIndex < 0 || lIndex > iCount )
  44. return NULL;
  45.     pParts = m_Polygon.GetAt(lIndex);
  46. return pParts;
  47. }
  48. double CMapPolygon::GetArea()
  49. {
  50. return 0;
  51. }
  52. void CMapPolygon::Add(CMapParts* pParts)
  53. {
  54.     if ( pParts == NULL )
  55. return;
  56. m_Polygon.Add( pParts );
  57. }
  58. void CMapPolygon::Set(long lIndex , CMapParts* pParts)
  59. {
  60. int iCount;
  61. CMapParts *pOldParts;
  62. if ( pParts == NULL )
  63. return;
  64. iCount = m_Polygon.GetSize()-1;
  65. if ( lIndex < 0 || lIndex > iCount )
  66. return ;
  67.     pOldParts = m_Polygon.GetAt( lIndex );
  68.     m_Polygon.SetAt(lIndex,pParts);
  69.     delete pOldParts; 
  70. }
  71. void CMapPolygon::Remove(long lIndex)
  72. {
  73. int iCount;
  74. CMapParts *pParts;
  75. iCount = m_Polygon.GetSize()-1;
  76. if ( lIndex < 0 || lIndex > iCount )
  77. return ;
  78. pParts = m_Polygon.GetAt( lIndex );  
  79.     m_Polygon.RemoveAt(lIndex,1);   
  80. delete pParts; 
  81. }
  82. void CMapPolygon::Insert(long lIndex , CMapParts* pParts)
  83. {
  84. int iCount;
  85. iCount = m_Polygon.GetSize()-1;
  86. if ( lIndex < 0 || lIndex > iCount )
  87. return ;
  88. m_Polygon.InsertAt(lIndex,pParts);
  89. }
  90. void CMapPolygon::Clear()
  91. {
  92.    int i,iCount;
  93.    CMapParts *pParts;
  94.    
  95.    iCount = m_Polygon.GetSize() - 1;
  96.    for ( i = iCount ; i >= 0   ; i-- )
  97.    {
  98. pParts = m_Polygon.GetAt(i);
  99. delete pParts;
  100.    } 
  101.    m_Polygon.RemoveAll(); 
  102. }
  103. /*************************************************
  104.   描述:         判断点是否在多边形内 
  105.   输入:         点对象
  106.   输出:        在返回TRUE 不在返回FALSE
  107. *************************************************/
  108. BOOL CMapPolygon::IsPointIn(CMapPoint& pt )
  109. {
  110.     int i,j,k,iNumber;
  111. double dblTemp;
  112. CMapParts*  pParts;
  113. CMapPoints* pPoints;
  114. CMapPoint  *ptFirst,*ptSecond;
  115. CMapPoint ptInfint;
  116. iNumber = 0;
  117. //不在矩形范围内直接返回 
  118. if ( !m_Extent.IsPointIn(pt) ) 
  119.   return FALSE;
  120. //做一条通过pt点的射线
  121. dblTemp = pt.GetY();
  122. ptInfint.SetY( dblTemp );
  123. dblTemp = infinity;
  124. ptInfint.SetX(dblTemp);
  125. //获得复合多边形的每一个多边形
  126. for ( i = 0 ; i < m_Polygon.GetSize() ; i++ )
  127.     {
  128. pParts = (CMapParts*)m_Polygon.GetAt(i); 
  129. //获得一个多边形的点集合
  130. for ( j = 0 ; j < pParts->GetCount() ; j++ )
  131. {
  132. pPoints = (CMapPoints*)pParts->Get(j);
  133. //获得每个点集合的顶点坐标
  134. for ( k = 0 ; k < pPoints->GetCount() - 1 ; k++ )
  135. {
  136. ptFirst  = (CMapPoint*)pPoints->Get(k);
  137. ptSecond = (CMapPoint*)pPoints->Get(k+1);
  138. if (pt.IsPointInLine(*ptFirst,*ptSecond) )
  139. return TRUE; //该点在多边形边上
  140.                 if ( ptSecond->GetY() == ptFirst->GetY() )
  141. continue;  //略过水平边
  142. if ( ptFirst->IsPointInLine(  pt , ptInfint ))
  143. {
  144. //边与射线相交于边第一个顶点
  145. if ( ptFirst->GetY() > ptSecond->GetY() )
  146. iNumber++;
  147. }
  148. else if( ptSecond->IsPointInLine( pt , ptInfint ))
  149. {
  150. //边与射线相交于边的第二个顶点
  151. if ( ptFirst->GetY() > ptSecond->GetY() )
  152.     iNumber++;
  153. } //判断是否有公共交点
  154. else if ( isIntersect(pt,ptInfint,*ptFirst,*ptSecond) )
  155. iNumber++ ; 
  156. if ( iNumber % 2 )
  157. return TRUE;
  158.     else
  159.     return FALSE;
  160. }
  161. /*****************************************************************************
  162.   描述:  判断两条直线是否相交 且交点不是顶点
  163.   参数: p1 --- 线段起点 p2 ---线段终点  p3 --- 线段起点 p4 --- 线段终点
  164.   返回值  在直线上 返回TRUE 否则返回FALSE
  165. ******************************************************************************/
  166. BOOL CMapPolygon::isIntersect(CMapPoint& p1 , CMapPoint& p2 , CMapPoint& p3 , CMapPoint& p4 )
  167. {
  168. double dblMulti,dblTmp1,dblTmp2;
  169. //顶点相交
  170. if ( p1.IsEqual(p3) || p1.IsEqual(p4) || p2.IsEqual(p3) || p2.IsEqual(p4) )
  171. return FALSE;
  172.     //判断两条线段外接矩形是否相交
  173. if ( min(p1.GetX(),p2.GetX()) > max(p3.GetX(),p4.GetX()) || max(p1.GetX(),p2.GetX())
  174. < min(p3.GetX(),p4.GetX()) || min(p1.GetY(),p2.GetY()) > max(p3.GetY(),p4.GetY())
  175. || max(p1.GetY(),p2.GetY()) < min(p3.GetY(),p4.GetY()))
  176. return FALSE;
  177.     //计算叉积  
  178. dblTmp1 = (double)((p1.GetX() - p3.GetX())*(p4.GetY()-p3.GetY()) - (p4.GetX()-p3.GetX())*(p1.GetY() - p3.GetY()));
  179. dblTmp2 = (double)((p4.GetX() -p3.GetX())*(p2.GetY() - p3.GetY()) - (p2.GetX()-p3.GetX())*(p4.GetY()-p3.GetY()));        ;
  180. dblMulti = dblTmp1 * dblTmp2;
  181. if ( dblMulti >= 0 )
  182. return TRUE;
  183. else
  184. return FALSE;
  185. }