Nothing
# tests/testthat/test-conversions.R
# Tests for coordinate system conversion functions
#
# Functions tested:
# - hexify_lonlat_to_quad_ij()
# - hexify_quad_ij_to_cell()
# - hexify_quad_ij_to_xy()
# - hexify_icosa_tri_to_quad_xy()
# - hexify_icosa_tri_to_quad_ij()
# - hexify_quad_xy_to_icosa_tri()
# - hexify_quad_ij_to_icosa_tri()
# =============================================================================
# LON/LAT TO QUAD IJ
# =============================================================================
test_that("lonlat_to_quad_ij returns valid structure", {
result <- hexify_lonlat_to_quad_ij(lon = 2.35, lat = 48.86,
resolution = 10, aperture = 3)
expect_true("quad" %in% names(result))
expect_true("i" %in% names(result))
expect_true("j" %in% names(result))
expect_true("icosa_triangle_face" %in% names(result))
expect_true("icosa_triangle_x" %in% names(result))
expect_true("icosa_triangle_y" %in% names(result))
})
test_that("lonlat_to_quad_ij quad is in valid range", {
result <- hexify_lonlat_to_quad_ij(lon = 0, lat = 0,
resolution = 10, aperture = 3)
expect_true(result$quad >= 0 && result$quad <= 11)
})
test_that("lonlat_to_quad_ij i,j are non-negative", {
result <- hexify_lonlat_to_quad_ij(lon = 16.37, lat = 48.21,
resolution = 10, aperture = 3)
expect_true(result$i >= 0)
expect_true(result$j >= 0)
})
test_that("lonlat_to_quad_ij works for all apertures", {
for (ap in c(3, 4, 7)) {
res <- if (ap == 7) 5 else 10
result <- hexify_lonlat_to_quad_ij(lon = 0, lat = 45,
resolution = res, aperture = ap)
expect_true(result$quad >= 0 && result$quad <= 11,
info = sprintf("aperture %d", ap))
}
})
# =============================================================================
# QUAD IJ TO CELL
# =============================================================================
test_that("quad_ij_to_cell returns positive cell IDs", {
cell_id <- hexify_quad_ij_to_cell(quad = 1, i = 100, j = 50,
resolution = 10, aperture = 3)
expect_true(cell_id > 0)
expect_true(is.numeric(cell_id))
})
test_that("quad_ij_to_cell is consistent with lonlat_to_cell", {
lon <- 16.37
lat <- 48.21
resolution <- 10
for (ap in c(3, 4)) {
# Get cell via lon/lat
cell_direct <- hexify_lonlat_to_cell(lon, lat, resolution, aperture = ap)
# Get cell via quad IJ
quad_ij <- hexify_lonlat_to_quad_ij(lon, lat, resolution, aperture = ap)
cell_indirect <- hexify_quad_ij_to_cell(quad_ij$quad, quad_ij$i, quad_ij$j,
resolution, aperture = ap)
expect_equal(cell_direct, cell_indirect,
info = sprintf("aperture %d", ap))
}
})
# =============================================================================
# QUAD IJ TO XY
# =============================================================================
test_that("quad_ij_to_xy returns valid structure", {
result <- hexify_quad_ij_to_xy(quad = 1, i = 100, j = 50,
resolution = 10, aperture = 3)
expect_true("quad_x" %in% names(result))
expect_true("quad_y" %in% names(result))
expect_true(is.numeric(result$quad_x))
expect_true(is.numeric(result$quad_y))
})
# =============================================================================
# ICOSA TRI TO QUAD XY
# =============================================================================
test_that("icosa_tri_to_quad_xy returns valid structure", {
hexify_build_icosa()
fwd <- hexify_forward(lon = 2.35, lat = 48.86)
result <- hexify_icosa_tri_to_quad_xy(
icosa_triangle_face = fwd["face"],
icosa_triangle_x = fwd["icosa_triangle_x"],
icosa_triangle_y = fwd["icosa_triangle_y"]
)
expect_true("quad" %in% names(result))
expect_true("quad_x" %in% names(result))
expect_true("quad_y" %in% names(result))
expect_true(result$quad >= 0 && result$quad <= 11)
})
# =============================================================================
# ICOSA TRI TO QUAD IJ
# =============================================================================
test_that("icosa_tri_to_quad_ij returns valid structure", {
hexify_build_icosa()
fwd <- hexify_forward(lon = 2.35, lat = 48.86)
result <- hexify_icosa_tri_to_quad_ij(
icosa_triangle_face = fwd["face"],
icosa_triangle_x = fwd["icosa_triangle_x"],
icosa_triangle_y = fwd["icosa_triangle_y"],
resolution = 10,
aperture = 3
)
expect_true("quad" %in% names(result))
expect_true("i" %in% names(result))
expect_true("j" %in% names(result))
expect_true(result$quad >= 0 && result$quad <= 11)
})
# =============================================================================
# QUAD XY TO ICOSA TRI (INVERSE)
# =============================================================================
test_that("quad_xy_to_icosa_tri returns valid structure", {
result <- hexify_quad_xy_to_icosa_tri(quad = 1, quad_x = 0.5, quad_y = 0.3)
expect_true("icosa_triangle_face" %in% names(result))
expect_true("icosa_triangle_x" %in% names(result))
expect_true("icosa_triangle_y" %in% names(result))
expect_true(result$icosa_triangle_face >= 0 && result$icosa_triangle_face <= 19)
})
test_that("icosa_tri <-> quad_xy round-trip is consistent", {
hexify_build_icosa()
# Forward: lon/lat -> icosa tri -> quad xy
fwd <- hexify_forward(lon = 10, lat = 45)
quad_xy <- hexify_icosa_tri_to_quad_xy(
icosa_triangle_face = fwd["face"],
icosa_triangle_x = fwd["icosa_triangle_x"],
icosa_triangle_y = fwd["icosa_triangle_y"]
)
# Inverse: quad xy -> icosa tri
back <- hexify_quad_xy_to_icosa_tri(
quad = quad_xy$quad,
quad_x = quad_xy$quad_x,
quad_y = quad_xy$quad_y
)
# Should recover original icosa tri coordinates
expect_equal(as.numeric(fwd["face"]), back$icosa_triangle_face)
expect_equal(as.numeric(fwd["icosa_triangle_x"]), back$icosa_triangle_x,
tolerance = 1e-10)
expect_equal(as.numeric(fwd["icosa_triangle_y"]), back$icosa_triangle_y,
tolerance = 1e-10)
})
# =============================================================================
# QUAD IJ TO ICOSA TRI
# =============================================================================
test_that("quad_ij_to_icosa_tri returns valid structure", {
result <- hexify_quad_ij_to_icosa_tri(quad = 1, i = 100, j = 50,
resolution = 10, aperture = 3)
expect_true("icosa_triangle_face" %in% names(result))
expect_true("icosa_triangle_x" %in% names(result))
expect_true("icosa_triangle_y" %in% names(result))
expect_true(result$icosa_triangle_face >= 0 && result$icosa_triangle_face <= 19)
})
# =============================================================================
# PIPELINE CONSISTENCY
# =============================================================================
test_that("coordinate pipeline is consistent end-to-end", {
hexify_build_icosa()
lon <- 16.37
lat <- 48.21
resolution <- 10
aperture <- 3
# Full pipeline: lon/lat -> quad IJ -> cell ID -> quad IJ (back)
quad_ij <- hexify_lonlat_to_quad_ij(lon, lat, resolution, aperture)
cell_id <- hexify_quad_ij_to_cell(quad_ij$quad, quad_ij$i, quad_ij$j,
resolution, aperture)
quad_ij_back <- hexify_cell_to_quad_ij(cell_id, resolution, aperture)
expect_equal(quad_ij$quad, quad_ij_back$quad)
expect_equal(quad_ij$i, quad_ij_back$i)
expect_equal(quad_ij$j, quad_ij_back$j)
})
test_that("all apertures have consistent coordinate pipeline", {
skip_on_cran() # Detailed loop test
hexify_build_icosa()
lon <- 0
lat <- 45
for (ap in c(3, 4, 7)) {
res <- if (ap == 7) 5 else 10
# lon/lat -> cell -> lonlat
cell_id <- hexify_lonlat_to_cell(lon, lat, res, aperture = ap)
coords <- hexify_cell_to_lonlat(cell_id, res, aperture = ap)
# Should be reasonably close
lon_error <- abs(coords$lon_deg - lon)
if (lon_error > 180) lon_error <- 360 - lon_error
lat_error <- abs(coords$lat_deg - lat)
max_error <- if (ap == 7) 5.0 else 2.0
expect_true(lon_error < max_error,
info = sprintf("aperture %d lon error", ap))
expect_true(lat_error < max_error,
info = sprintf("aperture %d lat error", ap))
}
})
# =============================================================================
# INPUT VALIDATION
# =============================================================================
test_that("hexify_lonlat_to_quad_ij validates aperture", {
expect_error(
hexify_lonlat_to_quad_ij(lon = 0, lat = 0, resolution = 5, aperture = 5),
"3, 4, or 7"
)
})
test_that("hexify_lonlat_to_quad_ij validates resolution", {
expect_error(
hexify_lonlat_to_quad_ij(lon = 0, lat = 0, resolution = -1, aperture = 3),
"between 0 and 30"
)
expect_error(
hexify_lonlat_to_quad_ij(lon = 0, lat = 0, resolution = 31, aperture = 3),
"between 0 and 30"
)
})
test_that("hexify_quad_ij_to_cell validates aperture", {
expect_error(
hexify_quad_ij_to_cell(quad = 0, i = 1, j = 1, resolution = 5, aperture = 5),
"3, 4, or 7"
)
})
test_that("hexify_quad_ij_to_cell validates resolution", {
expect_error(
hexify_quad_ij_to_cell(quad = 0, i = 1, j = 1, resolution = -1, aperture = 3),
"between 0 and 30"
)
})
test_that("hexify_quad_ij_to_xy validates aperture", {
expect_error(
hexify_quad_ij_to_xy(quad = 1, i = 10, j = 5, resolution = 5, aperture = 5),
"3, 4, or 7"
)
})
test_that("hexify_icosa_tri_to_quad_ij validates aperture", {
expect_error(
hexify_icosa_tri_to_quad_ij(
icosa_triangle_face = 0,
icosa_triangle_x = 0.5,
icosa_triangle_y = 0.5,
resolution = 5,
aperture = 5
),
"3, 4, or 7"
)
})
# =============================================================================
# CELL TO QUAD IJ
# =============================================================================
test_that("hexify_cell_to_quad_ij returns correct structure", {
hexify_build_icosa()
result <- hexify_cell_to_quad_ij(cell_id = 1000, resolution = 5, aperture = 3)
expect_s3_class(result, "data.frame")
expect_true("quad" %in% names(result))
expect_true("i" %in% names(result))
expect_true("j" %in% names(result))
})
test_that("hexify_cell_to_quad_ij validates aperture", {
expect_error(
hexify_cell_to_quad_ij(cell_id = 100, resolution = 5, aperture = 5),
"3, 4, or 7"
)
})
test_that("hexify_cell_to_quad_ij validates resolution", {
expect_error(
hexify_cell_to_quad_ij(cell_id = 100, resolution = -1, aperture = 3),
"between 0 and 30"
)
})
# =============================================================================
# CELL TO ICOSA TRIANGLE
# =============================================================================
test_that("hexify_cell_to_icosa_tri returns correct structure", {
hexify_build_icosa()
result <- hexify_cell_to_icosa_tri(cell_id = 1000, resolution = 5, aperture = 3)
expect_s3_class(result, "data.frame")
expect_true("icosa_triangle_face" %in% names(result))
expect_true("icosa_triangle_x" %in% names(result))
expect_true("icosa_triangle_y" %in% names(result))
})
test_that("hexify_cell_to_icosa_tri validates aperture", {
expect_error(
hexify_cell_to_icosa_tri(cell_id = 100, resolution = 5, aperture = 5),
"3, 4, or 7"
)
})
test_that("hexify_cell_to_icosa_tri validates resolution", {
expect_error(
hexify_cell_to_icosa_tri(cell_id = 100, resolution = -1, aperture = 3),
"between 0 and 30"
)
})
test_that("hexify_quad_ij_to_icosa_tri validates aperture", {
expect_error(
hexify_quad_ij_to_icosa_tri(
quad = 1, i = 10, j = 5, resolution = 5, aperture = 5
),
"3, 4, or 7"
)
})
test_that("hexify_quad_ij_to_icosa_tri validates resolution", {
expect_error(
hexify_quad_ij_to_icosa_tri(
quad = 1, i = 10, j = 5, resolution = -1, aperture = 3
),
"between 0 and 30"
)
})
# =============================================================================
# CELL TO QUAD XY (CONTINUOUS COORDINATES)
# =============================================================================
test_that("hexify_cell_to_quad_xy returns correct structure", {
hexify_build_icosa()
result <- hexify_cell_to_quad_xy(cell_id = 1000, resolution = 5, aperture = 3)
expect_s3_class(result, "data.frame")
expect_true("quad" %in% names(result))
expect_true("quad_x" %in% names(result))
expect_true("quad_y" %in% names(result))
})
test_that("hexify_cell_to_quad_xy validates aperture", {
expect_error(
hexify_cell_to_quad_xy(cell_id = 100, resolution = 5, aperture = 5),
"3, 4, or 7"
)
})
test_that("hexify_cell_to_quad_xy validates resolution", {
expect_error(
hexify_cell_to_quad_xy(cell_id = 100, resolution = -1, aperture = 3),
"between 0 and 30"
)
})
test_that("hexify_quad_xy_to_cell returns valid cell ID", {
hexify_build_icosa()
cell_id <- hexify_quad_xy_to_cell(
quad = 1, quad_x = 0.5, quad_y = 0.3,
resolution = 5, aperture = 3
)
expect_true(is.numeric(cell_id))
expect_true(cell_id > 0)
})
test_that("hexify_quad_xy_to_cell validates aperture", {
expect_error(
hexify_quad_xy_to_cell(
quad = 1, quad_x = 0.5, quad_y = 0.3, resolution = 5, aperture = 5
),
"3, 4, or 7"
)
})
test_that("hexify_quad_xy_to_cell validates resolution", {
expect_error(
hexify_quad_xy_to_cell(
quad = 1, quad_x = 0.5, quad_y = 0.3, resolution = -1, aperture = 3
),
"between 0 and 30"
)
})
test_that("quad_xy round-trip is consistent", {
hexify_build_icosa()
cell_id <- 1000
# cell -> quad_xy -> cell
result1 <- hexify_cell_to_quad_xy(cell_id = cell_id, resolution = 5, aperture = 3)
cell_id2 <- hexify_quad_xy_to_cell(
quad = result1$quad, quad_x = result1$quad_x, quad_y = result1$quad_y,
resolution = 5, aperture = 3
)
expect_equal(cell_id, cell_id2)
})
# =============================================================================
# PLANE COORDINATE CONVERSIONS
# =============================================================================
test_that("hexify_icosa_tri_to_plane returns correct structure", {
hexify_build_icosa()
fwd <- hexify_forward(lon = 10, lat = 50)
result <- hexify_icosa_tri_to_plane(
icosa_triangle_face = fwd["face"],
icosa_triangle_x = fwd["icosa_triangle_x"],
icosa_triangle_y = fwd["icosa_triangle_y"]
)
expect_s3_class(result, "data.frame")
expect_true("plane_x" %in% names(result))
expect_true("plane_y" %in% names(result))
})
test_that("hexify_cell_to_plane returns correct structure", {
hexify_build_icosa()
result <- hexify_cell_to_plane(cell_id = 1000, resolution = 5, aperture = 3)
expect_s3_class(result, "data.frame")
expect_true("plane_x" %in% names(result))
expect_true("plane_y" %in% names(result))
})
test_that("hexify_cell_to_plane validates aperture", {
expect_error(
hexify_cell_to_plane(cell_id = 100, resolution = 5, aperture = 5),
"3, 4, or 7"
)
})
test_that("hexify_cell_to_plane validates resolution", {
expect_error(
hexify_cell_to_plane(cell_id = 100, resolution = -1, aperture = 3),
"between 0 and 30"
)
})
test_that("hexify_lonlat_to_plane returns correct structure", {
hexify_build_icosa()
result <- hexify_lonlat_to_plane(lon = 10, lat = 50)
expect_s3_class(result, "data.frame")
expect_true("plane_x" %in% names(result))
expect_true("plane_y" %in% names(result))
})
test_that("hexify_lonlat_to_plane works for multiple points", {
hexify_build_icosa()
lons <- c(0, 45, -120, 180, -180)
lats <- c(0, 30, -45, 60, -60)
result <- hexify_lonlat_to_plane(lon = lons, lat = lats)
expect_equal(nrow(result), 5)
expect_true(all(is.finite(result$plane_x)))
expect_true(all(is.finite(result$plane_y)))
})
test_that("hexify_cell_to_plane handles multiple cells", {
hexify_build_icosa()
result <- hexify_cell_to_plane(
cell_id = c(100, 200, 300), resolution = 5, aperture = 3
)
expect_equal(nrow(result), 3)
expect_true(all(is.finite(result$plane_x)))
expect_true(all(is.finite(result$plane_y)))
})
# =============================================================================
# CROSS-APERTURE PLANE TESTS
# =============================================================================
test_that("plane conversions work for all apertures", {
skip_on_cran() # Loop test across apertures
hexify_build_icosa()
for (ap in c(3, 4, 7)) {
# cell -> plane
plane <- hexify_cell_to_plane(cell_id = 100, resolution = 5, aperture = ap)
expect_true(is.finite(plane$plane_x))
expect_true(is.finite(plane$plane_y))
}
})
# =============================================================================
# HIERARCHICAL INDEX FUNCTIONS
# =============================================================================
test_that("hexify_lonlat_to_h_index returns correct structure", {
grid <- hexify_grid(area = 1000, aperture = 3)
result <- hexify_lonlat_to_h_index(grid, lon = 0, lat = 45)
expect_s3_class(result, "data.frame")
expect_true("h_index" %in% names(result))
expect_true("face" %in% names(result))
expect_type(result$h_index, "character")
expect_type(result$face, "integer")
})
test_that("hexify_lonlat_to_h_index handles multiple points", {
grid <- hexify_grid(area = 1000, aperture = 3)
lons <- c(0, 10, -5)
lats <- c(45, 30, -20)
result <- hexify_lonlat_to_h_index(grid, lon = lons, lat = lats)
expect_equal(nrow(result), 3)
expect_true(all(nchar(result$h_index) > 0))
})
test_that("hexify_lonlat_to_h_index handles NA values", {
grid <- hexify_grid(area = 1000, aperture = 3)
result <- hexify_lonlat_to_h_index(grid, lon = c(0, NA), lat = c(45, NA))
expect_equal(nrow(result), 2)
expect_true(is.na(result$h_index[2]))
expect_true(is.na(result$face[2]))
})
test_that("hexify_lonlat_to_h_index validates grid object", {
expect_error(
hexify_lonlat_to_h_index(list(x = 1), lon = 0, lat = 0),
"hexify_grid object"
)
})
test_that("hexify_lonlat_to_h_index validates input lengths", {
grid <- hexify_grid(area = 1000, aperture = 3)
expect_error(
hexify_lonlat_to_h_index(grid, lon = c(0, 1), lat = 0),
"same length"
)
})
test_that("hexify_lonlat_to_h_index validates numeric input", {
grid <- hexify_grid(area = 1000, aperture = 3)
expect_error(
hexify_lonlat_to_h_index(grid, lon = "a", lat = "b"),
"must be numeric"
)
})
test_that("hexify_lonlat_to_h_index warns on out-of-range coordinates", {
grid <- hexify_grid(area = 1000, aperture = 3)
expect_warning(
hexify_lonlat_to_h_index(grid, lon = 200, lat = 45),
"outside valid range"
)
expect_warning(
hexify_lonlat_to_h_index(grid, lon = 0, lat = 100),
"outside valid range"
)
})
test_that("hexify_h_index_to_lonlat returns correct structure", {
grid <- hexify_grid(area = 1000, aperture = 3)
# First get an index
h_result <- hexify_lonlat_to_h_index(grid, lon = 5, lat = 45)
# Then convert back
result <- hexify_h_index_to_lonlat(grid, h_result$h_index)
expect_s3_class(result, "data.frame")
expect_true("lon" %in% names(result))
expect_true("lat" %in% names(result))
expect_type(result$lon, "double")
expect_type(result$lat, "double")
})
test_that("hexify_h_index_to_lonlat handles NA values", {
grid <- hexify_grid(area = 1000, aperture = 3)
# Get a valid h_index first
valid_index <- hexify_lonlat_to_h_index(grid, lon = 5, lat = 45)$h_index
result <- hexify_h_index_to_lonlat(grid, c(valid_index, NA_character_))
expect_equal(nrow(result), 2)
expect_true(!is.na(result$lon[1]))
expect_true(is.na(result$lon[2]))
expect_true(is.na(result$lat[2]))
})
test_that("hexify_h_index_to_lonlat validates grid object", {
expect_error(
hexify_h_index_to_lonlat(list(x = 1), "0100000"),
"hexify_grid object"
)
})
test_that("hexify_h_index_to_lonlat validates character input", {
grid <- hexify_grid(area = 1000, aperture = 3)
expect_error(
hexify_h_index_to_lonlat(grid, 12345),
"must be a character"
)
})
test_that("h_index round-trip is consistent", {
grid <- hexify_grid(area = 1000, aperture = 3)
lon <- 10
lat <- 45
# Forward
h_result <- hexify_lonlat_to_h_index(grid, lon = lon, lat = lat)
# Inverse
coords <- hexify_h_index_to_lonlat(grid, h_result$h_index)
# Should be close (within cell distance)
expect_true(abs(coords$lon - lon) < 5)
expect_true(abs(coords$lat - lat) < 5)
})
# =============================================================================
# GRID-BASED WRAPPERS
# =============================================================================
test_that("hexify_grid_to_cell returns cell IDs", {
grid <- hexify_grid(area = 1000, aperture = 3)
result <- hexify_grid_to_cell(grid, lon = c(0, 10), lat = c(45, 50))
expect_type(result, "double")
expect_length(result, 2)
expect_true(all(result > 0))
})
test_that("hexify_grid_to_cell validates grid object", {
expect_error(
hexify_grid_to_cell(list(x = 1), lon = 0, lat = 0),
"hexify_grid object"
)
})
test_that("hexify_grid_cell_to_lonlat returns coordinates", {
grid <- hexify_grid(area = 1000, aperture = 3)
# Get some cell IDs first
cell_ids <- hexify_grid_to_cell(grid, lon = c(0, 10), lat = c(45, 50))
# Convert back
result <- hexify_grid_cell_to_lonlat(grid, cell_ids)
expect_s3_class(result, "data.frame")
expect_true("lon_deg" %in% names(result))
expect_true("lat_deg" %in% names(result))
expect_equal(nrow(result), 2)
})
test_that("hexify_grid_cell_to_lonlat validates grid object", {
expect_error(
hexify_grid_cell_to_lonlat(list(x = 1), cell_id = 1000),
"hexify_grid object"
)
})
test_that("grid wrapper round-trip is consistent", {
grid <- hexify_grid(area = 1000, aperture = 3)
lon <- 5
lat <- 45
# Forward
cell_id <- hexify_grid_to_cell(grid, lon = lon, lat = lat)
# Inverse
coords <- hexify_grid_cell_to_lonlat(grid, cell_id)
# Should be close
expect_true(abs(coords$lon_deg - lon) < 5)
expect_true(abs(coords$lat_deg - lat) < 5)
})
# =============================================================================
# ROUNDTRIP TEST FUNCTION
# =============================================================================
test_that("hexify_roundtrip_test returns correct structure", {
grid <- hexify_grid(area = 1000, aperture = 3)
result <- hexify_roundtrip_test(grid, lon = 5, lat = 45)
expect_type(result, "list")
expect_true("original" %in% names(result))
expect_true("h_index" %in% names(result))
expect_true("reconstructed" %in% names(result))
expect_true("error" %in% names(result))
expect_true("units" %in% names(result))
})
test_that("hexify_roundtrip_test reports error in km", {
grid <- hexify_grid(area = 1000, aperture = 3)
result <- hexify_roundtrip_test(grid, lon = 5, lat = 45, units = "km")
expect_equal(result$units, "km")
expect_true(is.numeric(result$error))
expect_true(result$error >= 0)
})
test_that("hexify_roundtrip_test reports error in degrees", {
grid <- hexify_grid(area = 1000, aperture = 3)
result <- hexify_roundtrip_test(grid, lon = 5, lat = 45, units = "degrees")
expect_equal(result$units, "degrees")
expect_true(is.numeric(result$error))
expect_true(result$error >= 0)
})
test_that("hexify_roundtrip_test error is reasonable", {
grid <- hexify_grid(area = 1000, aperture = 3)
result <- hexify_roundtrip_test(grid, lon = 5, lat = 45, units = "km")
# Error should be less than the cell diagonal (for ~1000 km2 area, diagonal ~ 35-40 km)
expect_true(result$error < 50)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.