1,地圖數據分析-SHP數據讀取


1,地圖制作軟件

作為穩定的生產工具,地圖公司一般使用MapInfo和Arcgis作為制作地圖數據的軟件。一般使用SHP格式。

2,SHP 格式讀取

一個shapefile至少包括主文件*.shp,數據文件*.dbf,索引文件*.shx。一般來說在導航的開發中使用這三個文件。

.shp 是存儲地理的幾何屬性(點,線,面等)的文件。由文件頭和地理實體數據組成。

詳細的數據結構如下:

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;
View Code

實體數據由記錄頭和記錄內容組成,其中記錄頭文件結構如下:

typedef struct tagShpRecordHeader {
    int RecordNumber;    // 1..n                [BIG_ENDIAN]
    int ContentLength;     // ShpObjectByteSize/2 [BIG_ENDIAN]
}SHP_RECORD_HEADER;
View Code

每一個記錄內容記錄了一個地理實體的坐標信息,包括地理實體的類型和坐標。

.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 );
};
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM