Skip to content

Commit

Permalink
Integrate shp driver (#233)
Browse files Browse the repository at this point in the history
Solves #187
  • Loading branch information
pka authored Aug 30, 2024
1 parent bbd401b commit e9bb49c
Show file tree
Hide file tree
Showing 37 changed files with 106 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
shell: bash
# Make sure this list matches the members list in Cargo.toml
run: |
for package in geozero geozero-shp geozero-cli geozero-bench; do
for package in geozero geozero-cli geozero-bench; do
(echo "----- Testing doc build for package $package ----" && cargo doc -p $package --all-features --no-deps)
done
env:
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[workspace]
# Make sure this list matches the "Test Doc Build" section in .github/workflows/ci.yml
members = ["geozero", "geozero-shp", "geozero-cli", "geozero-bench"]
default-members = ["geozero", "geozero-shp", "geozero-cli"]
members = ["geozero", "geozero-cli", "geozero-bench"]
default-members = ["geozero", "geozero-cli"]
resolver = "2"

[workspace.package]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Supported dimensions: X, Y, Z, M, T
| [geo-types](https://github.com/georust/geo) ||| |
| MVT (Mapbox Vector Tiles) ||| |
| GPX ||| |
| Shapefile ||| Available via the [geozero-shp](https://crates.io/crates/geozero-shp) crate. |
| Shapefile ||| |
| FlatGeobuf ||| Available via the [flatgeobuf](https://crates.io/crates/flatgeobuf) crate. |
| GeoArrow ||| Available via the [geoarrow](https://crates.io/crates/geoarrow) crate. |
| GeoParquet ||| Available via the [geoarrow](https://crates.io/crates/geoarrow) crate. |
Expand Down
22 changes: 0 additions & 22 deletions geozero-shp/Cargo.toml

This file was deleted.

27 changes: 0 additions & 27 deletions geozero-shp/README.md

This file was deleted.

9 changes: 8 additions & 1 deletion geozero/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repository.workspace = true
license.workspace = true

[features]
default = ["with-svg", "with-wkt", "with-geo", "with-geojson"]
default = ["with-geo", "with-geojson", "with-svg", "with-wkt"]
with-csv = ["dep:csv", "with-wkt"]
with-gdal = ["dep:gdal", "dep:gdal-sys"]
with-gdal-bindgen = ["with-gdal", "gdal?/bindgen"]
Expand All @@ -25,6 +25,7 @@ with-mvt = ["dep:prost", "dep:prost-build", "dep:dup-indexer"]
with-postgis-diesel = ["with-wkb", "dep:diesel", "dep:byteorder"]
with-postgis-postgres = ["with-wkb", "dep:postgres-types", "dep:bytes"]
with-postgis-sqlx = ["with-wkb", "dep:sqlx", "sqlx?/postgres"]
with-shp = ["dep:byteorder", "dep:dbase"]
with-svg = []
with-tessellator = ["dep:lyon"]
with-wkb = ["dep:scroll", "with-wkt"]
Expand All @@ -39,6 +40,7 @@ thiserror.workspace = true
byteorder = { workspace = true, optional = true }
bytes = { workspace = true, optional = true }
csv = { workspace = true, optional = true }
dbase = { workspace = true, optional = true }
diesel = { workspace = true, optional = true }
dup-indexer = { workspace = true, optional = true }
gdal = { workspace = true, optional = true }
Expand Down Expand Up @@ -128,6 +130,11 @@ name = "gpx"
path = "tests/gpx.rs"
required-features = ["with-gpx", "with-wkt", "with-geojson"]

[[test]]
name = "shp-reader"
path = "tests/shp-reader.rs"
required-features = ["with-shp"]

[[test]]
name = "svg"
path = "tests/svg.rs"
Expand Down
5 changes: 4 additions & 1 deletion geozero/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
//! Supported dimensions: X, Y, Z, M, T
//!
//! Available implementations:
//! * [geozero-shp](https://docs.rs/geozero-shp)
//! * [flatgeobuf](https://docs.rs/flatgeobuf)
//! * [geoarrow](https://docs.rs/geoarrow)
//!
Expand All @@ -28,6 +27,7 @@
//! | GEOS | `geos::Geometry` | XYZ | - | [ToGeos] | [GeosWriter](geos::GeosWriter) |
//! | GPX | | XY | [GpxReader](gpx::GpxReader) | | |
//! | MVT | [mvt::tile::Feature] | XY | [mvt::tile::Layer] | [ToMvt] | [MvtWriter](mvt::MvtWriter) |
//! | Shapefile | - | XYZM | [shp::ShpReader] | | |
//! | SVG | - | XY | - | [ToSvg] | [SvgWriter](svg::SvgWriter) |
//! | WKB | [Wkb](wkb::Wkb), [Ewkb](wkb::Ewkb), [GpkgWkb](wkb::GpkgWkb), [SpatiaLiteWkb](wkb::SpatiaLiteWkb), [MySQL](wkb::MySQLWkb) | XYZM | - | [ToWkb] | [WkbWriter](wkb::WkbWriter) |
//! | WKT | [wkt::WktStr], [wkt::WktString], [wkt::EwktStr], [wkt::EwktString] | XYZM | [wkt::WktReader], [wkt::WktStr], [wkt::WktString], [wkt::EwktStr], [wkt::EwktString] | [ToWkt] | [WktWriter](wkt::WktWriter) |
Expand Down Expand Up @@ -99,6 +99,9 @@ pub mod gpx;
))]
pub mod postgis;

#[cfg(feature = "with-shp")]
pub mod shp;

#[cfg(feature = "with-svg")]
pub mod svg;
#[cfg(feature = "with-svg")]
Expand Down
6 changes: 3 additions & 3 deletions geozero-shp/src/header.rs → geozero/src/shp/header.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::point_z::BBoxZ;
use crate::Error;
use crate::shp::point_z::BBoxZ;
use crate::shp::Error;
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
use std::fmt;
use std::io::Read;
Expand Down Expand Up @@ -105,7 +105,7 @@ impl ShapeType {
/// Returns the ShapeType corresponding to the input code
/// if the code is valid
/// ```
/// use geozero_shp::ShapeType;
/// use geozero::shp::ShapeType;
///
/// assert_eq!(ShapeType::from(25), Some(ShapeType::PolygonM));
/// assert_eq!(ShapeType::from(60), None);
Expand Down
39 changes: 29 additions & 10 deletions geozero-shp/src/lib.rs → geozero/src/shp/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
#![deprecated(
note = "The geozero_shp crate has been deprecated. Instead, use geozero's built-in shapefile feature"
)]
//! Shapefile reader.
//!
//! Features:
//! - [x] Read support for OGC simple feature types
//! - [x] Convert to GeoJSON, WKB (PostGIS/GeoPackage), WKT, GEOS, GDAL formats and more
//! - [ ] Support for Multipatch types
//! - [ ] Read spatial index
//! - [ ] Read projection files
//!
//! For writing Shapefiles either use [shapefile-rs](https://crates.io/crates/shapefile) or the GDAL driver.
//!
//! Originally based on shapefile-rs from Thomas Montaigu.
//!
//! # Usage example:
//!
//! Use Shapefile feature iterator:
//!
//! ```rust,ignore
//! use geozero::geojson::GeoJsonWriter;
//! use geozero::shp::ShpReader;
//!
//! let reader = ShpReader::from_path("poly.shp")?;
//! let mut json: Vec<u8> = Vec::new();
//! let cnt = reader.iter_features(GeoJsonWriter::new(&mut json))?.count();
//! ```

mod header;
mod point_z;
Expand All @@ -9,12 +31,9 @@ pub mod reader;
mod shp_reader;
mod shx_reader;

pub use crate::header::ShapeType;
pub use crate::reader::Reader;
pub use crate::shp_reader::NO_DATA;

// Re-export GeoZero to help avoid version conflicts
pub use geozero;
pub use crate::shp::header::ShapeType;
pub use crate::shp::reader::ShpReader;
pub use crate::shp::shp_reader::NO_DATA;

/// All Errors that can happen when using this library
#[derive(thiserror::Error, Debug)]
Expand Down Expand Up @@ -50,5 +69,5 @@ pub enum Error {
#[error("Index file missing")]
MissingIndexFile,
#[error("Geozero error")]
GeozeroError(#[from] geozero::error::GeozeroError),
GeozeroError(#[from] crate::error::GeozeroError),
}
2 changes: 1 addition & 1 deletion geozero-shp/src/point_z.rs → geozero/src/shp/point_z.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::shp_reader::{is_no_data, NO_DATA};
use crate::shp::shp_reader::{is_no_data, NO_DATA};
use std::fmt;

/// Point with `x`, `y`, `m`, `z`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::reader::ShapeRecord;
use crate::error::Result;
use crate::shp::reader::ShapeRecord;
use crate::{ColumnValue, FeatureProperties, PropertyProcessor};
use dbase::FieldValue;
use geozero::error::Result;
use geozero::{ColumnValue, FeatureProperties, PropertyProcessor};

impl FeatureProperties for ShapeRecord {
/// Process feature properties.
Expand Down
20 changes: 10 additions & 10 deletions geozero-shp/src/reader.rs → geozero/src/shp/reader.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::shp_reader::{read_shape, RecordHeader};
use crate::shx_reader::{read_index_file, ShapeIndex};
use crate::{header, Error};
use crate::shp::shp_reader::{read_shape, RecordHeader};
use crate::shp::shx_reader::{read_index_file, ShapeIndex};
use crate::shp::{header, Error};
use crate::{FeatureProcessor, FeatureProperties, GeomProcessor};
pub use dbase::{FieldInfo, FieldType};
use geozero::{FeatureProcessor, FeatureProperties, GeomProcessor};
use std::fs::File;
use std::io::{BufReader, Read, Seek};
use std::iter::FusedIterator;
Expand Down Expand Up @@ -91,14 +91,14 @@ impl<'a, P: FeatureProcessor, T: Read + Seek + 'a> Iterator for ShapeRecordItera
impl<'a, P: FeatureProcessor, T: Read + Seek + 'a> FusedIterator for ShapeRecordIterator<'a, P, T> {}

/// struct that reads the content of a shapefile
pub struct Reader<T: Read + Seek> {
pub struct ShpReader<T: Read + Seek> {
source: T,
header: header::Header,
shapes_index: Option<Vec<ShapeIndex>>,
dbf_reader: Option<dbase::Reader<T>>,
}

impl<T: Read + Seek> Reader<T> {
impl<T: Read + Seek> ShpReader<T> {
/// Creates a new Reader from a source that implements the `Read` trait
///
/// The Shapefile header is read upon creation (but no reading of the Shapes is done)
Expand All @@ -110,10 +110,10 @@ impl<T: Read + Seek> Reader<T> {
/// Will also return an error if the data is not a shapefile (Wrong file code)
///
/// Will also return an error if the shape type read from the input source is invalid
pub fn new(mut source: T) -> Result<Reader<T>, Error> {
pub fn new(mut source: T) -> Result<ShpReader<T>, Error> {
let header = header::Header::read_from(&mut source)?;

Ok(Reader {
Ok(ShpReader {
source,
header,
shapes_index: None,
Expand Down Expand Up @@ -192,7 +192,7 @@ impl<T: Read + Seek> Reader<T> {
}
}

impl Reader<BufReader<File>> {
impl ShpReader<BufReader<File>> {
/// Creates a reader from a path to a file
///
/// Will attempt to read both the .shx and .dbf associated with the file,
Expand Down Expand Up @@ -220,7 +220,7 @@ impl Reader<BufReader<File>> {
}

// Does not work, because iter_features requires P instead of &mut P
// impl<T: Read> GeozeroDatasource for Reader<T> {
// impl<T: Read> GeozeroDatasource for ShpReader<T> {
// fn process<P: FeatureProcessor>(&mut self, processor: &mut P) -> geozero::error::Result<()> {
// self.iter_features(*processor).unwrap().all();
// Ok(())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{Error, ShapeType};
use crate::shp::{Error, ShapeType};
use crate::GeomProcessor;
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
use geozero::GeomProcessor;
use std::io::Read;
use std::mem::size_of;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{header, Error};
use crate::shp::{header, Error};
use byteorder::{BigEndian, ReadBytesExt};
use std::io::Read;

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit e9bb49c

Please sign in to comment.