From ea58b9a017a2e3528f03cc20f16ef531737b863f Mon Sep 17 00:00:00 2001 From: jesse Date: Mon, 14 Oct 2024 20:30:49 -0700 Subject: [PATCH] Super utiles (#174) --- .github/workflows/ci.yml | 6 +- CHANGELOG.md | 3 + Cargo.lock | 277 ++++++++------ crates/utiles-core/src/fns.rs | 21 +- crates/utiles-core/src/lib.rs | 3 +- crates/utiles-core/src/merge.rs | 97 ++++- crates/utiles-core/src/parent.rs | 26 ++ crates/utiles-core/src/tile.rs | 24 +- crates/utiles-core/src/traits.rs | 19 +- crates/utiles-dev/Cargo.toml | 5 +- crates/utiles-dev/src/cover.rs | 1 + crates/utiles-dev/src/edges.rs | 362 ++++++++++++++++++ crates/utiles-dev/src/lib.rs | 3 + crates/utiles-dev/src/main.rs | 64 +--- .../src/cli/commands/children_parent.rs | 7 +- utiles-pyo3/src/pyutiles/pyfns.rs | 13 +- utiles-pyo3/src/pyutiles/pytile.rs | 21 +- 17 files changed, 761 insertions(+), 191 deletions(-) create mode 100644 crates/utiles-core/src/parent.rs create mode 100644 crates/utiles-dev/src/cover.rs create mode 100644 crates/utiles-dev/src/edges.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2fe9380..e85150de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ permissions: jobs: linux: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: matrix: target: [x86_64, x86] #aarch64, armv7, s390x, ppc64le] # maybe add these back later can't bc of oxi-png + libdeflate? @@ -115,7 +115,7 @@ jobs: # pytest --benchmark-disable sdist: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Build sdist @@ -132,7 +132,7 @@ jobs: release: name: Release - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 if: "startsWith(github.ref, 'refs/tags/')" needs: [linux, windows, macos, sdist] steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 62aaabaf..7c0cd677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,12 @@ - Docs/readme update - Write/copy from planetiler/tippecanoe fails bc distinction between supported write schema and what is a recognized schema(s) - Move `utiles-oxipng` to own crate/bin +- `edges` api to find "edge" tiles of collection of tiles ## Unreleased/Future +- `simplify`/`merge` function(s) optimized for faster merging and WAY less memory usage +- Parent methods now returns `None` if `z<=0` - New command(s): - `agg-hash` command that computes the `agg-tiles-hash` of a tiles-db as standardized by the martin/maplibre team (this supports more hash-types; `xxh3` appears to be the fastest and what utiles will likely default to if not `xxh64`) - `commands` list all available commands (including hidden/dev/unimplemented commands) diff --git a/Cargo.lock b/Cargo.lock index 64d6e8fd..84d731a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -149,7 +149,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -160,9 +160,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-compression" -version = "0.4.12" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa" +checksum = "e26a9844c659a2a293d239c7910b752f8487fe122c6c8bd1659bf85a6507c302" dependencies = [ "flate2", "futures-core", @@ -193,14 +193,14 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "av1-grain" @@ -289,7 +289,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -376,9 +376,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" [[package]] name = "byteorder" @@ -406,9 +406,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.21" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "jobserver", "libc", @@ -474,9 +474,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -484,9 +484,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -504,7 +504,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -515,9 +515,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clap_mangen" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17415fd4dfbea46e3274fcd8d368284519b358654772afb700dc2e8d2b24eeb" +checksum = "fbae9cbfdc5d4fa8711c09bd7b83f644cb48281ac35bf97af3e47b0675864bdf" dependencies = [ "clap", "roff", @@ -689,7 +689,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -789,9 +789,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide 0.8.0", @@ -921,7 +921,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1011,9 +1011,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" @@ -1030,8 +1030,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -1053,13 +1053,19 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hashlink" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -1128,9 +1134,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1243,12 +1249,12 @@ checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.0", "rayon", ] @@ -1288,7 +1294,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1355,9 +1361,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1405,18 +1411,18 @@ checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libdeflate-sys" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b14a6afa4e2e1d343fd793a1c0a7e5857a73a2697c2ff2c98ac00d6c4ecc820" +checksum = "2f4ae7b48098016dc3bc64a35605668f0af4425ec1a4a175ce2d0c1129067932" dependencies = [ "cc", ] [[package]] name = "libdeflater" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17fe2badabdaf756f620748311e99ef99a5fdd681562dfd343fdb16ed7d4797" +checksum = "567ff5eb948d34d3f93d8da568e72db0f5a12c89efb6c3913e4d6b142cc7ec34" dependencies = [ "libdeflate-sys", ] @@ -1512,6 +1518,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "matrixmultiply" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "maybe-rayon" version = "0.1.1" @@ -1574,7 +1590,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", - "simd-adler32", ] [[package]] @@ -1584,6 +1599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -1598,6 +1614,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ndarray" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "portable-atomic", + "portable-atomic-util", + "rawpointer", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -1651,6 +1682,15 @@ dependencies = [ "num-traits", ] +[[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-conv" version = "0.1.0" @@ -1665,7 +1705,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1716,18 +1756,18 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" @@ -1819,7 +1859,7 @@ dependencies = [ "regex", "regex-syntax 0.7.5", "structmeta", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1900,22 +1940,31 @@ dependencies = [ [[package]] name = "png" -version = "0.17.13" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" dependencies = [ "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.7.4", + "miniz_oxide 0.8.0", ] [[package]] name = "portable-atomic" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + +[[package]] +name = "portable-atomic-util" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdd8420072e66d54a407b3316991fe946ce3ab1083a7f575b2463866624704d" +dependencies = [ + "portable-atomic", +] [[package]] name = "powerfmt" @@ -1934,37 +1983,37 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] name = "pyo3" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15ee168e30649f7f234c3d49ef5a7a6cbf5134289bc46c29ff3155fa3221c225" +checksum = "00e89ce2565d6044ca31a3eb79a334c3a79a841120a98f64eea9f579564cb691" dependencies = [ "cfg-if", "indoc", @@ -1980,9 +2029,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e61cef80755fe9e46bb8a0b8f20752ca7676dcc07a5277d8b7768c6172e529b3" +checksum = "d8afbaf3abd7325e08f35ffb8deb5892046fcb2608b703db6a583a5ba4cea01e" dependencies = [ "once_cell", "target-lexicon", @@ -1990,9 +2039,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce096073ec5405f5ee2b8b31f03a68e02aa10d5d4f565eca04acc41931fa1c" +checksum = "ec15a5ba277339d04763f4c23d85987a5b08cbb494860be141e6a10a8eb88022" dependencies = [ "libc", "pyo3-build-config", @@ -2000,27 +2049,27 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2440c6d12bc8f3ae39f1e775266fa5122fd0c8891ce7520fa6048e683ad3de28" +checksum = "15e0f01b5364bcfbb686a52fc4181d412b708a68ed20c330db9fc8d2c2bf5a43" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] name = "pyo3-macros-backend" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be962f0e06da8f8465729ea2cb71a416d2257dff56cbe40a70d3e62a93ae5d1" +checksum = "a09b550200e1e5ed9176976d0060cbc2ea82dc8515da07885e7b8153a85caacb" dependencies = [ "heck", "proc-macro2", "pyo3-build-config", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2146,6 +2195,12 @@ dependencies = [ "rgb", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.10.0" @@ -2168,23 +2223,23 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -2198,13 +2253,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -2221,9 +2276,9 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rgb" @@ -2290,9 +2345,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -2338,7 +2393,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2513,7 +2568,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2524,7 +2579,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2546,7 +2601,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2571,9 +2626,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -2644,7 +2699,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2735,7 +2790,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2866,7 +2921,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3015,7 +3070,11 @@ name = "utiles-dev" version = "0.7.0-alpha.9" dependencies = [ "anyhow", + "ndarray", + "serde", + "serde_json", "tokio", + "utiles-core", ] [[package]] @@ -3102,9 +3161,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -3113,24 +3172,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3138,28 +3197,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -3401,7 +3460,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] diff --git a/crates/utiles-core/src/fns.rs b/crates/utiles-core/src/fns.rs index d86dabfc..1588fd67 100644 --- a/crates/utiles-core/src/fns.rs +++ b/crates/utiles-core/src/fns.rs @@ -261,19 +261,28 @@ pub fn truncate_lnglat(lnglat: &LngLat) -> LngLat { /// Return the parent tile of a tile given x, y, z, and n (number of ancestors). #[must_use] -pub fn parent(x: u32, y: u32, z: u8, n: Option) -> Tile { +pub fn parent(x: u32, y: u32, z: u8, n: Option) -> Option { let n = n.unwrap_or(0); if n == 0 { - Tile { - x: x >> 1, - y: y >> 1, - z: z - 1, + if z == 0 { + None + } else { + Some(utile!(x >> 1, y >> 1, z - 1)) } } else { parent(x >> 1, y >> 1, z - 1, Some(n - 1)) } } - +/// Return the 4 direct children of a tile +#[must_use] +pub fn children1_zorder(x: u32, y: u32, z: u8) -> [Tile; 4] { + [ + utile!(x * 2, y * 2, z + 1), // top-left + utile!(x * 2 + 1, y * 2, z + 1), // top-right + utile!(x * 2, y * 2 + 1, z + 1), // bottom-left + utile!(x * 2 + 1, y * 2 + 1, z + 1), // bottom-right + ] +} /// Return the children of a tile given x, y, z, and zoom in z-order. /// /// # Examples diff --git a/crates/utiles-core/src/lib.rs b/crates/utiles-core/src/lib.rs index 895d52b4..57a5079f 100644 --- a/crates/utiles-core/src/lib.rs +++ b/crates/utiles-core/src/lib.rs @@ -31,7 +31,7 @@ pub use tile::Tile; pub use tile_like::TileLike; pub use tile_zbox::TileZBox; #[doc(inline)] -pub use traits::{Coord2dLike, IsOk, LngLatLike, TileParent}; +pub use traits::{Coord2dLike, IsOk, LngLatLike, TileChildren1, TileParent}; pub use zoom::*; pub mod bbox; @@ -46,6 +46,7 @@ pub mod lnglat; pub mod parsing; mod merge; +mod parent; #[cfg(feature = "pmtiles")] pub mod pmtiles; pub mod point; diff --git a/crates/utiles-core/src/merge.rs b/crates/utiles-core/src/merge.rs index 2dc1d3e5..c7483bf1 100644 --- a/crates/utiles-core/src/merge.rs +++ b/crates/utiles-core/src/merge.rs @@ -1,18 +1,21 @@ -use std::collections::{HashMap, HashSet}; - +use crate::traits::TileChildren1; use crate::TileParent; +use std::collections::{HashMap, HashSet}; +use std::hash::Hash; /// Merge a set of tiles into a simplified set of tiles /// #[must_use] -pub fn merge( +pub fn merge( merge_set: &HashSet, ) -> (HashSet, bool) { let mut upwards_merge: HashMap> = HashMap::new(); for tile in merge_set { - let tile_parent = tile.parent(None); - upwards_merge.entry(tile_parent).or_default().insert(*tile); + // let tile_parent = tile.parent(None); + if let Some(tile_parent) = tile.parent(None) { + upwards_merge.entry(tile_parent).or_default().insert(*tile); + } } let mut current_tileset: HashSet = HashSet::default(); let mut changed = false; @@ -33,7 +36,7 @@ pub fn merge( /// /// TODO: Add `minzoom` and `maxzoom` parameters #[must_use] -pub fn simplify( +pub fn simplify_v1( tiles: &HashSet, ) -> HashSet { let mut tilesv: Vec<&T> = tiles.iter().collect(); @@ -43,8 +46,10 @@ pub fn simplify( 'outer: for tile in tilesv { for i in 0..tile.z() { - if root_set.contains(&tile.parent(Some(i))) { - continue 'outer; + if let Some(par) = tile.parent(Some(i)) { + if root_set.contains(&par) { + continue 'outer; + } } } root_set.insert(*tile); @@ -59,3 +64,79 @@ pub fn simplify( root_set } + +struct TileMerger { + coverage_map: HashSet, +} + +impl TileMerger { + fn new() -> Self { + Self { + coverage_map: HashSet::new(), + } + } + + fn has_tile_or_parent(&self, tile: &T) -> bool { + self.coverage_map.contains(tile) + || tile + .iter_parents() + .any(|el| self.coverage_map.contains(&el)) + } + + fn put(&mut self, tile: &T) -> bool { + if self.has_tile_or_parent(tile) { + true + } else { + self.coverage_map.insert(*tile); + self.attempt_merge(*tile); + false + } + } + // fn attempt_merge(&mut self, tile: T) { + // tile.iter_parents().find_map(|parent_tile| { + // let siblings = parent_tile.children1(); + // + // if siblings.iter().all(|sibling| self.coverage_map.contains(sibling)) { + // siblings.iter().for_each(|sibling| { + // self.coverage_map.remove(sibling); + // }); + // self.coverage_map.insert(parent_tile); + // None // Continue merging, return None so the iteration continues + // } else { + // Some(()) // Stop merging, return Some to break the iteration + // } + // }); + // } + + fn attempt_merge(&mut self, tile: T) { + for parent_tile in tile.iter_parents() { + let siblings = parent_tile.children1(); + + if siblings + .iter() + .all(|sibling| self.coverage_map.contains(sibling)) + { + for sibling in &siblings { + self.coverage_map.remove(sibling); + } + self.coverage_map.insert(parent_tile); + } else { + // stop merging BC WE CANNOT! + break; + } + } + } +} + +#[must_use] +pub fn simplify( + tiles: &HashSet, +) -> HashSet { + let mut tiles_vec: Vec<_> = tiles.iter().collect(); + tiles_vec.sort_by_key(|a| a.z()); + let mut merger = TileMerger::new(); + for tile in tiles_vec { + merger.put(tile); + } + merger.coverage_map +} diff --git a/crates/utiles-core/src/parent.rs b/crates/utiles-core/src/parent.rs new file mode 100644 index 00000000..c6a10a9d --- /dev/null +++ b/crates/utiles-core/src/parent.rs @@ -0,0 +1,26 @@ +use crate::TileParent; + +/// Iterator over parent tiles. +pub struct Parents +where + T: TileParent + Clone, +{ + pub current: Option, +} + +impl Iterator for Parents +where + T: TileParent + Clone, +{ + type Item = T; + + fn next(&mut self) -> Option { + if let Some(current_tile) = self.current { + // Move to the next parent + self.current = current_tile.parent(None); + Some(current_tile) + } else { + None + } + } +} diff --git a/crates/utiles-core/src/tile.rs b/crates/utiles-core/src/tile.rs index 34cec4bf..a34db892 100644 --- a/crates/utiles-core/src/tile.rs +++ b/crates/utiles-core/src/tile.rs @@ -16,7 +16,9 @@ use crate::tile_feature::TileFeature; use crate::tile_like::TileLike; use crate::tile_tuple::TileTuple; use crate::traits::TileParent; -use crate::{pmtiles, quadkey2tile, rmid2xyz, xyz2quadkey, IsOk}; +use crate::{ + children1_zorder, pmtiles, quadkey2tile, rmid2xyz, xyz2quadkey, IsOk, TileChildren1, +}; /// Tile X-Y-Z struct #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -155,11 +157,17 @@ impl TileLike for Tile { } impl TileParent for Tile { - fn parent(&self, zoom: Option) -> Self { + fn parent(&self, zoom: Option) -> Option { self.parent(zoom) } } +impl TileChildren1 for Tile { + fn children1(&self) -> [Self; 4] { + self.children1() + } +} + impl Tile { /// Create a new Tile #[must_use] @@ -239,8 +247,8 @@ impl Tile { /// Return the parent tile's pmtile-id #[must_use] - pub fn parent_pmtileid(&self) -> u64 { - self.parent(None).pmtileid() + pub fn parent_pmtileid(&self) -> Option { + self.parent(None).map(|t| Self::pmtileid(&t)) } /// Convert quadkey string to Tile @@ -479,6 +487,12 @@ impl Tile { neighbors(self.x, self.y, self.z) } + /// Return direct children + #[must_use] + pub fn children1(&self) -> [Tile; 4] { + children1_zorder(self.x, self.y, self.z) + } + /// Return the children tiles of the tile #[must_use] pub fn children(&self, zoom: Option) -> Vec { @@ -487,7 +501,7 @@ impl Tile { /// Return the parent tile #[must_use] - pub fn parent(&self, zoom: Option) -> Self { + pub fn parent(&self, zoom: Option) -> Option { parent(self.x, self.y, self.z, zoom) } diff --git a/crates/utiles-core/src/traits.rs b/crates/utiles-core/src/traits.rs index 558e3cff..fe432080 100644 --- a/crates/utiles-core/src/traits.rs +++ b/crates/utiles-core/src/traits.rs @@ -1,5 +1,6 @@ //! Utiles traits +use crate::parent::Parents; use crate::TileLike; use std::hash::Hash; @@ -49,5 +50,21 @@ pub trait LngLatLike: Coord2dLike { pub trait TileParent: Eq + Hash + Copy + TileLike { #[must_use] - fn parent(&self, zoom: Option) -> Self; + fn parent(&self, zoom: Option) -> Option; + + fn iter_parents(&self) -> Parents { + Parents { + current: self.parent(None), + } + } +} + +pub trait TileChildren1: Eq + Hash + Copy + TileLike { + /// Returns direct children in Z order: + /// 1) top-left + /// 2) top-right + /// 3) bottom-left + /// 4) bottom-right + #[must_use] + fn children1(&self) -> [Self; 4]; } diff --git a/crates/utiles-dev/Cargo.toml b/crates/utiles-dev/Cargo.toml index a590c910..8b8fa474 100644 --- a/crates/utiles-dev/Cargo.toml +++ b/crates/utiles-dev/Cargo.toml @@ -19,6 +19,9 @@ path = "src/main.rs" [dependencies] anyhow.workspace = true +ndarray = "0.16.1" +serde.workspace = true +serde_json.workspace = true tokio.workspace = true # futures = "0.3.30" @@ -32,4 +35,4 @@ tokio.workspace = true # tilejson.workspace = true # tracing.workspace = true # tracing-subscriber.workspace = true -# utiles = { path = "../utiles" } +utiles-core = { path = "../utiles-core" } diff --git a/crates/utiles-dev/src/cover.rs b/crates/utiles-dev/src/cover.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/crates/utiles-dev/src/cover.rs @@ -0,0 +1 @@ + diff --git a/crates/utiles-dev/src/edges.rs b/crates/utiles-dev/src/edges.rs new file mode 100644 index 00000000..4f844f6a --- /dev/null +++ b/crates/utiles-dev/src/edges.rs @@ -0,0 +1,362 @@ +use ndarray::{stack, Array2, Axis}; +use std::collections::HashSet; +use utiles_core::{utile, Tile, TileLike}; + +fn get_range(tiles: &[Tile]) -> (usize, usize, usize, usize) { + let (xmin, xmax) = tiles.iter().fold((usize::MAX, 0), |(min_x, max_x), tile| { + (min_x.min(tile.x() as usize), max_x.max(tile.x())) + }); + + let (ymin, ymax) = tiles.iter().fold((usize::MAX, 0), |(min_y, max_y), tile| { + (min_y.min(tile.y() as usize), max_y.max(tile.y())) + }); + + (xmin, xmax as usize, ymin, ymax as usize) +} + +// Function to get zoom level (assumes all tiles have the same zoom). +fn get_zoom(tiles: &[Tile]) -> u8 { + tiles[0].z +} + +// Burn the tiles into a 2D array + +fn burn_tiles( + tiles: &[Tile], + xmin: usize, + xmax: usize, + ymin: usize, + ymax: usize, +) -> Array2 { + let mut burn = Array2::::default((xmax - xmin + 3, ymax - ymin + 3)); + for tile in tiles { + let x_us = tile.x() as usize; + let y_us = tile.y() as usize; + burn[(x_us - xmin + 1, y_us - ymin + 1)] = true; + } + burn +} + +// Roll function for 2D arrays +fn roll_2d(arr: &Array2, x_shift: isize, y_shift: isize) -> Array2 { + let (rows, cols) = arr.dim(); + let mut rolled = Array2::default((rows, cols)); + + for i in 0..rows { + for j in 0..cols { + let new_i = ((i as isize + x_shift).rem_euclid(rows as isize)) as usize; + let new_j = ((j as isize + y_shift).rem_euclid(cols as isize)) as usize; + rolled[(new_i, new_j)] = arr[(i, j)]; + } + } + rolled +} +static IDXS: &[(isize, isize)] = &[ + (-1, -1), + (-1, 0), + (-1, 1), + (0, -1), + (0, 1), + (1, -1), + (1, 0), + (1, 1), +]; +fn find_edges(tiles: Vec) -> Vec { + let (xmin, xmax, ymin, ymax) = get_range(&tiles); + let zoom = get_zoom(&tiles); + + // Create the 2D burn array + let burn = burn_tiles(&tiles, xmin, xmax, ymin, ymax); + + // Define the rolling indices + // let idxs = vec![ + // (-1, -1), + // (-1, 0), + // (-1, 1), + // (0, -1), + // (0, 1), + // (1, -1), + // (1, 0), + // (1, 1), + // ]; + + // Create the rolled arrays without adding an extra axis + let stacks: Vec> = IDXS + .iter() + .map(|(dx, dy)| roll_2d(&burn, *dx, *dy)) + .collect(); + // Stack along Axis(2), resulting in a 3D array + let stacked = stack( + Axis(2), + &stacks.iter().map(|a| a.view()).collect::>(), + ) + .expect("Failed to stack arrays"); + + // Calculate the edges + // let min_array = stacked.map_axis(Axis(2), |view| view.iter().copied().min().unwrap()); + let min_array = stacked.map_axis(Axis(2), |view| *view.iter().min().unwrap()); + + // get edges sans clone (xors the 2 arrs) + let xys_edge = &burn & !&min_array; + + // Collect the edge tiles + // let mut edge_indices = Vec::new(); + let uxmin = xmin - 1; + let uymin = ymin - 1; + + // v1 of weird itering + // ========================================== + // let tiles = xys_edge.indexed_iter().map( + // |((i, j), is_edge)| { + // if *is_edge{ + // let tile = Tile::new( + // (i + uxmin) as u32, + // (j + uymin) as u32, + // zoom, + // ); + // Some( + // tile + // ) + // }else{ + // None + // } + // + // } + // + // ).flatten().collect::>(); + // ========================================== + // more sane version: + + let tiles = xys_edge + .indexed_iter() + .filter(|(_, &is_edge)| is_edge) + .map(|((i, j), _)| Tile::new((i + uxmin) as u32, (j + uymin) as u32, zoom)) + .collect::>(); + + tiles +} + +fn _test_data_input() -> Vec { + vec![ + utile!(4188, 3104, 13), + utile!(4192, 2977, 13), + utile!(4192, 3098, 13), + utile!(4192, 2983, 13), + utile!(4192, 2935, 13), + utile!(4192, 2982, 13), + utile!(4192, 2980, 13), + utile!(4192, 3101, 13), + utile!(4192, 2987, 13), + utile!(4192, 2987, 13), + utile!(4192, 2986, 13), + utile!(4192, 2981, 13), + utile!(4192, 2997, 13), + utile!(4192, 2969, 13), + utile!(4192, 2947, 13), + utile!(4192, 2927, 13), + utile!(4192, 2961, 13), + utile!(4192, 2988, 13), + utile!(4192, 2976, 13), + utile!(4192, 2891, 13), + utile!(4192, 2994, 13), + utile!(4192, 2959, 13), + utile!(4192, 2892, 13), + utile!(4192, 2975, 13), + utile!(4192, 2931, 13), + utile!(4192, 2943, 13), + utile!(4192, 2971, 13), + utile!(4192, 2931, 13), + utile!(4192, 2919, 13), + utile!(4192, 2929, 13), + utile!(4192, 2930, 13), + utile!(4192, 2897, 13), + utile!(4192, 2878, 13), + utile!(4192, 2879, 13), + utile!(4192, 2980, 13), + utile!(4192, 2868, 13), + utile!(4192, 2887, 13), + utile!(4192, 2881, 13), + utile!(4192, 2913, 13), + utile!(4192, 2884, 13), + utile!(4192, 2899, 13), + utile!(4192, 2809, 13), + utile!(4192, 2859, 13), + utile!(4192, 2807, 13), + utile!(4192, 2921, 13), + utile!(4192, 2775, 13), + utile!(4192, 2811, 13), + utile!(4192, 2827, 13), + utile!(4192, 2867, 13), + utile!(4192, 2865, 13), + utile!(4192, 2856, 13), + utile!(4192, 2873, 13), + utile!(4192, 2863, 13), + utile!(4192, 2839, 13), + utile!(4192, 2774, 13), + utile!(4192, 2974, 13), + utile!(4192, 2808, 13), + utile!(4192, 2832, 13), + utile!(4192, 2793, 13), + utile!(4192, 3098, 13), + utile!(4192, 2787, 13), + utile!(4192, 2859, 13), + utile!(4192, 2853, 13), + utile!(4192, 2825, 13), + utile!(4192, 2825, 13), + utile!(4192, 2808, 13), + utile!(4192, 2787, 13), + utile!(4192, 2898, 13), + utile!(4192, 2812, 13), + utile!(4192, 2859, 13), + utile!(4192, 2765, 13), + utile!(4192, 2806, 13), + utile!(4192, 2769, 13), + utile!(4192, 2964, 13), + utile!(4192, 2821, 13), + utile!(4192, 2778, 13), + utile!(4192, 2785, 13), + utile!(4192, 2805, 13), + utile!(4192, 2737, 13), + utile!(4192, 2800, 13), + utile!(4192, 2762, 13), + utile!(4192, 2756, 13), + utile!(4192, 2986, 13), + utile!(4192, 2794, 13), + utile!(4192, 2760, 13), + utile!(4192, 2777, 13), + utile!(4192, 2782, 13), + utile!(4192, 2746, 13), + utile!(4192, 2748, 13), + utile!(4192, 2745, 13), + utile!(4192, 2871, 13), + utile!(4192, 2798, 13), + utile!(4192, 2758, 13), + utile!(4192, 2756, 13), + utile!(4192, 2750, 13), + utile!(4192, 2977, 13), + utile!(4192, 2765, 13), + utile!(4192, 2981, 13), + utile!(4192, 3099, 13), + utile!(4192, 2983, 13), + ] +} + +fn _test_expected() -> Vec { + vec![ + utile!(4188, 3104, 13), + utile!(4192, 2737, 13), + utile!(4192, 2745, 13), + utile!(4192, 2746, 13), + utile!(4192, 2748, 13), + utile!(4192, 2750, 13), + utile!(4192, 2756, 13), + utile!(4192, 2758, 13), + utile!(4192, 2760, 13), + utile!(4192, 2762, 13), + utile!(4192, 2765, 13), + utile!(4192, 2769, 13), + utile!(4192, 2774, 13), + utile!(4192, 2775, 13), + utile!(4192, 2777, 13), + utile!(4192, 2778, 13), + utile!(4192, 2782, 13), + utile!(4192, 2785, 13), + utile!(4192, 2787, 13), + utile!(4192, 2793, 13), + utile!(4192, 2794, 13), + utile!(4192, 2798, 13), + utile!(4192, 2800, 13), + utile!(4192, 2805, 13), + utile!(4192, 2806, 13), + utile!(4192, 2807, 13), + utile!(4192, 2808, 13), + utile!(4192, 2809, 13), + utile!(4192, 2811, 13), + utile!(4192, 2812, 13), + utile!(4192, 2821, 13), + utile!(4192, 2825, 13), + utile!(4192, 2827, 13), + utile!(4192, 2832, 13), + utile!(4192, 2839, 13), + utile!(4192, 2853, 13), + utile!(4192, 2856, 13), + utile!(4192, 2859, 13), + utile!(4192, 2863, 13), + utile!(4192, 2865, 13), + utile!(4192, 2867, 13), + utile!(4192, 2868, 13), + utile!(4192, 2871, 13), + utile!(4192, 2873, 13), + utile!(4192, 2878, 13), + utile!(4192, 2879, 13), + utile!(4192, 2881, 13), + utile!(4192, 2884, 13), + utile!(4192, 2887, 13), + utile!(4192, 2891, 13), + utile!(4192, 2892, 13), + utile!(4192, 2897, 13), + utile!(4192, 2898, 13), + utile!(4192, 2899, 13), + utile!(4192, 2913, 13), + utile!(4192, 2919, 13), + utile!(4192, 2921, 13), + utile!(4192, 2927, 13), + utile!(4192, 2929, 13), + utile!(4192, 2930, 13), + utile!(4192, 2931, 13), + utile!(4192, 2935, 13), + utile!(4192, 2943, 13), + utile!(4192, 2947, 13), + utile!(4192, 2959, 13), + utile!(4192, 2961, 13), + utile!(4192, 2964, 13), + utile!(4192, 2969, 13), + utile!(4192, 2971, 13), + utile!(4192, 2974, 13), + utile!(4192, 2975, 13), + utile!(4192, 2976, 13), + utile!(4192, 2977, 13), + utile!(4192, 2980, 13), + utile!(4192, 2981, 13), + utile!(4192, 2982, 13), + utile!(4192, 2983, 13), + utile!(4192, 2986, 13), + utile!(4192, 2987, 13), + utile!(4192, 2988, 13), + utile!(4192, 2994, 13), + utile!(4192, 2997, 13), + utile!(4192, 3098, 13), + utile!(4192, 3099, 13), + utile!(4192, 3101, 13), + ] +} +pub fn edges_main() { + let tdata = _test_data_input(); + let edges = find_edges(tdata); + + println!("Edges:\n{:?}", edges); + let expected = _test_expected(); + + let expected_set = expected.into_iter().collect::>(); + let edges_set = edges.into_iter().collect::>(); + + println!("EQUAH: {}", expected_set.eq(&edges_set)); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_edges() { + let tdata = _test_data_input(); + let edges = find_edges(tdata); + + let expected = _test_expected(); + + let expected_set = expected.into_iter().collect::>(); + let edges_set = edges.into_iter().collect::>(); + + assert_eq!(expected_set, edges_set); + } +} diff --git a/crates/utiles-dev/src/lib.rs b/crates/utiles-dev/src/lib.rs index 013acbd6..e4b9b515 100644 --- a/crates/utiles-dev/src/lib.rs +++ b/crates/utiles-dev/src/lib.rs @@ -1,3 +1,6 @@ +pub mod cover; +pub mod edges; + use anyhow::Result; pub fn quick_maths() -> Result<()> { let mut n = 2; // 2 diff --git a/crates/utiles-dev/src/main.rs b/crates/utiles-dev/src/main.rs index 70c37fae..735eda91 100644 --- a/crates/utiles-dev/src/main.rs +++ b/crates/utiles-dev/src/main.rs @@ -1,49 +1,21 @@ -// fn mvt_dev() { -// let filepath = "D:\\utiles\\crates\\utiles-dev\\12665.vector.pbf"; -// // read to vec of bytes -// let bytes = std::fs::read(filepath).unwrap(); -// -// println!("bytes: {:?}", bytes.len()); -// // let buf = bytes.as_slice(); -// -// let cursor = std::io::Cursor::new(bytes.as_slice()); -// -// let mt = Tile::decode(cursor).unwrap(); -// -// println!("mt: {:?}", mt); -// // let t = -// -// // let gj = mt.to_json().unwrap(); -// -// let num_layers = mt.layers.len(); -// println!("num_layers: {:?}", num_layers); -// -// // mt.layers -// // mt.layers.into_iter().map( -// // |layer| { -// // let mut l = layer.clone(); -// // println!("l: {:?}", l); -// // let s = l.to_json().unwrap(); -// // println!("s:"); -// // println!("{}", s); -// // } -// // ).collect::>(); -// -// // println!("gj: {:?}", gj); -// // number of layers in tile -// // let mtjson = serde_json::to_string(&mt).unwrap(); -// -// // let gj = geozero::mvt::to_geojson(&mt).unwrap(); -// // println!("mtjson: {:?}", mtjson); -// } +use utiles_dev::edges::edges_main; -#[tokio::main] -async fn main() { +fn main() { println!("utiles ~ dev"); - let r = utiles_dev::quick_maths(); - if let Err(e) = r { - println!("e: {:?}", e); - } else { - println!("2 + 2, that's 4, minus 1 that's 3, quick-maths."); - } + + edges_main(); } + +// #[tokio::main] +// async fn main_async() { +// println!("utiles ~ dev"); + +// edges_main(); + +// let r = utiles_dev::quick_maths(); +// if let Err(e) = r { +// println!("e: {:?}", e); +// } else { +// println!("2 + 2, that's 4, minus 1 that's 3, quick-maths."); +// } +// } diff --git a/crates/utiles/src/cli/commands/children_parent.rs b/crates/utiles/src/cli/commands/children_parent.rs index 46a759cf..e01a53a6 100644 --- a/crates/utiles/src/cli/commands/children_parent.rs +++ b/crates/utiles/src/cli/commands/children_parent.rs @@ -12,9 +12,10 @@ pub fn parent_main(args: ParentChildrenArgs) -> UtilesResult<()> { let nup = i32::from(tile.z) - i32::from(args.depth); // error assert!(nup >= 0, "depth must be less than or equal to tile zoom"); - let parent = tile.parent(Option::from(args.depth - 1)); - let rs = if args.fmtopts.seq { "\x1e\n" } else { "" }; - println!("{}{}", rs, parent.json_arr()); + if let Some(parent) = tile.parent(Option::from(args.depth - 1)) { + let rs = if args.fmtopts.seq { "\x1e\n" } else { "" }; + println!("{}{}", rs, parent.json_arr()); + } } Ok(()) } diff --git a/utiles-pyo3/src/pyutiles/pyfns.rs b/utiles-pyo3/src/pyutiles/pyfns.rs index d4f4e6f6..0cd94487 100644 --- a/utiles-pyo3/src/pyutiles/pyfns.rs +++ b/utiles-pyo3/src/pyutiles/pyfns.rs @@ -103,7 +103,8 @@ pub fn from_tuple(tile: TileTuple) -> PyTile { PyTile::new(tile.0, tile.1, tile.2) } #[pyfunction] -#[pyo3(signature = (tile, fid = None, props = None, projected = None, buffer = None, precision = None))] +#[pyo3(signature = (tile, fid = None, props = None, projected = None, buffer = None, precision = None) +)] pub fn feature( py: Python, tile: PyTileLike, @@ -230,8 +231,14 @@ pub fn parent(args: &Bound<'_, PyTuple>, zoom: Option) -> PyResult u64 { + pub fn parent_pmtileid(&self) -> Option { self.xyz.parent_pmtileid() } @@ -359,8 +359,8 @@ impl PyTile { } #[pyo3(signature = (n = None))] - pub fn parent(&self, n: Option) -> Self { - self.xyz.parent(n).into() + pub fn parent(&self, n: Option) -> Option { + self.xyz.parent(n).map(PyTile::from) } #[pyo3(signature = (zoom = None))] @@ -369,6 +369,11 @@ impl PyTile { xyzs.into_iter().map(Self::from).collect() } + pub fn children1(&self) -> [Self; 4] { + let direct_child_tiles = self.xyz.children1(); + direct_child_tiles.map(Self::from) + } + pub fn siblings(&self) -> Vec { self.xyz.siblings().into_iter().map(Self::from).collect() } @@ -499,11 +504,17 @@ impl TileLike for &PyTile { } impl TileParent for PyTile { - fn parent(&self, zoom: Option) -> Self { + fn parent(&self, zoom: Option) -> Option { self.parent(zoom) } } +impl TileChildren1 for PyTile { + fn children1(&self) -> [PyTile; 4] { + self.children1() + } +} + impl From for Tile { fn from(val: PyTile) -> Self { val.xyz