高分求解读写arcview的shape文件的c++代码(200分)

  • 主题发起人 gzljh2003
  • 开始时间
G

gzljh2003

Unregistered / Unconfirmed
GUEST, unregistred user!

峻祁连

Unregistered / Unconfirmed
GUEST, unregistred user!
delphi的行不行?
http://delphibbs.com/delphibbs/dispq.asp?lid=758924
 
H

Haw Wang

Unregistered / Unconfirmed
GUEST, unregistred user!
告诉你一个网址
www.freegis.org
这里有你要的东西,大概叫shapelib吧,我试过,简单的一些读写功能可以实现。
另外
http://www.nrdb.co.uk/
有一个带源码的程序,可以编辑shape文件。
 

吕雪松

Unregistered / Unconfirmed
GUEST, unregistred user!
class GeoFile
{
private:
virtual BOOL ReadFileHeader(GeoLayer* pLayer);
virtual BOOL ReadObjHeader(GeoObj**);
virtual BOOL ReadObjXY(GeoObj* pObj);
public:
UINT fileFlag; //CFile打开方式
UINT arMode; //CArchive 打开方式
LPCSTR szFileName;
GeoFile(LPCSTR szFileName);
virtual ~GeoFile();
public:
virtual void ReadToLayer(GeoLayer* pLayer);
virtual void OpenFile(UINT nOpenFlag);
virtual void SaveFile();
virtual void CloseFile();
};

class GeoShapeFile : public GeoFile
{
private:
int nBigInt;
BYTE buf8_1,buf8_2,buf8_3,buf8_4;
int buf32;
double buf64;
//用于转换BigInt的两个函数
int GetBigIntFrom4Byte(BYTE A1,BYTE A2,BYTE A3,BYTE A4); //将连续的四个字节转化为一个BigInt
int GetBigIntFromInt(int VV); //将一个普通int转化为BigInt
private:
BOOL ReadFileHeader(GeoLayer* pLayer);
BOOL ReadObjHeader(GeoObj**);
BOOL ReadObjXY(GeoObj* pObj);
public:
CFile shpFile;
GeoShapeFile(LPCSTR fileName);
virtual ~GeoShapeFile();
virtual void OpenFile(UINT nOpenFlag);
virtual void SaveFile();
virtual void CloseFile();
virtual void ReadToLayer(GeoLayer* pLayer);
};

//////////////////////////////////////////////////////////////////////////
// GeoShapeFile ArcView Shape 3.0文件定义
//////////////////////////////////////////////////////////////////////////
GeoShapeFile::GeoShapeFile(LPCSTR szFileName) : GeoFile(szFileName)
{

}

GeoShapeFile::~GeoShapeFile()
{

}

void GeoShapeFile::OpenFile(UINT nOpenFlag)
{
shpFile.Open(szFileName,nOpenFlag);
}

void GeoShapeFile::SaveFile()
{
GeoFile::SaveFile();
}

void GeoShapeFile::CloseFile()
{
GeoFile::CloseFile();
shpFile.Close();
}

BOOL GeoShapeFile::ReadFileHeader(GeoLayer* pLayer)
{
for (int i = 1;i<=7;i++){
shpFile.Read(&amp;buf8_1,sizeof(BYTE));
shpFile.Read(&amp;buf8_2,sizeof(BYTE));
shpFile.Read(&amp;buf8_3,sizeof(BYTE));
shpFile.Read(&amp;buf8_4,sizeof(BYTE));
//9994
nBigInt = GetBigIntFrom4Byte(buf8_1,buf8_2,buf8_3,buf8_4);
}
//version
shpFile.Read(&amp;buf32,sizeof(int));
//shptype
shpFile.Read(&amp;buf32,sizeof(int));

switch (buf32) {
case 1 : {
pLayer->m_nLayerType = 1;
break;
} //点
case 3 : {
pLayer->m_nLayerType = 2;
break;
} //线
case 5 : {
pLayer->m_nLayerType = 3;
break;
}//多边形
case 8 : {
pLayer->m_nLayerType = 1;
break;
}//多点
}

shpFile.Read(&amp;buf64,sizeof(buf64));
pLayer->m_layerRect.left = buf64;
shpFile.Read(&amp;buf64,sizeof(buf64));
pLayer->m_layerRect.top = buf64;
shpFile.Read(&amp;buf64,sizeof(buf64));
pLayer->m_layerRect.right = buf64;
shpFile.Read(&amp;buf64,sizeof(buf64));
pLayer->m_layerRect.bottom = buf64;

//以下32个字节没有使用,跳过
shpFile.Seek(32,CFile::current);
return TRUE;
}

BOOL GeoShapeFile::ReadObjHeader(GeoObj** pObj)
{
//读记录号,为整数
if (shpFile.Read(&amp;buf8_1,sizeof(BYTE)) < sizeof(BYTE))
return FALSE;
*pObj = new GeoObj;
shpFile.Read(&amp;buf8_2,sizeof(BYTE));
shpFile.Read(&amp;buf8_3,sizeof(BYTE));
shpFile.Read(&amp;buf8_4,sizeof(BYTE));
sprintf((*pObj)->m_nObjHeader.id,"%d",GetBigIntFrom4Byte(buf8_1,buf8_2,buf8_3,buf8_4));
//get ID from record NO
//记录长度,不要
shpFile.Read(&amp;buf8_1,sizeof(BYTE));
shpFile.Read(&amp;buf8_2,sizeof(BYTE));
shpFile.Read(&amp;buf8_3,sizeof(BYTE));
shpFile.Read(&amp;buf8_4,sizeof(BYTE));

shpFile.Read(&amp;buf32,sizeof(int));
//get shape type
switch(buf32){
case 1 : {
(*pObj)->m_nObjHeader.ObjType = 1;
break;
}
case 3 : {
(*pObj)->m_nObjHeader.ObjType = 2;
break;
}
case 5 : {
(*pObj)->m_nObjHeader.ObjType = 3;
break;
}
case 8 : {
(*pObj)->m_nObjHeader.ObjType = 4;
break;
}
}
if ((*pObj)->m_nObjHeader.ObjType == 1) {
(*pObj)->m_nObjHeader.m_nPtCount = 1;
}
else
if ((*pObj)->m_nObjHeader.ObjType == 2 || (*pObj)->m_nObjHeader.ObjType == 3){
///////////读BOX//////////////
shpFile.Read(&amp;buf64,sizeof(double));
(*pObj)->m_nObjHeader.objRect.left = buf64;
shpFile.Read(&amp;buf64,sizeof(double));
(*pObj)->m_nObjHeader.objRect.top = buf64;
shpFile.Read(&amp;buf64,sizeof(double));
(*pObj)->m_nObjHeader.objRect.right = buf64;
shpFile.Read(&amp;buf64,sizeof(double));
(*pObj)->m_nObjHeader.objRect.bottom = buf64;
///////////读部分数////////
shpFile.Read(&amp;buf32,sizeof(int));
(*pObj)->m_nObjHeader.subObjNum = buf32;
///////////读总的点数///////
shpFile.Read(&amp;buf32,sizeof(int));
(*pObj)->m_nObjHeader.m_nPtCount = buf32;
//读每个部分的起点号
(*pObj)->m_nObjHeader.pnVerPt = (int*)malloc((*pObj)->m_nObjHeader.subObjNum * sizeof(int));
for (int i = 0;i< (*pObj)->m_nObjHeader.subObjNum;i++){
shpFile.Read(&amp;buf32,sizeof(int));
(*pObj)->m_nObjHeader.pnVerPt = buf32;
}
}
return TRUE;
}

