src/apps/testapps/testCellToLocalIj.c (214 lines of code) (raw):

/* * Copyright 2018-2019 Uber Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** @file * @brief tests H3 index to local IJ and IJK+ grid functions. * * usage: `testCellToLocalIj` */ #include <h3api.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "algos.h" #include "baseCells.h" #include "constants.h" #include "h3Index.h" #include "h3api.h" #include "localij.h" #include "test.h" #include "utility.h" SUITE(h3ToLocalIj) { // Some indexes that represent base cells. Base cells // are hexagons except for `pent1`. H3Index bc1 = H3_INIT; setH3Index(&bc1, 0, 15, 0); H3Index bc2 = H3_INIT; setH3Index(&bc2, 0, 8, 0); H3Index bc3 = H3_INIT; setH3Index(&bc3, 0, 31, 0); H3Index pent1 = H3_INIT; setH3Index(&pent1, 0, 4, 0); TEST(ijBaseCells) { CoordIJ ij = {.i = 0, .j = 0}; H3Index origin = 0x8029fffffffffff; H3Index retrieved; t_assert( H3_EXPORT(localIjToCell)(origin, &ij, 0, &retrieved) == E_SUCCESS, "got origin back"); t_assert(retrieved == 0x8029fffffffffff, "origin matches self"); ij.i = 1; t_assert( H3_EXPORT(localIjToCell)(origin, &ij, 0, &retrieved) == E_SUCCESS, "got offset index"); t_assert(retrieved == 0x8051fffffffffff, "modified index matches expected"); ij.i = 2; t_assert( H3_EXPORT(localIjToCell)(origin, &ij, 0, &retrieved) == E_FAILED, "out of range base cell (1)"); ij.i = 0; ij.j = 2; t_assert( H3_EXPORT(localIjToCell)(origin, &ij, 0, &retrieved) == E_FAILED, "out of range base cell (2)"); ij.i = -2; ij.j = -2; t_assert( H3_EXPORT(localIjToCell)(origin, &ij, 0, &retrieved) == E_FAILED, "out of range base cell (3)"); } TEST(ijOutOfRange) { const int numCoords = 7; const CoordIJ coords[] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {-4, 0}, {0, 4}}; const H3Index expected[] = {0x81283ffffffffff, 0x81293ffffffffff, 0x8150bffffffffff, 0x8151bffffffffff, H3_NULL, H3_NULL, H3_NULL}; for (int i = 0; i < numCoords; i++) { H3Index result; const H3Error err = H3_EXPORT(localIjToCell)(expected[0], &coords[i], 0, &result); if (expected[i] == H3_NULL) { t_assert(err != 0, "coordinates out of range"); } else { t_assert(err == 0, "coordinates in range"); t_assert(result == expected[i], "result matches expectation"); } } } TEST(cellToLocalIjFailed) { CoordIJ ij; t_assert(H3_EXPORT(cellToLocalIj)(bc1, bc1, 0, &ij) == 0, "found IJ (1)"); t_assert(ij.i == 0 && ij.j == 0, "ij correct (1)"); t_assert(H3_EXPORT(cellToLocalIj)(bc1, pent1, 0, &ij) == 0, "found IJ (2)"); t_assert(ij.i == 1 && ij.j == 0, "ij correct (2)"); t_assert(H3_EXPORT(cellToLocalIj)(bc1, bc2, 0, &ij) == 0, "found IJ (3)"); t_assert(ij.i == 0 && ij.j == -1, "ij correct (3)"); t_assert(H3_EXPORT(cellToLocalIj)(bc1, bc3, 0, &ij) == 0, "found IJ (4)"); t_assert(ij.i == -1 && ij.j == 0, "ij correct (4)"); t_assert(H3_EXPORT(cellToLocalIj)(pent1, bc3, 0, &ij) == E_FAILED, "found IJ (5)"); } TEST(cellToLocalIjInvalid) { CoordIJ ij; H3Index invalidIndex = 0x7fffffffffffffff; H3_SET_RESOLUTION(invalidIndex, H3_GET_RESOLUTION(bc1)); t_assert(H3_EXPORT(cellToLocalIj)(bc1, invalidIndex, 0, &ij) == E_CELL_INVALID, "invalid index"); t_assert(H3_EXPORT(cellToLocalIj)(0x7fffffffffffffff, bc1, 0, &ij) == E_RES_MISMATCH, "invalid origin"); t_assert( H3_EXPORT(cellToLocalIj)(0x7fffffffffffffff, 0x7fffffffffffffff, 0, &ij) == E_CELL_INVALID, "invalid origin and index"); } TEST(localIjToCellInvalid) { CoordIJ ij = {0, 0}; H3Index index; t_assert(H3_EXPORT(localIjToCell)(0x7fffffffffffffff, &ij, 0, &index) == E_CELL_INVALID, "invalid origin for ijToH3"); } /** * Tests for INVALID_DIGIT being detected and failed on in various cases. */ TEST(indexOnPentInvalid) { H3Index onPentInvalid; setH3Index(&onPentInvalid, 1, 4, INVALID_DIGIT); H3Index offPent; setH3Index(&offPent, 1, 3, CENTER_DIGIT); CoordIJ ij; t_assert(H3_EXPORT(cellToLocalIj)(offPent, onPentInvalid, 0, &ij) == E_CELL_INVALID, "invalid index on pentagon"); H3Index onPentValid; setH3Index(&onPentValid, 1, 4, CENTER_DIGIT); t_assert(H3_EXPORT(cellToLocalIj)(onPentInvalid, onPentValid, 0, &ij) == E_CELL_INVALID, "invalid both on pentagon"); t_assert(H3_EXPORT(cellToLocalIj)(onPentValid, onPentInvalid, 0, &ij) == E_CELL_INVALID, "invalid both on pentagon"); ij.i = 0; ij.j = 0; H3Index out; t_assert(H3_EXPORT(localIjToCell)(onPentInvalid, &ij, 0, &out) == E_CELL_INVALID, "invalid both on pentagon"); ij.i = 3; ij.j = 3; t_assert(H3_EXPORT(localIjToCell)(onPentInvalid, &ij, 0, &out) == E_CELL_INVALID, "invalid origin on pentagon"); } TEST(invalidMode) { CoordIJ ij; H3Index cell = 0x85283473fffffff; t_assertSuccess(H3_EXPORT(cellToLocalIj)(cell, cell, 0, &ij)); for (uint32_t i = 1; i <= 32; i++) { CoordIJ ij2; t_assert(H3_EXPORT(cellToLocalIj)(cell, cell, i, &ij2) == E_OPTION_INVALID, "Invalid mode fail for cellToLocalIj"); H3Index cell2; t_assert(H3_EXPORT(localIjToCell)(cell, &ij2, i, &cell2) == E_OPTION_INVALID, "Invalid mode fail for cellToLocalIj"); } } TEST(invalid_negativeIj) { H3Index index = 0x200f202020202020; CoordIJ ij = {.i = -14671840, .j = INT32_MIN}; H3Index out; t_assert(H3_EXPORT(localIjToCell)(index, &ij, 0, &out) == E_FAILED, "Negative I and J components fail"); } TEST(localIjToCell_overflow_i) { H3Index origin; setH3Index(&origin, 2, 2, CENTER_DIGIT); CoordIJ ij = {.i = INT32_MIN, .j = INT32_MAX}; H3Index out; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "High magnitude I and J components fail"); } TEST(localIjToCell_overflow_j) { H3Index origin; setH3Index(&origin, 2, 2, CENTER_DIGIT); CoordIJ ij = {.i = INT32_MAX, .j = INT32_MIN}; H3Index out; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "High magnitude J and I components fail"); } TEST(localIjToCell_overflow_ij) { H3Index origin; setH3Index(&origin, 2, 2, CENTER_DIGIT); CoordIJ ij = {.i = INT32_MIN, .j = INT32_MIN}; H3Index out; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "High magnitude J and I components fail"); } TEST(localIjToCell_overflow_particularCases) { H3Index origin; setH3Index(&origin, 2, 2, CENTER_DIGIT); H3Index originRes3; setH3Index(&originRes3, 2, 2, CENTER_DIGIT); CoordIJ ij = {.i = 553648127, .j = -2145378272}; H3Index out; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "Particular high magnitude J and I components fail (1)"); ij.i = INT32_MAX - 10; ij.j = -11; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "Particular high magnitude J and I components fail (2)"); ij.i = 553648127; ij.j = -2145378272; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "Particular high magnitude J and I components fail (3)"); ij.i = INT32_MAX - 10; ij.j = -10; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "Particular high magnitude J and I components fail (4)"); ij.i = INT32_MAX - 10; ij.j = -9; t_assert(H3_EXPORT(localIjToCell)(origin, &ij, 0, &out) == E_FAILED, "Particular high magnitude J and I components fail (5)"); } }