Skip to content

refactor(rust/sedona-raster-functions): extract CachedCrsToSRIDMapping and simplify SRID/CRS logic#590

Merged
Kontinuation merged 3 commits intoapache:mainfrom
Kontinuation:pr4-rs-srid-crs-mapping
Feb 13, 2026
Merged

refactor(rust/sedona-raster-functions): extract CachedCrsToSRIDMapping and simplify SRID/CRS logic#590
Kontinuation merged 3 commits intoapache:mainfrom
Kontinuation:pr4-rs-srid-crs-mapping

Conversation

@Kontinuation
Copy link
Member

Summary

  • Extract CachedCrsToSRIDMapping struct into sedona-schema::crs for reusable CRS-to-SRID caching, replacing ad-hoc HashMap caching in ST_SRID and duplicated logic in RS_SRID
  • Refactor RS_SRID and RS_CRS in sedona-raster-functions to use early-return patterns instead of deeply nested match arms
  • Add crs_str_ref() to RasterRefImpl for zero-copy CRS string access
  • Make with_global_proj_engine generic (pub fn ... -> Result<R>) and public for external use
  • Add test coverage for rasters with missing CRS and CRS without SRID

Dependencies

@Kontinuation Kontinuation changed the title refactor(raster): extract CachedCrsToSRIDMapping and simplify SRID/CRS logic feat(rust/sedona-raster-functions): extract CachedCrsToSRIDMapping and simplify SRID/CRS logic Feb 10, 2026
@Kontinuation Kontinuation changed the title feat(rust/sedona-raster-functions): extract CachedCrsToSRIDMapping and simplify SRID/CRS logic refactor(rust/sedona-raster-functions): extract CachedCrsToSRIDMapping and simplify SRID/CRS logic Feb 10, 2026
@Kontinuation Kontinuation marked this pull request as ready for review February 11, 2026 12:39
@Kontinuation Kontinuation requested a review from Copilot February 11, 2026 12:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors CRS/SRID handling to reuse a shared CRS→SRID cache and simplify raster SRID/CRS UDF logic, while also exposing a public/global PROJ engine helper and adding tests for missing/unsupported CRS cases.

Changes:

  • Added CachedCrsToSRIDMapping in sedona-schema::crs and updated SRID UDFs to use it.
  • Simplified RS_SRID / RS_CRS raster UDF logic (early returns) and added raster CRS string ref accessor.
  • Made with_global_proj_engine public + generic and added tests for missing CRS / CRS-without-SRID.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
rust/sedona-schema/src/crs.rs Introduces reusable cached CRS→SRID mapping + tweaks CRS deserialization behavior.
rust/sedona-raster/src/array.rs Refactors band metadata access and adds RasterRefImpl::crs_str_ref().
rust/sedona-raster-functions/src/rs_srid.rs Updates RS_SRID/RS_CRS to use caching and early-return flow; adds tests.
rust/sedona-functions/src/st_srid.rs Replaces per-batch HashMap caching with shared CachedCrsToSRIDMapping.
c/sedona-proj/src/st_transform.rs Makes global PROJ engine helper public and returns generic Result<R>.
c/sedona-proj/src/lib.rs Exposes st_transform module publicly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Kontinuation Kontinuation force-pushed the pr4-rs-srid-crs-mapping branch from 65a552d to cd4a87e Compare February 11, 2026 14:28
…S logic

Add CachedCrsToSRIDMapping to sedona-schema for reusable CRS-to-SRID
caching. Refactor RS_SRID, RS_CRS, and ST_SRID to use it, replacing
deeply nested match arms with early-return patterns. Add crs_str_ref()
to RasterRefImpl and make with_global_proj_engine generic and public.
@Kontinuation Kontinuation force-pushed the pr4-rs-srid-crs-mapping branch from fa7e695 to 0de5bb2 Compare February 13, 2026 03:05
Copy link
Member

@paleolimbot paleolimbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

pub mod register;
pub mod sd_order_lnglat;
mod st_transform;
pub mod st_transform;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be reverted? (I don't see a reference to with_global_proj_engine() in this PR?)

We should probably move the PROJ engine to its own public module and/or abstract it so we can switch to something faster for simple transforms.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. We may need to make it pub later, but definitely not in this PR. I'll revert it.

Comment on lines 429 to 431
thread_local! {
static PROJ_CACHE_SIZE: OnceCell<usize> = const { OnceCell::new() };
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. I'll remove it.

Comment on lines +111 to +114
/// Translating CRS into integer SRID with a cache to avoid expensive CRS deserialization.
pub struct CachedCrsToSRIDMapping {
cache: HashMap<Cow<'static, str>, u32>,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but the abbreviated CRS should probably have this too (I have a batch-local cache for st_setsrid):

let mut known_abbreviated = HashMap::<String, String>::new();
let string_value = crs_value.cast_to(&DataType::Utf8View, None)?;
let string_array_ref = ColumnarValue::values_to_arrays(&[string_value])?;
let string_view_array = as_string_view_array(&string_array_ref[0])?;
let utf8_view_array = string_view_array
.iter()
.map(|maybe_crs| -> Result<Option<String>> {
if let Some(crs_str) = maybe_crs {
if crs_str == "0" {
return Ok(None);
}
if let Some(abbreviated_crs) = known_abbreviated.get(crs_str) {
Ok(Some(abbreviated_crs.clone()))
} else if let Some(crs) = deserialize_crs(crs_str)? {
let abbreviated_crs =
if let Some(auth_code) = crs.to_authority_code()? {
auth_code
} else {
crs_str.to_string()
};
known_abbreviated.insert(crs.to_string(), abbreviated_crs.clone());
Ok(Some(abbreviated_crs))
} else {
Ok(None)
}
} else {
Ok(None)
}
})
.collect::<Result<StringViewArray>>()?;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll handle it when implementing RS_SetSRID and RS_SetCRS.

@Kontinuation Kontinuation merged commit c0b406e into apache:main Feb 13, 2026
17 checks passed
@paleolimbot paleolimbot added this to the 0.3.0 milestone Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants