Skip to content
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

actually test embed_extent #29

Merged
merged 4 commits into from
Dec 24, 2023
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
1 change: 1 addition & 0 deletions src/GeometryOps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ include("methods/polygonize.jl")
include("methods/barycentric.jl")
include("methods/equals.jl")

include("transformations/extent.jl")
include("transformations/flip.jl")
include("transformations/simplify.jl")
include("transformations/reproject.jl")
Expand Down
17 changes: 15 additions & 2 deletions src/primitives.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
const THREADED_KEYWORD = "- `threaded`: `true` or `false`. Whether to use multithreading. Defaults to `false`."
Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh this is such a good way of not having to retype the same documentation over and over. I am so stealing this for my other project 😆

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, from Rasters.jl experience. Actually the main reason is so users see exactly the same things everywhere and it feels consistent

const CRS_KEYWORD = "- `crs`: The CRS to attach to geometries. Defaults to `nothing`."
const CALC_EXTENT_KEYWORD = "- `calc_extent`: `true` or `false`. Whether to calculate the extent. Defaults to `false`."

const APPLY_KEYWORDS = """
$THREADED_KEYWORD
$CRS_KEYWORD
$CALC_EXTENT_KEYWORD
"""

# # Primitive functions

# This file mainly defines the [`apply`](@ref) function.

"""
apply(f, target::Type{<:AbstractTrait}, obj; crs)
apply(f, target::Type{<:AbstractTrait}, obj; kw...)

Reconstruct a geometry or feature using the function `f` on the `target` trait.

`f(target_geom) => x` where `x` also has the `target` trait, or an equivalent.

The result is an functionally similar geometry with values depending on `f`

# Flipped point the order in any feature or geometry, or iterables of either:
$APPLY_KEYWORDS

# Example

Flipped point the order in any feature or geometry, or iterables of either:

```juia
import GeoInterface as GI
Expand Down
29 changes: 11 additions & 18 deletions src/transformations/extent.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
"""
embed_extent(obj)

Recursively wrap the object with a `GeoInterface.Wrappers` geometry,
Recursively wrap the object with a GeoInterface.jl geometry,
calculating and adding an `Extents.Extent` to all objects.

This can improve performance when extents need to be checked multiple times.
"""
embed_extent(x; kw...) = apply(AbstractTrait, x; kw...)
This can improve performance when extents need to be checked multiple times,
such when needing to check if many points are in geometries, and using their extents
as a quick filter for obviously exterior points.

# Keywords

extent_applicator(x) = extent_applicator(trait(x), x)
extent_applicator(::Nothing, xs::AbstractArray) = embed_extent.(xs)
extent_applicator(::Union{AbstractCurveTrait,MultiPointTrait}, point) = point

function extent_applicator(trait::AbstractGeometryTrait, geom)
children_with_extents = map(GI.getgeom(geom)) do g
embed_extent(g)
end
wrapper_type = GI.geointerface_geomtype(trait)
extent = GI.extent(wrapper_type(children_with_extents))
return wrapper_type(children_with_extents, extent)
end
extent_applicator(::PointTrait, point) = point
extent_applicator(::PointTrait, point) = point
$THREADED_KEYWORD
$CRS_KEYWORD
"""
embed_extent(x; threaded=false, crs=nothing) =
apply(identity, GI.PointTrait, x; calc_extent=true, threaded, crs)
4 changes: 4 additions & 0 deletions src/transformations/flip.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
Swap all of the x and y coordinates in obj, otherwise
keeping the original structure (but not necessarily the
original type).

## Keywords

