?? shpfile.cpp
字號:
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 == 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;
Sleep(200);
pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
pDC->SelectObject(&br2);
pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
i = 0;
Sleep(500);
pDC->PolyPolygon(pPtArray,pPolygonCount,iCount);
}
else
{
pDC->Polygon(pPtArray, m);
i = 0;
Sleep(200);
pDC->Polygon(pPtArray, m);
pDC->SelectObject(&br2);
pDC->Polygon(pPtArray, m);
i = 0;
Sleep(500);
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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -