Skip to content

Commit d131823

Browse files
authored
Implement promote for Points & Handle -180° == 180° in latlon coordinates (#1032)
* Handle -180° == 180° in latlon coordinates * Fix typo * Apply suggestions * Fix tests * Implement promote for Points * Remove unused code * Fix promote * Fix tests * Rename variables * Bump version
1 parent f7a29f0 commit d131823

File tree

4 files changed

+57
-14
lines changed

4 files changed

+57
-14
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ MeshesMakieExt = "Makie"
3131
Bessels = "0.2"
3232
CircularArrays = "1.3"
3333
Colorfy = "0.1"
34-
CoordRefSystems = "0.12"
34+
CoordRefSystems = "0.13.1"
3535
DelaunayTriangulation = "1.0"
3636
Distances = "0.10"
3737
LinearAlgebra = "1.9"

src/geometries/primitives/point.jl

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,34 @@ Point(coords::CRS) = Point{_manifold(coords)}(coords)
4444
# convenience constructor
4545
Point(coords...) = Point(Cartesian(coords...))
4646

47-
# conversions
47+
# conversion
4848
Base.convert(::Type{Point{M,CRSₜ}}, p::Point{M,CRSₛ}) where {M,CRSₜ,CRSₛ} = Point{M}(convert(CRSₜ, p.coords))
4949
Base.convert(::Type{Point{M,CRS}}, p::Point{M,CRS}) where {M,CRS} = p
5050

51+
# promotion
52+
function Base.promote(A::Point, B::Point)
53+
a, b = promote(coords(A), coords(B))
54+
Point(a), Point(b)
55+
end
56+
5157
paramdim(::Type{<:Point}) = 0
5258

53-
==(A::Point, B::Point) = to(A) == to(B)
59+
function ==(A::Point, B::Point)
60+
A′, B′ = promote(A, B)
61+
to(A′) == to(B′)
62+
end
63+
64+
function ==(A::Point{🌐,<:LatLon}, B::Point{🌐,<:LatLon})
65+
A′, B′ = promote(A, B)
66+
lat₁, lon₁ = A′.coords.lat, A′.coords.lon
67+
lat₂, lon₂ = B′.coords.lat, B′.coords.lon
68+
lat₁ == lat₂ && lon₁ == lon₂ || (abs(lon₁) == 180u"°" && lon₁ == -lon₂)
69+
end
5470

55-
Base.isapprox(A::Point, B::Point; atol=atol(lentype(A)), kwargs...) = isapprox(to(A), to(B); atol, kwargs...)
71+
function Base.isapprox(A::Point, B::Point; atol=atol(lentype(A)), kwargs...)
72+
A′, B′ = promote(A, B)
73+
isapprox(to(A′), to(B′); atol, kwargs...)
74+
end
5675

5776
"""
5877
coords(point)

test/primitives.jl

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
@test embeddim(Point(1)) == 1
33
@test embeddim(Point(1, 2)) == 2
44
@test embeddim(Point(1, 2, 3)) == 3
5+
@test paramdim(Point(1)) == 0
6+
@test paramdim(Point(1, 2)) == 0
7+
@test paramdim(Point(1, 2, 3)) == 0
58
@test crs(cart(1, 1)) <: Cartesian{NoDatum}
69
@test crs(Point(Polar(T(2), T/ 4)))) <: Polar{NoDatum}
710
@test crs(Point(Cylindrical(T(2), T/ 4), T(1)))) <: Cylindrical{NoDatum}
@@ -11,13 +14,43 @@
1114
@test Meshes.lentype(Point((T(1), T(1)))) ==
1215
@test Meshes.lentype(Point(T(1), T(1))) ==
1316

17+
# conversion
18+
P = typeof(cart(1, 1))
19+
p1 = Point(1.0, 1.0)
20+
p2 = convert(P, p1)
21+
@test p2 isa P
22+
p1 = Point(1.0f0, 1.0f0)
23+
p2 = convert(P, p1)
24+
@test p2 isa P
25+
26+
# promotion
27+
p1 = Point(T(1), T(1))
28+
p2 = Point(1.0, 1.0)
29+
p3 = Point(1.0f0, 1.0f0)
30+
ps = promote(p1, p2)
31+
@test allequal(Meshes.lentype.(ps))
32+
@test Meshes.lentype(first(ps)) == Meshes.Met{Float64}
33+
ps = promote(p1, p3)
34+
@test allequal(Meshes.lentype.(ps))
35+
@test Meshes.lentype(first(ps)) == Meshes.Met{T}
36+
1437
equaltest(cart(1))
1538
equaltest(cart(1, 2))
1639
equaltest(cart(1, 2, 3))
1740
isapproxtest(cart(1))
1841
isapproxtest(cart(1, 2))
1942
isapproxtest(cart(1, 2, 3))
2043

44+
# different datums
45+
p1 = Point(Cartesian{WGS84{1762}}(T(1), T(1), T(1)))
46+
p2 = Point(Cartesian{ITRF{2008}}(T(1), T(1), T(1)))
47+
@test p1 == p2
48+
@test p1 p2
49+
50+
# latlon special cases
51+
@test latlon(45, 180) == latlon(45, -180)
52+
@test latlon(45, -180) == latlon(45, 180)
53+
2154
@test to(cart(1)) == vector(1)
2255
@test to(cart(1, 2)) == vector(1, 2)
2356
@test to(cart(1, 2, 3)) == vector(1, 2, 3)
@@ -89,15 +122,6 @@
89122
@test unit(Meshes.lentype(p)) == u"m"
90123
@test Unitful.numtype(Meshes.lentype(p)) === Float32
91124

92-
# conversions
93-
P = typeof(cart(1, 1))
94-
p1 = Point(1.0, 1.0)
95-
p2 = convert(P, p1)
96-
@test p2 isa P
97-
p1 = Point(1.0f0, 1.0f0)
98-
p2 = convert(P, p1)
99-
@test p2 isa P
100-
101125
# centroid
102126
@test centroid(cart(1, 1)) == cart(1, 1)
103127

test/transforms.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,7 @@ end
11291129
g = latlon(0, 0)
11301130
r, c = TB.apply(f, g)
11311131
@test manifold(r) === 🌐
1132-
@test r cart(6378137.0, 0, 0)
1132+
@test r Point(Cartesian{WGS84Latest}(T(6378137.0), T(0), T(0)))
11331133

11341134
# --------
11351135
# SEGMENT

0 commit comments

Comments
 (0)