/
dataset.rs
108 lines (93 loc) · 3.2 KB
/
dataset.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use std::ffi::CString;
use std::path::Path;
use std::ptr::null_mut;
use libc::c_int;
use vector::Layer;
use vector::driver::_register_drivers;
use gdal_major_object::MajorObject;
use metadata::Metadata;
use gdal_sys::{self, GDALMajorObjectH, OGRDataSourceH, OGRLayerH, OGRwkbGeometryType};
use utils::_last_null_pointer_err;
use errors::*;
/// Vector dataset
///
/// ```
/// use std::path::Path;
/// use gdal::vector::Dataset;
///
/// let mut dataset = Dataset::open(Path::new("fixtures/roads.geojson")).unwrap();
/// println!("Dataset has {} layers", dataset.count());
/// ```
pub struct Dataset {
c_dataset: OGRDataSourceH,
layers: Vec<Layer>,
}
impl MajorObject for Dataset {
unsafe fn gdal_object_ptr(&self) -> GDALMajorObjectH {
self.c_dataset
}
}
impl Metadata for Dataset {}
impl Dataset {
pub unsafe fn _with_c_dataset(c_dataset: OGRDataSourceH) -> Dataset {
Dataset{c_dataset: c_dataset, layers: vec!()}
}
/// Open the dataset at `path`.
pub fn open(path: &Path) -> Result<Dataset> {
_register_drivers();
let filename = path.to_string_lossy();
let c_filename = CString::new(filename.as_ref())?;
let c_dataset = unsafe { gdal_sys::OGROpen(c_filename.as_ptr(), 0, null_mut()) };
if c_dataset.is_null() {
return Err(_last_null_pointer_err("OGROpen").into());
};
Ok(Dataset{c_dataset: c_dataset, layers: vec!()})
}
/// Get number of layers.
pub fn count(&self) -> isize {
(unsafe { gdal_sys::OGR_DS_GetLayerCount(self.c_dataset) }) as isize
}
fn _child_layer(&mut self, c_layer: OGRLayerH) -> &Layer {
let layer = unsafe { Layer::_with_c_layer(c_layer) };
self.layers.push(layer);
self.layers.last().unwrap()
}
/// Get layer number `idx`.
pub fn layer(&mut self, idx: isize) -> Result<&Layer> {
let c_layer = unsafe { gdal_sys::OGR_DS_GetLayer(self.c_dataset, idx as c_int) };
if c_layer.is_null() {
return Err(_last_null_pointer_err("OGR_DS_GetLayer").into());
}
Ok(self._child_layer(c_layer))
}
/// Get layer with `name`.
pub fn layer_by_name(&mut self, name: &str) -> Result<&Layer> {
let c_name = CString::new(name)?;
let c_layer = unsafe { gdal_sys::OGR_DS_GetLayerByName(self.c_dataset, c_name.as_ptr()) };
if c_layer.is_null() {
return Err(_last_null_pointer_err("OGR_DS_GetLayerByName").into());
}
Ok(self._child_layer(c_layer))
}
/// Create a new layer with a blank definition.
pub fn create_layer(&mut self) -> Result<&mut Layer> {
let c_name = CString::new("")?;
let c_layer = unsafe { gdal_sys::OGR_DS_CreateLayer(
self.c_dataset,
c_name.as_ptr(),
null_mut(),
OGRwkbGeometryType::wkbUnknown,
null_mut(),
) };
if c_layer.is_null() {
return Err(_last_null_pointer_err("OGR_DS_CreateLayer").into());
};
self._child_layer(c_layer);
Ok(self.layers.last_mut().unwrap()) // TODO: is this safe?
}
}
impl Drop for Dataset {
fn drop(&mut self) {
unsafe { gdal_sys::OGR_DS_Destroy(self.c_dataset); }
}
}