1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#pragma once
#include <cstdint>
#include "common/utils.h"
#include <fstream>
/*
Basic Shapefile parser, based on https://support.esri.com/en/white-paper/279.
This does not implement the full specification, only NullShape, Point, MultiPoint,
PolyLine and Polygon are currently implemented.
*/
namespace shapefile
{
enum ShapeType
{
NullShape = 0,
Point = 1,
PolyLine = 3,
Polygon = 5,
MultiPoint = 8,
PointZ = 11, // Unsupported
PolyLineZ = 13, // Unsupported
PolygonZ = 15, // Unsupported
MultiPointZ = 18, // Unsupported
PointM = 21, // Unsupported
PolyLineM = 23, // Unsupported
PolygonM = 25, // Unsupported
MultiPointM = 28, // Unsupported
MultiPatch = 31 // Unsupported
};
#ifdef _WIN32
#pragma pack(push, 1)
#endif
struct box_t
{
double box1;
double box2;
double box3;
double box4;
}
#ifdef _WIN32
;
#else
__attribute__((packed));
#endif
#ifdef _WIN32
#pragma pack(pop)
#endif
#ifdef _WIN32
#pragma pack(push, 1)
#endif
struct point_t
{
double x;
double y;
}
#ifdef _WIN32
;
#else
__attribute__((packed));
#endif
#ifdef _WIN32
#pragma pack(pop)
#endif
struct ShapefileHeader
{
int32_t file_code;
int32_t unused1;
int32_t unused2;
int32_t unused3;
int32_t unused4;
int32_t unused5;
int32_t file_length;
int32_t version;
int32_t shape_type;
double bounding_box_xmin;
double bounding_box_ymin;
double bounding_box_xmax;
double bounding_box_ymax;
double bounding_box_zmin;
double bounding_box_zmax;
double bounding_box_mmin;
double bounding_box_mmax;
ShapefileHeader(std::istream &stream);
};
struct RecordHeader
{
int32_t record_number;
int32_t content_length;
int32_t shape_type;
RecordHeader(std::istream &stream);
};
struct NullShapeRecord : RecordHeader
{
NullShapeRecord(std::istream &stream, RecordHeader &header);
};
struct PointRecord : RecordHeader
{
point_t point;
PointRecord(std::istream &stream, RecordHeader &header);
};
struct MultiPointRecord : RecordHeader
{
box_t box;
int32_t point_number;
std::vector<point_t> points;
MultiPointRecord(std::istream &stream, RecordHeader &header);
};
struct PolyLineRecord : RecordHeader
{
box_t box;
int32_t part_number;
int32_t point_number;
std::vector<std::vector<point_t>> parts_points;
PolyLineRecord(std::istream &stream, RecordHeader &header);
};
struct PolygonRecord : public PolyLineRecord // Identical
{
PolygonRecord(std::istream &stream, RecordHeader &header);
};
struct Shapefile
{
ShapefileHeader header;
std::vector<PointRecord> point_records;
std::vector<MultiPointRecord> multipoint_records;
std::vector<PolyLineRecord> polyline_records;
std::vector<PolygonRecord> polygon_records;
Shapefile(std::istream &stream);
};
};
|