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  }