Skip to content

Commit

Permalink
convert to geo types
Browse files Browse the repository at this point in the history
  • Loading branch information
gauteh committed May 18, 2024
1 parent 5554415 commit d92b2d6
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 58 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ name = "make_bitmap"
path = "src/devel/make_bitmap.rs"

[dependencies]
geos = { version = "9" }
geo = "0.28"
lazy_static = "1.4"
numpy = { version = "0.21" }
pyo3 = { version = "0.21" , features = [ "abi3-py310" ] }
roaring = "0.10"
rust-embed = "8"
xz2 = "0.1"
ndarray = { version = "0.15", features = [ "rayon" ] }
shapefile = { version = "0.6.0", features = ["geo-types"] }

[dev-dependencies]
rayon = "1"
Expand All @@ -38,7 +39,6 @@ path-slash = "0.2"
[features]
extension-module = ["pyo3/extension-module"]
simd = [ "roaring/simd" ]
static = [ "geos/static", "geos/v3_11_0" ]
nightly = []
default = [ "simd" ]

Expand Down
69 changes: 13 additions & 56 deletions src/shapes.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,24 @@
use pyo3::{prelude::*, types::PyBytes};
use std::borrow::Borrow;
use std::fs::File;
use std::io::{self, prelude::*};
use std::io::{self, prelude::*, Cursor};
use std::path::Path;

use geos::{CoordSeq, Geom, Geometry, PreparedGeometry};
use geo::{Geometry, Contains, point};
use numpy::{PyArray, PyReadonlyArrayDyn};

pub static GSHHS_F: &str = "gshhs_f_-180.000000E-90.000000N180.000000E90.000000N.wkb.xz";

#[pyclass]
#[derive(Clone)]
pub struct Gshhg {
geom: *mut Geometry,

// prepped requires `geom` above to be around, and is valid as long as geom is alive.
prepped: PreparedGeometry,
}

impl Drop for Gshhg {
fn drop(&mut self) {
unsafe { drop(Box::from_raw(self.geom)) }
}
}

// PreparedGeometry is Send+Sync, Geometry is Send+Sync. *mut Geometry is never modified.
unsafe impl Send for Gshhg {}
unsafe impl Sync for Gshhg {}

// `PreparededGeometry::contains` needs a call to `contains` before it is thread-safe:
// https://github.com/georust/geos/issues/95
fn warmup_prepped(prepped: &PreparedGeometry) {
let point = CoordSeq::new_from_vec(&[&[0.0, 0.0]]).unwrap();
let point = Geometry::create_point(point).unwrap();
prepped.contains(&point).unwrap();
}

impl Clone for Gshhg {
fn clone(&self) -> Self {
let gptr = self.geom.clone();
debug_assert!(gptr != self.geom);
let prepped = unsafe { (&*gptr).to_prepared_geom().unwrap() };
warmup_prepped(&prepped);

Gshhg {
geom: gptr,
prepped,
}
}
geom: Geometry,
}

impl Gshhg {
pub fn from_geom(geom: Geometry) -> io::Result<Gshhg> {
let bxd = Box::new(geom);
let gptr = Box::into_raw(bxd);
let prepped = unsafe { (&*gptr).to_prepared_geom() }
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "cannot prepare geomtry"))?;
warmup_prepped(&prepped);

Ok(Gshhg {
geom: gptr,
prepped,
geom
})
}

Expand All @@ -75,8 +34,9 @@ impl Gshhg {
let mut fd = xz2::bufread::XzDecoder::new(fd);
let mut buf = Vec::new();
fd.read_to_end(&mut buf)?;

Ok(geos::Geometry::new_from_wkb(&buf).unwrap())
let mut buf = Cursor::new(buf);
let shape = shapefile::ShapeReader::new(buf).unwrap();
shape.read_as()
}
}

Expand All @@ -85,8 +45,7 @@ impl Gshhg {
/// Make a new Gshhg shapes instance.
#[staticmethod]
pub fn new(py: Python) -> io::Result<Self> {
let buf = Gshhg::wkb(py)?;
let g = geos::Geometry::new_from_wkb(buf.as_bytes()).unwrap();
let g = Gshhg::get_geometry_from_compressed(&GSHHS_F)?;
Gshhg::from_geom(g)
}

Expand Down Expand Up @@ -117,16 +76,14 @@ impl Gshhg {
debug_assert!(x >= -180. && x <= 180.);
assert!(y > -90. && y <= 90.);

let point = CoordSeq::new_from_vec(&[&[x as f64, y as f64]]).unwrap();
let point = Geometry::create_point(point).unwrap();
self.prepped.contains(&point).unwrap()
let p = point!(x: x, y: y);
self.geom.contains(&p)
}

/// Same as `contains`, but does not check for bounds.
pub(crate) fn contains_unchecked(&self, x: f64, y: f64) -> bool {
let point = CoordSeq::new_from_vec(&[&[x, y]]).unwrap();
let point = Geometry::create_point(point).unwrap();
self.prepped.contains(&point).unwrap()
let p = point!(x: x, y: y);
self.geom.contains(&p)
}

pub fn contains_many(
Expand Down

0 comments on commit d92b2d6

Please sign in to comment.