1,地圖製做軟件數據庫
做爲穩定的生產工具,地圖公司通常使用MapInfo和Arcgis做爲製做地圖數據的軟件。通常使用SHP格式。數據結構
2,SHP 格式讀取ide
一個shapefile至少包括主文件*.shp,數據文件*.dbf,索引文件*.shx。通常來講在導航的開發中使用這三個文件。工具
.shp 是存儲地理的幾何屬性(點,線,面等)的文件。由文件頭和地理實體數據組成。spa
詳細的數據結構以下:設計
typedef struct tagShpFileHeader { int FileCode; // 9994 [BIG_ENDIAN] int Unused0; // 0 [BIG_ENDIAN] int Unused1; // 0 [BIG_ENDIAN] int Unused2; // 0 [BIG_ENDIAN] int Unused3; // 0 [BIG_ENDIAN] int Unused4; // 0 [BIG_ENDIAN] int FileLength; // [BIG_ENDIAN] int Version; // 1000 [LITTLE_ENDIAN] int ShapeType; // SHP_OBJ_TYPE [LITTLE_ENDIAN] double Xmin; // [LITTLE_ENDIAN] double Ymin; double Xmax; double Ymax; int Unused5; int Unused6; int Unused7; int Unused8; int Unused9; int Unused10; int Unused11; int Unused12; }SHP_FILE_HEADER;
實體數據由記錄頭和記錄內容組成,其中記錄頭文件結構以下:code
typedef struct tagShpRecordHeader { int RecordNumber; // 1..n [BIG_ENDIAN] int ContentLength; // ShpObjectByteSize/2 [BIG_ENDIAN] }SHP_RECORD_HEADER;
每個記錄內容記錄了一個地理實體的座標信息,包括地理實體的類型和座標。blog
.dbf是一種經常使用的數據庫格式文件,這裏略去不講。索引
*.shx是索引文件,由文件頭和內容組成。文件頭是由固定的100個字節的記錄段,每一條內容包含了一個偏移量和記錄段的長度。主要目的是爲了快速方便的在座標文件中定位到指定的目標的座標信息。開發
下面是關於.shp 和.dbf 讀寫類的設計
class XSHPReader { FILE *m_fpSHP; FILE *m_fpDBF; FILE *m_fpSHX; int m_nPreFetchIdx; bool m_bPreFetchDBF; bool m_bPreFetchSHP; SHPGeometry *m_ShpObj; XExtBuffer m_ShpBuffer; char *m_DbfRecBuffer; XExtBuffer m_DbfBuffer; TDBF_INFO m_DbfHeader; int m_DbfFieldCnt; TDBF_FIELDINFO *m_DbfFields; ARC_FILE_HEADER m_ShpHeader; void FreeMem( void ); bool ReadRecordDBF( void ); SHPGeometry *ReadRecordSHP( void ); long m_lRecordNum; public: char m_szFileName[ 256 ]; XSHPReader(); ~XSHPReader(); bool Open( const char *fname ); void Close(); SHP_OBJ_TYPE GetShpObjectType( void ); void GetEnvelope( SBox *box ); int GetFieldCount( void ); bool GetFieldInfo( int col, DBF_FIELD_INFO &FieldInfo ); bool RenameField( int col, const char *szFieldName ); int GetFieldIdx( const char *szFieldName ); int GetRecordCount( void ); bool Fetch( long off ); bool GetDataAsString( int col, char *str, int max_len ); SHPGeometry *GetGeometry( void ) { return m_ShpObj; }; }; class XSHPWriter { FILE *m_fpSHP; FILE *m_fpDBF; FILE *m_fpSHX; int m_nRecordCount; char *m_DbfRecBuffer; TDBF_INFO m_DbfHeader; int m_DbfFieldCnt; TDBF_FIELDINFO *m_DbfFields; SHPGeometry *m_ShpObj; ARC_FILE_HEADER m_ShpHeader; int m_nShpWrittenOffset; int m_nShpTotalSize; void FreeMem( void ); public: XSHPWriter(); ~XSHPWriter(); bool Create( const char *fname ); bool WriteSHPHeader( SHP_OBJ_TYPE shp_obj_type, const SBox *box ); bool WriteDBFHeader( int nFieldCnt, DBF_FIELD_INFO *pFieldsInfo ); void Close(); int GetFieldIdx( const char *szFieldName ); bool SetGeometry( SHPGeometry *pObj ); bool SetDataAsString( int col, char *str, int max_len ); bool WriteRecord( void ); }; class XDBFReader { FILE *m_fpDBF; int m_nPreFetchIdx; char *m_DbfRecBuffer; XExtBuffer m_DbfBuffer; TDBF_INFO m_DbfHeader; int m_DbfFieldCnt; TDBF_FIELDINFO *m_DbfFields; void FreeMem( void ); bool ReadRecordDBF( void ); public: char m_szFileName[ 256 ]; XDBFReader(); ~XDBFReader(); bool Open( const char *fname ); void Close(); int GetFieldCount( void ); bool GetFieldInfo( int col, DBF_FIELD_INFO &FieldInfo ); int GetFieldIdx( const char *szFieldName ); bool RenameField( int col, const char *szFieldName ); int GetRecordCount( void ); bool Fetch( long off ); bool GetDataAsString( int col, char *str, int max_len ); }; class XDBFWriter { FILE *m_fpDBF; int m_nRecordCount; char *m_DbfRecBuffer; TDBF_INFO m_DbfHeader; int m_DbfFieldCnt; TDBF_FIELDINFO *m_DbfFields; void FreeMem( void ); public: XDBFWriter(); ~XDBFWriter(); bool Create( const char *fname ); bool WriteDBFHeader( int nFieldCnt, DBF_FIELD_INFO *pFieldsInfo ); void Close(); bool SetDataAsString( int col, char *str, int max_len ); bool WriteRecord( void ); };