Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 13 additions & 48 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 19 additions & 28 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,21 @@ keywords = ["geospatial", "gis", "spatial", "datafusion", "arrow"]
categories = ["science::geo", "database"]

[workspace.dependencies]
approx = "0.5"
adbc_core = ">=0.22.0"
adbc_ffi = ">=0.22.0"
lru = "0.16"
approx = "0.5"
arrow = { version = "57.0.0", features = ["prettyprint", "ffi", "chrono-tz"] }
arrow-array = { version = "57.0.0" }
arrow-buffer = { version = "57.0.0" }
arrow-cast = { version = "57.0.0" }
arrow-data = { version = "57.0.0" }
arrow-ipc = { version = "57.0.0" }
arrow-json = { version = "57.0.0" }
arrow-schema = { version = "57.0.0" }
arrow-buffer = { version = "57.0.0" }
async-trait = { version = "0.1.87" }
bytemuck = "1.25"
bytes = "1.11"
byteorder = "1"
bytes = "1.11"
chrono = { version = "0.4.41", default-features = false }
comfy-table = { version = "7.2" }
criterion = { version = "0.8", features = ["html_reports"] }
Expand All @@ -94,36 +93,26 @@ datafusion-physical-plan = { version = "51.0.0" }
datafusion-pruning = { version = "51.0.0" }
dirs = "6.0.0"
env_logger = "0.11"
log = "^0.4"
fastrand = "2.0"
float_next_after = "2"
futures = "0.3"
pin-project-lite = "0.2"
geo = "0.31.0"
geo-index = { version = "0.3.3", features = ["use-geo_0_31"] }
geo-traits = "0.3.0"
geo-types = "0.7.17"
geojson = "0.24.2"
geos = { version = "11.0.0", features = ["geo", "v3_12_0"] }
glam = "0.32.0"
object_store = { version = "0.12.4", default-features = false }
float_next_after = "2"
num-traits = { version = "0.2", default-features = false, features = ["libm"] }
mimalloc = { version = "0.1", default-features = false }
libmimalloc-sys = { version = "0.1", default-features = false }
log = "^0.4"
lru = "0.16"
mimalloc = { version = "0.1", default-features = false }
num-traits = { version = "0.2", default-features = false, features = ["libm"] }
object_store = { version = "0.12.4", default-features = false }
once_cell = "1.20"

geos = { git="https://github.com/georust/geos.git", rev="47afbad2483e489911ddb456417808340e9342c3", features = ["geo", "v3_12_0"] }

geo-types = "0.7.17"
geo-traits = "0.3.0"
geo = "0.31.0"
geojson = "0.24.2"

geo-index = { version = "0.3.3", features = ["use-geo_0_31"] }

wkb = "0.9.2"
wkt = "0.14.0"

parking_lot = "0.12"
parquet = { version = "57.0.0", default-features = false, features = [
"arrow",
"async",
"object_store",
] }
parquet = { version = "57.0.0", default-features = false, features = ["arrow", "async", "object_store"] }
pin-project-lite = "0.2"
rand = "0.10"
regex = "1.12"
rstest = "0.26.1"
Expand All @@ -134,6 +123,8 @@ tempfile = { version = "3"}
thiserror = { version = "2" }
tokio = { version = "1.48", features = ["macros", "rt", "sync"] }
url = "2.5.7"
wkb = "0.9.2"
wkt = "0.14.0"