BOOL GeoShapeFile::ReadObjXY(GeoObj* pObj)
{
GeoPt* pt;
for (int i = 0;i< pObj->m_nObjHeader.m_nPtCount;i++){
pt = new GeoPt;
shpFile.Read(&amp;buf64,sizeof(double));
pt->x = buf64;
shpFile.Read(&amp;buf64,sizeof(double));
pt->y = buf64;
pObj->AddPt(pt);
}
return TRUE;
}

void GeoShapeFile::ReadToLayer(GeoLayer* pLayer)
{
GeoObj* pObj;

ReadFileHeader(pLayer);

pLayer->m_dataSource = "ArcView Shape";
pLayer->m_dataAuthor = "3G";
pLayer->m_dataVersion = "1000";

while (TRUE){
if (!ReadObjHeader(&amp;pObj)){ //pObj在子函数内部分配内存
//到文件结束
break;
}
//SHP文件的地物类型同图层一致
pObj->m_nObjHeader.ObjType = pLayer->m_nLayerType;

if (!ReadObjXY(pObj)){
break;
}

//对于SHP文件的地物,缺省的Brush为白色,Pen为黑色,Font为缺省字体

pObj->m_Pen.m_Pen.lopnColor = RGB(0,0,0);
pObj->m_Brush.m_Brush.lbColor = RGB(220,255,220);
//pObj->m_Font.CreateStockObject(DEFAULT_GUI_FONT);

((GeoVectorLayer*)pLayer)->AddObj(pObj);
}

//Connect dbf table to m_infoTable
CString sTableName = pLayer->m_layerName + ".dbf";

CString sDatabaseName = pLayer->m_layerPath;
sDatabaseName.MakeReverse();
sDatabaseName.Delete(0,sDatabaseName.Find("//",0));
sDatabaseName.MakeReverse();

//construct connect string
CString sConnStr;
sConnStr = "select * from [" + sTableName + "]";

CDaoDatabase db;
// db.Open(sDatabaseName,FALSE,FALSE,"dBASE III;");

// ((GeoVectorLayer*)pLayer)->m_infoTable.m_pDatabase = &amp;db;
// ((GeoVectorLayer*)pLayer)->m_infoTable.Open(dbOpenDynaset,sConnStr);
// ((GeoVectorLayer*)pLayer)->m_infoTable.MoveLast();
// ((GeoVectorLayer*)pLayer)->nFieldCount = ((GeoVectorLayer*)pLayer)->m_infoTable.GetFieldCount();
// char info[100];
// sprintf(info,"%d",((GeoVectorLayer*)pLayer)->m_infoTable.GetRecordCount());
// TRACE(info);
}

int GeoShapeFile::GetBigIntFrom4Byte(BYTE A1,BYTE A2,BYTE A3,BYTE A4) //将连续的四个字节转化为一个BigInt
{
return A1 * 16777216 +A2 * 65536+ A3 * 256+A4;
}

int GeoShapeFile::GetBigIntFromInt(int VV) //将一个普通int转化为BigInt
{
buf8_1 = VV >> 24;

buf8_2 = (VV << 8) >> 24;
buf8_3 = (VV << 16) >> 24;
buf8_4 = (VV << 24) >> 24;
return buf8_4 * 16777216 + buf8_3 * 65536 + buf8_2 * 256 + buf8_1;
}
 
G

giswang

Unregistered / Unconfirmed
GUEST, unregistred user!
头文件

enum
{
SHPNullShape=0,
SHPPoint=1,
SHPPolyLine=3,
SHPPolygon=5,
SHPMultipoint=8,
SHPPointZ=11,
SHPPolyLineZ=13,
SHPPolygonZ=15,
SHPMultiPointZ=18,
SHPPointM=21,
SHPPolyLineM=23,
SHPPolygonM=25,
SHPMultipointM=28,
SHPMultiPatch=31
};

#pragma pack(1)

struct CMainHeader
{
int m_nFileCode;
// Big Endian
int m_nUnused1;
// ""
int m_nUnused2;
int m_nUnused3;
int m_nUnused4;
int m_nUnused5;
int m_nFileLength;
int m_nVersion;
// Little endian
int m_nShapeType;
// ""
do
uble m_dXMin;
do
uble m_dYMin;
do
uble m_dXMax;
do
uble m_dYMax;
do
uble m_dZMin;
do
uble m_dZMax;
do
uble m_dMMin;
do
uble m_dMMax;

};

struct CRecordHeader
{
int m_nRecordNumber;
// Big Endian
int m_nContentLength;
// ""
};

struct CIndexRecord
{
int m_nOffset;
int m_nContentLength;
};

struct CPolyLine
{
CPolyLine();

do
uble m_dBox[4];
// Little endian
DWORD m_nParts;
// ""
DWORD m_nPoints;

};

struct CShapePoint
{
do
uble m_dX;
// Little endian
do
uble m_dY;

};

struct CDBFHeader
{
BYTE m_nValid;
char m_aDate[3];
int m_nNumRecords;
short m_nHeaderBytes;
short m_nRecordBytes;
BYTE m_nReserved1[3];
BYTE m_nReserved2[13];
BYTE m_nReserved3[4];
};

struct CDBFDescriptor
{
char m_sName[11];
BYTE m_nType;
BYTE m_nAddress[4];
BYTE m_nFieldLength;
BYTE m_nFieldCount;
BYTE m_nReserved1[2];
BYTE m_nWorkArea;
BYTE m_nReserved2[2];
BYTE m_nSetFieldsFlag;
BYTE m_nReserved3[8];
};


