feat: add optional GeoTIFF importer #10
Generated
+315
-1
@@ -37,6 +37,12 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "android-activity"
|
||||
version = "0.6.1"
|
||||
@@ -461,6 +467,25 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
@@ -657,6 +682,12 @@ dependencies = [
|
||||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.32.3"
|
||||
@@ -712,6 +743,12 @@ version = "3.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
|
||||
|
||||
[[package]]
|
||||
name = "fax"
|
||||
version = "0.2.7"
|
||||
@@ -749,6 +786,12 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.5.0"
|
||||
@@ -809,6 +852,41 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "geotiff-core"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63dcef5fa901867a96414d2e7f41bc29d8ab62f0c386982759d0592d23907622"
|
||||
|
||||
[[package]]
|
||||
name = "geotiff-reader"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59c23512e155c5be744bed8b22b52ac14ec445f4b8301a85c3a8f9a9a8927392"
|
||||
dependencies = [
|
||||
"geotiff-core",
|
||||
"lru",
|
||||
"memmap2",
|
||||
"ndarray",
|
||||
"parking_lot",
|
||||
"thiserror 2.0.18",
|
||||
"tiff-reader",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "geotiff-writer"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff56075759ffbb8531bb7a752f587d8f33ed0ad7dc80e4825558ddaa93a6b3c"
|
||||
dependencies = [
|
||||
"geotiff-core",
|
||||
"ndarray",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tiff-core",
|
||||
"tiff-writer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "1.1.0"
|
||||
@@ -938,7 +1016,18 @@ version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
"foldhash 0.1.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1165,6 +1254,21 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
|
||||
dependencies = [
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-encoder"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b454d911ac55068f53495488d8ccd0646eaa540c033a28ee15b07838afafb01f"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.98"
|
||||
@@ -1183,6 +1287,38 @@ version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||
|
||||
[[package]]
|
||||
name = "lerc-band-materialize"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07ad02b62a38008d9615a52159fd3b7e56aca97ee013fdec55cfe80040cc5aa5"
|
||||
|
||||
[[package]]
|
||||
name = "lerc-core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f428c60749fada87c7a95d08bc3942d05e4a9e3e0543a460a3331bb751dd2ddc"
|
||||
|
||||
[[package]]
|
||||
name = "lerc-reader"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68327488da0851ab38d662f6aa0baf29ee16192a5e286429aa02b3ffd71a5565"
|
||||
dependencies = [
|
||||
"lerc-band-materialize",
|
||||
"lerc-core",
|
||||
"ndarray",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lerc-writer"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d281f7aaa603b0562ceb1901c9b85bec7f19b1f2b9fc651cbc122906f4422411"
|
||||
dependencies = [
|
||||
"lerc-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.186"
|
||||
@@ -1256,6 +1392,25 @@ version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.16.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
|
||||
dependencies = [
|
||||
"hashbrown 0.16.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matrixmultiply"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
@@ -1324,6 +1479,21 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndarray"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d"
|
||||
dependencies = [
|
||||
"matrixmultiply",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"portable-atomic",
|
||||
"portable-atomic-util",
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.9.0"
|
||||
@@ -1360,6 +1530,24 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@@ -1681,7 +1869,10 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"eframe",
|
||||
"geotiff-reader",
|
||||
"geotiff-writer",
|
||||
"image",
|
||||
"ndarray",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
@@ -1811,6 +2002,15 @@ version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic-util"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
|
||||
dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.5"
|
||||
@@ -1886,6 +2086,32 @@ version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[package]]
|
||||
name = "rawpointer"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
@@ -2221,6 +2447,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix 1.1.4",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
@@ -2284,6 +2523,53 @@ dependencies = [
|
||||
"zune-jpeg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff-core"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baaa9ce13dd11a58b8fd1f834c97eb6f752e42f497cb3ec24fa293932a475f4b"
|
||||
dependencies = [
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff-reader"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98c4f45d57ee731f4a27baf7a4db00e79a6ccecc64f5dd62dc23327b82af9a24"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"jpeg-decoder",
|
||||
"lerc-core",
|
||||
"lerc-reader",
|
||||
"lru",
|
||||
"memmap2",
|
||||
"ndarray",
|
||||
"parking_lot",
|
||||
"rayon",
|
||||
"smallvec",
|
||||
"thiserror 2.0.18",
|
||||
"tiff-core",
|
||||
"weezl",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff-writer"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22edef41291232fd124f76f05de090143dde08874d919a7bc11882728aa05842"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"jpeg-encoder",
|
||||
"lerc-core",
|
||||
"lerc-writer",
|
||||
"thiserror 2.0.18",
|
||||
"tiff-core",
|
||||
"weezl",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.3"
|
||||
@@ -3236,6 +3522,34 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
|
||||
dependencies = [
|
||||
"zstd-safe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-safe"
|
||||
version = "7.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
|
||||
dependencies = [
|
||||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-sys"
|
||||
version = "2.0.16+zstd.1.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
version = "0.4.12"
|
||||
|
||||
@@ -8,15 +8,21 @@ default = []
|
||||
app = ["dep:eframe"]
|
||||
hgt = []
|
||||
ascii-grid-import = []
|
||||
import-geotiff = ["dep:geotiff-reader"]
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.6.1", features = ["derive"] }
|
||||
eframe = { version = "0.32.3", optional = true, default-features = false, features = ["default_fonts", "wayland", "wgpu", "x11"] }
|
||||
#wgpu = { version = "25.0.2", features = ["metal"] }
|
||||
image = { version = "0.25.9", default-features = false, features = ["png"] }
|
||||
geotiff-reader = { version = "0.4.0", optional = true, default-features = false, features = ["local"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
toml = "0.8"
|
||||
|
||||
[dev-dependencies]
|
||||
geotiff-writer = { version = "0.4.0", default-features = false }
|
||||
ndarray = "0.17"
|
||||
|
||||
[[bin]]
|
||||
name = "openvistapro_app"
|
||||
path = "src/bin/openvistapro_app.rs"
|
||||
|
||||
+66
-5
@@ -151,19 +151,67 @@ pub fn supported_presets() -> &'static [&'static str] {
|
||||
}
|
||||
|
||||
pub fn supported_importers() -> &'static [&'static str] {
|
||||
#[cfg(all(feature = "hgt", feature = "ascii-grid-import"))]
|
||||
#[cfg(all(
|
||||
feature = "hgt",
|
||||
feature = "ascii-grid-import",
|
||||
feature = "import-geotiff"
|
||||
))]
|
||||
{
|
||||
&["heightmap", "hgt", "esri-ascii-grid", "geotiff"]
|
||||
}
|
||||
#[cfg(all(
|
||||
feature = "hgt",
|
||||
feature = "ascii-grid-import",
|
||||
not(feature = "import-geotiff")
|
||||
))]
|
||||
{
|
||||
&["heightmap", "hgt", "esri-ascii-grid"]
|
||||
}
|
||||
#[cfg(all(feature = "hgt", not(feature = "ascii-grid-import")))]
|
||||
#[cfg(all(
|
||||
feature = "hgt",
|
||||
not(feature = "ascii-grid-import"),
|
||||
feature = "import-geotiff"
|
||||
))]
|
||||
{
|
||||
&["heightmap", "hgt", "geotiff"]
|
||||
}
|
||||
#[cfg(all(
|
||||
feature = "hgt",
|
||||
not(feature = "ascii-grid-import"),
|
||||
not(feature = "import-geotiff")
|
||||
))]
|
||||
{
|
||||
&["heightmap", "hgt"]
|
||||
}
|
||||
#[cfg(all(not(feature = "hgt"), feature = "ascii-grid-import"))]
|
||||
#[cfg(all(
|
||||
not(feature = "hgt"),
|
||||
feature = "ascii-grid-import",
|
||||
feature = "import-geotiff"
|
||||
))]
|
||||
{
|
||||
&["heightmap", "esri-ascii-grid", "geotiff"]
|
||||
}
|
||||
#[cfg(all(
|
||||
not(feature = "hgt"),
|
||||
feature = "ascii-grid-import",
|
||||
not(feature = "import-geotiff")
|
||||
))]
|
||||
{
|
||||
&["heightmap", "esri-ascii-grid"]
|
||||
}
|
||||
#[cfg(all(not(feature = "hgt"), not(feature = "ascii-grid-import")))]
|
||||
#[cfg(all(
|
||||
not(feature = "hgt"),
|
||||
not(feature = "ascii-grid-import"),
|
||||
feature = "import-geotiff"
|
||||
))]
|
||||
{
|
||||
&["heightmap", "geotiff"]
|
||||
}
|
||||
#[cfg(all(
|
||||
not(feature = "hgt"),
|
||||
not(feature = "ascii-grid-import"),
|
||||
not(feature = "import-geotiff")
|
||||
))]
|
||||
{
|
||||
&["heightmap"]
|
||||
}
|
||||
@@ -322,7 +370,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "hgt"))]
|
||||
#[cfg(all(not(feature = "hgt"), not(feature = "import-geotiff")))]
|
||||
fn hgt_importer_is_hidden_when_feature_is_disabled() {
|
||||
assert!(!supported_importers().contains(&"hgt"));
|
||||
}
|
||||
@@ -340,6 +388,19 @@ mod tests {
|
||||
assert!(text.contains("hgt"), "got: {text:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "import-geotiff")]
|
||||
fn supported_importers_lists_geotiff_when_feature_is_enabled() {
|
||||
assert!(supported_importers().contains(&"geotiff"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "import-geotiff")]
|
||||
fn info_text_lists_geotiff_importer_when_feature_is_enabled() {
|
||||
let text = info_text();
|
||||
assert!(text.contains("geotiff"), "got: {text:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn info_text_contains_program_name_and_version() {
|
||||
let text = info_text();
|
||||
|
||||
@@ -64,9 +64,20 @@
|
||||
//! row-major [`f32`] samples and the source unit is recorded as metres. The
|
||||
//! parser is gated behind the feature so the default build keeps only the
|
||||
//! project-owned `ovp-text` importer.
|
||||
//!
|
||||
//! # The `geotiff` format
|
||||
//!
|
||||
//! With the optional `import-geotiff` Cargo feature enabled, [`geotiff::parse_geotiff_bytes`]
|
||||
//! reads tiny synthetic GeoTIFF elevation tiles using the pure-Rust
|
||||
//! `geotiff-reader` crate. The importer starts with a deliberately small
|
||||
//! supported subset so default builds stay lean.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "import-geotiff")]
|
||||
#[path = "import/geotiff.rs"]
|
||||
pub mod geotiff;
|
||||
|
||||
use crate::terrain::{HeightGrid, TerrainError};
|
||||
|
||||
/// Vertical unit of the elevation samples in an imported terrain source.
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//! GeoTIFF terrain importer behind the optional `import-geotiff` feature.
|
||||
//!
|
||||
//! This importer parses tiny synthetic GeoTIFF elevation tiles entirely in
|
||||
//! memory using the pure-Rust `geotiff-reader` crate. It supports a
|
||||
//! deliberately small subset: a single-band raster decoded as `f32`.
|
||||
|
||||
use crate::import::{ElevationUnit, ImportError, ImportedTerrain, TerrainSourceMetadata};
|
||||
use crate::terrain::HeightGrid;
|
||||
use geotiff_reader::GeoTiffFile;
|
||||
|
||||
/// Format identifier recorded for terrains parsed by [`parse_geotiff_bytes`].
|
||||
const GEOTIFF_FORMAT: &str = "geotiff";
|
||||
|
||||
/// Parse a GeoTIFF payload from memory into an [`ImportedTerrain`].
|
||||
///
|
||||
/// Only single-band rasters are supported; the raster is decoded as `f32` and
|
||||
/// flattened in row-major order into a [`HeightGrid`]. Any reader failure
|
||||
/// (including non-GeoTIFF input) is reported as [`ImportError::MalformedSource`].
|
||||
pub fn parse_geotiff_bytes(source: &[u8]) -> Result<ImportedTerrain, ImportError> {
|
||||
let file = GeoTiffFile::from_bytes(source.to_vec())
|
||||
.map_err(|e| ImportError::MalformedSource(format!("could not read GeoTIFF: {e}")))?;
|
||||
|
||||
let band_count = file.band_count();
|
||||
if band_count != 1 {
|
||||
return Err(ImportError::MalformedSource(format!(
|
||||
"expected a single-band GeoTIFF, got {band_count} bands"
|
||||
)));
|
||||
}
|
||||
|
||||
let raster = file.read_raster::<f32>().map_err(|e| {
|
||||
ImportError::MalformedSource(format!("could not decode GeoTIFF raster: {e}"))
|
||||
})?;
|
||||
|
||||
let samples: Vec<f32> = raster.iter().copied().collect();
|
||||
|
||||
let width = file.width();
|
||||
let height = file.height();
|
||||
|
||||
let grid = HeightGrid::new(width, height, samples)?;
|
||||
let metadata = TerrainSourceMetadata::new(GEOTIFF_FORMAT, width, height, ElevationUnit::Meters);
|
||||
Ok(ImportedTerrain::new(grid, metadata))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::parse_geotiff_bytes;
|
||||
use crate::import::{ElevationUnit, ImportError};
|
||||
use geotiff_writer::GeoTiffBuilder;
|
||||
use ndarray::array;
|
||||
use std::io::Cursor;
|
||||
|
||||
fn tiny_synthetic_geotiff_bytes() -> Vec<u8> {
|
||||
let data = array![[10.0_f32, 20.0, 30.0], [40.0, 50.0, 60.0]];
|
||||
let mut cursor = Cursor::new(Vec::new());
|
||||
GeoTiffBuilder::new(3, 2)
|
||||
.epsg(4326)
|
||||
.pixel_scale(1.0, 1.0)
|
||||
.origin(0.0, 2.0)
|
||||
.write_2d_to(&mut cursor, data.view())
|
||||
.expect("synthetic GeoTIFF fixture should write");
|
||||
cursor.into_inner()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_tiny_synthetic_geotiff_dimensions_and_samples() {
|
||||
let bytes = tiny_synthetic_geotiff_bytes();
|
||||
let imported = parse_geotiff_bytes(&bytes).expect("GeoTIFF fixture should parse");
|
||||
assert_eq!(imported.grid().width(), 3);
|
||||
assert_eq!(imported.grid().height(), 2);
|
||||
assert_eq!(imported.grid().sample(0, 0), Some(10.0));
|
||||
assert_eq!(imported.grid().sample(2, 1), Some(60.0));
|
||||
assert_eq!(imported.metadata().format(), "geotiff");
|
||||
assert_eq!(imported.metadata().width(), 3);
|
||||
assert_eq!(imported.metadata().height(), 2);
|
||||
assert_eq!(imported.metadata().elevation_unit(), ElevationUnit::Meters);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_non_geotiff_payloads() {
|
||||
let err = parse_geotiff_bytes(b"not a geotiff").expect_err("bad bytes must be rejected");
|
||||
assert!(
|
||||
matches!(err, ImportError::MalformedSource(_)),
|
||||
"got: {err:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tiny_fixture_is_not_empty() {
|
||||
let bytes = tiny_synthetic_geotiff_bytes();
|
||||
assert!(
|
||||
bytes.len() > 64,
|
||||
"fixture should contain real GeoTIFF bytes"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user