Support PATH type with geo::LineString
This commit is contained in:
parent
efbf30c4fe
commit
e07b7b04e4
15
README.md
15
README.md
@ -268,6 +268,13 @@ types. The driver currently supports the following conversions:
|
|||||||
</td>
|
</td>
|
||||||
<td>BOX</td>
|
<td>BOX</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/georust/rust-geo">geo::LineString<f64></a>
|
||||||
|
(<a href="#optional-features">optional</a>)
|
||||||
|
</td>
|
||||||
|
<td>PATH</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@ -340,3 +347,11 @@ support is provided optionally by the `with-geo` feature, which adds `ToSql` and
|
|||||||
|
|
||||||
[BOX](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6883)
|
[BOX](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6883)
|
||||||
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo`'s `Bbox` type.
|
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo`'s `Bbox` type.
|
||||||
|
|
||||||
|
### PATH type
|
||||||
|
|
||||||
|
[PATH](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6912)
|
||||||
|
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo`'s `LineString` type.
|
||||||
|
Paths converted from LineString are always treated as "open" paths. Use the
|
||||||
|
[pclose](https://www.postgresql.org/docs/8.2/static/functions-geometry.html#FUNCTIONS-GEOMETRY-FUNC-TABLE)
|
||||||
|
geometric function to insert a closed path.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
extern crate geo;
|
extern crate geo;
|
||||||
|
|
||||||
use postgres_protocol::types;
|
use postgres_protocol::types;
|
||||||
use self::geo::{Bbox, Point};
|
use self::geo::{Bbox, LineString, Point};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use types::{FromSql, ToSql, IsNull, Type};
|
use types::{FromSql, ToSql, IsNull, Type};
|
||||||
@ -59,3 +59,44 @@ impl ToSql for Bbox<f64> {
|
|||||||
accepts!(Type::Box);
|
accepts!(Type::Box);
|
||||||
to_sql_checked!();
|
to_sql_checked!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromSql for LineString<f64> {
|
||||||
|
fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> {
|
||||||
|
if raw.len() < 5 {
|
||||||
|
return Err("invalid message length".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// let _ = types::bool_from_sql(&raw[0..1])?; // is path open or closed
|
||||||
|
let n_points = types::int4_from_sql(&raw[1..5])? as usize;
|
||||||
|
let raw_points = &raw[5..raw.len()-1];
|
||||||
|
if raw_points.len() != 16 * n_points {
|
||||||
|
return Err("invalid message length".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut points = Vec::with_capacity(n_points);
|
||||||
|
for n in 0..n_points {
|
||||||
|
let x = types::float8_from_sql(&raw[n..n+8])?;
|
||||||
|
let y = types::float8_from_sql(&raw[n+8..n+16])?;
|
||||||
|
points.push(Point::new(x, y));
|
||||||
|
}
|
||||||
|
Ok(LineString(points))
|
||||||
|
}
|
||||||
|
|
||||||
|
accepts!(Type::Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToSql for LineString<f64> {
|
||||||
|
fn to_sql(&self, _: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
|
||||||
|
let closed = false; // always encode an open path from LineString
|
||||||
|
types::bool_to_sql(closed, out);
|
||||||
|
types::int4_to_sql(self.0.len() as i32, out);
|
||||||
|
for point in &self.0 {
|
||||||
|
types::float8_to_sql(point.x(), out);
|
||||||
|
types::float8_to_sql(point.y(), out);
|
||||||
|
}
|
||||||
|
Ok(IsNull::No)
|
||||||
|
}
|
||||||
|
|
||||||
|
accepts!(Type::Path);
|
||||||
|
to_sql_checked!();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user