struct CDBFRecordPoint
{
char m_sID[8];

char m_sName[32];

};

#define DBF_TEXT 256
#define DBF_NUMBER 16
#define DBF_BOOL 1
#define DBF_DATE 8

//////////////////////////////////////////////////////////////////////

class CShapeFile
{
public:
CShapeFile();
virtual ~CShapeFile();

BOOL ImportShapeFile(CMapLines* pMapLines, LPCSTR sFileName);

BOOL ExportShapeFile(CMapLines* pMapLines, LPCSTR sFileName, int nFlags);

BOOL ExportShapeFile(CMapLayer* pMapLayer, LPCSTR sFileName, int nFlags);

BOOL ImportShapeFile(CMapLayer* pMapLayer, LPCSTR sFileName);

void Convert();

enum {LatLon=1, Header=2, PolyLine=4, Points=8, Polygon=16};

protected:

BOOL ImportPolyLine(CMapLines* pMapLines, FILE* pFile, BOOL bLatLon, CRectDbl* pRect = NULL);
BOOL ImportPoints(CCoordArray* pPoints, FILE* pFile, BOOL bLatLon);
BOOL ExportPoints(CMapLayer* pMapLayer, FILE* pFile, BOOL bLatLon);
BOOL ImportDBase(CMapLayer* pMapLayer, LPCSTR sFileName);

BOOL ExportPolyLine(CMapLayer* pMapLayer, FILE* pFile, BOOL bLatLon, DWORD nShape);
BOOL ExportShapeFilePoint(CMapLayer* pMapLayer, LPCSTR sFileName, BOOL bLatLon);
BOOL ExportShapeFilePoly(CMapLayer* pMapLayer, LPCSTR sFileName, BOOL bLatLon);
BOOL ExportIndexFile(CPolyLine&amp;
polyline, CMapLayer* pMapLayer, LPCSTR sFileName, CMainHeader&amp;
mainheader);
BOOL ExportIndexFile(CMapLayer* pMapLayer, LPCSTR sFileName, CMainHeader&amp;
mainheader);

BOOL ExportDBase(CMapLayer* pMapLayer, LPCSTR sFileName);
int ReverseBytes(int);
CPolyLine GetBoundingBoxPoly(CMapLines* pMapLines, BOOL bLatLon, int i1 = 0, int j2 = 0);
CPolyLine GetBoundingBox(CMapLayer* pMapLayer, BOOL bLatLon);
CPolyLine GetNumParts(CMapLines* pMapLines);
CString GetLineText(CMapLayer*, CMapLayerObj*);
void fwritex(void* p, size_t size, DWORD n, FILE* pFile);

BOOL ConvertShapeFile();
BOOL ConvertPolyLine();
BOOL ConvertPoints();
BOOL ConvertIndex();
BOOL ConvertDBaseFile();

BOOL PolylineToPolygon(CMapLayer*);

};

CPP:
//////////////////////////////////////////////////////////////////////

inline void Swap(double &amp;A,do
uble&amp;
B)
{
do
uble C = A;
A = B;
B = C;
}