$APPLY_KEYWORDS
"""
function flip(geom; kw...)
if _is3d(geom)
Expand Down
5 changes: 3 additions & 2 deletions src/transformations/reproject.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ needed if it is not retreivable from the geometry with `GeoInterface.crs(geometr

## Keywords

-`always_xy`: force x, y coordinate order, `true` by default.
- `always_xy`: force x, y coordinate order, `true` by default.
`false` will expect and return points in the crs coordinate order.
-`time`: the time for the coordinates. `Inf` by default.
- `time`: the time for the coordinates. `Inf` by default.
$APPLY_KEYWORDS
"""
function reproject(geom;
source_crs=nothing, target_crs=nothing, transform=nothing, kw...
Expand Down
15 changes: 12 additions & 3 deletions src/transformations/simplify.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ abstract type SimplifyAlg end

const SIMPLIFY_ALG_KEYWORDS = """
## Keywords

- `ratio`: the fraction of points that should remain after `simplify`.
Useful as it will generalise for large collections of objects.
- `number`: the number of points that should remain after `simplify`.
Expand All @@ -48,7 +49,7 @@ end

"""
simplify(obj; kw...)
simplify(::SimplifyAlg, obj)
simplify(::SimplifyAlg, obj; kw...)

Simplify a geometry, feature, feature collection,
or nested vectors or a table of these.
Expand All @@ -62,6 +63,14 @@ listed in order of increasing quality but decreaseing performance.
The default behaviour is `simplify(DouglasPeucker(; kw...), obj)`.
Pass in other [`SimplifyAlg`](@ref) to use other algorithms.

# Keywords

$APPLY_KEYWORDS

Keywords for DouglasPeucker are allowed when no algorithm is specified:

$SIMPLIFY_ALG_KEYWORDS

# Example

Simplify a polygon to have six points:
Expand Down Expand Up @@ -99,8 +108,8 @@ GI.npoint(simple)
6
```
"""
simplify(data; calc_extent=false, threaded=false, kw...) =
_simplify(DouglasPeucker(; kw...), data; calc_extent, threaded)
simplify(data; calc_extent=false, threaded=false, crs=nothing, kw...) =
_simplify(DouglasPeucker(; kw...), data; calc_extent, threaded, crs)
simplify(alg::SimplifyAlg, data; kw...) = _simplify(alg, data; kw...)

function _simplify(alg::SimplifyAlg, data; kw...)
Expand Down
9 changes: 8 additions & 1 deletion src/transformations/tuples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
"""
tuples(obj)

Convert all points on obj to `Tuple`s.
Convert all points in `obj` to `Tuple`s, wherever the are nested.

Returns a similar object or collection of objects using GeoInterface.jl
geometries wrapping `Tuple` points.

# Keywords

$APPLY_KEYWORDS
"""
function tuples(geom; kw...)
if _is3d(geom)
Expand Down
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const GO = GeometryOps
@testset "Signed Area" begin include("methods/signed_area.jl") end
@testset "Overlaps" begin include("methods/overlaps.jl") end
# Transformations
@testset "Embed Extent" begin include("transformations/extent.jl") end
@testset "Reproject" begin include("transformations/reproject.jl") end
@testset "Flip" begin include("transformations/flip.jl") end
@testset "Simplify" begin include("transformations/simplify.jl") end
Expand Down
16 changes: 16 additions & 0 deletions test/transformations/extent.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Test

import GeoInterface as GI
import GeometryOps as GO
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would be good to test at least one curve or something that isn't nested since that is a separate function

Copy link
Member Author

Choose a reason for hiding this comment

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

If we use apply for everything than it also needs less tests.

using GeoInterface: Extents

@testset "embed_extent" begin
poly = GI.Polygon([GI.LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]),
GI.LinearRing([(3, 4), (5, 6), (6, 7), (3, 4)])])

ext_poly = GO.embed_extent(poly)
lr1, lr2 = GI.getgeom(ext_poly)
@test ext_poly.extent == Extents.Extent(X=(1, 6), Y=(2, 7))
@test lr1.extent == Extents.Extent(X=(1, 5), Y=(2, 6))
@test lr2.extent == Extents.Extent(X=(3, 6), Y=(4, 7))
end
Loading