📄 shpfile.cpp
字号:
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 == 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 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -