1,地图数据分析-SHP数据读取

本文详细介绍了地图制作软件MapInfo和Arcgis的使用,以及SHP格式文件的结构和读取方式,包括文件头、实体数据和索引文件的组成。重点阐述了在导航开发中如何利用.shp、.dbf和*.shx文件进行地图数据的高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

转载于:https://www.cnblogs.com/273809717/p/5144928.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值