Skip to content

Commit

Permalink
Merge pull request #199 from ChristianBeilschmidt/get-field-as-x
Browse files Browse the repository at this point in the history
Get field as x
  • Loading branch information
jdroenner authored Jul 23, 2021
2 parents 7ba8bad + 28a0291 commit 46d8a0a
Show file tree
Hide file tree
Showing 3 changed files with 401 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ let mut dataset = driver
Well-Known Binary
- <https://github.com/georust/gdal/pull/173>
- Fixed memory leak in `Geometry::from_wkt`

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

- **Breaking**: Changed `Dataset::create_layer` to take a new `LayerOptions`
Expand Down Expand Up @@ -169,6 +170,9 @@ 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>

## 0.7.1

- fix docs.rs build for gdal-sys
Expand Down
240 changes: 237 additions & 3 deletions src/vector/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@ impl<'a> Feature<'a> {
}
#[cfg(feature = "datetime")]
OGRFieldType::OFTDateTime => Ok(Some(FieldValue::DateTimeValue(
self.get_field_datetime(field_id)?,
self._field_as_datetime(field_id)?,
))),
#[cfg(feature = "datetime")]
OGRFieldType::OFTDate => Ok(Some(FieldValue::DateValue(
self.get_field_datetime(field_id)?.date(),
self._field_as_datetime(field_id)?.date(),
))),
_ => Err(GdalError::UnhandledFieldType {
field_type,
Expand All @@ -177,8 +177,242 @@ impl<'a> Feature<'a> {
}
}

/// Get the index of the named field.
///
/// If the field is missing, returns [`GdalError::InvalidFieldName`].
///
fn field_idx_from_name(&self, field_name: &str) -> Result<i32> {
let c_str_field_name = CString::new(field_name)?;
let field_id =
unsafe { gdal_sys::OGR_F_GetFieldIndex(self.c_feature, c_str_field_name.as_ptr()) };
if field_id == -1 {
return Err(GdalError::InvalidFieldName {
field_name: field_name.to_string(),
method_name: "OGR_F_GetFieldIndex",
});
}

Ok(field_id)
}

/// Get the value of the specified field as a [`i32`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldIndex`].
///
/// Returns `Ok(None)` if the field is null.
/// Returns `Ok(Some(0))` on other kinds of errors.
///
pub fn field_as_integer(&self, field_idx: i32) -> Result<Option<i32>> {
if field_idx >= self.field_count() {
return Err(GdalError::InvalidFieldIndex {
index: field_idx as usize,
method_name: "field_as_integer",
});
}

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.c_feature, field_idx) };

Ok(Some(value))
}

/// Get the value of the specified field as a [`i32`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldName`].
///
/// Returns `Ok(None)` if the field is null.
/// Returns `Ok(Some(0))` on other kinds of errors.
///
pub fn field_as_integer_by_name(&self, field_name: &str) -> Result<Option<i32>> {
let field_idx = self.field_idx_from_name(field_name)?;

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.c_feature, field_idx) };

Ok(Some(value))
}

/// Get the value of the specified field as a [`i64`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldName`].
///
/// Returns `Ok(None)` if the field is null.
/// Returns `Ok(Some(0))` on other kinds of errors.
///
pub fn field_as_integer64_by_name(&self, field_name: &str) -> Result<Option<i64>> {
let field_idx = self.field_idx_from_name(field_name)?;

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.c_feature, field_idx) };

Ok(Some(value))
}

/// Get the value of the specified field as a [`i64`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldIndex`].
///
/// Returns `Ok(None)` if the field is null.
/// Returns `Ok(Some(0))` on other kinds of errors.
///
pub fn field_as_integer64(&self, field_idx: i32) -> Result<Option<i64>> {
if field_idx >= self.field_count() {
return Err(GdalError::InvalidFieldIndex {
index: field_idx as usize,
method_name: "field_as_integer64",
});
}

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.c_feature, field_idx) };

Ok(Some(value))
}

/// Get the value of the specified field as a [`f64`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldName`].
///
/// Returns `Ok(None)` if the field is null.
/// Returns `Ok(Some(0.))` on other kinds of errors.
///
pub fn field_as_double_by_name(&self, field_name: &str) -> Result<Option<f64>> {
let field_idx = self.field_idx_from_name(field_name)?;

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.c_feature, field_idx) };

Ok(Some(value))
}

/// Get the value of the specified field as a [`f64`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldIndex`].
///
/// Returns `Ok(None)` if the field is null.
/// Returns `Ok(Some(0.))` on other kinds of errors.
///
pub fn field_as_double(&self, field_idx: i32) -> Result<Option<f64>> {
if field_idx >= self.field_count() {
return Err(GdalError::InvalidFieldIndex {
index: field_idx as usize,
method_name: "field_as_double",
});
}

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.c_feature, field_idx) };

Ok(Some(value))
}

/// Get the value of the specified field as a [`String`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldName`].
///
/// Returns `Ok(None)` if the field is null.
///
pub fn field_as_string_by_name(&self, field_name: &str) -> Result<Option<String>> {
let field_idx = self.field_idx_from_name(field_name)?;

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = _string(unsafe { gdal_sys::OGR_F_GetFieldAsString(self.c_feature, field_idx) });

Ok(Some(value))
}

/// Get the value of the specified field as a [`String`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldIndex`].
///
/// Returns `Ok(None)` if the field is null.
///
pub fn field_as_string(&self, field_idx: i32) -> Result<Option<String>> {
if field_idx >= self.field_count() {
return Err(GdalError::InvalidFieldIndex {
index: field_idx as usize,
method_name: "field_as_string",
});
}

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = _string(unsafe { gdal_sys::OGR_F_GetFieldAsString(self.c_feature, field_idx) });

Ok(Some(value))
}

/// Get the value of the specified field as a [`DateTime<FixedOffset>`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldName`].
///
/// Returns `Ok(None)` if the field is null.
///
#[cfg(feature = "datetime")]
pub fn field_as_datetime_by_name(
&self,
field_name: &str,
) -> Result<Option<DateTime<FixedOffset>>> {
let field_idx = self.field_idx_from_name(field_name)?;

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = self._field_as_datetime(field_idx)?;

Ok(Some(value))
}

/// Get the value of the specified field as a [`DateTime<FixedOffset>`].
///
/// If the field is missing, returns [`GdalError::InvalidFieldIndex`].
///
/// Returns `Ok(None)` if the field is null.
///
#[cfg(feature = "datetime")]
pub fn field_as_datetime(&self, field_idx: i32) -> Result<Option<DateTime<FixedOffset>>> {
if field_idx >= self.field_count() {
return Err(GdalError::InvalidFieldIndex {
index: field_idx as usize,
method_name: "field_as_datetime",
});
}

if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 {
return Ok(None);
}

let value = self._field_as_datetime(field_idx)?;

Ok(Some(value))
}

#[cfg(feature = "datetime")]
fn get_field_datetime(&self, field_id: c_int) -> Result<DateTime<FixedOffset>> {
fn _field_as_datetime(&self, field_id: c_int) -> Result<DateTime<FixedOffset>> {
let mut year: c_int = 0;
let mut month: c_int = 0;
let mut day: c_int = 0;
Expand Down
Loading

0 comments on commit 46d8a0a

Please sign in to comment.