Skip to content

Commit

Permalink
Merge pull request #200 from ChristianBeilschmidt/ogr-set-attributes
Browse files Browse the repository at this point in the history
OGR Layer: Set Attribute Filter & Set Spatial Filter as Rectangle
  • Loading branch information
jdroenner committed Jul 28, 2021
2 parents 46d8a0a + 05c99b5 commit 8facee4
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
9 changes: 7 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,13 @@ let mut dataset = driver

- <https://github.com/georust/gdal/pull/186>

- Wrapper functions for `OGR_F_GetFieldAs…` methods
- <https://github.com/georust/gdal/pull/199>
- Wrapper functions for `OGR_F_GetFieldAs…` methods

- <https://github.com/georust/gdal/pull/199>

- Wrapper functions for `OGR_L_SetAttributeFilter` and `OGR_L_SetSpatialFilterRect`

- <https://github.com/georust/gdal/pull/200>

## 0.7.1

Expand Down
31 changes: 31 additions & 0 deletions src/vector/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ impl<'a> Layer<'a> {
unsafe { gdal_sys::OGR_L_SetSpatialFilter(self.c_layer, geometry.c_geometry()) };
}

/// Set a spatial rectangle filter on this layer by specifying the bounds of a rectangle.
pub fn set_spatial_filter_rect(&mut self, min_x: f64, min_y: f64, max_x: f64, max_y: f64) {
unsafe { gdal_sys::OGR_L_SetSpatialFilterRect(self.c_layer, min_x, min_y, max_x, max_y) };
}

/// Clear spatial filters set on this layer.
pub fn clear_spatial_filter(&mut self) {
unsafe { gdal_sys::OGR_L_SetSpatialFilter(self.c_layer, null_mut()) };
Expand Down Expand Up @@ -330,6 +335,32 @@ impl<'a> Layer<'a> {
gdal_sys::OGR_L_ResetReading(self.c_layer);
}
}

/// Set a new attribute query that restricts features when using the feature iterator.
///
/// Parameters:
/// - `query` in restricted SQL WHERE format
///
pub fn set_attribute_filter(&self, query: &str) -> Result<()> {
let c_str = CString::new(query)?;
let rv = unsafe { gdal_sys::OGR_L_SetAttributeFilter(self.c_layer, c_str.as_ptr()) };

if rv != OGRErr::OGRERR_NONE {
return Err(GdalError::OgrError {
err: rv,
method_name: "OGR_L_SetAttributeFilter",
});
}

Ok(())
}

/// Clear the attribute filter set on this layer
pub fn clear_attribute_filter(&self) {
unsafe {
gdal_sys::OGR_L_SetAttributeFilter(self.c_layer, null_mut());
}
}
}

pub struct FeatureIterator<'a> {
Expand Down
45 changes: 45 additions & 0 deletions src/vector/vector_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,10 @@ mod tests {

layer.clear_spatial_filter();
assert_eq!(layer.features().count(), 21);

// test filter as rectangle
layer.set_spatial_filter_rect(26.1017, 44.4297, 26.1025, 44.4303);
assert_eq!(layer.features().count(), 7);
}

#[test]
Expand Down Expand Up @@ -690,4 +694,45 @@ mod tests {
// }
// });
// }

#[test]
fn test_set_attribute_filter() {
with_layer("roads.geojson", |mut layer| {
// check number without calling any function
assert_eq!(layer.features().count(), 21);

// check if clearing does not corrupt anything
layer.clear_attribute_filter();
assert_eq!(layer.features().count(), 21);

// apply actual filter
layer.set_attribute_filter("highway = 'primary'").unwrap();

assert_eq!(layer.features().count(), 1);
assert_eq!(
layer
.features()
.next()
.unwrap()
.field_as_string_by_name("highway")
.unwrap()
.unwrap(),
"primary"
);

// clearing and check again
layer.clear_attribute_filter();

assert_eq!(layer.features().count(), 21);

// force error
assert_eq!(
layer.set_attribute_filter("foo = bar"),
Err(GdalError::OgrError {
err: gdal_sys::OGRErr::OGRERR_CORRUPT_DATA,
method_name: "OGR_L_SetAttributeFilter",
})
);
});
}
}

0 comments on commit 8facee4

Please sign in to comment.