github.com/liucxer/courier@v1.7.1/h3/geo_coord_test.go (about) 1 package h3 2 3 import ( 4 "math" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 ) 9 10 func Test_radsToDegs(t *testing.T) { 11 originalRads := 0.1 12 degs := radsToDegs(originalRads) 13 rads := degsToRads(degs) 14 require.True(t, math.Abs(rads-originalRads) < EPSILON_RAD, "radsToDegs/degsToRads invertible") 15 } 16 17 func Test__geoDistRads(t *testing.T) { 18 var p1 GeoCoord 19 setGeoDegs(&p1, 10, 10) 20 var p2 GeoCoord 21 setGeoDegs(&p2, 0, 10) 22 23 // TODO: Epsilon is relatively large 24 require.True(t, _geoDistRads(&p1, &p1) < EPSILON_RAD*1000, "0 distance as expected") 25 require.True(t, math.Abs(_geoDistRads(&p1, &p2)-degsToRads(10)) < EPSILON_RAD*1000, "distance along longitude as expected") 26 } 27 28 func Test_constrainLatLng(t *testing.T) { 29 require.True(t, constrainLat(0) == 0, "Lat 0") 30 require.True(t, constrainLat(1) == 1, "Lat 1") 31 require.True(t, constrainLat(M_PI_2) == M_PI_2, "Lat pi/2") 32 require.True(t, constrainLat(M_PI) == 0, "Lat pi") 33 require.True(t, constrainLat(M_PI+1) == 1, "Lat pi+1") 34 require.True(t, constrainLat(2*M_PI+1) == 1, "Lat 2pi+1") 35 require.True(t, constrainLng(0) == 0, "lng 0") 36 require.True(t, constrainLng(1) == 1, "lng 1") 37 require.True(t, constrainLng(M_PI) == M_PI, "lng pi") 38 require.True(t, constrainLng(2*M_PI) == 0, "lng 2pi") 39 require.True(t, constrainLng(3*M_PI) == M_PI, "lng 2pi") 40 require.True(t, constrainLng(4*M_PI) == 0, "lng 4pi") 41 } 42 43 func Test__geoAzDistanceRads_noop(t *testing.T) { 44 start := GeoCoord{15, 10} 45 var out GeoCoord 46 expected := GeoCoord{15, 10} 47 _geoAzDistanceRads(&start, 0, 0, &out) 48 require.True(t, geoAlmostEqual(&expected, &out), 49 "0 distance produces same point") 50 } 51 52 func Test__geoAzDistanceRads_dueNorthSouth(t *testing.T) { 53 var start GeoCoord 54 var out GeoCoord 55 var expected GeoCoord 56 57 // Due north to north pole 58 setGeoDegs(&start, 45, 1) 59 setGeoDegs(&expected, 90, 0) 60 _geoAzDistanceRads(&start, 0, degsToRads(45), &out) 61 require.True(t, geoAlmostEqual(&expected, &out), 62 "due north to north pole produces north pole") 63 64 // Due north to south pole, which doesn't get wrapped correctly 65 setGeoDegs(&start, 45, 1) 66 setGeoDegs(&expected, 270, 1) 67 _geoAzDistanceRads(&start, 0, degsToRads(45+180), &out) 68 require.True(t, geoAlmostEqual(&expected, &out), 69 "due north to south pole produces south pole") 70 71 // Due south to south pole 72 setGeoDegs(&start, -45, 2) 73 setGeoDegs(&expected, -90, 0) 74 _geoAzDistanceRads(&start, degsToRads(180), degsToRads(45), &out) 75 require.True(t, geoAlmostEqual(&expected, &out), 76 "due south to south pole produces south pole") 77 78 // Due north to non-pole 79 setGeoDegs(&start, -45, 10) 80 setGeoDegs(&expected, -10, 10) 81 _geoAzDistanceRads(&start, 0, degsToRads(35), &out) 82 require.True(t, geoAlmostEqual(&expected, &out), 83 "due north produces expected result") 84 } 85 86 func Test__geoAzDistanceRads_poleToPole(t *testing.T) { 87 var start GeoCoord 88 var out GeoCoord 89 var expected GeoCoord 90 91 // Azimuth doesn't really matter in this case. Any azimuth from the 92 // north pole is south, any azimuth from the south pole is north. 93 94 setGeoDegs(&start, 90, 0) 95 setGeoDegs(&expected, -90, 0) 96 _geoAzDistanceRads(&start, degsToRads(12), degsToRads(180), &out) 97 require.True(t, geoAlmostEqual(&expected, &out), 98 "some direction to south pole produces south pole") 99 setGeoDegs(&start, -90, 0) 100 setGeoDegs(&expected, 90, 0) 101 _geoAzDistanceRads(&start, degsToRads(34), degsToRads(180), &out) 102 require.True(t, geoAlmostEqual(&expected, &out), "some direction to north pole produces north pole") 103 } 104 105 func Test__geoAzDistanceRads_invertible(t *testing.T) { 106 var start GeoCoord 107 setGeoDegs(&start, 15, 10) 108 109 var out GeoCoord 110 azimuth := degsToRads(20) 111 degrees180 := degsToRads(180) 112 distance := degsToRads(15) 113 114 _geoAzDistanceRads(&start, azimuth, distance, &out) 115 116 require.True(t, math.Abs(_geoDistRads(&start, &out)-distance) < EPSILON_RAD, "moved distance is as expected") 117 var start2 GeoCoord = out 118 _geoAzDistanceRads(&start2, azimuth+degrees180, distance, &out) 119 // TODO: Epsilon is relatively large 120 require.True(t, _geoDistRads(&start, &out) < 0.01, "moved back to origin") 121 } 122 123 func Test__geoDistRads_wrappedLongitude(t *testing.T) { 124 negativeLongitude := GeoCoord{Lat: -(M_PI + M_PI_2)} 125 zero := GeoCoord{} 126 127 require.True(t, math.Abs(M_PI_2-_geoDistRads(&negativeLongitude, &zero)) < EPSILON_RAD, "Distance with wrapped longitude") 128 require.True(t, math.Abs(M_PI_2-_geoDistRads(&zero, &negativeLongitude)) < EPSILON_RAD, "Distance with wrapped longitude and swapped arguments") 129 } 130 131 func Test_doubleConstants(t *testing.T) { 132 // Simple checks for ordering of values 133 testDecreasingFunction(t, hexAreaKm2, "hexAreaKm2 ordering") 134 testDecreasingFunction(t, hexAreaM2, "hexAreaM2 ordering") 135 testDecreasingFunction(t, edgeLengthKm, "edgeLengthKm ordering") 136 testDecreasingFunction(t, edgeLengthM, "edgeLengthM ordering") 137 } 138 139 func testDecreasingFunction(t *testing.T, fn func(i int) float64, message string) { 140 last := float64(0) 141 next := float64(0) 142 143 for i := MAX_H3_RES; i >= 0; i-- { 144 next = fn(i) 145 require.True(t, next > last, message) 146 last = next 147 } 148 } 149 150 func Test_intConstants(t *testing.T) { 151 // Simple checks for ordering of values 152 last := 0 153 next := 0 154 for i := 0; i <= MAX_H3_RES; i++ { 155 next = int(numHexagons(i)) 156 require.True(t, next > last, "numHexagons ordering") 157 last = next 158 } 159 }