# Workspace path dependencies for internal crates
sedona = { version = "0.3.0", path = "rust/sedona" }
Expand Down
20 changes: 18 additions & 2 deletions c/sedona-geos/src/geos_to_wkb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ use std::io::Write;
use byteorder::{LittleEndian, WriteBytesExt};
use datafusion_common::{error::Result, DataFusionError};
use geo_traits::Dimensions;
use geos::{Geom, Geometry, GeometryTypes};
use geos::{CoordType, Geom, Geometry, GeometryTypes};
use sedona_common::sedona_internal_err;
use sedona_geometry::wkb_factory::{
write_wkb_geometrycollection_header, write_wkb_linestring_header,
write_wkb_multilinestring_header, write_wkb_multipoint_header, write_wkb_multipolygon_header,
Expand Down Expand Up @@ -265,8 +266,16 @@ fn write_coord_seq(
dim: Dimensions,
writer: &mut impl Write,
) -> Result<()> {
let coord_type = match dim {
Dimensions::Xy => CoordType::XY,
Dimensions::Xyz => CoordType::XYZ,
Dimensions::Xym => CoordType::XYM,
Dimensions::Xyzm => CoordType::XYZM,
_ => return sedona_internal_err!("Unexpected dimensions {dim:?}"),
};

let coords = coord_seq
.as_buffer(Some(dim.size()))
.as_buffer(Some(coord_type))
.map_err(|e| DataFusionError::Execution(format!("Failed to get coord seq buffer: {e}")))?;

// Cast Vec<f64> to &[u8] so we can write the bytes directly to the writer buffer
Expand Down Expand Up @@ -339,6 +348,13 @@ mod tests {
test_wkb_round_trip("LINESTRING Z (0 0 10, 1 1 11, 2 2 12)");
}

#[test]
fn test_write_linestring_xym() {
test_wkb_round_trip("LINESTRING M (0 0 0, 1 1 1)");
test_wkb_round_trip("LINESTRING M (0 0 0, 1 1 1, 2 2 2)");
test_wkb_round_trip("LINESTRING M (0 0 10, 1 1 11, 2 2 12)");
}

#[test]
fn test_write_linestring_xyzm() {
test_wkb_round_trip("LINESTRING ZM (0 0 1 2, 1 1 3 4)");
Expand Down
18 changes: 9 additions & 9 deletions c/sedona-geos/src/wkb_to_geos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::cell::RefCell;

use byteorder::{BigEndian, ByteOrder, LittleEndian};
use geo_traits::*;
use geos::GResult;
use geos::{CoordType, GResult};
use wkb::{reader::*, Endianness};

/// A factory for converting WKB to GEOS geometries.
Expand Down Expand Up @@ -215,11 +215,11 @@ fn create_coord_sequence_from_raw_parts(
num_coords: usize,
scratch: &mut Vec<f64>,
) -> GResult<geos::CoordSeq> {
let (has_z, has_m, dim_size) = match dim {
Dimension::Xy => (false, false, 2),
Dimension::Xyz => (true, false, 3),
Dimension::Xym => (false, true, 3),
Dimension::Xyzm => (true, true, 4),
let (coord_type, dim_size) = match dim {
Dimension::Xy => (CoordType::XY, 2),
Dimension::Xyz => (CoordType::XYZ, 3),
Dimension::Xym => (CoordType::XYM, 3),
Dimension::Xyzm => (CoordType::XYZM, 4),
};
let num_ordinates = dim_size * num_coords;

Expand All @@ -233,7 +233,7 @@ fn create_coord_sequence_from_raw_parts(
{
let coords_f64 =
unsafe { &*core::ptr::slice_from_raw_parts(ptr as *const f64, num_ordinates) };
geos::CoordSeq::new_from_buffer(coords_f64, num_coords, has_z, has_m)
geos::CoordSeq::new_from_buffer(coords_f64, num_coords, coord_type)
}

// On platforms without unaligned memory access support, we need to copy the data to the
Expand All @@ -249,7 +249,7 @@ fn create_coord_sequence_from_raw_parts(
scratch.as_mut_ptr() as *mut u8,
num_ordinates * std::mem::size_of::<f64>(),
);
geos::CoordSeq::new_from_buffer(scratch.as_slice(), num_coords, has_z, has_m)
geos::CoordSeq::new_from_buffer(scratch.as_slice(), num_coords, coord_type)
}
}
} else {
Expand All @@ -262,7 +262,7 @@ fn create_coord_sequence_from_raw_parts(
save_f64_to_scratch::<LittleEndian>(scratch, buf, num_ordinates);
}
}
geos::CoordSeq::new_from_buffer(scratch.as_slice(), num_coords, has_z, has_m)
geos::CoordSeq::new_from_buffer(scratch.as_slice(), num_coords, coord_type)
}
}

Expand Down
4 changes: 2 additions & 2 deletions python/sedonadb/tests/functions/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,10 +1174,10 @@ def test_st_unaryunion(eng, geom, expected):
@pytest.mark.parametrize(
("geom", "expected"),
[
# Skip M tests because geos rust isn't capable of writing XYM geometries yet
# https://github.com/apache/sedona-db/issues/481
("POINT M EMPTY", "POINT M EMPTY"),
("POINT Z EMPTY", "POINT Z EMPTY"),
("POINT ZM EMPTY", "POINT ZM EMPTY"),
("POINT M (0 1 2)", "POINT M(0 1 2)"),
("POINT Z (0 0 0)", "POINT Z(0 0 0)"),
("POINT ZM (1 2 3 4)", "POINT ZM(1 2 3 4)"),
("LINESTRING Z (0 0 0, 1 1 1)", "LINESTRING Z(0 0 0,1 1 1)"),
Expand Down