inline void Swap(int &amp;A, int&amp;
B)
{
int C = A;
A = B;
B = C;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction

CShapeFile::CShapeFile()
{
}

CShapeFile::~CShapeFile()
{

}

//////////////////////////////////////////////////////////////////////

CPolyLine::CPolyLine()
{
for (int i = 0;
i < 4;
i++ ) m_dBox = 0;
m_nParts = 0;
m_nPoints = 0;
}

///////////////////////////////////////////////////////////////////////////////

void CShapeFile::fwritex(void* p, size_t size, DWORD n, FILE* pFile)
{
if (fwrite(p, size, n, pFile) != n)
{
AfxThrowUserException();
}
}

///////////////////////////////////////////////////////////////////////////////
//
// Import a shapefile with each record as a separate layer, this should overcome the
// problem of reallocating memory all the time for large files
//

BOOL CShapeFile::ImportShapeFile(CMapLayer* pMapLayer, LPCSTR sFileName)
{
BOOL bOK = TRUE;

CRecordHeader recordheader;
CMainHeader mainheader;
DWORD nShape;

int nBytes = sizeof(CMainHeader);
int iFlag = 0;

// Open the file as binary

FILE* pFile = fopen(sFileName, "rb");
if (pFile != NULL)
{
// Read the file header

if (fread(&amp;mainheader, sizeof(CMainHeader),1,pFile) == 1)
{
mainheader.m_nFileCode = ReverseBytes(mainheader.m_nFileCode);
mainheader.m_nFileLength = ReverseBytes(mainheader.m_nFileLength);

// Determine if lat/long or coordinates

if (mainheader.m_dXMin >= -180 &amp;&amp;
mainheader.m_dXMax <= 180 &amp;&amp;
mainheader.m_dYMax <= 90 &amp;&amp;
mainheader.m_dYMin >= -90)
{
iFlag |= LatLon;
}

// Latitude/longitude not supported

if (iFlag &amp;
LatLon)
{
AfxMessageBox("This shapefile appears to be in latitude/longitude. This version "
"of NRDB View only accepts data in metres.");
bOK = FALSE;
}

// Read the record header

while (bOK &amp;&amp;
fread(&amp;recordheader, sizeof(CRecordHeader),1,pFile) == 1 &amp;&amp;

!(iFlag &amp;
Header))
{
// Read the shape type
if (fread(&amp;nShape,sizeof(nShape),1,pFile) == 1)
{
CMapLayerObj* pMapLayerObj = new CMapLayerObj;

// Import only polylines

if (nShape == SHPPolyLine || nShape == SHPPolygon)
{
CMapLines* pMapLines = new CMapLines;
pMapLayerObj->SetMapObject(pMapLines);

pMapLayerObj->SetDataType(BDMAPLINES);

CRectDbl rect;
bOK = ImportPolyLine(pMapLines, pFile, iFlag &amp;
LatLon, &amp;rect);

// Set the extent

pMapLayerObj->GetExtent() = rect;

}

else
if (nShape == SHPPoint)
{
CCoordArray aCoord;
bOK = ImportPoints(&amp;aCoord, pFile, iFlag &amp;
LatLon);

CCoord* pCoord = new CCoord(aCoord[0]);

pMapLayerObj->SetMapObject(pCoord);
pMapLayerObj->SetDataType(BDCOORD);

// Set the extent

pMapLayerObj->GetExtent().left = pCoord->x;
pMapLayerObj->GetExtent().top = pCoord->y;
pMapLayerObj->GetExtent().right = pCoord->x;
pMapLayerObj->GetExtent().bottom = pCoord->y;


}
// Skip the record

else

{
// Handles corrupt shapefile

if (nShape != 0)
{
bOK = FALSE;
} else
if (mainheader.m_nShapeType == SHPPolyLine || mainheader.m_nShapeType == SHPPolygon)
{
CMapLines* pMapLines = new CMapLines;
pMapLayerObj->SetMapObject(pMapLines);

pMapLayerObj->SetDataType(BDMAPLINES);
} else
if (mainheader.m_nShapeType == SHPPoint)
{
CCoord* pCoord = new CCoord;

pMapLayerObj->SetMapObject(pCoord);
pMapLayerObj->SetDataType(BDCOORD);
}

ASSERT(nShape >= 0 &amp;&amp;
nShape <= 31);
int nContentLength = ReverseBytes(recordheader.m_nContentLength);
for (int i = 0;
bOK &amp;&amp;
i < nContentLength-2;
i++)
{
WORD word;

if (fread(&amp;word,sizeof(word),1,pFile) != 1)
{
bOK = FALSE;
}
}
}
nBytes += ReverseBytes(recordheader.m_nContentLength);

// Add to the array of map objects

pMapLayer->Add(pMapLayerObj);

} else

{
bOK = FALSE;
}
}
} else

{
bOK = FALSE;
}
}
if (pFile != NULL) fclose(pFile);


// Set the shape

if (bOK)
{
if (nShape == SHPPolygon) pMapLayer->GetMapProp().m_nShapeType = CViewMap::polygon;
else
if (nShape == SHPPolyLine) pMapLayer->GetMapProp().m_nShapeType = CViewMap::polyline;
else
if (nShape == SHPPoint) pMapLayer->GetMapProp().m_nShapeType = CViewMap::points;

}

// Import the corresponding data

if (bOK)
{
bOK = ImportDBase(pMapLayer, sFileName);
}

// Report on error

if (!bOK)
{
AfxMessageBox("Invalid shapefile");
bOK = FALSE;
}

return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Import polylines or the format
//

BOOL CShapeFile::ImportPolyLine(CMapLines* pMapLines, FILE* pFile, BOOL bLatLon, CRectDbl* pRect)
{
CPolyLine polyline;
BOOL bOK = TRUE;
CArray <DWORD,DWORD> anParts;
CArray <double,double> adPoints;
CCoord coord;

// Read header

if (fread(&amp;polyline, sizeof(CPolyLine), 1, pFile))
{
// Assign space for data

anParts.SetSize(polyline.m_nParts);

adPoints.SetSize(polyline.m_nPoints*2);

// Read data

if (fread(anParts.GetData(),sizeof(int),polyline.m_nParts, pFile) == polyline.m_nParts &amp;&amp;
fread(adPoints.GetData(), sizeof(double)*2,polyline.m_nPoints, pFile) == polyline.m_nPoints)
{
// Add a last point to the list of points showing the last array

anParts.Add(polyline.m_nPoints);

int k = pMapLines->GetSize();
pMapLines->SetSize(pMapLines->GetSize() + polyline.m_nPoints+polyline.m_nParts);

// Preallocate the size of the array

for (DWORD i = 0;
i < polyline.m_nParts;
i++)
{
for (DWORD j = anParts;
j < anParts[i+1];
j++)
{
do
uble dX = adPoints[j*2];
do
uble dY = adPoints[j*2+1];

coord.x = dX;
coord.y = dY;

// Convert the units to metres

pMapLines->SetAt(k++, coord);
}
coord.SetNull();
if (i+1 == polyline.m_nParts) coord.SetEOL();
pMapLines->SetAt(k++, coord);

}
}
else

{
bOK = FALSE;
}
} else

{
bOK = FALSE;
}

// Optimization, store extent read from shapefile

if (bOK &amp;&amp;
pRect != NULL)
{
pRect->left = polyline.m_dBox[0];
pRect->right = polyline.m_dBox[2];
pRect->top = polyline.m_dBox[1];
pRect->bottom = polyline.m_dBox[3];

if (pRect->top > pRect->bottom) Swap(pRect->top, pRect->bottom);
}

return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Imports a single point into the array of points from a shapefile
//

BOOL CShapeFile::ImportPoints(CCoordArray* pPoints, FILE* pFile, BOOL bLatLon)
{
CShapePoint shapepoint;

BOOL bOK = TRUE;

CCoord coord;

// Read header

if (fread(&amp;shapepoint, sizeof(shapepoint), 1, pFile))
{
do
uble dX = shapepoint.m_dX;
do
uble dY = shapepoint.m_dY;

coord.x = dX;
coord.y = dY;

pPoints->Add(coord);

} else

{
bOK = FALSE;
}
return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Import the data from the DBase file corresponding to the shapefile into the
// CAttrArray part of the map layer
//

BOOL CShapeFile::ImportDBase(CMapLayer* pMapLayer, LPCSTR sFileName)
{
BOOL bOK = TRUE;
CDBFHeader header;
CDBFDescriptor descriptor;
BYTE nRecord;
BYTE nTerminator;
BYTE* pBuffer = NULL;
int nBufferLen = 0;

CAttrArray&amp;
aAttr = pMapLayer->GetAttr();


// Determine the file name

CString sDBaseFile = sFileName;
sDBaseFile = sDBaseFile.Left(sDBaseFile.ReverseFind('.'));
sDBaseFile += ".dbf";


// Open the file

FILE* pFile = fopen(sDBaseFile, "rb");
if (pFile != NULL)
{
// Read header information

if (fread(&amp;header, sizeof(header), 1, pFile) == 1 &amp;&amp;

header.m_nValid == 0x03)
{
// Read the field types

int nFields = (header.m_nHeaderBytes - sizeof(header) - sizeof(BYTE)) /
sizeof(descriptor);

aAttr.SetSize(nFields);

for (int i = 0;
i < nFields &amp;&amp;
bOK;
i++)
{
if (fread(&amp;descriptor, sizeof(descriptor), 1, pFile) == 1)
{
// Determine the type

if (descriptor.m_nType == 'N') aAttr.SetDataType(BDNUMBER);
else
if (descriptor.m_nType == 'D') aAttr.SetDataType(BDDATE);
else
if (descriptor.m_nType == 'L') aAttr.SetDataType(BDBOOLEAN);
else
aAttr.SetDataType(BDTEXT);

// Determine the length

aAttr.SetLength(descriptor.m_nFieldLength);

// Set the title

CString sDesc;

strncpy(sDesc.GetBuffer(11), descriptor.m_sName, 11);
aAttr.SetDesc(sDesc);

};

}

// Skip the header terminator character

fread(&amp;nTerminator,sizeof(BYTE),1,pFile);


// Set the number of rows

aAttr.SetNumRows(header.m_nNumRecords);

// Now read the data

for (i = 0;
i < header.m_nNumRecords;
i++)
{
// Read the record separator

fread(&amp;nRecord,sizeof(BYTE),1,pFile);

for (int j = 0;
j < nFields;
j++)
{
// Allocate buffer to read data into

if (aAttr[j].GetLength() > nBufferLen)
{
nBufferLen = aAttr[j].GetLength();
if (pBuffer != NULL) delete [] pBuffer;
pBuffer = new BYTE[nBufferLen];
}

// Now read the record

fread(pBuffer, aAttr[j].GetLength(), 1, pFile);

// Now store the value

aAttr[j].SetValue(i, (LPCSTR)pBuffer);
};
}
} else

{
bOK = FALSE;
}

fclose(pFile);
} else

{
bOK = TRUE;
}

// Tidy

if (pBuffer != NULL) delete pBuffer;

return bOK;
}

///////////////////////////////////////////////////////////////////////////////


BOOL CShapeFile::ExportShapeFile(CMapLines* pMapLines, LPCSTR sFileName, int nFlags)
{
BOOL bOK;

// Convert the maplines into a map object and export it

CMapLayer maplayer;
CMapLayerObj mapobj;
mapobj.SetMapObject(pMapLines);
mapobj.SetDataType(BDMAPLINES);
maplayer.Add(&amp;mapobj);
bOK = ExportShapeFile(&amp;maplayer, sFileName, nFlags);
if (bOK)
{
AfxMessageBox("Shapefile exported");
} else

{
AfxMessageBox("Error exporting shapefile");

}

mapobj.SetMapObject(NULL);
maplayer.CArray <CMapLayerObj*, CMapLayerObj*>::RemoveAll();
// Prevents deletion of memory

return bOK;
}


///////////////////////////////////////////////////////////////////////////////
//
// Exports map lines in the format of a shape file
//

BOOL CShapeFile::ExportShapeFilePoly(CMapLayer* pMapLayer, LPCSTR sFileName, int nFlags)
{
BOOL bOK = TRUE;
CMainHeader mainheader;

CPolyLine polyline;
DWORD nShape = SHPPolyLine;
FILE* pFile = NULL;

// Retrieve query data

BOOL bLatLon = nFlags &amp;
LatLon;

if (nFlags &amp;
Polygon) nShape = nShape = SHPPolygon;

// If polygon, make sure that the last point is closed

if (nShape == SHPPolygon)
{
PolylineToPolygon(pMapLayer);
};

// Determine the extend of the points

polyline = GetBoundingBox(pMapLayer, bLatLon);

memset(&amp;mainheader,0,sizeof(mainheader));

mainheader.m_dXMin = polyline.m_dBox[0];
mainheader.m_dXMax = polyline.m_dBox[2];
mainheader.m_dYMin = polyline.m_dBox[1];
mainheader.m_dYMax = polyline.m_dBox[3];


// Initialise the polyline

polyline.m_nParts = 0;
polyline.m_nPoints = 0;


// First create the header

mainheader.m_nFileCode = ReverseBytes(9994);

mainheader.m_nVersion = 1000;
mainheader.m_nShapeType = nShape;


// Count the number of points, exclude repeating null values

for (int j = 0;
j < pMapLayer->GetSize();
j++)
{
CMapLayerObj* pMapObj = pMapLayer->GetAt(j);
if (pMapObj->GetDataType() == BDMAPLINES)
{
CMapLines* pMapLines = (CMapLines*)pMapObj->GetMapObject();


CPolyLine polylineP = GetNumParts(pMapLines);
polyline.m_nParts += polylineP.m_nParts;
polyline.m_nPoints += polylineP.m_nPoints;

}
};

// Determine the file length

// Support for multipart polylines
int nFileLength = sizeof(CMainHeader) + (sizeof(CRecordHeader) + sizeof(CPolyLine) + sizeof(int)) * pMapLayer->GetSize() +
sizeof(int) * polyline.m_nParts + sizeof(double)*2 * polyline.m_nPoints;

mainheader.m_nFileLength = ReverseBytes(nFileLength/2);

// Open the file as binary

TRY
{
pFile = fopen(sFileName, "wb");
if (pFile != NULL)
{
// Write the file header

if (fwrite(&amp;mainheader, sizeof(CMainHeader),1,pFile) == 1)
{
bOK = ExportPolyLine(pMapLayer, pFile, bLatLon, nShape);
} else

{
bOK = FALSE;
}
}
} CATCH(CException, ex)
{
bOK = FALSE;
} END_CATCH

if (pFile != NULL) fclose(pFile);

// Export the index file

if (bOK)
{
bOK = ExportIndexFile(polyline, pMapLayer, sFileName, mainheader);
};

// Export DBASE format

if (bOK)
{
bOK = ExportDBase(pMapLayer, sFileName);
};

return bOK;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CShapeFile::polylineToPolygon(CMapLayer* pMapLayer)
{
CCoord coord1, coord2;

for (int j = 0;
j < pMapLayer->GetSize();
j++)
{
CMapLayerObj* pMapLayerObj = pMapLayer->GetAt(j);
CMapLines* pMapLines = (CMapLines*)pMapLayerObj->GetMapObject();

// For each map lines, close polygons

for (int i = 0;
i < pMapLines->GetSize();
i++)
{
// Determine the start of a line

if (!pMapLines->GetAt(i).IsNull() &amp;&amp;

(i == 0 || (i > 0 &amp;&amp;
pMapLines->GetAt(i-1).IsNull())))
{
coord1 = pMapLines->GetAt(i);
}

// Determine the end of a line

if (i + 1 < pMapLines->GetSize() &amp;&amp;

pMapLines->GetAt(i+1).IsNull() &amp;&amp;
!pMapLines->GetAt(i).IsNull())
{
coord2 = pMapLines->GetAt(i);

// If the two ends are not the same then
make them the same

if (coord1.x != coord2.x &amp;&amp;
coord1.y != coord2.y)
{
pMapLines->InsertAt(i+1, coord1);

i++;
}
}
}
}
return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//
// Exports the polyline part of the shape file - retains multipart polylines
//

BOOL CShapeFile::ExportPolyLine(CMapLayer* pMapLayer, FILE* pFile, BOOL bLatLon, DWORD nShape)
{
BOOL bOK = TRUE;

CRecordHeader recordheader;

CPolyLine polyline;

// Determine parts

int nRecord = 1;

for (int j = 0;
j < pMapLayer->GetSize();
j++)
{
BOOL bStart = TRUE;

CMapLayerObj* pMapObj = pMapLayer->GetAt(j);
if (pMapObj->GetDataType() == BDMAPLINES)
{
CMapLines* pMapLines = (CMapLines*)pMapObj->GetMapObject();


// Determine bounding rectangle

polyline = GetBoundingBoxPoly(pMapLines, bLatLon);


// For each polyline determine its parts

CLongArray anParts;
anParts.Add(0);

polyline.m_nPoints = 0;
for (int k = 0;
k < pMapLines->GetSize();
k++)
{
CCoord coord = pMapLines->GetAt(k);
if (!coord.IsNull()) polyline.m_nPoints++;
else
if (k + 1 < pMapLines->GetSize()) anParts.Add(polyline.m_nPoints);

}
polyline.m_nParts = anParts.GetSize();


// Write record header

recordheader.m_nRecordNumber = ReverseBytes(nRecord++);
int nRecordLength = sizeof(int) + sizeof(CPolyLine) + sizeof(int)*polyline.m_nParts +
sizeof(double)*2 * polyline.m_nPoints;
recordheader.m_nContentLength = ReverseBytes(nRecordLength/2);

fwritex(&amp;recordheader, sizeof(CRecordHeader),1,pFile);

// Write shape type

fwritex(&amp;nShape,sizeof(nShape),1,pFile);

// Write polyline record contents

fwritex(&amp;polyline, sizeof(CPolyLine),1,pFile);

// Write the parts data

fwritex(anParts.GetData(), sizeof(int),anParts.GetSize(),pFile);

// Write the points data

for (int i = 0;
i < pMapLines->GetSize() &amp;&amp;
bOK;
i++)
{
CCoord coord = pMapLines->GetAt(i);
if (!coord.IsNull())
{
// Output the data

do
uble dX = coord.x;
do
uble dY = coord.y;

fwritex(&amp;dX, sizeof(double), 1, pFile);
fwritex(&amp;dY, sizeof(double), 1, pFile);

}
}
}
}
return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Export an entire layer to a shape file (as points)
//

BOOL CShapeFile::ExportPoints(CMapLayer* pMapLayer, FILE* pFile, BOOL bLatLon)
{
BOOL bOK = TRUE;
DWORD nShape = SHPPoint;
CRecordHeader recordheader;

CShapePoint point;


// Determine parts

int nRecord = 1;

for (int i = 0;
i < pMapLayer->GetSize() &amp;&amp;
bOK;
i++)
{
CCoord* pCoord = (CCoord*)pMapLayer->GetAt(i)->GetMapObject();


// Initialise the header

recordheader.m_nRecordNumber = ReverseBytes(nRecord++);

int nRecordLength = sizeof(CShapePoint) + sizeof(int);
recordheader.m_nContentLength = ReverseBytes(nRecordLength/2);

// Write the record header

fwritex(&amp;recordheader, sizeof(CRecordHeader),1,pFile);

// Write the shape type

fwritex(&amp;nShape,sizeof(nShape),1,pFile);

// Write the x,y data

point.m_dX = pCoord->x;
point.m_dY = pCoord->y;

fwritex(&amp;point, sizeof(CShapePoint), 1, pFile);

}

return bOK;

}


///////////////////////////////////////////////////////////////////////////////
//
// Export the index file (points)
//

BOOL CShapeFile::ExportIndexFile(CMapLayer* pMapLayer, LPCSTR sFileName, CMainHeader&amp;
mainheader)
{
CIndexRecord indexrecord;

FILE* pFile = NULL;
BOOL bOK = TRUE;

CString sIndexFile = sFileName;
sIndexFile = sIndexFile.Left(sIndexFile.ReverseFind('.'));
sIndexFile += ".shx";


TRY
{
pFile = fopen(sIndexFile,"wb");
if (pFile != NULL)
{
// Write the header

int nFileLength = sizeof(CMainHeader)+sizeof(CIndexRecord)*pMapLayer->GetSize();
mainheader.m_nFileLength = ReverseBytes(nFileLength/2);
fwritex(&amp;mainheader, sizeof(CMainHeader),1,pFile);

// Determine the indexes

indexrecord.m_nOffset = ReverseBytes((sizeof(CMainHeader)-sizeof(CRecordHeader))/2);
indexrecord.m_nContentLength = 0;

for (int i = 0;
i < pMapLayer->GetSize() &amp;&amp;
bOK;
i++)
{
CCoord* pCoord = (CCoord*)pMapLayer->GetAt(i)->GetMapObject();


// Write record header

indexrecord.m_nOffset = ReverseBytes(indexrecord.m_nContentLength)+
ReverseBytes(indexrecord.m_nOffset) +
sizeof(CRecordHeader)/2;
indexrecord.m_nOffset = ReverseBytes(indexrecord.m_nOffset);

int nRecordLength = sizeof(CShapePoint) + sizeof(int);
indexrecord.m_nContentLength = ReverseBytes(nRecordLength/2);

// Write the record header

fwritex(&amp;indexrecord, sizeof(CIndexRecord),1,pFile);

}
} else

{
bOK = FALSE;
}
}
CATCH (CException, ex)
{
bOK = FALSE;
} END_CATCH

if (pFile != NULL) fclose(pFile);

return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Export the index file multi-part polygons
//

BOOL CShapeFile::ExportIndexFile(CPolyLine&amp;
polyline, CMapLayer* pMapLayer, LPCSTR sFileName, CMainHeader&amp;
mainheader)
{
CIndexRecord indexrecord;

FILE* pFile = NULL;
BOOL bOK = TRUE;

CString sIndexFile = sFileName;
sIndexFile = sIndexFile.Left(sIndexFile.ReverseFind('.'));
sIndexFile += ".shx";


TRY
{
pFile = fopen(sIndexFile,"wb");
if (pFile != NULL)
{
// Write the header

int nFileLength = sizeof(CMainHeader)+sizeof(CIndexRecord)*pMapLayer->GetSize();
mainheader.m_nFileLength = ReverseBytes(nFileLength/2);
fwritex(&amp;mainheader, sizeof(CMainHeader),1,pFile);

// Determine the indexes

indexrecord.m_nOffset = ReverseBytes(sizeof(CMainHeader)/2);


for (int j = 0;
j < pMapLayer->GetSize() &amp;&amp;
bOK;
j++)
{
CMapLayerObj* pMapObj = pMapLayer->GetAt(j);
if (pMapObj->GetDataType() == BDMAPLINES)
{
// For each polyline determine its parts

CMapLines* pMapLines = (CMapLines*)pMapObj->GetMapObject();

polyline.m_nPoints = 0;
polyline.m_nParts = 1;
for (int k = 0;
k < pMapLines->GetSize();
k++)
{
CCoord coord = pMapLines->GetAt(k);
if (!coord.IsNull()) polyline.m_nPoints++;
else
if (k + 1 < pMapLines->GetSize()) polyline.m_nParts++;
}
int nRecordLength = sizeof(int) + sizeof(CPolyLine) + sizeof(int)*polyline.m_nParts +
sizeof(double)*2 * polyline.m_nPoints;

// Write index
indexrecord.m_nContentLength = ReverseBytes(nRecordLength/2);
fwritex(&amp;indexrecord, sizeof(CIndexRecord),1,pFile);


// Update the next index record

int nOffSet = ReverseBytes(indexrecord.m_nOffset)*2 + nRecordLength +
sizeof(CRecordHeader);
indexrecord.m_nOffset = ReverseBytes(nOffSet/2);

} else

{
bOK = FALSE;
}
}
} else

{
bOK = FALSE;
}
}
CATCH (CException, ex)
{
bOK = FALSE;
} END_CATCH

if (pFile != NULL) fclose(pFile);

return bOK;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CShapeFile::ExportShapeFile(CMapLayer* pMapLayer, LPCSTR sFileName, int nFlags)
{
BOOL bOK = TRUE;


if (pMapLayer->GetSize() == 0)
{
AfxMessageBox("No data in layer");

}


if (pMapLayer->GetAt(0)->GetDataType() == BDMAPLINES)
{
bOK = ExportShapeFilePoly(pMapLayer, sFileName, nFlags);

};

if (pMapLayer->GetAt(0)->GetDataType() == BDCOORD)
{
bOK = ExportShapeFilePoint(pMapLayer, sFileName, nFlags);

};

return bOK;
};

///////////////////////////////////////////////////////////////////////////////
//
// This exports an entire layer to a shape file
//

BOOL CShapeFile::ExportShapeFilePoint(CMapLayer* pMapLayer, LPCSTR sFileName, BOOL bLatLon)
{
BOOL bOK = TRUE;
CMainHeader mainheader;

DWORD nShape = SHPPoint;
FILE* pFile = NULL;

// Determine the extent of the points

CPolyLine polyline = GetBoundingBox(pMapLayer, bLatLon);

memset(&amp;mainheader,0,sizeof(mainheader));

mainheader.m_dXMin = polyline.m_dBox[0];
mainheader.m_dXMax = polyline.m_dBox[2];
mainheader.m_dYMin = polyline.m_dBox[1];
mainheader.m_dYMax = polyline.m_dBox[3];

// Initialise the polyline

polyline.m_nParts = 0;
polyline.m_nPoints = 0;


// First create the header

mainheader.m_nFileCode = ReverseBytes(9994);

mainheader.m_nVersion = 1000;
mainheader.m_nShapeType = nShape;


// Determine the file length

int nFileLength = sizeof(CMainHeader)+(sizeof(CRecordHeader)+sizeof(CShapePoint) + sizeof(int)*2)*pMapLayer->GetSize();

mainheader.m_nFileLength = ReverseBytes(nFileLength/2);

// Open the file as binary

TRY
{
pFile = fopen(sFileName, "wb");
if (bOK &amp;&amp;
pFile != NULL)
{
// Write the file header

if (fwrite(&amp;mainheader, sizeof(CMainHeader),1,pFile) == 1)
{
bOK = ExportPoints(pMapLayer, pFile, bLatLon);
} else

{
bOK = FALSE;
}
} else

{
bOK = FALSE;
}
} CATCH(CException, ex)
{
bOK = FALSE;
} END_CATCH

if (pFile != NULL) fclose(pFile);

// Export the index file

if (bOK)
{
bOK = ExportIndexFile(pMapLayer, sFileName, mainheader);
};


// Export DBASE format

if (bOK)
{
bOK = ExportDBase(pMapLayer, sFileName);

};
return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Retrieves a bounding box for an entire layer
//

CPolyLine CShapeFile::GetBoundingBox(CMapLayer* pMapLayer, BOOL bLatLon)
{
// Initialise polyline

CPolyLine polyline;

polyline.m_dBox[0] = DBL_MAX;
polyline.m_dBox[1] = DBL_MAX;
polyline.m_dBox[2] = -DBL_MAX;
polyline.m_dBox[3] = -DBL_MAX;

for (int i = 0;
i < pMapLayer->GetSize();
i++)
{
// Map layer

CMapLayerObj* pMapLayerObj = pMapLayer->GetAt(i);
if (pMapLayerObj->GetDataType() == BDMAPLINES)
{
CMapLines* pMapLines = (CMapLines*)pMapLayerObj->GetMapObject();
CPolyLine polylineP = GetBoundingBoxPoly(pMapLines, bLatLon);


polyline.m_dBox[0] = min(polyline.m_dBox[0], polylineP.m_dBox[0]);
polyline.m_dBox[1] = min(polyline.m_dBox[1], polylineP.m_dBox[1]);
polyline.m_dBox[2] = max(polyline.m_dBox[2], polylineP.m_dBox[2]);
polyline.m_dBox[3] = max(polyline.m_dBox[3], polylineP.m_dBox[3]);
}

// Points

else
if (pMapLayerObj->GetDataType() == BDCOORD)
{
CCoord coord = *(CCoord*)pMapLayerObj->GetMapObject();

// Convert to lat/lon if necessary

do
uble dX, dY;

dX = coord.x;
dY = coord.y;

polyline.m_dBox[0] = min(polyline.m_dBox[0], dX);
polyline.m_dBox[1] = min(polyline.m_dBox[1], dY);
polyline.m_dBox[2] = max(polyline.m_dBox[2], dX);
polyline.m_dBox[3] = max(polyline.m_dBox[3], dY);

}
}

return polyline;
}

///////////////////////////////////////////////////////////////////////////////
//
// Retrieves the bounding box for a map line
//

CPolyLine CShapeFile::GetBoundingBoxPoly(CMapLines* pMapLines, BOOL bLatLon, int i1, int i2)
{
CPolyLine polyline;

if (i1 == i2) i2 = pMapLines->GetSize();

polyline.m_dBox[0] = DBL_MAX;
polyline.m_dBox[1] = DBL_MAX;
polyline.m_dBox[2] = -DBL_MAX;
polyline.m_dBox[3] = -DBL_MAX;

for (int i = i1;
i < i2;
i++)
{
CCoord coord = pMapLines->GetAt(i);
if (!coord.IsNull())
{
polyline.m_dBox[0] = min(polyline.m_dBox[0], coord.x);
polyline.m_dBox[1] = min(polyline.m_dBox[1], coord.y);
polyline.m_dBox[2] = max(polyline.m_dBox[2], coord.x);
polyline.m_dBox[3] = max(polyline.m_dBox[3], coord.y);
};

}

return polyline;
}

///////////////////////////////////////////////////////////////////////////////

CPolyLine CShapeFile::GetNumParts(CMapLines* pMapLines)
{
CPolyLine polyline;

BOOL bStart = TRUE;
for (int i = 0;
i < pMapLines->GetSize();
i++)
{
CCoord coord = pMapLines->GetAt(i);
if (coord.IsNull())
{
bStart = TRUE;

}
else

{
if (bStart) polyline.m_nParts++;
polyline.m_nPoints++;

bStart = FALSE;
}
}
return polyline;
}

///////////////////////////////////////////////////////////////////////////////
//
// Export the dbase data for shapefile. For NRDBPro, this includes ALL
// columns from the query
//

BOOL CShapeFile::ExportDBase(CMapLayer* pMapLayer, LPCSTR sFileName)
{
BOOL bOK = TRUE;

CDBFHeader header;
CDBFDescriptor descriptor;

// Create file name

CString sIndexFile = sFileName;
sIndexFile = sIndexFile.Left(sIndexFile.ReverseFind('.'));
sIndexFile += ".dbf";


FILE* pFile = fopen(sIndexFile,"wb");

TRY
{

if (bOK &amp;&amp;
pFile != NULL)
{

// Create header

time_t time_tDate;
// Current system time and date
struct tm *pTmDate;
// Current system time and date

time(&amp;time_tDate);

pTmDate = localtime(&amp;time_tDate);


memset(&amp;header, 0, sizeof(header));
header.m_nValid = 0x03;
header.m_aDate[0] = (pTmDate->tm_year+1900)%100+100;
header.m_aDate[1] = pTmDate->tm_mon+1;
header.m_aDate[2] = pTmDate->tm_mday;

int nRecords = pMapLayer->GetAttr().GetNumRows();

header.m_nNumRecords = nRecords;


// Determine number of record bytes and fields

CAttrArray&amp;
aAttr = pMapLayer->GetAttr();
int nRecordBytes = 0;
int nFields = 0;

for (int i = 0;
i < aAttr.GetSize();
i++)
{
switch (aAttr.GetDataType())
{
case BDTEXT :
nRecordBytes += aAttr.GetLength();
nFields++;
break;
case BDBOOLEAN : nRecordBytes += DBF_BOOL;
nFields++;
break;
case BDNUMBER : nRecordBytes += DBF_NUMBER;
nFields++;
break;
case BDDATE : nRecordBytes += DBF_DATE;
nFields++;
break;
}

}

// Set number of field descriptor bytes

header.m_nHeaderBytes = sizeof(header) + sizeof(CDBFDescriptor) *
nFields + sizeof(BYTE);
header.m_nRecordBytes = nRecordBytes + sizeof(BYTE);


header.m_nReserved3[1] = 0;

fwritex(&amp;header,sizeof(header),1,pFile);

// Create the record descriptors

for (i = 0;
i < aAttr.GetSize();
i++)
{
memset(&amp;descriptor,0,sizeof(descriptor));
strncpy(descriptor.m_sName, aAttr.GetDesc(), 10);

switch (aAttr.GetDataType())
{
case BDTEXT :
descriptor.m_nType = 'C';
descriptor.m_nFieldLength = aAttr.GetLength();
break;
case BDNUMBER :
descriptor.m_nType = 'N';
descriptor.m_nFieldLength = DBF_NUMBER;
break;
case BDDATE :
descriptor.m_nType = 'D';
descriptor.m_nFieldLength = DBF_DATE;
break;
case BDBOOLEAN :
descriptor.m_nType = 'L';
descriptor.m_nFieldLength = DBF_BOOL;
break;
}
if (descriptor.m_nType != 0)
{
fwritex(&amp;descriptor,sizeof(descriptor),1,pFile);
}
}

BYTE nTerminator = 0x0D;
fwritex(&amp;nTerminator,sizeof(BYTE),1,pFile);


// Write the data

for (i = 0;
i < nRecords;
i++)
{
// Write the record separator

BYTE nRecord = 0x20;
fwritex(&amp;nRecord,sizeof(BYTE),1,pFile);

// Write the attribute data

for (int j = 0;
j < aAttr.GetSize();
j++)
{
CString s;
char record[DBF_TEXT];

memset(&amp;record, 0x20, sizeof(record));

// Get pointer to attribute, not a copy

CAttribute* pAttr = aAttr.GetData()+j;

int nLength = 0;
switch(pAttr->GetDataType())
{
case BDTEXT :
s = pAttr->GetValue(i);
strncpy(record, s, min(pAttr->GetLength(), s.GetLength()));
nLength = pAttr->GetLength();
break;
case BDNUMBER :
s.Format("%8lf", pAttr->GetDouble(i));
strncpy(record, s, DBF_NUMBER);
nLength = DBF_NUMBER;
break;
case BDBOOLEAN :
if (pAttr->GetBoolean(i) == TRUE) record[0] = 'Y';
else
if (pAttr->GetBoolean(i) == FALSE) record[0] = 'N';
else
record[0] = '?';
nLength = DBF_BOOL;
break;
case BDDATE :
CDateX date = pAttr->GetDate(i);

CString s1,s2;
s.Format("%4d",date.m_nYear);

s1.Format("%02d",date.m_nMonth);

s2.Format("%02d",date.m_nDay);

s += s1 + s2;
strncpy(record, s, min(DBF_DATE, s.GetLength()));
nLength = DBF_DATE;
break;
}
ASSERT(nLength != 0);
if (nLength != 0) fwritex(&amp;record, nLength, 1, pFile);
}
}
// Write the end of file marker

BYTE nEnd = 0x1a;
fwritex(&amp;nEnd, sizeof(nEnd), 1, pFile);

} else

{
bOK = FALSE;
}

} CATCH(CException, ex)
{
bOK = FALSE;
} END_CATCH

if (pFile != NULL) fclose(pFile);

return bOK;
}

///////////////////////////////////////////////////////////////////////////////
//
// Converts big endian to little endian
//

int CShapeFile::ReverseBytes(int n)
{
union
{
BYTE a[4];
int n;
} u,v;

u.n = n;

v.a[0] = u.a[3];
v.a[1] = u.a[2];
v.a[2] = u.a[1];
v.a[3] = u.a[0];


return v.n;
}

 
顶部