georust / gdal

Rust bindings for GDAL
https://crates.io/crates/gdal
MIT License
359 stars 94 forks source link

FR: Wrapper for OGR_G_Difference #432

Closed nms-scribe closed 10 months ago

nms-scribe commented 1 year ago

(Sorry if I'm getting annoying with these feature requests)

I needed to do a 'difference' on two polygon features and realized it wasn't implemented. The following is my helper trait to work around it, but in this case, because of private fields, I couldn't just copy the code in union, so I'm unsure if this is safe. (That's related to #306 )

pub(crate) trait GeometryFix: Sized {
    fn difference(&self, other: &Self) -> Option<Self>;
}

impl GeometryFix for Geometry {
    fn difference(&self, other: &Self) -> Option<Self>  {
        if !self.has_gdal_ptr() {
            return None;
        }
        if !other.has_gdal_ptr() {
            return None;
        }
        unsafe {
            let ogr_geom = gdal_sys::OGR_G_Difference(self.c_geometry(), other.c_geometry());
            if ogr_geom.is_null() {
                return None;
            }
            // TODO: Unfortunately, with_c_geometry is private, so I can't use it.
            let geometry = Self::lazy_feature_geometry();
            geometry.set_c_geometry(ogr_geom);
            // TODO: DANGER!: I can't set owned = true on the thing, there's no way.
            // However, I *think* cloning will take care of that. Because the original
            // value won't dereference the API handle, as it's not owned, but clone
            // will set it to owned.
            Some(geometry.clone())
        }
    }
}
lnicola commented 1 year ago

Yup, that's really annoying. I needed to use it recently and I went through WKT instead :sweat_smile:.