Skip to content

Commit

Permalink
style: cleanup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmach committed Nov 12, 2021
1 parent fa5ad2b commit 151ae31
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 108 deletions.
31 changes: 16 additions & 15 deletions geo/distance.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,13 @@ func PointAtBearingAndDistance(p orb.Point, bearing, distance float64) orb.Point

distanceRatio := distance / orb.EarthRadius
bLat := math.Asin(math.Sin(aLat)*math.Cos(distanceRatio) + math.Cos(aLat)*math.Sin(distanceRatio)*math.Cos(bearingRadians))
bLon := aLon + math.Atan2(math.Sin(bearingRadians)*math.Sin(distanceRatio)*math.Cos(aLat), math.Cos(distanceRatio)-math.Sin(aLat)*math.Sin(bLat))
bLon := aLon +
math.Atan2(
math.Sin(bearingRadians)*math.Sin(distanceRatio)*math.Cos(aLat),
math.Cos(distanceRatio)-math.Sin(aLat)*math.Sin(bLat),
)

r := orb.Point{
rad2deg(bLon),
rad2deg(bLat),
}

return r
return orb.Point{rad2deg(bLon), rad2deg(bLat)}
}

func PointAtDistanceAlongLine(ls orb.LineString, distance float64) (orb.Point, float64) {
Expand All @@ -98,21 +97,23 @@ func PointAtDistanceAlongLine(ls orb.LineString, distance float64) (orb.Point, f
return ls[0], 0.0
}

travelled := 0.0
i := 1
var from, to orb.Point
for ; i < len(ls); i++ {
from = ls[i-1]
to = ls[i]
var (
travelled = 0.0
from, to orb.Point
)

for i := 1; i < len(ls); i++ {
from, to = ls[i-1], ls[i]

actualSegmentDistance := DistanceHaversine(from, to)
expectedSegmentDistance := distance - travelled

if expectedSegmentDistance < actualSegmentDistance {
bearing := Bearing(from, to)
return PointAtBearingAndDistance(from, bearing, expectedSegmentDistance), bearing
}
travelled += actualSegmentDistance
}

bearing := Bearing(from, to)
return to, bearing
return to, Bearing(from, to)
}
205 changes: 112 additions & 93 deletions geo/distance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,27 +91,119 @@ func TestMidpoint(t *testing.T) {
}

func TestPointAtBearingAndDistance(t *testing.T) {
expected := orb.Point{-0.841153, 52.68179432}
bearing := 127.373
distance := 85194.89
actual := PointAtBearingAndDistance(orb.Point{-1.8444, 53.1506}, bearing, distance)

if d := DistanceHaversine(actual, expected); d > 1 {
t.Errorf("expected %v, got %v (%vm away)", expected, actual, d)
}
cases := []struct {
name string
point orb.Point
bearing float64
distance float64
expected orb.Point
}{
{
name: "simple",
point: orb.Point{-1.8444, 53.1506},
bearing: 127.373,
distance: 85194.89,
expected: orb.Point{-0.841153, 52.68179432},
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
actual := PointAtBearingAndDistance(tc.point, tc.bearing, tc.distance)

if d := DistanceHaversine(actual, tc.expected); d > 1 {
t.Errorf("expected %v, got %v (%vm away)", tc.expected, actual, d)
}
})
}

t.Run("midpoint", func(t *testing.T) {
a := orb.Point{-1.8444, 53.1506}
b := orb.Point{0.1406, 52.2047}
bearing := Bearing(a, b)
distance := DistanceHaversine(a, b)

p1 := PointAtBearingAndDistance(a, bearing, distance/2)
p2 := Midpoint(a, b)

if d := DistanceHaversine(p1, p2); d > epsilon {
t.Errorf("expected %v to be within %vm of %v", p1, epsilon, p2)
}
})
}
func TestMidpointAgainstPointAtBearingAndDistance(t *testing.T) {
a := orb.Point{-1.8444, 53.1506}
b := orb.Point{0.1406, 52.2047}
bearing := Bearing(a, b)
distance := DistanceHaversine(a, b)
acceptableTolerance := 1e-06 // unit is meters

p1 := PointAtBearingAndDistance(a, bearing, distance/2)
p2 := Midpoint(a, b)

if d := DistanceHaversine(p1, p2); d > acceptableTolerance {
t.Errorf("expected %v to be within %vm of %v", p1, acceptableTolerance, p2)

func TestPointAtDistanceAlongLineWithSinglePoint(t *testing.T) {
cases := []struct {
name string
line orb.LineString
distance float64
expectedPoint orb.Point
expectedBearing float64
}{
{
name: "with single point",
line: orb.LineString{
orb.Point{-1.8444, 53.1506},
},
distance: 9000,
expectedPoint: orb.Point{-1.8444, 53.1506},
expectedBearing: 0,
},
{
name: "with minimal points",
line: orb.LineString{
orb.Point{-1.8444, 53.1506},
orb.Point{0.1406, 52.2047},
},
distance: 85194.89,
expectedPoint: orb.Point{-0.841153, 52.68179432},
expectedBearing: Bearing(
orb.Point{-1.8444, 53.1506},
orb.Point{0.1406, 52.2047},
),
},
{
name: "with single point",
line: orb.LineString{
orb.Point{-1.8444, 53.1506},
orb.Point{-0.8411, 52.6817},
orb.Point{0.1406, 52.2047},
},
distance: 90000,
expectedPoint: orb.Point{-0.78526, 52.65506},
expectedBearing: Bearing(
orb.Point{-0.8411, 52.6817},
orb.Point{0.1406, 52.2047},
),
},
{
name: "past end of line",
line: orb.LineString{
orb.Point{-1.8444, 53.1506},
orb.Point{-0.8411, 52.6817},
orb.Point{0.1406, 52.2047},
},
distance: 200000,
expectedPoint: orb.Point{0.1406, 52.2047},
expectedBearing: Bearing(
orb.Point{-0.8411, 52.6817},
orb.Point{0.1406, 52.2047},
),
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
actualPoint, actualBearing := PointAtDistanceAlongLine(tc.line, tc.distance)

if d := DistanceHaversine(actualPoint, tc.expectedPoint); d > 1 {
t.Errorf("point %v != %v", actualPoint, tc.expectedPoint)
}

if d := math.Abs(actualBearing - tc.expectedBearing); d > 1 {
t.Errorf("bearing %v != %v", tc.expectedBearing, actualBearing)
}
})
}
}

Expand All @@ -125,76 +217,3 @@ func TestPointAtDistanceAlongLineWithEmptyLineString(t *testing.T) {
line := orb.LineString{}
PointAtDistanceAlongLine(line, 90000)
}

func TestPointAtDistanceAlongLineWithSinglePoint(t *testing.T) {
expectedPoint := orb.Point{-1.8444, 53.1506}
line := orb.LineString{
expectedPoint,
}
actualPoint, actualBearing := PointAtDistanceAlongLine(line, 90000)

if actualPoint != expectedPoint {
t.Errorf("expected %v but got %v", expectedPoint, actualPoint)
}
if actualBearing != 0.0 {
t.Errorf("expected %v but got %v", actualBearing, 0.0)
}
}

func TestPointAtDistanceAlongLineWithMinimalPoints(t *testing.T) {
expected := orb.Point{-0.841153, 52.68179432}
acceptableDistanceTolerance := 1.0 // unit is meters
line := orb.LineString{
orb.Point{-1.8444, 53.1506},
orb.Point{0.1406, 52.2047},
}
acceptableBearingTolerance := 0.01 // unit is degrees
expectedBearing := Bearing(line[0], line[1])
actual, actualBearing := PointAtDistanceAlongLine(line, 85194.89)

if d := DistanceHaversine(expected, actual); d > acceptableDistanceTolerance {
t.Errorf("expected %v to be within %vm of %v (%vm away)", actual, acceptableDistanceTolerance, expected, d)
}
if b := math.Abs(actualBearing - expectedBearing); b > acceptableBearingTolerance {
t.Errorf("expected bearing %v to be within %v degrees of %v", actualBearing, acceptableBearingTolerance, expectedBearing)
}
}

func TestPointAtDistanceAlongLineWithMultiplePoints(t *testing.T) {
expected := orb.Point{-0.78526, 52.65506}
acceptableTolerance := 1.0 // unit is meters
line := orb.LineString{
orb.Point{-1.8444, 53.1506},
orb.Point{-0.8411, 52.6817},
orb.Point{0.1406, 52.2047},
}
acceptableBearingTolerance := 0.01 // unit is degrees
expectedBearing := Bearing(line[1], line[2])
actualPoint, actualBearing := PointAtDistanceAlongLine(line, 90000)

if d := DistanceHaversine(expected, actualPoint); d > acceptableTolerance {
t.Errorf("expected %v to be within %vm of %v (%vm away)", expected, acceptableTolerance, actualPoint, d)
}
if b := math.Abs(actualBearing - expectedBearing); b > acceptableBearingTolerance {
t.Errorf("expected bearing %v to be within %v degrees of %v", actualBearing, acceptableBearingTolerance, expectedBearing)
}
}

func TestPointAtDistanceAlongLinePastEndOfLine(t *testing.T) {
expected := orb.Point{0.1406, 52.2047}
line := orb.LineString{
orb.Point{-1.8444, 53.1506},
orb.Point{-0.8411, 52.6817},
expected,
}
acceptableBearingTolerance := 0.01 // unit is degrees
expectedBearing := Bearing(line[1], line[2])
actualPoint, actualBearing := PointAtDistanceAlongLine(line, 200000)

if actualPoint != expected {
t.Errorf("expected %v but got %v", expected, actualPoint)
}
if b := math.Abs(actualBearing - expectedBearing); b > acceptableBearingTolerance {
t.Errorf("expected bearing %v to be within %v degrees of %v", actualBearing, acceptableBearingTolerance, expectedBearing)
}
}

0 comments on commit 151ae31

Please sign in to comment.