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

文件操作

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include <d3dtypes.h>
  3. #include "shpFile.h"
  4. #include "MapPoint.h"
  5. #include "MapPoints.h"
  6. #include "MapLine.h"
  7. #include "MapPolygon.h"
  8. #include "MapFields.h"
  9. CShpFile::CShpFile() 
  10. {
  11. int i;
  12. bShpOpen = FALSE;
  13. bShxOpen = FALSE;
  14. m_shpType = NULLSHP;
  15. /* -------------------------------------------------------------------- */
  16.             /* Establish the byte order on this machine. */
  17.     /* -------------------------------------------------------------------- */
  18.     i = 1;
  19.     if( *((uchar *) &i) == 1 )
  20. m_bBigEndian = FALSE;
  21. else
  22. m_bBigEndian = TRUE;
  23. }
  24. CShpFile::~CShpFile()
  25. {
  26.  CMapPoint*    pPt;
  27.  CMapPoints*   pPts;
  28.  CMapLine*     pLine;
  29.  CMapPolygon*  pPolygon;
  30.  while(!m_ObList.IsEmpty())
  31.  {
  32. switch ( m_shpType )
  33.         {  
  34. case POINT:
  35. pPt =(CMapPoint*)m_ObList.RemoveTail();
  36. delete pPt;
  37. break;
  38.             case MULTIPOINT:
  39. pPts =(CMapPoints*)m_ObList.RemoveTail();
  40. delete pPts;
  41. break;
  42. case POLYLINE:
  43.                 pLine =(CMapLine*)m_ObList.RemoveTail();
  44. delete pLine;
  45. break;
  46. case POLYGON:
  47.                 pPolygon =(CMapPolygon*)m_ObList.RemoveTail();
  48. delete pPolygon;
  49. break;
  50.             default:
  51. m_ObList.RemoveTail();
  52. break;
  53.  
  54. }
  55.      }    
  56.  if ( bShpOpen )
  57. fShp.Close();
  58.  if (bShxOpen)
  59. fShx.Close();
  60.  if ( pRecordSet )
  61.  delete pRecordSet;
  62.  
  63. }
  64. /*************************************************
  65.   描述:         读入Shp、shx文件 格式 参阅ESRI技术白皮书
  66.   输入:         文件名(全路径) 
  67.   输出:        成功返回TRUE 失败返回FALSE
  68. *************************************************/
  69. BOOL CShpFile::ReadShp(CString& csFileName)
  70. {
  71. int   iTemp;
  72. CString csShxName;
  73. CFileException fe;
  74.     SHPHEADER varHeader;
  75. //打开主文件
  76. if ( !fShp.Open(csFileName, CFile::modeRead|CFile::shareDenyWrite,&fe))
  77. return FALSE;
  78. bShpOpen = TRUE;
  79.     
  80. //打开索引文件
  81. csShxName = csFileName.Left(csFileName.GetLength() - 3);
  82. csShxName = csShxName + "shx";
  83.     if ( !fShx.Open(csShxName, CFile::modeRead|CFile::shareDenyWrite,&fe))
  84. return FALSE;
  85. bShxOpen = TRUE;
  86.        
  87. TRY
  88.     {
  89.     //读主文件头 长100字节
  90. if ( fShp.Read(&varHeader , sizeof(SHPHEADER))!= sizeof(SHPHEADER))
  91. return FILE_READERR;
  92.         iTemp = varHeader.iFileCode; 
  93. if ( !m_bBigEndian )
  94. SwapWord(sizeof(int),&iTemp);
  95. if ( iTemp != 9994 ) //是否是shp文件
  96. return FILE_CODEERR;
  97.         if ( varHeader.iVersion != FILE_VERSION ) //文件版本是否正确
  98. return FILE_VERSIONERR;
  99.         
  100. //shp 类型  
  101. m_shpType = varHeader.iShpType;  
  102. m_shpFileLength = varHeader.iFileLength;
  103.     if ( !m_bBigEndian )
  104. SwapWord(sizeof(int),&m_shpFileLength);
  105. //保存数据最大矩形范围
  106. m_Extent.SetLeft(varHeader.dbXMin);
  107. m_Extent.SetRight(varHeader.dbXMax);
  108. m_Extent.SetTop(varHeader.dbYMin);
  109. m_Extent.SetBottom(varHeader.dbYMax);
  110.         
  111. //读索引文件头 长100字节
  112. if ( fShx.Read(&varHeader , sizeof(SHPHEADER))!= sizeof(SHPHEADER))
  113. return FILE_READERR;
  114. iTemp = varHeader.iFileCode; 
  115. if ( !m_bBigEndian )
  116. SwapWord(sizeof(int),&iTemp);
  117. if ( iTemp != 9994 ) //是否是shx文件
  118. return FILE_CODEERR;
  119.         if ( varHeader.iVersion != FILE_VERSION ) //文件版本是否正确
  120. return FILE_VERSIONERR;
  121. m_shxFileLength = varHeader.iFileLength; 
  122. if ( !m_bBigEndian )
  123. SwapWord(sizeof(int),&m_shxFileLength);
  124. //通过索引文件计算主文件记录个数 文件长度数值以16位计
  125. m_iRecordCount = ((m_shxFileLength - 50 )*2)/sizeof(SHXRECORD);
  126. if ( !ReadRecord() )
  127. return FILE_READERR;
  128.          if ( !ReadDBF(csFileName))
  129.  return FALSE;
  130. }
  131. CATCH(CFileException ,eload)
  132.     {
  133. fShp.Abort();
  134. return FALSE;
  135.     }
  136. END_CATCH
  137. return TRUE;
  138. }
  139. /*************************************************
  140.   描述:         读入DBF文件格式 
  141.   输入:         文件名(全路径) 
  142.   输出:        成功返回TRUE 失败返回FALSE
  143. *************************************************/
  144. BOOL CShpFile::ReadDBF(CString& csFileName)
  145. {
  146. CString csDbfName;
  147. BOOL bResult;
  148. //创建记录集对象
  149. pRecordSet = new CMapRecordSet;
  150. ASSERT ( pRecordSet != NULL ); 
  151. csDbfName = csFileName.Left(csFileName.GetLength() - 3);
  152. csDbfName = csDbfName + "dbf";
  153. //打开DBF文件
  154. bResult =  pRecordSet->openDBF(csDbfName); 
  155.     if ( !bResult )
  156. delete pRecordSet;
  157. return bResult;
  158. }
  159. /*************************************************
  160.   描述:         获得当前地图文件最大矩形范围 
  161.   输入:         无
  162.   输出:        地图矩形范围   
  163. *************************************************/
  164. CMapRectangle CShpFile::GetExtent()
  165. {
  166. return m_Extent;
  167. }
  168. /*************************************************
  169.   描述:         设置地图文件最大矩形范围 
  170.   输入:         地图矩形范围
  171.   输出:        无   
  172. *************************************************/
  173. void CShpFile::SetExtent(CMapRectangle& extent )
  174. {
  175. m_Extent.SetLeft(extent.GetLeft());  
  176.     m_Extent.SetRight(extent.GetRight());
  177. m_Extent.SetTop(extent.GetTop()); 
  178.     m_Extent.SetBottom(extent.GetBottom());
  179. }
  180. /*************************************************
  181.   描述:         设置Shp对象类型 
  182.   输入:         shp 类型
  183.   输出:        无   
  184. *************************************************/
  185. void CShpFile::SetShpType(int& iShpType)
  186. {
  187. m_shpType = iShpType;
  188. }
  189. /*************************************************
  190.   描述:         读入Shp对象坐标 
  191.   输入:         无
  192.   输出:        成功返回TRUE 失败返回FALSE  
  193. *************************************************/
  194. BOOL CShpFile::ReadRecord()
  195. {
  196. int i,j,k,m;
  197. int iDataLen,iLength,iIndex;
  198. int *pIParts;
  199. double dbTmp;
  200. char *pszBuffer,*lpVer;
  201. BOOL bEof;
  202. SHPINFO shpIn;
  203. SHPRECORDHEADER RecordHeader;
  204.     CMapRectangle objRectangle;
  205.     CMapPoint   *pPoint;
  206. CMapPoints  *pPoints;
  207. CMapParts   *pParts;
  208. CMapLine    *pLine;
  209. CMapPolygon *pPolygon;
  210. bEof = FALSE;
  211. switch ( m_shpType )
  212. {
  213. case NULLSHP:
  214. return FALSE;
  215. break;
  216.         case POINT:
  217. {
  218. SHPPTCONTENT point;
  219. //读入点记录
  220. for ( i = 1 ; i <= m_iRecordCount ; i++ ) 
  221. {
  222. iLength = SetRecordPos(i);
  223. if ( iLength <= 0 )
  224. return FALSE;
  225. //获得记录头信息
  226. if (!GetRecordHeader(RecordHeader))
  227. return FALSE;
  228. //记录内容长度是否与shp实体大小一致,索引记录长度是否与记录内容长度一致
  229. if ( RecordHeader.iContentLength*2 != sizeof(point)||
  230. RecordHeader.iContentLength*2 != iLength)
  231. return FALSE;
  232. if(fShp.Read(&point,sizeof(point))!= sizeof(point))
  233. return FALSE;
  234. pPoint = new CMapPoint;
  235. iIndex = i - 1;
  236.     pPoint->SetIndex(iIndex); 
  237. if ( pPoint == NULL )
  238. return FALSE;
  239. //类型是否匹配
  240. if ( point.iShpType != m_shpType) 
  241. return FALSE;
  242.                     pPoint->SetX(point.dbX );
  243. pPoint->SetY(point.dbY );
  244. m_ObList.AddTail(pPoint);  
  245.     
  246.  } 
  247. break;
  248.         case POLYLINE:
  249.     
  250. pszBuffer = new char [MAX_BUFFER_SIZE]; //分配缓冲区
  251. if ( pszBuffer == NULL )
  252. return FALSE;
  253. memset(pszBuffer , 0 , MAX_BUFFER_SIZE);
  254.             
  255. //读入线记录
  256. for ( i = 1 ; i <= m_iRecordCount ; i++ ) //m_iRecordCount
  257. {
  258. iLength = SetRecordPos(i);
  259. if ( iLength <= 0 )
  260. return FALSE;
  261. pLine = new CMapLine();
  262. iIndex = i - 1;
  263. pLine->SetIndex(iIndex); 
  264. if ( pLine == NULL )
  265. return FALSE;
  266. //获得记录头信息
  267. if (!GetRecordHeader(RecordHeader))
  268. return FALSE;
  269. if ( !GetShpInfo(shpIn))
  270. return FALSE;
  271.  if (shpIn.ishpType != POLYLINE )//类型不匹配
  272.                  {  
  273.                       delete pLine;
  274.   continue;
  275.  }
  276.  if ( shpIn.iNumParts*sizeof(int) > MAX_BUFFER_SIZE )
  277.                  {
  278.  //多义线段数大于最大缓冲区长度,忽略该对象
  279.  delete pLine;
  280.  continue;
  281.                  } 
  282.  //计算对象内容实际长度
  283.  j = sizeof(SHPINFO) + shpIn.iNumParts*sizeof(int) ;
  284.  j += shpIn.iNumPoints*sizeof(SHPPOINT);  
  285.                  
  286.  //判断实际长度是否与索引文件中记录的一致 
  287.  if ( RecordHeader.iContentLength*2 != j )
  288.                  {
  289.      delete pLine;
  290.  continue;
  291.  }  
  292.  //设置shp矩形范围
  293.  objRectangle.SetLeft(shpIn.Box[0].dbX);
  294.  objRectangle.SetTop(shpIn.Box[0].dbY);
  295.  objRectangle.SetRight(shpIn.Box[1].dbX);
  296.  objRectangle.SetBottom(shpIn.Box[1].dbY);
  297.  pLine->SetExtent(objRectangle);
  298.  pIParts = new int[shpIn.iNumParts];
  299.  if ( pIParts == NULL )
  300.                  {
  301. delete pLine;
  302. return FALSE;
  303.  }
  304.  //读入多义线段索引
  305.  if ( fShp.Read(pIParts,shpIn.iNumParts*4) != (uint)(shpIn.iNumParts*4))
  306.  {
  307. delete pLine;
  308. return FALSE;
  309.  }
  310.  //点坐标存储所占字节数
  311.  iLength = shpIn.iNumPoints*sizeof(SHPPOINT);
  312.  //初始化缓冲区数据
  313.  iDataLen = ReadPoint(pszBuffer,iLength,bEof);
  314.  if ( iDataLen < 0 )
  315.                  {
  316.   delete pLine;
  317.   delete pIParts;
  318.   return FALSE;
  319.  
  320.  }  
  321.  lpVer = pszBuffer;
  322.  for ( j = 0 ;  j < shpIn.iNumParts ; j++ )
  323.  {
  324. pParts  = new CMapParts();
  325. pPoints = new CMapPoints();
  326.   if ( pParts == NULL || pPoints == NULL)
  327. return FALSE;
  328. if ( j == shpIn.iNumParts - 1 )
  329.                     {
  330.     k = pIParts[j];        //本段第一个顶点索引
  331.     m = shpIn.iNumPoints ; //下一个段第一个顶点索引 
  332.                     }
  333.                    else
  334.                     {
  335. k = pIParts[j];
  336. m = pIParts[j+1];
  337. }
  338. //处理第i段的顶点
  339.     for ( ; k < m ; k++)
  340.                     {   
  341. pPoint = new CMapPoint();
  342. if ( pPoint == NULL )
  343. return FALSE;
  344. //需要读入数据更新缓冲区
  345. if ( lpVer == pszBuffer + iDataLen && !bEof)
  346. {
  347. iDataLen = ReadPoint(pszBuffer,iLength,bEof);
  348. if ( iDataLen < 0 )
  349. {
  350. delete pPoint;
  351. delete pPoints;
  352. delete pLine;
  353. delete pIParts;
  354. return FALSE;
  355.  
  356. }  
  357. lpVer = pszBuffer;
  358. }
  359. dbTmp = *(double*)lpVer;
  360.     pPoint->SetX(dbTmp);
  361.                         lpVer += 8;
  362. //需要读入数据更新缓冲区
  363. if ( lpVer == pszBuffer + iDataLen && !bEof)
  364. {
  365. iDataLen = ReadPoint(pszBuffer,iLength,bEof);
  366. if ( iDataLen < 0 )
  367. {
  368. delete pPoint;
  369. delete pPoints;
  370. delete pLine;
  371. delete pIParts;
  372. return FALSE;
  373.  
  374. }  
  375. lpVer = pszBuffer;
  376. }
  377. dbTmp = *(double*)(lpVer);
  378. lpVer += 8;
  379.                         pPoint->SetY(dbTmp); 
  380. pPoints->Add(pPoint); 
  381. }  
  382.                     pParts->Add(pPoints);   
  383.     pLine->Add(pParts); 
  384.  }
  385.  m_ObList.AddTail( pLine);
  386.  delete []pIParts;
  387.             }
  388. delete []pszBuffer;
  389. break;
  390.         case POLYGON:
  391. pszBuffer = new char [MAX_BUFFER_SIZE]; //分配缓冲区
  392. if ( pszBuffer == NULL )
  393. return FALSE;
  394. memset(pszBuffer , 0 , MAX_BUFFER_SIZE);
  395.             
  396. //读入多边形记录
  397. for ( i = 1 ; i <= m_iRecordCount ; i++ ) //m_iRecordCount
  398. {
  399. iLength = SetRecordPos(i);
  400. if ( iLength <= 0 )
  401. return FALSE;
  402. pPolygon = new CMapPolygon();
  403. iIndex = i - 1;
  404.                 pPolygon->SetIndex(iIndex);
  405. if (pPolygon == NULL )
  406. return FALSE;
  407. //获得记录头信息
  408. if (!GetRecordHeader(RecordHeader))
  409. return FALSE;
  410. if ( !GetShpInfo(shpIn))
  411. return FALSE;
  412.  if (shpIn.ishpType != POLYGON )//类型不匹配
  413.                  {  
  414.                       delete pPolygon;
  415.   continue;
  416.  }
  417.  if ( shpIn.iNumParts*sizeof(int) > MAX_BUFFER_SIZE )
  418.                  {
  419.  //复合多边型中的多边形个数大于最大缓冲区长度,忽略该对象
  420.  delete pPolygon;
  421.  continue;
  422.                  } 
  423.  //计算对象内容实际长度
  424.  j = sizeof(SHPINFO) + shpIn.iNumParts*sizeof(int) ;
  425.  j += shpIn.iNumPoints*sizeof(SHPPOINT);  
  426.                  
  427.  //判断实际长度是否与索引文件中记录的一致 
  428.  if ( RecordHeader.iContentLength*2 != j )
  429.                  {
  430.      delete pPolygon;
  431.  continue;
  432.  }  
  433.  //设置shp矩形范围
  434.  objRectangle.SetLeft(shpIn.Box[0].dbX);
  435.  objRectangle.SetTop(shpIn.Box[0].dbY);
  436.  objRectangle.SetRight(shpIn.Box[1].dbX);
  437.  objRectangle.SetBottom(shpIn.Box[1].dbY); 
  438.  pPolygon->SetExtent(objRectangle);
  439.  pIParts = new int[shpIn.iNumParts];
  440.  if ( pIParts == NULL )
  441.                  {
  442. delete pPolygon;
  443. return FALSE;
  444.  }
  445.  //读入复合多边型段索引
  446.  if ( fShp.Read(pIParts,shpIn.iNumParts*4) != (uint)(shpIn.iNumParts*4))
  447.  {
  448. delete pPolygon;
  449. return FALSE;
  450.  }
  451.  //点坐标存储所占字节数
  452.  iLength = shpIn.iNumPoints*sizeof(SHPPOINT);
  453.  //初始化缓冲区数据
  454.  iDataLen = ReadPoint(pszBuffer,iLength,bEof);
  455.  if ( iDataLen < 0 )
  456.                  {
  457.   delete pPolygon;
  458.   delete pIParts;
  459.   return FALSE;
  460.  
  461.  }  
  462.  lpVer = pszBuffer;
  463.  for ( j = 0 ;  j < shpIn.iNumParts ; j++ )
  464.  {
  465. pParts  = new CMapParts();
  466. pPoints = new CMapPoints();
  467.   if ( pParts == NULL || pPoints == NULL)
  468. return FALSE;
  469. if ( j == shpIn.iNumParts - 1 )
  470.                     {
  471.     k = pIParts[j];        //本段第一个顶点索引
  472.     m = shpIn.iNumPoints ; //下一个段第一个顶点索引 
  473.                     }
  474.                    else
  475.                     {
  476. k = pIParts[j];
  477. m = pIParts[j+1];
  478. }
  479. //处理第i段的顶点
  480.     for ( ; k < m ; k++)
  481.                     {   
  482. pPoint = new CMapPoint();
  483. if ( pPoint == NULL )
  484. return FALSE;
  485. //需要读入数据更新缓冲区
  486. if ( lpVer == pszBuffer + iDataLen && !bEof)
  487. {
  488. iDataLen = ReadPoint(pszBuffer,iLength,bEof);
  489. if ( iDataLen < 0 )
  490. {
  491. delete pPolygon;
  492. delete pIParts;
  493. return FALSE;
  494.  
  495. }  
  496. lpVer = pszBuffer;
  497. }
  498. dbTmp = *(double*)lpVer;
  499.     pPoint->SetX(dbTmp);
  500.                         lpVer += 8;
  501. //需要读入数据更新缓冲区
  502. if ( lpVer == pszBuffer + iDataLen && !bEof)
  503. {
  504. iDataLen = ReadPoint(pszBuffer,iLength,bEof);
  505. if ( iDataLen < 0 )
  506. {
  507. delete pPolygon;
  508. delete pIParts;
  509. return FALSE;
  510.  
  511. }  
  512. lpVer = pszBuffer;
  513. }
  514. dbTmp = *(double*)(lpVer);
  515.                         pPoint->SetY(dbTmp); 
  516. pPoints->Add(pPoint); 
  517. lpVer += 8;
  518. }  
  519.                     pParts->Add(pPoints);   
  520.     pPolygon->Add(pParts); 
  521.  }
  522.  m_ObList.AddTail( pPolygon);
  523.      delete []pIParts;
  524.             }
  525. delete []pszBuffer;
  526. break;
  527. default:
  528. return FALSE;
  529. break;
  530.     }    
  531. return TRUE;   
  532. }
  533. /*************************************************
  534.   描述:         计算每条shp对象相对文件头的偏移量
  535.   输入:         记录索引值(从零开始)
  536.   输出:        该shp对象数据在文件中的位置  
  537. *************************************************/
  538. int CShpFile::SetRecordPos( int iRecord )
  539. {
  540.     unsigned int iOffset,iTmp;
  541. SHXRECORD shxRD;
  542. if ( iRecord < 0 )
  543. return 0;
  544.     //获得索引文件记录偏移量相对文件头
  545. if (iRecord == 1 )
  546.      iOffset = sizeof(SHPHEADER)  ;  
  547. else
  548. iOffset = sizeof(SHPHEADER) + (iRecord-1)*sizeof(shxRecord) ;
  549. if ( iOffset > m_shxFileLength*2 - sizeof(shxRecord) )
  550. return 0;
  551. fShx.Seek( iOffset , CFile::begin );
  552. int m = sizeof(shxRD);
  553. fShx.Read( &shxRD , sizeof(shxRD));
  554. iTmp = shxRD.iOffset;
  555. SwapWord(sizeof(int),&iTmp);
  556. fShp.Seek(iTmp*2 ,  CFile::begin );
  557. iTmp = shxRD.iContentLength;
  558. SwapWord(sizeof(int),&iTmp);
  559.    
  560. return iTmp*2;
  561. }
  562. /*************************************************
  563.   描述:         获得每条shp对象记录记录头的信息
  564.   输入:         记录头结构对象
  565.   输出:        成功返回TRUE 失败返回FALSE    
  566. *************************************************/
  567. BOOL CShpFile::GetRecordHeader(SHPRECORDHEADER& RecordHeader )
  568. {
  569. int iLength,iNum;
  570. if(fShp.Read(&RecordHeader,sizeof(RecordHeader))!= sizeof(RecordHeader))
  571. return FALSE;
  572. if ( !m_bBigEndian )
  573.     {  
  574. iNum    = RecordHeader.iRecordNum;
  575.         iLength = RecordHeader.iContentLength;
  576. SwapWord(sizeof(int),&iLength);
  577. SwapWord(sizeof(int),&iNum);
  578. RecordHeader.iRecordNum = iNum;
  579.         RecordHeader.iContentLength = iLength;
  580. }
  581.     return TRUE;
  582. }
  583. /*************************************************
  584.   描述:         获得每条shp对象描述信息
  585.   输入:         描述信息结构对象
  586.   输出:        成功返回TRUE 失败返回FALSE    
  587. *************************************************/
  588. BOOL CShpFile::GetShpInfo(SHPINFO& varInfo)
  589. {
  590. if(fShp.Read(&varInfo,sizeof(varInfo))!= sizeof(varInfo))
  591. return FALSE;
  592. return TRUE;
  593. }
  594. /*************************************************
  595.   描述:         读入点对象数据
  596.   输入:         数据缓冲区指针 缓冲区最大32K 
  597.                 如果超出需要分多次读取,要读取的长度、
  598. 是否已读取完成
  599.   输出:        读取数据的实际长度   
  600. *************************************************/
  601. int  CShpFile::ReadPoint(char* pszBuffer,int& iLength,BOOL& bEof)
  602. {
  603. if ( iLength > MAX_BUFFER_SIZE)
  604.     {
  605. iLength -= MAX_BUFFER_SIZE;
  606. if ( fShp.Read(pszBuffer,MAX_BUFFER_SIZE) != MAX_BUFFER_SIZE )
  607. return FILE_READERR;
  608. bEof = FALSE;
  609. return MAX_BUFFER_SIZE;
  610.     }
  611.     else
  612.     {   
  613. if ( fShp.Read(pszBuffer,iLength) != (uint)iLength )
  614. return FILE_READERR;
  615. bEof = TRUE;
  616. return iLength;
  617. }     
  618. }
  619. /*************************************************
  620.   描述:         根据点对象查找shp对象是否选中
  621.   输入:         点对象
  622.   输出:        查找到shp对象的索引值 返回值-表示未查找到   
  623. *************************************************/
  624. int CShpFile::SearchShape(CMapPoint& pt )
  625. {
  626. unsigned long iCount;
  627. POSITION pos;
  628.     CMapPolygon *pPolygon;
  629. if ( GetShpType() != POLYGON ) //只判断多边形对象
  630. return -1;
  631. iCount = m_ObList.GetCount()-1;
  632. for ( pos = m_ObList.GetHeadPosition()  ; pos != NULL ;  )
  633.     {
  634. pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
  635. if ( pPolygon->IsPointIn(pt) )
  636.   return pPolygon->GetIndex(); 
  637. m_ObList.GetNext(pos); 
  638.     } 
  639. return -1;
  640. }
  641. /*************************************************
  642.   描述:         绘制shp对象
  643.   输入:         设备指针、图例对象指针、坐标变换参数结构对象
  644.   输出:        无
  645. *************************************************/
  646. void CShpFile::DrawShp(CDC*pDC ,  CMapRender* m_pRender , DrawParam& draw )
  647.  {           
  648.     
  649.  int iDrawMode;
  650.  //计算当前屏幕的实际坐标范围
  651.  m_CurMapExtent.SetLeft(draw.m_StartX );
  652.  m_CurMapExtent.SetBottom(draw.m_StartY);
  653.  m_CurMapExtent.SetRight(draw.m_StartX + draw.m_ScreenWidth * draw.m_Scale);
  654.  m_CurMapExtent.SetTop(draw.m_StartY - draw.m_ScreenHeigh *draw.m_Scale);  
  655.  
  656.  //设置绘制模式
  657.  iDrawMode = pDC->SetROP2(R2_COPYPEN);
  658.  
  659.  switch ( m_shpType )
  660.      {
  661.  case POINT: 
  662. {
  663.                 DrawPoint(pDC , m_pRender ,  draw );
  664. }
  665. break;
  666.          case POLYLINE: 
  667. {
  668.     DrawPLine(pDC , m_pRender ,  draw );
  669.             break;
  670.  case POLYGON: 
  671. {
  672.     DrawPolygon(pDC , m_pRender ,  draw );
  673. }  
  674.     break;     
  675.         default:
  676. break;
  677.  }
  678.  pDC->SetROP2(iDrawMode);
  679.  //int r = RGB_GETRED(16773020);
  680.  //int g = RGB_GETGREEN(16773020);
  681.  //int b = RGB_GETBLUE(16773020);
  682.     
  683.  
  684.  }
  685. /*************************************************
  686.   描述:         对选中的shp对象闪烁
  687.   输入:         设备指针、坐标变换参数结构对象、
  688.                 shp对象的索引值
  689.   输出:        无
  690. *************************************************/
  691. void  CShpFile::FlashShp(CDC*pDC , DrawParam& draw , int iIndex)
  692. {
  693.  int i,j,k,m,iCount,iDrawMode;
  694.  CMapPoint *pPoint;
  695.  CMapPoints *pPoints;
  696.  CMapParts *pParts;
  697.  //CMapLine  *pPline;
  698.  CMapPolygon *pPolygon;
  699.  CMapRectangle MapExtent;
  700.  CPoint    *pPtArray;  //顶点数组
  701.  int       *pPolygonCount; //每个多边型的顶点数组
  702.  CRect  rc;
  703.  POSITION pos;
  704.  CBrush br1(RGB(0,0,0));
  705.      CBrush br2(RGB(255,255,255));
  706.  CBrush *pOldBrush;
  707.   if ( iIndex < 0 )
  708.   return;
  709.  iDrawMode = pDC->SetROP2(R2_XORPEN);
  710.  switch ( m_shpType )
  711.  {
  712. case POINT: {
  713. }
  714. break;
  715. case POLYLINE: {
  716.    }
  717.         break; 
  718. case POLYGON: {
  719. for ( pos = m_ObList.GetHeadPosition()  ; pos != NULL ;  )
  720. {
  721. pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
  722.         if (iIndex == (int) pPolygon->GetIndex() )
  723. {
  724. iCount = pPolygon->GetCount(); //多边形个数
  725.                     pPolygonCount = new int[iCount];
  726. if ( pPolygonCount == NULL )
  727. return;
  728. //计算复合多边型每部分的顶点数,和总顶点数
  729. for ( m= 0,i = 0 ; i < pPolygon->GetCount() ; i++ )
  730. {
  731. pParts =  pPolygon->GetParts(i);
  732. k = 0;
  733. for ( j = 0 ; j < pParts->GetCount() ; j++)
  734. {
  735. pPoints = pParts->Get(j); 
  736.                             k += pPoints->GetCount();
  737. pPolygonCount[i] = k;
  738. m += k;
  739. }
  740. pPtArray = new CPoint[m];
  741.                     if ( pPtArray == NULL )
  742.                     { 
  743. delete []pPolygonCount;
  744. return ;
  745. }
  746. for ( m= 0 , i = 0 ; i < pPolygon->GetCount() ; i++ )
  747. {
  748. pParts =  pPolygon->GetParts(i);
  749. for ( j = 0 ; j < pParts->GetCount() ; j++)
  750. {
  751. pPoints = pParts->Get(j); 
  752.                             for ( k = 0 ; k < pPoints->GetCount(); k++ )
  753.                             {
  754. pPoint = pPoints->Get(k); 
  755. pPtArray[m].x = (int)((pPoint->GetX() - draw.m_StartX)/draw.m_Scale);
  756.                                 pPtArray[m++].y =  (long)((draw.m_StartY - pPoint->GetY() )/draw.m_Scale);
  757. }
  758. }
  759. pOldBrush = pDC->SelectObject(&br1); 
  760. if ( pPolygon->GetCount() > 1)
  761.                     { 
  762. pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
  763.                         i = 0;
  764. while ( i < 150000 )
  765.                         {
  766. i++;
  767. }
  768. pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
  769. pDC->SelectObject(&br2);
  770. pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
  771. i = 0;
  772. while ( i < 350000 ) //延时
  773.                         {
  774. i++;
  775. }
  776. pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
  777. }
  778. else
  779.                     {      
  780.    pDC->Polygon(pPtArray, m);
  781.    i = 0;
  782.    while ( i < 150000 )
  783.                        {
  784. i++;
  785.    }
  786.    pDC->Polygon(pPtArray, m);
  787.    pDC->SelectObject(&br2);
  788.    pDC->Polygon(pPtArray, m);
  789.    i = 0;
  790.    while ( i < 350000 )
  791.                        {
  792. i++;
  793.    }
  794.    pDC->Polygon(pPtArray, m);
  795. }
  796. delete []pPolygonCount;
  797. delete []pPtArray;
  798.                     pDC->SelectObject(pOldBrush); 
  799. break;   
  800.                 }
  801. m_ObList.GetNext(pos); 
  802. }
  803. break;
  804.         default:
  805. break;
  806.  } 
  807.  pDC->SetROP2(iDrawMode); 
  808. }
  809. /*************************************************
  810.   描述:         绘制点对象
  811.   输入:         设备指针、图例对象指针、坐标变换参数结构对象
  812.   输出:        无
  813. *************************************************/
  814. void CShpFile::DrawPoint(CDC*pDC ,  CMapRender* m_pRender , DrawParam& draw )
  815. {
  816. int    iIndex,iField;
  817. CBrush *pOldBrush;
  818. SIMPLERENDER simpleRender;
  819. CBrush brSimple;
  820. CPen   pen;
  821. CBrush br(RGB(255,239,156));
  822. CMapFields *pFields;
  823.     CMapField  *pField;
  824.     CMapPoint *pPoint;
  825. POSITION pos;
  826. CString csValue;
  827. RENDERINFO *rInfo;
  828. if ( m_pRender == NULL )
  829.     {
  830. pOldBrush = pDC->SelectObject(&br);
  831. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  832. {  
  833. pPoint = (CMapPoint*)m_ObList.GetAt(pos);
  834. //判断要绘制的的对象是否在当前屏幕范围内
  835. if ( !m_CurMapExtent.IsPointIn(*pPoint)) 
  836.             {
  837. m_ObList.GetNext(pos);
  838. continue;
  839.             }
  840. DrawPointElement(pDC,pPoint,draw );
  841. m_ObList.GetNext(pos);
  842. }
  843. pDC->SelectObject(pOldBrush);
  844. } else if ( m_pRender->GetRenderType() == SIMPLE_RENDER )
  845. {
  846. m_pRender->GetSimpleRender(simpleRender);
  847. //pen.CreatePen(PS_SOLID,1,simpleRender.OutlineColor);
  848. if ( simpleRender.iIndex == 0 )
  849.         {  
  850.          brSimple.CreateSolidBrush(simpleRender.FillColor);
  851. pOldBrush = pDC->SelectObject(&brSimple);
  852.         }
  853.         else
  854. {
  855.    if (!brSimple.CreateHatchBrush( simpleRender.iIndex,
  856.                                simpleRender.FillColor))
  857.    { 
  858.   pOldBrush = pDC->SelectObject(&br);
  859.    } 
  860.    else
  861.            {
  862.   pOldBrush = pDC->SelectObject(&brSimple);
  863.    }   
  864. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  865. {  
  866. pPoint = (CMapPoint*)m_ObList.GetAt(pos);
  867. if ( !m_CurMapExtent.IsPointIn(*pPoint)) 
  868.             {
  869. m_ObList.GetNext(pos);
  870. continue;
  871.             }
  872. DrawPointElement(pDC,pPoint,draw );
  873. m_ObList.GetNext(pos);
  874. }
  875. pDC->SelectObject(pOldBrush);
  876. pen.DeleteObject();
  877. brSimple.DeleteObject(); 
  878.         
  879.     } 
  880. else if ( m_pRender->GetRenderType() == UNIQUE_RENDER )
  881.     { 
  882. iField = m_pRender->GetFieldIndex();
  883. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  884. {  
  885. pPoint = (CMapPoint*)m_ObList.GetAt(pos);
  886. if ( !m_CurMapExtent.IsPointIn(*pPoint)) 
  887.             {
  888. m_ObList.GetNext(pos);
  889. continue;
  890.             }
  891.             iIndex = pPoint->GetIndex();
  892.             pRecordSet->Move(iIndex,BookmarkFirst);
  893. pFields = pRecordSet->GetFields(0);
  894. if ( iField >= 0 && iField < pFields->GetCout())   
  895. {  
  896. pField = pFields->GetField(iField);
  897. csValue = pField->GetValueAsString();
  898. rInfo = m_pRender->GetByValue(csValue);
  899. ASSERT(rInfo);
  900. CBrush brush(rInfo->clr); 
  901.     pOldBrush = pDC->SelectObject(&brush);
  902.     DrawPointElement(pDC,pPoint,draw );
  903.                 pDC->SelectObject(pOldBrush);
  904. }
  905. m_ObList.GetNext(pos);
  906. }
  907. }
  908. }
  909. /*************************************************
  910.   描述:         绘制单个的点对象
  911.   输入:         设备指针、点对象对象指针、
  912.                 坐标变换参数结构对象
  913.   输出:        无
  914. *************************************************/
  915. void CShpFile::DrawPointElement(CDC*pDC,CMapPoint *pPoint, DrawParam& draw )
  916. {
  917. int iX,iY;
  918. CRect rc;
  919. if ( pPoint == NULL )
  920. return;
  921. iX = (int)((pPoint->GetX()-draw.m_StartX )/draw.m_Scale);
  922. iY = (int)((draw.m_StartY-pPoint->GetY())/draw.m_Scale);
  923. rc.left = iX - 4;
  924. rc.right = iX  + 4;
  925. rc.top = iY  - 4;
  926. rc.bottom = iY  + 4;
  927. pDC->Rectangle(&rc); 
  928. }
  929. /*************************************************
  930.   描述:         绘制线对象
  931.   输入:         设备指针、图例对象指针、坐标变换参数结构对象
  932.   输出:        无
  933. *************************************************/
  934. void CShpFile::DrawPLine(CDC*pDC ,  CMapRender* m_pRender , DrawParam& draw )
  935. {
  936.     int    iIndex,iField; 
  937. CPen   *pOldPen;
  938. SIMPLERENDER simpleRender;
  939. CPen   penSimple;
  940. CPen   pen(PS_SOLID,1,RGB(255,0,0));
  941. CBrush br(RGB(255,239,156));
  942. CMapFields *pFields;
  943.     CMapField  *pField;
  944.     CMapLine *pLine;
  945. POSITION pos;
  946. CString csValue;
  947. CMapRectangle shpRC;
  948. RENDERINFO *rInfo;
  949. if ( m_pRender == NULL )
  950.     {
  951. pOldPen = pDC->SelectObject(&pen);
  952. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  953. {  
  954. pLine = (CMapLine*)m_ObList.GetAt(pos);
  955.             shpRC = pLine->GetExtent();
  956. if ( !m_CurMapExtent.IsInsercet(shpRC))
  957. {
  958. m_ObList.GetNext(pos);
  959. continue;
  960. }
  961. DrawPLineElement(pDC,pLine,draw );
  962. m_ObList.GetNext(pos);
  963. }
  964. pDC->SelectObject(pOldPen);
  965. } else if ( m_pRender->GetRenderType() == SIMPLE_RENDER )
  966. {
  967. m_pRender->GetSimpleRender(simpleRender);
  968. if ( simpleRender.iIndex == 0 )
  969.         {  
  970.          pOldPen = pDC->SelectObject(&pen);
  971.         }
  972.         else
  973. {
  974.    if (!penSimple.CreatePen(PS_SOLID,1,simpleRender.FillColor))
  975.    { 
  976.   pOldPen = pDC->SelectObject(&pen);
  977.    } 
  978.    else
  979.            {
  980.    pOldPen = pDC->SelectObject(&penSimple);
  981.    }   
  982. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  983. {  
  984. pLine = (CMapLine*)m_ObList.GetAt(pos);
  985. shpRC = pLine->GetExtent();
  986. if ( !m_CurMapExtent.IsInsercet(shpRC))
  987. {
  988. m_ObList.GetNext(pos);
  989. continue;
  990. }
  991. DrawPLineElement(pDC,pLine,draw );
  992. m_ObList.GetNext(pos);
  993. }
  994. pDC->SelectObject(pOldPen);
  995. if ( penSimple.GetSafeHandle() != NULL ) 
  996.          penSimple.DeleteObject();  
  997.         
  998.     } 
  999. else if (m_pRender->GetRenderType() == UNIQUE_RENDER )
  1000.     { 
  1001. iField = m_pRender->GetFieldIndex();
  1002. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  1003. {  
  1004. pLine = (CMapLine*)m_ObList.GetAt(pos); 
  1005. shpRC = pLine->GetExtent();
  1006. if ( !m_CurMapExtent.IsInsercet(shpRC))
  1007. {
  1008. m_ObList.GetNext(pos);
  1009. continue;
  1010. }
  1011.             iIndex = pLine->GetIndex();
  1012.             pRecordSet->Move(iIndex,BookmarkFirst);
  1013. pFields = pRecordSet->GetFields(0);
  1014. if ( iField >= 0 && iField < pFields->GetCout())   
  1015. {  
  1016. pField = pFields->GetField(iField);
  1017. csValue = pField->GetValueAsString();
  1018. rInfo = m_pRender->GetByValue(csValue);
  1019. ASSERT(rInfo);
  1020. CPen penTemp(PS_SOLID,1,rInfo->clr); 
  1021.     pOldPen = pDC->SelectObject(&penTemp);
  1022.     DrawPLineElement(pDC,pLine,draw );
  1023.                 pDC->SelectObject(pOldPen);
  1024. }
  1025. m_ObList.GetNext(pos);
  1026. }
  1027. }
  1028. }
  1029. /*************************************************
  1030.   描述:         绘制单个的线对象
  1031.   输入:         设备指针、线对象对象指针、
  1032.                 坐标变换参数结构对象
  1033.   输出:        无
  1034. *************************************************/
  1035. void CShpFile::DrawPLineElement(CDC*pDC, CMapLine *pPline , DrawParam& draw )
  1036. {
  1037. int i,j,k,iCount;
  1038. CMapPoint *pPoint;
  1039. CMapPoints *pPoints;
  1040. CMapParts *pParts;
  1041. CMapRectangle MapExtent;
  1042. CPoint    *pPtArray;  //顶点数组
  1043. if ( pPline == NULL )
  1044. return;
  1045. for ( i = 0 ; i < pPline->GetCount() ; i++ )
  1046. {
  1047. pParts =  pPline->GetParts(i);
  1048. for ( j = 0 ; j < pParts->GetCount() ; j++)
  1049. {
  1050. pPoints = pParts->Get(j); 
  1051. iCount = pPoints->GetCount();
  1052. pPtArray = new CPoint[iCount];
  1053. if ( pPtArray == NULL )
  1054. return ;
  1055. for ( k = 0 ; k < iCount; k++)
  1056. {
  1057. pPoint = pPoints->Get(k); 
  1058. pPtArray[k].x = (int)((pPoint->GetX()-draw.m_StartX)/draw.m_Scale);
  1059. pPtArray[k].y = (int)((draw.m_StartY - pPoint->GetY())/draw.m_Scale);
  1060.     
  1061. }
  1062. }
  1063. }
  1064. //绘制多义线
  1065. pDC->Polyline(pPtArray,pPoints->GetCount()); 
  1066. delete []pPtArray;
  1067. }
  1068. /*************************************************
  1069.   描述:         绘制面对象
  1070.   输入:         设备指针、图例对象指针、坐标变换参数结构对象
  1071.   输出:        无
  1072. *************************************************/
  1073. void CShpFile::DrawPolygon(CDC*pDC ,  CMapRender* m_pRender , DrawParam& draw )
  1074. {
  1075. int    iIndex,iField; 
  1076. //CPen   *pOldPen;
  1077. CBrush *pOldBrush;
  1078. SIMPLERENDER simpleRender;
  1079. CBrush brSimple;
  1080. CPen   pen;
  1081. CBrush br(RGB(255,239,156));
  1082. CMapFields *pFields;
  1083.     CMapField  *pField;
  1084.     POSITION pos;
  1085. CString csValue;
  1086. RENDERINFO *rInfo;
  1087. CMapPolygon *pPolygon;
  1088. CMapRectangle shpRC;
  1089. if ( m_pRender == NULL )
  1090.     {
  1091. pOldBrush = pDC->SelectObject(&br);
  1092. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  1093. {  
  1094. pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
  1095. shpRC = pPolygon->GetExtent(); 
  1096. if ( !m_CurMapExtent.IsInsercet(shpRC))
  1097. {
  1098. //要绘制的对象外接矩形是不是与屏幕相交
  1099. m_ObList.GetNext(pos);
  1100. continue;
  1101.             }
  1102. DrawPolygonElement(pDC,pPolygon,draw );
  1103. m_ObList.GetNext(pos);
  1104. }
  1105. pDC->SelectObject(pOldBrush);
  1106. } else if ( m_pRender->GetRenderType() == SIMPLE_RENDER )
  1107. {
  1108. m_pRender->GetSimpleRender(simpleRender);
  1109. //pen.CreatePen(PS_SOLID,1,simpleRender.OutlineColor);
  1110. if ( simpleRender.iIndex == 0 )
  1111.         {  
  1112.          brSimple.CreateSolidBrush(simpleRender.FillColor);
  1113. pOldBrush = pDC->SelectObject(&brSimple);
  1114.         }
  1115.         else
  1116. {
  1117.    if (!brSimple.CreateHatchBrush( simpleRender.iIndex,
  1118.                                simpleRender.FillColor))
  1119.    { 
  1120.   pOldBrush = pDC->SelectObject(&br);
  1121.    } 
  1122.    else
  1123.            {
  1124.   pOldBrush = pDC->SelectObject(&brSimple);
  1125.    }   
  1126. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  1127. {  
  1128. pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
  1129. shpRC = pPolygon->GetExtent();
  1130. if ( !m_CurMapExtent.IsInsercet(shpRC))
  1131. {
  1132. //要绘制的对象外接矩形是不是与屏幕相交
  1133. m_ObList.GetNext(pos);
  1134. continue;
  1135.             }
  1136. DrawPolygonElement(pDC,pPolygon,draw );
  1137. m_ObList.GetNext(pos);
  1138. }
  1139. pDC->SelectObject(pOldBrush);
  1140. if ( brSimple.GetSafeHandle() != NULL )
  1141. brSimple.DeleteObject(); 
  1142.         
  1143.     } 
  1144. else if ( m_pRender->GetRenderType() == UNIQUE_RENDER )
  1145.     { 
  1146. iField = m_pRender->GetFieldIndex();
  1147. for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
  1148. {  
  1149. pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
  1150.             shpRC = pPolygon->GetExtent(); 
  1151. if ( !m_CurMapExtent.IsInsercet(shpRC))
  1152. {
  1153. //要绘制的对象外接矩形是不是与屏幕相交
  1154. m_ObList.GetNext(pos);
  1155. continue;
  1156.             }
  1157.         iIndex = pPolygon ->GetIndex();
  1158.             pRecordSet->Move(iIndex,BookmarkFirst);
  1159. pFields = pRecordSet->GetFields(0);
  1160. if ( iField >= 0 && iField < pFields->GetCout())   
  1161. {  
  1162. pField = pFields->GetField(iField);
  1163. csValue = pField->GetValueAsString();
  1164. rInfo = m_pRender->GetByValue(csValue);
  1165. ASSERT(rInfo != NULL);
  1166. CBrush brush(rInfo->clr); 
  1167.     pOldBrush = pDC->SelectObject(&brush);
  1168.     DrawPolygonElement(pDC,pPolygon,draw );
  1169.                 pDC->SelectObject(pOldBrush);
  1170. }
  1171. m_ObList.GetNext(pos);
  1172. }
  1173. }
  1174. }
  1175. /*************************************************
  1176.   描述:         绘制单个的面对象
  1177.   输入:         设备指针、面对象对象指针、
  1178.                 坐标变换参数结构对象
  1179.   输出:        无
  1180. *************************************************/
  1181. void CShpFile::DrawPolygonElement(CDC*pDC , CMapPolygon* pPolygon , DrawParam& draw )
  1182. {
  1183. int i,j,k,m,iCount;
  1184. CMapPoint *pPoint;
  1185. CMapPoints *pPoints;
  1186. CMapParts *pParts;
  1187. CPoint    *pPtArray;  //顶点数组
  1188. int       *pPolygonCount; //每个多边型的顶点数组
  1189. if ( pPolygon == NULL )
  1190. return;
  1191. iCount = pPolygon->GetCount(); //多边形个数
  1192.     pPolygonCount = new int[iCount];
  1193.     
  1194. if ( pPolygonCount == NULL )
  1195. return;
  1196. //计算复合多边型每部分的顶点数,和总顶点数
  1197. for ( m= 0,i = 0 ; i < pPolygon->GetCount() ; i++ )
  1198. {
  1199. pParts =  pPolygon->GetParts(i);
  1200. k = 0;
  1201. for ( j = 0 ; j < pParts->GetCount() ; j++)
  1202. {
  1203. pPoints = pParts->Get(j); 
  1204.             k += pPoints->GetCount();
  1205. pPolygonCount[i] = k;
  1206. m += k;
  1207. }
  1208. pPtArray = new CPoint[m];
  1209.     if ( pPtArray == NULL )
  1210.     { 
  1211. delete []pPolygonCount;
  1212. return ;
  1213. }
  1214. for ( m= 0 , i = 0 ; i < pPolygon->GetCount() ; i++ )
  1215. {
  1216. pParts =  pPolygon->GetParts(i);
  1217. for ( j = 0 ; j < pParts->GetCount() ; j++)
  1218. {
  1219. pPoints = pParts->Get(j); 
  1220.             for ( k = 0 ; k < pPoints->GetCount(); k++ )
  1221.             {
  1222. pPoint = pPoints->Get(k); 
  1223. pPtArray[m].x = (int)((pPoint->GetX() - draw.m_StartX)/draw.m_Scale);
  1224.                 pPtArray[m++].y =  (long)((draw.m_StartY - pPoint->GetY() )/draw.m_Scale);
  1225. }
  1226. }
  1227. if ( pPolygon->GetCount() > 1)
  1228. pDC->PolyPolygon(pPtArray,pPolygonCount,iCount); //绘制复合多边形
  1229. else
  1230. pDC->Polygon(pPtArray, m); 
  1231. delete []pPolygonCount;
  1232. delete []pPtArray;  
  1233. }