-
Notifications
You must be signed in to change notification settings - Fork 10
Add support for Extent #131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -262,6 +262,64 @@ function (trans::Transformation)(coord) | |
| end | ||
| end | ||
|
|
||
| """ | ||
| (trans::Transformation)(extent::Extents.Extent) -> Extents.Extent | ||
|
|
||
| Transform an `Extents.Extent` using the transformation. The extent must have X and Y | ||
| dimensions. Extra dimensions (Z, Ti, etc.) are preserved unchanged. | ||
|
|
||
| Throws an `ArgumentError` if the transformation is rotated or non-axis-aligned, | ||
| since an axis-aligned bounding box cannot accurately represent a rotated extent. | ||
|
|
||
| # Examples | ||
| ```julia | ||
| julia> trans = Proj.Transformation("EPSG:4326", "EPSG:28992", always_xy=true) | ||
| julia> extent = Extents.Extent(X=(5.0, 6.0), Y=(52.0, 53.0)) | ||
| julia> trans(extent) | ||
| Extent(X = (131793.0, 199684.0), Y = (449093.0, 560431.0)) | ||
| ``` | ||
| """ | ||
| function (trans::Transformation)(extent::Extents.Extent) | ||
| haskey(extent, :X) && haskey(extent, :Y) || | ||
| throw(ArgumentError("Extent must have X and Y dimensions")) | ||
|
|
||
| _check_axis_aligned(trans, extent) || | ||
| throw(ArgumentError("Cannot transform Extent: CRS is rotated or non-axis-aligned")) | ||
|
|
||
| (xmin, xmax), (ymin, ymax) = bounds(trans, extent.X, extent.Y) | ||
|
|
||
| return Extents.Extent(merge(NamedTuple(extent), (X=(xmin, xmax), Y=(ymin, ymax)))) | ||
| end | ||
|
|
||
| # Check if corners transform to an axis-aligned rectangle | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do you need this at all,
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this check would seem to make this method completely useless in most cases 😅 |
||
| function _check_axis_aligned(trans::Transformation, extent::Extents.Extent; rtol=0.1) | ||
| xmin, xmax = extent.X | ||
| ymin, ymax = extent.Y | ||
|
|
||
| # Transform the 4 corners | ||
| c1 = trans(xmin, ymin) # bottom-left | ||
| c2 = trans(xmax, ymin) # bottom-right | ||
| c3 = trans(xmin, ymax) # top-left | ||
| c4 = trans(xmax, ymax) # top-right | ||
|
|
||
| # For axis-aligned transform, vertical edges should have similar x-coords | ||
| # and horizontal edges should have similar y-coords | ||
| # Use relative tolerance to allow for projection curvature | ||
| x_range = max(abs(c1[1] - c2[1]), abs(c3[1] - c4[1]), 1.0) | ||
| y_range = max(abs(c1[2] - c3[2]), abs(c2[2] - c4[2]), 1.0) | ||
|
|
||
| # Check left edge: c1 and c3 should have similar x | ||
| abs(c1[1] - c3[1]) < rtol * x_range || return false | ||
| # Check right edge: c2 and c4 should have similar x | ||
| abs(c2[1] - c4[1]) < rtol * x_range || return false | ||
| # Check bottom edge: c1 and c2 should have similar y | ||
| abs(c1[2] - c2[2]) < rtol * y_range || return false | ||
| # Check top edge: c3 and c4 should have similar y | ||
| abs(c3[2] - c4[2]) < rtol * y_range || return false | ||
|
|
||
| return true | ||
| end | ||
|
|
||
| """ | ||
| Proj.bounds(trans::Transformation, (xmin, xmax), (ymin,ymax); densify_pts=21) -> ((bxmin, bxmax), (bymin, bymax)) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to pass that kwarg down