func filterRows( rows []string, timeOrigin int64, timeDistance int, geoOrigin util.GeoPoint, geoDistance int, ) []string { withinTimeRange := func(time int64) bool { if time < timeOrigin-int64(timeDistance) { return false } if time > timeOrigin+int64(timeDistance) { return false } return true } pointOrigin := geoOrigin.Point() withinGeoRange := func(geo util.GeoPoint) bool { distance := pointOrigin.GreatCircleDistance(geo.Point()) return distance <= float64(geoDistance)/1000 } filterRow := func(s string) (string, bool) { row := &util.LogRow{} util.StructFromString(s, &row) return s, withinTimeRange(row.Timestamp) && withinGeoRange(row.Geo) } return map_reduce.DoMap(rows, filterRow) }
// Note: This test involves random logic and therefore may be inconsistent. Reference the seed for repeatability. func TestRandomGeo(t *testing.T) { seed := time.Now().Unix() rand.Seed(seed) origin := util.GeoPoint{ Latitude: TEST_LATITUDE, Longitude: TEST_LONGITUDE, } for i := 0; i < TEST_RANDOM_GEO_RUNS; i++ { randGeoPoint := randomGeoPoint(origin, TEST_DISTANCE_M) distance := origin.Point().GreatCircleDistance(randGeoPoint.Point()) if !assert.True( t, distance <= TEST_DISTNACE_KM, fmt.Sprintf( "The random point %v is %f kms away from the test origin. Seed: %d.", randGeoPoint, distance, seed, ), ) { t.FailNow() } } assert.NotEqual( t, randomGeoPoint(origin, TEST_DISTANCE_M), randomGeoPoint(origin, TEST_DISTANCE_M), fmt.Sprintf("Two random points should not be the same. Seed: %d.", seed), ) }
func randomGeoPoint(origin util.GeoPoint, distance int) util.GeoPoint { randDistance := rand.Float64() * float64(distance) / 1000 randBearing := rand.Float64()*360 - 180 point := origin.Point() newPoint := point.PointAtDistanceAndBearing(randDistance, randBearing) return util.NewGeoPoint(newPoint) }