Skip to content

Commit

Permalink
add transform method for coordinate transformations (#35)
Browse files Browse the repository at this point in the history
* add transform method for coordinate transformations

* clean up tests

* actually run the test

* dont flip!

* no flip

* fix the doc
  • Loading branch information
rafaqz authored Jan 2, 2024
1 parent 75603bd commit 135be02
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/GeometryOps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ using GeometryBasics
import Proj
using LinearAlgebra
import ExactPredicates
import Proj.CoordinateTransformations.StaticArrays

using GeoInterface.Extents: Extents

Expand Down Expand Up @@ -38,5 +39,6 @@ include("transformations/flip.jl")
include("transformations/simplify.jl")
include("transformations/reproject.jl")
include("transformations/tuples.jl")
include("transformations/transform.jl")

end
56 changes: 56 additions & 0 deletions src/transformations/transform.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

"""
transform(f, obj)
Apply a function `f` to all the points in `obj`.
Points will be passed to `f` as an `SVector` to allow
using CoordinateTransformations.jl and Rotations.jl
without hassle.
`SVector` is also a valid GeoInterface.jl point, so will
work in all GeoInterface.jl methods.
## Example
```julia
julia> import GeoInterface as GI
julia> import GeometryOps as GO
julia> geom = GI.Polygon([GI.LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), GI.LinearRing([(3, 4), (5, 6), (6, 7), (3, 4)])]);
julia> f = CoordinateTransformations.Translation(3.5, 1.5)
Translation(3.5, 1.5)
julia> GO.transform(f, geom)
GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}}, Nothing, Nothing}(GeoInterface.Wrappers.Linea
rRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}[GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}(StaticArraysCo
re.SVector{2, Float64}[[4.5, 3.5], [6.5, 5.5], [8.5, 7.5], [4.5, 3.5]], nothing, nothing), GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}(StaticA
rraysCore.SVector{2, Float64}[[6.5, 5.5], [8.5, 7.5], [9.5, 8.5], [6.5, 5.5]], nothing, nothing)], nothing, nothing)
```
With Rotations.jl you need to actuall multiply the Rotation
by the `SVector` point, which is easy using an anonymous function.
```julia
julia> using Rotations
julia> GO.transform(p -> one(RotMatrix{2}) * p, geom)
GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}}, Nothing, Nothing}(GeoInterface.Wrappers.LinearR
ing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}[GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}(StaticArraysCore.SVe
ctor{2, Int64}[[2, 1], [4, 3], [6, 5], [2, 1]], nothing, nothing), GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}(StaticArraysCore.SVector{2, Int64
}[[4, 3], [6, 5], [7, 6], [4, 3]], nothing, nothing)], nothing, nothing)
```
"""
function transform(f, geom; kw...)
if _is3d(geom)
return apply(PointTrait, geom; kw...) do p
f(StaticArrays.SVector{3}((GI.x(p), GI.y(p), GI.z(p))))
end
else
return apply(PointTrait, geom; kw...) do p
f(StaticArrays.SVector{2}((GI.x(p), GI.y(p))))
end
end
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ const GO = GeometryOps
@testset "Reproject" begin include("transformations/reproject.jl") end
@testset "Flip" begin include("transformations/flip.jl") end
@testset "Simplify" begin include("transformations/simplify.jl") end
@testset "Transform" begin include("transformations/transform.jl") end
end
14 changes: 14 additions & 0 deletions test/transformations/transform.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Test

import GeoInterface as GI
import GeometryOps as GO
using GeometryOps.Proj.CoordinateTransformations

@testset "transform" begin
geom = GI.Polygon([GI.LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]),
GI.LinearRing([(3, 4), (5, 6), (6, 7), (3, 4)])])
translated = GI.Polygon([GI.LinearRing([[4.5, 3.5], [6.5, 5.5], [8.5, 7.5], [4.5, 3.5]]),
GI.LinearRing([[6.5, 5.5], [8.5, 7.5], [9.5, 8.5], [6.5, 5.5]])])
f = CoordinateTransformations.Translation(3.5, 1.5)
@test GO.transform(f, geom) == translated
end

0 comments on commit 135be02

Please sign in to comment.