extern crate byteorder;
pub extern crate dbase;
pub mod header;
pub mod reader;
pub mod record;
pub mod writer;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::convert::From;
use std::fmt;
use std::io::{Read, Write};
pub use reader::{read, read_as, Reader};
pub use record::Multipatch;
pub use record::{convert_shapes_to_vec_of, HasShapeType, ReadableShape};
pub use record::{Multipoint, MultipointM, MultipointZ};
pub use record::{Patch, Shape, NO_DATA};
pub use record::{Point, PointM, PointZ};
pub use record::{Polygon, PolygonM, PolygonRing, PolygonZ};
pub use record::{Polyline, PolylineM, PolylineZ};
pub use writer::Writer;
extern crate core;
#[cfg(feature = "geo-types")]
extern crate geo_types;
#[derive(Debug)]
pub enum Error {
IoError(std::io::Error),
InvalidFileCode(i32),
InvalidShapeType(i32),
InvalidPatchType(i32),
MismatchShapeType {
requested: ShapeType,
actual: ShapeType,
},
InvalidShapeRecordSize,
DbaseError(dbase::Error),
MissingDbf,
MissingIndexFile,
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Error {
Error::IoError(error)
}
}
impl From<dbase::Error> for Error {
fn from(e: dbase::Error) -> Error {
Error::DbaseError(e)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::IoError(e) => write!(f, "{}", e),
Error::InvalidFileCode(code) => write!(
f,
"The file code ' {} ' is invalid, is this a Shapefile ?",
code
),
Error::InvalidShapeType(code) => write!(
f,
"The code ' {} ' does not correspond to any of the ShapeType code defined by ESRI",
code
),
Error::MismatchShapeType { requested, actual } => write!(
f,
"The requested type: '{}' does not correspond to the actual shape type: '{}'",
requested, actual
),
e => write!(f, "{:?}", e),
}
}
}
impl std::error::Error for Error {}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ShapeType {
NullShape = 0,
Point = 1,
Polyline = 3,
Polygon = 5,
Multipoint = 8,
PointZ = 11,
PolylineZ = 13,
PolygonZ = 15,
MultipointZ = 18,
PointM = 21,
PolylineM = 23,
PolygonM = 25,
MultipointM = 28,
Multipatch = 31,
}
impl ShapeType {
pub(crate) fn read_from<T: Read>(source: &mut T) -> Result<ShapeType, Error> {
let code = source.read_i32::<LittleEndian>()?;
Self::from(code).ok_or_else(|| Error::InvalidShapeType(code))
}
pub(crate) fn write_to<T: Write>(self, dest: &mut T) -> Result<(), std::io::Error> {
dest.write_i32::<LittleEndian>(self as i32)?;
Ok(())
}
pub fn from(code: i32) -> Option<ShapeType> {
match code {
0 => Some(ShapeType::NullShape),
1 => Some(ShapeType::Point),
3 => Some(ShapeType::Polyline),
5 => Some(ShapeType::Polygon),
8 => Some(ShapeType::Multipoint),
11 => Some(ShapeType::PointZ),
13 => Some(ShapeType::PolylineZ),
15 => Some(ShapeType::PolygonZ),
18 => Some(ShapeType::MultipointZ),
21 => Some(ShapeType::PointM),
23 => Some(ShapeType::PolylineM),
25 => Some(ShapeType::PolygonM),
28 => Some(ShapeType::MultipointM),
31 => Some(ShapeType::Multipatch),
_ => None,
}
}
pub fn has_z(self) -> bool {
match self {
ShapeType::PointZ
| ShapeType::PolylineZ
| ShapeType::PolygonZ
| ShapeType::MultipointZ => true,
_ => false,
}
}
pub fn has_m(self) -> bool {
match self {
ShapeType::PointZ
| ShapeType::PolylineZ
| ShapeType::PolygonZ
| ShapeType::MultipointZ
| ShapeType::PointM
| ShapeType::PolylineM
| ShapeType::PolygonM
| ShapeType::MultipointM => true,
_ => false,
}
}
pub fn is_multipart(self) -> bool {
match self {
ShapeType::Point
| ShapeType::PointM
| ShapeType::PointZ
| ShapeType::Multipoint
| ShapeType::MultipointM
| ShapeType::MultipointZ => false,
_ => true,
}
}
}
impl fmt::Display for ShapeType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ShapeType::NullShape => write!(f, "NullShape"),
ShapeType::Point => write!(f, "Point"),
ShapeType::Polyline => write!(f, "Polyline"),
ShapeType::Polygon => write!(f, "Polygon"),
ShapeType::Multipoint => write!(f, "Multipoint"),
ShapeType::PointZ => write!(f, "PointZ"),
ShapeType::PolylineZ => write!(f, "PolylineZ"),
ShapeType::PolygonZ => write!(f, "PolygonZ"),
ShapeType::MultipointZ => write!(f, "MultipointZ"),
ShapeType::PointM => write!(f, "PointM"),
ShapeType::PolylineM => write!(f, "PolylineM"),
ShapeType::PolygonM => write!(f, "PolygonM"),
ShapeType::MultipointM => write!(f, "MultipointM"),
ShapeType::Multipatch => write!(f, "Multipatch"),
}
}
}