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

svector points #112

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 8 additions & 9 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,13 @@ struct _False <: BoolsAsTypes end
@inline _booltype(x::BoolsAsTypes)::BoolsAsTypes = x


const TuplePoint{N, T} = Tuple{T, T} where T <: AbstractFloat
const TuplePoint{T} = Tuple{T, T} where T <: AbstractFloat
const TupleEdge{T} = Tuple{TuplePoint{T},TuplePoint{T}} where T

# Should we just have default Float64??
TuplePoint_2D(vals) = (GI.x(vals), GI.y(vals))
TuplePoint_2D(vals, ::Type{T}) where T <: AbstractFloat = T.((GI.x(vals), GI.y(vals)))

TuplePoint_3D(vals) = (GI.x(vals), GI.y(vals), GI.z(vals))
TuplePoint_3D(vals, ::Type{T}) where T <: AbstractFloat = T.((GI.x(vals), GI.y(vals), GI.z(vals)))

TuplePoint_4D(vals) = (GI.x(vals), GI.y(vals), GI.z(vals), GI.m(vals))
TuplePoint_4D(vals, ::Type{T}) where T <: AbstractFloat = T.((GI.x(vals), GI.y(vals), GI.z(vals), GI.m(vals)))
TuplePoint_2D(vals, ::Type{T} = Float64) where T <: AbstractFloat = T.((GI.x(vals), GI.y(vals)))
TuplePoint_3D(vals, ::Type{T} = Float64) where T <: AbstractFloat = T.((GI.x(vals), GI.y(vals), GI.z(vals)))
TuplePoint_4D(vals, ::Type{T} = Float64) where T <: AbstractFloat = T.((GI.x(vals), GI.y(vals), GI.z(vals), GI.m(vals)))

#=
## `SVPoint`
Expand All @@ -92,6 +87,10 @@ struct SVPoint{N, T, Z, M} <: GeometryBasics.StaticArraysCore.StaticVector{N,T}
end
Base.getindex(p::SVPoint, i::Int64) = p.vals[i]

const Point_2D = SVPoint{2, T, false, false}
const Point_3D = SVPoint{3, T, true, false}
const Point_4D = SVPoint{4, T, true, true}

# Syntactic sugar for type stability within functions with known point types
SVPoint_2D(vals, ::Type{T} = Float64) where T <: AbstractFloat = _SVPoint_2D(TuplePoint_2D(vals, T))
_SVPoint_2D(vals::NTuple{2,T}) where T = SVPoint{2, T, false, false}(vals)
Expand Down
12 changes: 12 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,23 @@ Convert any geometry or collection of geometries into a flat
vector of `Tuple{Tuple{Float64,Float64},Tuple{Float64,Float64}}` edges.
"""
function to_edges(x, ::Type{T} = Float64) where T

edges = Vector{TupleEdge{T}}(undef, _nedge(x))
_to_edges!(edges, x, 1)
return edges
end

function find_point_constructor(x, ::Type{T})
if _ismeasured(x)
SVPoint_4D
elseif _is3d
SVPoint_3D
else
SVPoint_2D
end

end
Copy link
Member

@asinghvi17 asinghvi17 Jun 20, 2024

Choose a reason for hiding this comment

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

Suggested change
function find_point_constructor(x, ::Type{T})
if _ismeasured(x)
SVPoint_4D
elseif _is3d
SVPoint_3D
else
SVPoint_2D
end
end
function find_point_constructor(x, ::Type{T})
M = _ismeasured(x)
Z = _is3d(x)
N = 2 + M + Z
return SVPoint{N, T, Z, M}
end

This is what we should have, IMO, but it does overlap in purpose with the SVPoint_4D etc constructors defined earlier. I wonder whether we should simply define a default and a fallback for three-dimensional points, since that's where all the uncertainty is...

Here, the constructor for SVPoint{N, T, Z, M} would be overloaded to provide fallbacks (zero(T)) in case the input is not measured or 3d. Usually, that does compile out in most cases where it can.

Copy link
Collaborator Author

@skygering skygering Jun 21, 2024

Choose a reason for hiding this comment

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

What do you mean? I don't understand what you mean. I like your constructor - it is very elegant, but seems type unstable. I don't really understand your fallback concept.

These (M = _ismeasured(x), Z = _is3d(x)) return false which is equivalent to zero(T) when it isn't measured or 3d. I don't understand how we would have a fallback without running those lines. And then if we are running those lines, we are basically within find_point_constructor that you defined.

The reason I defined the SVPoint_4D etc. constructors was to eliminate type instability within functions where we know what types we are working with (i.e. clipping).


_to_edges!(edges::Vector, x, n) = _to_edges!(edges, trait(x), x, n)
function _to_edges!(edges::Vector, ::GI.FeatureCollectionTrait, fc, n)
for f in GI.getfeature(fc)
Expand Down