shpFile.cpp
上传用户:bjslfz
上传日期:2022-07-25
资源大小:4430k
文件大小:35k
- #include "stdafx.h"
- #include <d3dtypes.h>
- #include "shpFile.h"
- #include "MapPoint.h"
- #include "MapPoints.h"
- #include "MapLine.h"
- #include "MapPolygon.h"
- #include "MapFields.h"
- CShpFile::CShpFile()
- {
- int i;
- bShpOpen = FALSE;
- bShxOpen = FALSE;
- m_shpType = NULLSHP;
- /* -------------------------------------------------------------------- */
- /* Establish the byte order on this machine. */
- /* -------------------------------------------------------------------- */
- i = 1;
- if( *((uchar *) &i) == 1 )
- m_bBigEndian = FALSE;
- else
- m_bBigEndian = TRUE;
- }
- CShpFile::~CShpFile()
- {
-
- CMapPoint* pPt;
- CMapPoints* pPts;
- CMapLine* pLine;
- CMapPolygon* pPolygon;
- while(!m_ObList.IsEmpty())
- {
- switch ( m_shpType )
- {
- case POINT:
- pPt =(CMapPoint*)m_ObList.RemoveTail();
- delete pPt;
- break;
- case MULTIPOINT:
- pPts =(CMapPoints*)m_ObList.RemoveTail();
- delete pPts;
- break;
- case POLYLINE:
- pLine =(CMapLine*)m_ObList.RemoveTail();
- delete pLine;
- break;
- case POLYGON:
- pPolygon =(CMapPolygon*)m_ObList.RemoveTail();
- delete pPolygon;
- break;
- default:
- m_ObList.RemoveTail();
- break;
-
- }
- }
- if ( bShpOpen )
- fShp.Close();
- if (bShxOpen)
- fShx.Close();
- if ( pRecordSet )
- delete pRecordSet;
-
- }
- /*************************************************
- 描述: 读入Shp、shx文件 格式 参阅ESRI技术白皮书
- 输入: 文件名(全路径)
- 输出: 成功返回TRUE 失败返回FALSE
- *************************************************/
- BOOL CShpFile::ReadShp(CString& csFileName)
- {
- int iTemp;
- CString csShxName;
- CFileException fe;
- SHPHEADER varHeader;
-
- //打开主文件
- if ( !fShp.Open(csFileName, CFile::modeRead|CFile::shareDenyWrite,&fe))
- return FALSE;
- bShpOpen = TRUE;
-
- //打开索引文件
- csShxName = csFileName.Left(csFileName.GetLength() - 3);
-
- csShxName = csShxName + "shx";
- if ( !fShx.Open(csShxName, CFile::modeRead|CFile::shareDenyWrite,&fe))
- return FALSE;
- bShxOpen = TRUE;
-
- TRY
- {
- //读主文件头 长100字节
- if ( fShp.Read(&varHeader , sizeof(SHPHEADER))!= sizeof(SHPHEADER))
- return FILE_READERR;
-
- iTemp = varHeader.iFileCode;
- if ( !m_bBigEndian )
- SwapWord(sizeof(int),&iTemp);
- if ( iTemp != 9994 ) //是否是shp文件
- return FILE_CODEERR;
- if ( varHeader.iVersion != FILE_VERSION ) //文件版本是否正确
- return FILE_VERSIONERR;
-
- //shp 类型
- m_shpType = varHeader.iShpType;
- m_shpFileLength = varHeader.iFileLength;
- if ( !m_bBigEndian )
- SwapWord(sizeof(int),&m_shpFileLength);
-
- //保存数据最大矩形范围
- m_Extent.SetLeft(varHeader.dbXMin);
- m_Extent.SetRight(varHeader.dbXMax);
- m_Extent.SetTop(varHeader.dbYMin);
- m_Extent.SetBottom(varHeader.dbYMax);
-
- //读索引文件头 长100字节
- if ( fShx.Read(&varHeader , sizeof(SHPHEADER))!= sizeof(SHPHEADER))
- return FILE_READERR;
- iTemp = varHeader.iFileCode;
- if ( !m_bBigEndian )
- SwapWord(sizeof(int),&iTemp);
- if ( iTemp != 9994 ) //是否是shx文件
- return FILE_CODEERR;
- if ( varHeader.iVersion != FILE_VERSION ) //文件版本是否正确
- return FILE_VERSIONERR;
- m_shxFileLength = varHeader.iFileLength;
- if ( !m_bBigEndian )
- SwapWord(sizeof(int),&m_shxFileLength);
- //通过索引文件计算主文件记录个数 文件长度数值以16位计
- m_iRecordCount = ((m_shxFileLength - 50 )*2)/sizeof(SHXRECORD);
-
- if ( !ReadRecord() )
- return FILE_READERR;
- if ( !ReadDBF(csFileName))
- return FALSE;
- }
- CATCH(CFileException ,eload)
- {
- fShp.Abort();
- return FALSE;
- }
- END_CATCH
-
-
- return TRUE;
- }
- /*************************************************
- 描述: 读入DBF文件格式
- 输入: 文件名(全路径)
- 输出: 成功返回TRUE 失败返回FALSE
- *************************************************/
- BOOL CShpFile::ReadDBF(CString& csFileName)
- {
- CString csDbfName;
- BOOL bResult;
- //创建记录集对象
- pRecordSet = new CMapRecordSet;
- ASSERT ( pRecordSet != NULL );
- csDbfName = csFileName.Left(csFileName.GetLength() - 3);
- csDbfName = csDbfName + "dbf";
- //打开DBF文件
- bResult = pRecordSet->openDBF(csDbfName);
- if ( !bResult )
- delete pRecordSet;
- return bResult;
- }
- /*************************************************
- 描述: 获得当前地图文件最大矩形范围
- 输入: 无
- 输出: 地图矩形范围
- *************************************************/
- CMapRectangle CShpFile::GetExtent()
- {
- return m_Extent;
- }
- /*************************************************
- 描述: 设置地图文件最大矩形范围
- 输入: 地图矩形范围
- 输出: 无
- *************************************************/
- void CShpFile::SetExtent(CMapRectangle& extent )
- {
- m_Extent.SetLeft(extent.GetLeft());
- m_Extent.SetRight(extent.GetRight());
- m_Extent.SetTop(extent.GetTop());
- m_Extent.SetBottom(extent.GetBottom());
- }
- /*************************************************
- 描述: 设置Shp对象类型
- 输入: shp 类型
- 输出: 无
- *************************************************/
- void CShpFile::SetShpType(int& iShpType)
- {
- m_shpType = iShpType;
- }
- /*************************************************
- 描述: 读入Shp对象坐标
- 输入: 无
- 输出: 成功返回TRUE 失败返回FALSE
- *************************************************/
- BOOL CShpFile::ReadRecord()
- {
- int i,j,k,m;
- int iDataLen,iLength,iIndex;
- int *pIParts;
- double dbTmp;
- char *pszBuffer,*lpVer;
- BOOL bEof;
- SHPINFO shpIn;
- SHPRECORDHEADER RecordHeader;
- CMapRectangle objRectangle;
- CMapPoint *pPoint;
- CMapPoints *pPoints;
- CMapParts *pParts;
- CMapLine *pLine;
- CMapPolygon *pPolygon;
-
- bEof = FALSE;
- switch ( m_shpType )
- {
- case NULLSHP:
- return FALSE;
- break;
- case POINT:
- {
-
- SHPPTCONTENT point;
- //读入点记录
- for ( i = 1 ; i <= m_iRecordCount ; i++ )
- {
- iLength = SetRecordPos(i);
- if ( iLength <= 0 )
- return FALSE;
- //获得记录头信息
- if (!GetRecordHeader(RecordHeader))
- return FALSE;
- //记录内容长度是否与shp实体大小一致,索引记录长度是否与记录内容长度一致
- if ( RecordHeader.iContentLength*2 != sizeof(point)||
- RecordHeader.iContentLength*2 != iLength)
- return FALSE;
- if(fShp.Read(&point,sizeof(point))!= sizeof(point))
- return FALSE;
- pPoint = new CMapPoint;
- iIndex = i - 1;
- pPoint->SetIndex(iIndex);
- if ( pPoint == NULL )
- return FALSE;
- //类型是否匹配
- if ( point.iShpType != m_shpType)
- return FALSE;
- pPoint->SetX(point.dbX );
- pPoint->SetY(point.dbY );
- m_ObList.AddTail(pPoint);
-
- }
- }
- break;
- case POLYLINE:
-
- pszBuffer = new char [MAX_BUFFER_SIZE]; //分配缓冲区
- if ( pszBuffer == NULL )
- return FALSE;
- memset(pszBuffer , 0 , MAX_BUFFER_SIZE);
-
- //读入线记录
- for ( i = 1 ; i <= m_iRecordCount ; i++ ) //m_iRecordCount
- {
-
- iLength = SetRecordPos(i);
- if ( iLength <= 0 )
- return FALSE;
- pLine = new CMapLine();
- iIndex = i - 1;
- pLine->SetIndex(iIndex);
- if ( pLine == NULL )
- return FALSE;
- //获得记录头信息
- if (!GetRecordHeader(RecordHeader))
- return FALSE;
- if ( !GetShpInfo(shpIn))
- return FALSE;
- if (shpIn.ishpType != POLYLINE )//类型不匹配
- {
- delete pLine;
- continue;
- }
- if ( shpIn.iNumParts*sizeof(int) > MAX_BUFFER_SIZE )
- {
- //多义线段数大于最大缓冲区长度,忽略该对象
- delete pLine;
- continue;
- }
- //计算对象内容实际长度
- j = sizeof(SHPINFO) + shpIn.iNumParts*sizeof(int) ;
- j += shpIn.iNumPoints*sizeof(SHPPOINT);
-
- //判断实际长度是否与索引文件中记录的一致
- if ( RecordHeader.iContentLength*2 != j )
- {
- delete pLine;
- continue;
- }
- //设置shp矩形范围
- objRectangle.SetLeft(shpIn.Box[0].dbX);
- objRectangle.SetTop(shpIn.Box[0].dbY);
- objRectangle.SetRight(shpIn.Box[1].dbX);
- objRectangle.SetBottom(shpIn.Box[1].dbY);
- pLine->SetExtent(objRectangle);
- pIParts = new int[shpIn.iNumParts];
- if ( pIParts == NULL )
- {
- delete pLine;
- return FALSE;
- }
- //读入多义线段索引
- if ( fShp.Read(pIParts,shpIn.iNumParts*4) != (uint)(shpIn.iNumParts*4))
- {
- delete pLine;
- return FALSE;
- }
- //点坐标存储所占字节数
- iLength = shpIn.iNumPoints*sizeof(SHPPOINT);
- //初始化缓冲区数据
- iDataLen = ReadPoint(pszBuffer,iLength,bEof);
- if ( iDataLen < 0 )
- {
- delete pLine;
- delete pIParts;
- return FALSE;
-
- }
- lpVer = pszBuffer;
- for ( j = 0 ; j < shpIn.iNumParts ; j++ )
- {
- pParts = new CMapParts();
- pPoints = new CMapPoints();
- if ( pParts == NULL || pPoints == NULL)
- return FALSE;
- if ( j == shpIn.iNumParts - 1 )
- {
- k = pIParts[j]; //本段第一个顶点索引
- m = shpIn.iNumPoints ; //下一个段第一个顶点索引
- }
- else
- {
- k = pIParts[j];
- m = pIParts[j+1];
- }
- //处理第i段的顶点
- for ( ; k < m ; k++)
- {
- pPoint = new CMapPoint();
- if ( pPoint == NULL )
- return FALSE;
-
- //需要读入数据更新缓冲区
- if ( lpVer == pszBuffer + iDataLen && !bEof)
- {
- iDataLen = ReadPoint(pszBuffer,iLength,bEof);
- if ( iDataLen < 0 )
- {
- delete pPoint;
- delete pPoints;
- delete pLine;
- delete pIParts;
-
- return FALSE;
-
- }
- lpVer = pszBuffer;
- }
- dbTmp = *(double*)lpVer;
- pPoint->SetX(dbTmp);
- lpVer += 8;
- //需要读入数据更新缓冲区
- if ( lpVer == pszBuffer + iDataLen && !bEof)
- {
- iDataLen = ReadPoint(pszBuffer,iLength,bEof);
- if ( iDataLen < 0 )
- {
- delete pPoint;
- delete pPoints;
- delete pLine;
- delete pIParts;
- return FALSE;
-
- }
- lpVer = pszBuffer;
- }
- dbTmp = *(double*)(lpVer);
- lpVer += 8;
- pPoint->SetY(dbTmp);
- pPoints->Add(pPoint);
-
- }
- pParts->Add(pPoints);
- pLine->Add(pParts);
- }
- m_ObList.AddTail( pLine);
- delete []pIParts;
-
- }
- delete []pszBuffer;
- break;
- case POLYGON:
- pszBuffer = new char [MAX_BUFFER_SIZE]; //分配缓冲区
- if ( pszBuffer == NULL )
- return FALSE;
- memset(pszBuffer , 0 , MAX_BUFFER_SIZE);
-
- //读入多边形记录
- for ( i = 1 ; i <= m_iRecordCount ; i++ ) //m_iRecordCount
- {
- iLength = SetRecordPos(i);
- if ( iLength <= 0 )
- return FALSE;
- pPolygon = new CMapPolygon();
- iIndex = i - 1;
- pPolygon->SetIndex(iIndex);
- if (pPolygon == NULL )
- return FALSE;
- //获得记录头信息
- if (!GetRecordHeader(RecordHeader))
- return FALSE;
- if ( !GetShpInfo(shpIn))
- return FALSE;
- if (shpIn.ishpType != POLYGON )//类型不匹配
- {
- delete pPolygon;
- continue;
- }
- if ( shpIn.iNumParts*sizeof(int) > MAX_BUFFER_SIZE )
- {
- //复合多边型中的多边形个数大于最大缓冲区长度,忽略该对象
- delete pPolygon;
- continue;
- }
- //计算对象内容实际长度
- j = sizeof(SHPINFO) + shpIn.iNumParts*sizeof(int) ;
- j += shpIn.iNumPoints*sizeof(SHPPOINT);
-
- //判断实际长度是否与索引文件中记录的一致
- if ( RecordHeader.iContentLength*2 != j )
- {
- delete pPolygon;
- continue;
- }
- //设置shp矩形范围
- objRectangle.SetLeft(shpIn.Box[0].dbX);
- objRectangle.SetTop(shpIn.Box[0].dbY);
- objRectangle.SetRight(shpIn.Box[1].dbX);
- objRectangle.SetBottom(shpIn.Box[1].dbY);
- pPolygon->SetExtent(objRectangle);
- pIParts = new int[shpIn.iNumParts];
- if ( pIParts == NULL )
- {
- delete pPolygon;
- return FALSE;
- }
- //读入复合多边型段索引
- if ( fShp.Read(pIParts,shpIn.iNumParts*4) != (uint)(shpIn.iNumParts*4))
- {
- delete pPolygon;
- return FALSE;
- }
- //点坐标存储所占字节数
- iLength = shpIn.iNumPoints*sizeof(SHPPOINT);
- //初始化缓冲区数据
- iDataLen = ReadPoint(pszBuffer,iLength,bEof);
- if ( iDataLen < 0 )
- {
- delete pPolygon;
- delete pIParts;
- return FALSE;
-
- }
- lpVer = pszBuffer;
- for ( j = 0 ; j < shpIn.iNumParts ; j++ )
- {
- pParts = new CMapParts();
- pPoints = new CMapPoints();
- if ( pParts == NULL || pPoints == NULL)
- return FALSE;
- if ( j == shpIn.iNumParts - 1 )
- {
- k = pIParts[j]; //本段第一个顶点索引
- m = shpIn.iNumPoints ; //下一个段第一个顶点索引
- }
- else
- {
- k = pIParts[j];
- m = pIParts[j+1];
- }
- //处理第i段的顶点
- for ( ; k < m ; k++)
- {
- pPoint = new CMapPoint();
- if ( pPoint == NULL )
- return FALSE;
-
- //需要读入数据更新缓冲区
- if ( lpVer == pszBuffer + iDataLen && !bEof)
- {
- iDataLen = ReadPoint(pszBuffer,iLength,bEof);
- if ( iDataLen < 0 )
- {
- delete pPolygon;
- delete pIParts;
- return FALSE;
-
- }
- lpVer = pszBuffer;
- }
- dbTmp = *(double*)lpVer;
- pPoint->SetX(dbTmp);
- lpVer += 8;
- //需要读入数据更新缓冲区
- if ( lpVer == pszBuffer + iDataLen && !bEof)
- {
- iDataLen = ReadPoint(pszBuffer,iLength,bEof);
- if ( iDataLen < 0 )
- {
- delete pPolygon;
- delete pIParts;
- return FALSE;
-
- }
- lpVer = pszBuffer;
- }
- dbTmp = *(double*)(lpVer);
- pPoint->SetY(dbTmp);
- pPoints->Add(pPoint);
- lpVer += 8;
-
- }
- pParts->Add(pPoints);
- pPolygon->Add(pParts);
- }
- m_ObList.AddTail( pPolygon);
- delete []pIParts;
- }
- delete []pszBuffer;
- break;
- default:
- return FALSE;
- break;
- }
- return TRUE;
- }
- /*************************************************
- 描述: 计算每条shp对象相对文件头的偏移量
- 输入: 记录索引值(从零开始)
- 输出: 该shp对象数据在文件中的位置
- *************************************************/
- int CShpFile::SetRecordPos( int iRecord )
- {
- unsigned int iOffset,iTmp;
- SHXRECORD shxRD;
- if ( iRecord < 0 )
- return 0;
- //获得索引文件记录偏移量相对文件头
- if (iRecord == 1 )
- iOffset = sizeof(SHPHEADER) ;
- else
- iOffset = sizeof(SHPHEADER) + (iRecord-1)*sizeof(shxRecord) ;
- if ( iOffset > m_shxFileLength*2 - sizeof(shxRecord) )
- return 0;
- fShx.Seek( iOffset , CFile::begin );
- int m = sizeof(shxRD);
- fShx.Read( &shxRD , sizeof(shxRD));
- iTmp = shxRD.iOffset;
- SwapWord(sizeof(int),&iTmp);
- fShp.Seek(iTmp*2 , CFile::begin );
- iTmp = shxRD.iContentLength;
- SwapWord(sizeof(int),&iTmp);
-
-
- return iTmp*2;
- }
- /*************************************************
- 描述: 获得每条shp对象记录记录头的信息
- 输入: 记录头结构对象
- 输出: 成功返回TRUE 失败返回FALSE
- *************************************************/
- BOOL CShpFile::GetRecordHeader(SHPRECORDHEADER& RecordHeader )
- {
- int iLength,iNum;
- if(fShp.Read(&RecordHeader,sizeof(RecordHeader))!= sizeof(RecordHeader))
- return FALSE;
- if ( !m_bBigEndian )
- {
- iNum = RecordHeader.iRecordNum;
- iLength = RecordHeader.iContentLength;
- SwapWord(sizeof(int),&iLength);
- SwapWord(sizeof(int),&iNum);
- RecordHeader.iRecordNum = iNum;
- RecordHeader.iContentLength = iLength;
- }
- return TRUE;
- }
- /*************************************************
- 描述: 获得每条shp对象描述信息
- 输入: 描述信息结构对象
- 输出: 成功返回TRUE 失败返回FALSE
- *************************************************/
- BOOL CShpFile::GetShpInfo(SHPINFO& varInfo)
- {
- if(fShp.Read(&varInfo,sizeof(varInfo))!= sizeof(varInfo))
- return FALSE;
- return TRUE;
- }
- /*************************************************
- 描述: 读入点对象数据
- 输入: 数据缓冲区指针 缓冲区最大32K
- 如果超出需要分多次读取,要读取的长度、
- 是否已读取完成
- 输出: 读取数据的实际长度
- *************************************************/
- int CShpFile::ReadPoint(char* pszBuffer,int& iLength,BOOL& bEof)
- {
- if ( iLength > MAX_BUFFER_SIZE)
- {
- iLength -= MAX_BUFFER_SIZE;
- if ( fShp.Read(pszBuffer,MAX_BUFFER_SIZE) != MAX_BUFFER_SIZE )
- return FILE_READERR;
- bEof = FALSE;
- return MAX_BUFFER_SIZE;
- }
- else
- {
- if ( fShp.Read(pszBuffer,iLength) != (uint)iLength )
- return FILE_READERR;
- bEof = TRUE;
- return iLength;
- }
- }
- /*************************************************
- 描述: 根据点对象查找shp对象是否选中
- 输入: 点对象
- 输出: 查找到shp对象的索引值 返回值-表示未查找到
- *************************************************/
- int CShpFile::SearchShape(CMapPoint& pt )
- {
- unsigned long iCount;
- POSITION pos;
- CMapPolygon *pPolygon;
- if ( GetShpType() != POLYGON ) //只判断多边形对象
- return -1;
- iCount = m_ObList.GetCount()-1;
-
- for ( pos = m_ObList.GetHeadPosition() ; pos != NULL ; )
- {
- pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
- if ( pPolygon->IsPointIn(pt) )
- return pPolygon->GetIndex();
- m_ObList.GetNext(pos);
- }
- return -1;
- }
- /*************************************************
- 描述: 绘制shp对象
- 输入: 设备指针、图例对象指针、坐标变换参数结构对象
- 输出: 无
- *************************************************/
- void CShpFile::DrawShp(CDC*pDC , CMapRender* m_pRender , DrawParam& draw )
- {
-
- int iDrawMode;
- //计算当前屏幕的实际坐标范围
- m_CurMapExtent.SetLeft(draw.m_StartX );
- m_CurMapExtent.SetBottom(draw.m_StartY);
- m_CurMapExtent.SetRight(draw.m_StartX + draw.m_ScreenWidth * draw.m_Scale);
- m_CurMapExtent.SetTop(draw.m_StartY - draw.m_ScreenHeigh *draw.m_Scale);
-
- //设置绘制模式
- iDrawMode = pDC->SetROP2(R2_COPYPEN);
-
- switch ( m_shpType )
- {
- case POINT:
- {
- DrawPoint(pDC , m_pRender , draw );
- }
- break;
- case POLYLINE:
- {
- DrawPLine(pDC , m_pRender , draw );
-
- }
- break;
- case POLYGON:
- {
- DrawPolygon(pDC , m_pRender , draw );
- }
- break;
- default:
- break;
- }
- pDC->SetROP2(iDrawMode);
- //int r = RGB_GETRED(16773020);
- //int g = RGB_GETGREEN(16773020);
- //int b = RGB_GETBLUE(16773020);
-
-
- }
- /*************************************************
- 描述: 对选中的shp对象闪烁
- 输入: 设备指针、坐标变换参数结构对象、
- shp对象的索引值
- 输出: 无
- *************************************************/
- void CShpFile::FlashShp(CDC*pDC , DrawParam& draw , int iIndex)
- {
-
- int i,j,k,m,iCount,iDrawMode;
- CMapPoint *pPoint;
- CMapPoints *pPoints;
- CMapParts *pParts;
- //CMapLine *pPline;
- CMapPolygon *pPolygon;
- CMapRectangle MapExtent;
- CPoint *pPtArray; //顶点数组
- int *pPolygonCount; //每个多边型的顶点数组
- CRect rc;
- POSITION pos;
- CBrush br1(RGB(0,0,0));
- CBrush br2(RGB(255,255,255));
- CBrush *pOldBrush;
-
- if ( iIndex < 0 )
- return;
- iDrawMode = pDC->SetROP2(R2_XORPEN);
- switch ( m_shpType )
- {
- case POINT: {
- }
- break;
- case POLYLINE: {
- }
- break;
- case POLYGON: {
- for ( pos = m_ObList.GetHeadPosition() ; pos != NULL ; )
- {
- pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
- if (iIndex == (int) pPolygon->GetIndex() )
- {
- iCount = pPolygon->GetCount(); //多边形个数
- pPolygonCount = new int[iCount];
- if ( pPolygonCount == NULL )
- return;
-
- //计算复合多边型每部分的顶点数,和总顶点数
-
- for ( m= 0,i = 0 ; i < pPolygon->GetCount() ; i++ )
- {
- pParts = pPolygon->GetParts(i);
- k = 0;
- for ( j = 0 ; j < pParts->GetCount() ; j++)
- {
- pPoints = pParts->Get(j);
- k += pPoints->GetCount();
- }
- pPolygonCount[i] = k;
- m += k;
- }
- pPtArray = new CPoint[m];
- if ( pPtArray == NULL )
- {
- delete []pPolygonCount;
- return ;
- }
-
- for ( m= 0 , i = 0 ; i < pPolygon->GetCount() ; i++ )
- {
- pParts = pPolygon->GetParts(i);
- for ( j = 0 ; j < pParts->GetCount() ; j++)
- {
- pPoints = pParts->Get(j);
- for ( k = 0 ; k < pPoints->GetCount(); k++ )
- {
- pPoint = pPoints->Get(k);
- pPtArray[m].x = (int)((pPoint->GetX() - draw.m_StartX)/draw.m_Scale);
- pPtArray[m++].y = (long)((draw.m_StartY - pPoint->GetY() )/draw.m_Scale);
-
- }
- }
-
- }
- pOldBrush = pDC->SelectObject(&br1);
- if ( pPolygon->GetCount() > 1)
- {
-
- pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
- i = 0;
- while ( i < 150000 )
- {
- i++;
- }
- pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
- pDC->SelectObject(&br2);
- pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
- i = 0;
- while ( i < 350000 ) //延时
- {
- i++;
- }
- pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
-
- }
- else
- {
- pDC->Polygon(pPtArray, m);
- i = 0;
- while ( i < 150000 )
- {
- i++;
- }
- pDC->Polygon(pPtArray, m);
- pDC->SelectObject(&br2);
- pDC->Polygon(pPtArray, m);
- i = 0;
- while ( i < 350000 )
- {
- i++;
- }
- pDC->Polygon(pPtArray, m);
- }
- delete []pPolygonCount;
- delete []pPtArray;
- pDC->SelectObject(pOldBrush);
- break;
- }
- m_ObList.GetNext(pos);
- }
-
- }
- break;
- default:
- break;
- }
- pDC->SetROP2(iDrawMode);
- }
- /*************************************************
- 描述: 绘制点对象
- 输入: 设备指针、图例对象指针、坐标变换参数结构对象
- 输出: 无
- *************************************************/
- void CShpFile::DrawPoint(CDC*pDC , CMapRender* m_pRender , DrawParam& draw )
- {
-
- int iIndex,iField;
- CBrush *pOldBrush;
- SIMPLERENDER simpleRender;
- CBrush brSimple;
- CPen pen;
- CBrush br(RGB(255,239,156));
- CMapFields *pFields;
- CMapField *pField;
- CMapPoint *pPoint;
- POSITION pos;
- CString csValue;
- RENDERINFO *rInfo;
-
- if ( m_pRender == NULL )
- {
- pOldBrush = pDC->SelectObject(&br);
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
- pPoint = (CMapPoint*)m_ObList.GetAt(pos);
- //判断要绘制的的对象是否在当前屏幕范围内
- if ( !m_CurMapExtent.IsPointIn(*pPoint))
- {
-
- m_ObList.GetNext(pos);
- continue;
- }
- DrawPointElement(pDC,pPoint,draw );
- m_ObList.GetNext(pos);
- }
- pDC->SelectObject(pOldBrush);
-
- } else if ( m_pRender->GetRenderType() == SIMPLE_RENDER )
- {
- m_pRender->GetSimpleRender(simpleRender);
- //pen.CreatePen(PS_SOLID,1,simpleRender.OutlineColor);
- if ( simpleRender.iIndex == 0 )
- {
- brSimple.CreateSolidBrush(simpleRender.FillColor);
- pOldBrush = pDC->SelectObject(&brSimple);
- }
- else
- {
- if (!brSimple.CreateHatchBrush( simpleRender.iIndex,
- simpleRender.FillColor))
- {
- pOldBrush = pDC->SelectObject(&br);
- }
- else
- {
- pOldBrush = pDC->SelectObject(&brSimple);
- }
- }
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
- pPoint = (CMapPoint*)m_ObList.GetAt(pos);
- if ( !m_CurMapExtent.IsPointIn(*pPoint))
- {
- m_ObList.GetNext(pos);
- continue;
- }
- DrawPointElement(pDC,pPoint,draw );
- m_ObList.GetNext(pos);
- }
- pDC->SelectObject(pOldBrush);
- pen.DeleteObject();
- brSimple.DeleteObject();
-
- }
- else if ( m_pRender->GetRenderType() == UNIQUE_RENDER )
- {
- iField = m_pRender->GetFieldIndex();
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
-
- pPoint = (CMapPoint*)m_ObList.GetAt(pos);
- if ( !m_CurMapExtent.IsPointIn(*pPoint))
- {
- m_ObList.GetNext(pos);
- continue;
- }
- iIndex = pPoint->GetIndex();
- pRecordSet->Move(iIndex,BookmarkFirst);
- pFields = pRecordSet->GetFields(0);
- if ( iField >= 0 && iField < pFields->GetCout())
- {
- pField = pFields->GetField(iField);
- csValue = pField->GetValueAsString();
- rInfo = m_pRender->GetByValue(csValue);
- ASSERT(rInfo);
- CBrush brush(rInfo->clr);
- pOldBrush = pDC->SelectObject(&brush);
- DrawPointElement(pDC,pPoint,draw );
- pDC->SelectObject(pOldBrush);
- }
- m_ObList.GetNext(pos);
- }
- }
- }
- /*************************************************
- 描述: 绘制单个的点对象
- 输入: 设备指针、点对象对象指针、
- 坐标变换参数结构对象
- 输出: 无
- *************************************************/
- void CShpFile::DrawPointElement(CDC*pDC,CMapPoint *pPoint, DrawParam& draw )
- {
- int iX,iY;
- CRect rc;
- if ( pPoint == NULL )
- return;
-
- iX = (int)((pPoint->GetX()-draw.m_StartX )/draw.m_Scale);
- iY = (int)((draw.m_StartY-pPoint->GetY())/draw.m_Scale);
- rc.left = iX - 4;
- rc.right = iX + 4;
- rc.top = iY - 4;
- rc.bottom = iY + 4;
- pDC->Rectangle(&rc);
- }
- /*************************************************
- 描述: 绘制线对象
- 输入: 设备指针、图例对象指针、坐标变换参数结构对象
- 输出: 无
- *************************************************/
- void CShpFile::DrawPLine(CDC*pDC , CMapRender* m_pRender , DrawParam& draw )
- {
- int iIndex,iField;
- CPen *pOldPen;
- SIMPLERENDER simpleRender;
- CPen penSimple;
- CPen pen(PS_SOLID,1,RGB(255,0,0));
- CBrush br(RGB(255,239,156));
- CMapFields *pFields;
- CMapField *pField;
- CMapLine *pLine;
- POSITION pos;
- CString csValue;
- CMapRectangle shpRC;
- RENDERINFO *rInfo;
- if ( m_pRender == NULL )
- {
- pOldPen = pDC->SelectObject(&pen);
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
- pLine = (CMapLine*)m_ObList.GetAt(pos);
- shpRC = pLine->GetExtent();
- if ( !m_CurMapExtent.IsInsercet(shpRC))
- {
- m_ObList.GetNext(pos);
- continue;
- }
- DrawPLineElement(pDC,pLine,draw );
- m_ObList.GetNext(pos);
- }
- pDC->SelectObject(pOldPen);
-
- } else if ( m_pRender->GetRenderType() == SIMPLE_RENDER )
- {
- m_pRender->GetSimpleRender(simpleRender);
- if ( simpleRender.iIndex == 0 )
- {
- pOldPen = pDC->SelectObject(&pen);
- }
- else
- {
- if (!penSimple.CreatePen(PS_SOLID,1,simpleRender.FillColor))
- {
- pOldPen = pDC->SelectObject(&pen);
- }
- else
- {
- pOldPen = pDC->SelectObject(&penSimple);
- }
- }
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
- pLine = (CMapLine*)m_ObList.GetAt(pos);
- shpRC = pLine->GetExtent();
- if ( !m_CurMapExtent.IsInsercet(shpRC))
- {
- m_ObList.GetNext(pos);
- continue;
- }
- DrawPLineElement(pDC,pLine,draw );
- m_ObList.GetNext(pos);
- }
- pDC->SelectObject(pOldPen);
- if ( penSimple.GetSafeHandle() != NULL )
- penSimple.DeleteObject();
-
-
- }
- else if (m_pRender->GetRenderType() == UNIQUE_RENDER )
- {
- iField = m_pRender->GetFieldIndex();
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
-
- pLine = (CMapLine*)m_ObList.GetAt(pos);
- shpRC = pLine->GetExtent();
- if ( !m_CurMapExtent.IsInsercet(shpRC))
- {
- m_ObList.GetNext(pos);
- continue;
- }
- iIndex = pLine->GetIndex();
- pRecordSet->Move(iIndex,BookmarkFirst);
- pFields = pRecordSet->GetFields(0);
- if ( iField >= 0 && iField < pFields->GetCout())
- {
- pField = pFields->GetField(iField);
- csValue = pField->GetValueAsString();
- rInfo = m_pRender->GetByValue(csValue);
- ASSERT(rInfo);
- CPen penTemp(PS_SOLID,1,rInfo->clr);
- pOldPen = pDC->SelectObject(&penTemp);
- DrawPLineElement(pDC,pLine,draw );
- pDC->SelectObject(pOldPen);
- }
- m_ObList.GetNext(pos);
- }
- }
-
- }
- /*************************************************
- 描述: 绘制单个的线对象
- 输入: 设备指针、线对象对象指针、
- 坐标变换参数结构对象
- 输出: 无
- *************************************************/
- void CShpFile::DrawPLineElement(CDC*pDC, CMapLine *pPline , DrawParam& draw )
- {
- int i,j,k,iCount;
- CMapPoint *pPoint;
- CMapPoints *pPoints;
- CMapParts *pParts;
- CMapRectangle MapExtent;
- CPoint *pPtArray; //顶点数组
- if ( pPline == NULL )
- return;
- for ( i = 0 ; i < pPline->GetCount() ; i++ )
- {
- pParts = pPline->GetParts(i);
- for ( j = 0 ; j < pParts->GetCount() ; j++)
- {
- pPoints = pParts->Get(j);
- iCount = pPoints->GetCount();
- pPtArray = new CPoint[iCount];
- if ( pPtArray == NULL )
- return ;
- for ( k = 0 ; k < iCount; k++)
- {
- pPoint = pPoints->Get(k);
- pPtArray[k].x = (int)((pPoint->GetX()-draw.m_StartX)/draw.m_Scale);
- pPtArray[k].y = (int)((draw.m_StartY - pPoint->GetY())/draw.m_Scale);
-
- }
- }
- }
- //绘制多义线
- pDC->Polyline(pPtArray,pPoints->GetCount());
- delete []pPtArray;
-
- }
- /*************************************************
- 描述: 绘制面对象
- 输入: 设备指针、图例对象指针、坐标变换参数结构对象
- 输出: 无
- *************************************************/
- void CShpFile::DrawPolygon(CDC*pDC , CMapRender* m_pRender , DrawParam& draw )
- {
- int iIndex,iField;
- //CPen *pOldPen;
- CBrush *pOldBrush;
- SIMPLERENDER simpleRender;
- CBrush brSimple;
- CPen pen;
- CBrush br(RGB(255,239,156));
- CMapFields *pFields;
- CMapField *pField;
- POSITION pos;
- CString csValue;
- RENDERINFO *rInfo;
- CMapPolygon *pPolygon;
- CMapRectangle shpRC;
- if ( m_pRender == NULL )
- {
- pOldBrush = pDC->SelectObject(&br);
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
- pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
- shpRC = pPolygon->GetExtent();
- if ( !m_CurMapExtent.IsInsercet(shpRC))
- {
- //要绘制的对象外接矩形是不是与屏幕相交
- m_ObList.GetNext(pos);
- continue;
- }
- DrawPolygonElement(pDC,pPolygon,draw );
- m_ObList.GetNext(pos);
- }
- pDC->SelectObject(pOldBrush);
-
- } else if ( m_pRender->GetRenderType() == SIMPLE_RENDER )
- {
- m_pRender->GetSimpleRender(simpleRender);
- //pen.CreatePen(PS_SOLID,1,simpleRender.OutlineColor);
- if ( simpleRender.iIndex == 0 )
- {
- brSimple.CreateSolidBrush(simpleRender.FillColor);
- pOldBrush = pDC->SelectObject(&brSimple);
- }
- else
- {
- if (!brSimple.CreateHatchBrush( simpleRender.iIndex,
- simpleRender.FillColor))
- {
- pOldBrush = pDC->SelectObject(&br);
- }
- else
- {
- pOldBrush = pDC->SelectObject(&brSimple);
- }
- }
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
- pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
- shpRC = pPolygon->GetExtent();
- if ( !m_CurMapExtent.IsInsercet(shpRC))
- {
- //要绘制的对象外接矩形是不是与屏幕相交
- m_ObList.GetNext(pos);
- continue;
- }
- DrawPolygonElement(pDC,pPolygon,draw );
- m_ObList.GetNext(pos);
- }
- pDC->SelectObject(pOldBrush);
- if ( brSimple.GetSafeHandle() != NULL )
- brSimple.DeleteObject();
-
- }
- else if ( m_pRender->GetRenderType() == UNIQUE_RENDER )
- {
- iField = m_pRender->GetFieldIndex();
- for( pos = m_ObList.GetHeadPosition(); pos != NULL; )
- {
-
- pPolygon = (CMapPolygon*)m_ObList.GetAt(pos);
- shpRC = pPolygon->GetExtent();
- if ( !m_CurMapExtent.IsInsercet(shpRC))
- {
- //要绘制的对象外接矩形是不是与屏幕相交
- m_ObList.GetNext(pos);
- continue;
- }
- iIndex = pPolygon ->GetIndex();
- pRecordSet->Move(iIndex,BookmarkFirst);
- pFields = pRecordSet->GetFields(0);
- if ( iField >= 0 && iField < pFields->GetCout())
- {
- pField = pFields->GetField(iField);
- csValue = pField->GetValueAsString();
- rInfo = m_pRender->GetByValue(csValue);
- ASSERT(rInfo != NULL);
- CBrush brush(rInfo->clr);
- pOldBrush = pDC->SelectObject(&brush);
- DrawPolygonElement(pDC,pPolygon,draw );
- pDC->SelectObject(pOldBrush);
- }
- m_ObList.GetNext(pos);
- }
- }
- }
- /*************************************************
- 描述: 绘制单个的面对象
- 输入: 设备指针、面对象对象指针、
- 坐标变换参数结构对象
- 输出: 无
- *************************************************/
- void CShpFile::DrawPolygonElement(CDC*pDC , CMapPolygon* pPolygon , DrawParam& draw )
- {
- int i,j,k,m,iCount;
- CMapPoint *pPoint;
- CMapPoints *pPoints;
- CMapParts *pParts;
- CPoint *pPtArray; //顶点数组
- int *pPolygonCount; //每个多边型的顶点数组
- if ( pPolygon == NULL )
- return;
- iCount = pPolygon->GetCount(); //多边形个数
- pPolygonCount = new int[iCount];
-
- if ( pPolygonCount == NULL )
- return;
-
- //计算复合多边型每部分的顶点数,和总顶点数
- for ( m= 0,i = 0 ; i < pPolygon->GetCount() ; i++ )
- {
- pParts = pPolygon->GetParts(i);
- k = 0;
- for ( j = 0 ; j < pParts->GetCount() ; j++)
- {
- pPoints = pParts->Get(j);
- k += pPoints->GetCount();
- }
- pPolygonCount[i] = k;
- m += k;
- }
-
- pPtArray = new CPoint[m];
- if ( pPtArray == NULL )
- {
- delete []pPolygonCount;
- return ;
- }
-
- for ( m= 0 , i = 0 ; i < pPolygon->GetCount() ; i++ )
- {
- pParts = pPolygon->GetParts(i);
- for ( j = 0 ; j < pParts->GetCount() ; j++)
- {
- pPoints = pParts->Get(j);
- for ( k = 0 ; k < pPoints->GetCount(); k++ )
- {
- pPoint = pPoints->Get(k);
- pPtArray[m].x = (int)((pPoint->GetX() - draw.m_StartX)/draw.m_Scale);
- pPtArray[m++].y = (long)((draw.m_StartY - pPoint->GetY() )/draw.m_Scale);
-
- }
- }
-
- }
- if ( pPolygon->GetCount() > 1)
- pDC->PolyPolygon(pPtArray,pPolygonCount,iCount); //绘制复合多边形
- else
- pDC->Polygon(pPtArray, m);
- delete []pPolygonCount;
- delete []pPtArray;
- }