diff --git a/Cargo.lock b/Cargo.lock index a87f5ffc3bb9..22233c207c76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,7 +38,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cipher", "cpufeatures", ] @@ -60,7 +60,7 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "const-random", "getrandom 0.2.12", "once_cell", @@ -737,7 +737,7 @@ checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ "async-lock 2.8.0", "autocfg", - "cfg-if", + "cfg-if 1.0.0", "concurrent-queue", "futures-lite 1.13.0", "log", @@ -756,7 +756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65" dependencies = [ "async-lock 3.3.0", - "cfg-if", + "cfg-if 1.0.0", "concurrent-queue", "futures-io", "futures-lite 2.2.0", @@ -1383,7 +1383,7 @@ source = "git+https://github.com/rust-lang/backtrace-rs.git?rev=72265be#72265bea dependencies = [ "addr2line 0.22.0", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", "object 0.36.2", @@ -1624,7 +1624,7 @@ dependencies = [ "arrayref", "arrayvec 0.7.4", "cc", - "cfg-if", + "cfg-if 1.0.0", "constant_time_eq", ] @@ -2117,6 +2117,12 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -2341,7 +2347,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7fc6734af48458f72f5a3fa7b840903606427d98a710256e808f76a965047d9" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "clap", "is-terminal", "libc", @@ -2506,6 +2512,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "console_log" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f" +dependencies = [ + "log", + "web-sys", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -2590,7 +2606,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -2726,7 +2742,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -2863,6 +2879,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "crs-definitions" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a5c99491ee16d7f1549494bcab90bdfb2f283ef48a25fc6c870e7e7c9f12bb" + [[package]] name = "crunchy" version = "0.2.2" @@ -3007,7 +3029,7 @@ version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "hashbrown 0.14.3", "lock_api", "once_cell", @@ -3512,6 +3534,7 @@ dependencies = [ "num-traits", "once_cell", "ordered-float 4.2.0", + "proj4rs", "rand 0.8.5", "regex", "roaring", @@ -3549,7 +3572,7 @@ version = "0.1.0" dependencies = [ "ahash 0.8.10", "bumpalo", - "cfg-if", + "cfg-if 1.0.0", "databend-common-arrow", "databend-common-base", "ethnum", @@ -5924,7 +5947,7 @@ dependencies = [ "arrow-select", "async-trait", "bytes", - "cfg-if", + "cfg-if 1.0.0", "chrono", "dashmap", "delta_kernel", @@ -6110,7 +6133,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "dirs-sys-next", ] @@ -6324,7 +6347,7 @@ version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -6634,7 +6657,7 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "rustix 0.38.31", "windows-sys 0.52.0", ] @@ -6684,7 +6707,7 @@ version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall 0.4.1", "windows-sys 0.52.0", @@ -7333,7 +7356,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -7344,7 +7367,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", @@ -8667,7 +8690,7 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crunchy", "num-traits", ] @@ -8830,7 +8853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "091a6fbccf4860009355e3efc52ff4acf37a63489aad7435372d44ceeb6fbbcf" dependencies = [ "async-trait", - "cfg-if", + "cfg-if 1.0.0", "data-encoding", "enum-as-inner 0.6.0", "futures-channel", @@ -8853,7 +8876,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35b8f021164e6a984c9030023544c57789c51760065cd510572fedcfb04164e8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "futures-util", "hickory-proto", "ipconfig", @@ -9455,7 +9478,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -9765,7 +9788,7 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "ecdsa 0.16.9", "elliptic-curve 0.13.8", "once_cell", @@ -9996,7 +10019,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2caa5afb8bf9f3a2652760ce7d4f62d21c4d5a423e68466fca30df82f2330164" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "windows-targets 0.52.4", ] @@ -10163,7 +10186,7 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "generator", "pin-utils", "scoped-tls", @@ -10319,7 +10342,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "digest", ] @@ -10375,6 +10398,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + [[package]] name = "metainfo" version = "0.7.9" @@ -10476,7 +10505,7 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "downcast", "fragile", "lazy_static", @@ -10491,7 +10520,7 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "proc-macro2", "quote", "syn 1.0.109", @@ -10730,7 +10759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", - "cfg-if", + "cfg-if 1.0.0", "libc", ] @@ -10741,7 +10770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ "bitflags 2.4.2", - "cfg-if", + "cfg-if 1.0.0", "libc", ] @@ -10752,7 +10781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ "bitflags 2.4.2", - "cfg-if", + "cfg-if 1.0.0", "cfg_aliases", "libc", "memoffset", @@ -11177,7 +11206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.4.2", - "cfg-if", + "cfg-if 1.0.0", "foreign-types 0.3.2", "libc", "once_cell", @@ -11496,7 +11525,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "instant", "libc", "redox_syscall 0.2.16", @@ -11510,7 +11539,7 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall 0.4.1", "smallvec", @@ -11964,7 +11993,7 @@ checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg", "bitflags 1.3.2", - "cfg-if", + "cfg-if 1.0.0", "concurrent-queue", "libc", "log", @@ -11978,7 +12007,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "concurrent-queue", "pin-project-lite", "rustix 0.38.31", @@ -12019,7 +12048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "196ded5d4be535690899a4631cc9f18cdc41b7ebf24a79400f46f48e49a11059" dependencies = [ "backtrace", - "cfg-if", + "cfg-if 1.0.0", "findshlibs", "inferno", "libc", @@ -12249,6 +12278,23 @@ dependencies = [ "human_format", ] +[[package]] +name = "proj4rs" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5847217d30c155a90885e9a2ad25aa8f572c5be36664e114182b4c317b2eb5bb" +dependencies = [ + "console_log", + "crs-definitions", + "geo-types", + "js-sys", + "lazy_static", + "thiserror", + "wasm-bindgen", + "web-sys", + "wee_alloc", +] + [[package]] name = "prometheus-client" version = "0.22.2" @@ -12513,7 +12559,7 @@ version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "indoc", "libc", "memoffset", @@ -13171,7 +13217,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.0", "getrandom 0.2.12", "libc", "spin 0.9.8", @@ -13403,7 +13449,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "ordered-multimap 0.4.3", ] @@ -13413,7 +13459,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d625ed57d8f49af6cfa514c42e1a71fadcff60eb0b1c517ff82fe41aa025b41" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "ordered-multimap 0.7.3", "trim-in-place", ] @@ -13627,7 +13673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" dependencies = [ "bitflags 2.4.2", - "cfg-if", + "cfg-if 1.0.0", "clipboard-win", "fd-lock", "home", @@ -13981,7 +14027,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -13998,7 +14044,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -14305,7 +14351,7 @@ dependencies = [ "arrayref", "bumpalo", "bytes", - "cfg-if", + "cfg-if 1.0.0", "faststr", "itoa", "page_size", @@ -14458,7 +14504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "psm", "winapi", @@ -14821,7 +14867,7 @@ version = "0.30.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6746919caf9f2a85bff759535664c060109f21975c5ac2e8652e60102bd4d196" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "core-foundation-sys", "libc", "ntapi", @@ -15052,7 +15098,7 @@ version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand 2.1.0", "rustix 0.38.31", "windows-sys 0.52.0", @@ -15130,7 +15176,7 @@ version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "once_cell", ] @@ -15657,7 +15703,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "rand 0.8.5", "static_assertions", ] @@ -15998,7 +16044,7 @@ checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525" dependencies = [ "anyhow", "cargo_metadata 0.18.1", - "cfg-if", + "cfg-if 1.0.0", "gix 0.57.1", "regex", "rustc_version", @@ -16191,7 +16237,7 @@ version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -16216,7 +16262,7 @@ version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -16314,7 +16360,7 @@ dependencies = [ "async-trait", "bincode 1.3.3", "bumpalo", - "cfg-if", + "cfg-if 1.0.0", "encoding_rs", "fxprof-processed-profile", "gimli 0.28.1", @@ -16355,7 +16401,7 @@ version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625ee94c72004f3ea0228989c9506596e469517d7d0ed66f7300d1067bdf1ca9" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -16406,7 +16452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b60df0ee08c6a536c765f69e9e8205273435b66d02dd401e938769a2622a6c1a" dependencies = [ "anyhow", - "cfg-if", + "cfg-if 1.0.0", "cranelift-codegen", "cranelift-control", "cranelift-entity", @@ -16457,7 +16503,7 @@ checksum = "f043514a23792761c5765f8ba61a4aa7d67f260c0c37494caabceb41d8ae81de" dependencies = [ "anyhow", "cc", - "cfg-if", + "cfg-if 1.0.0", "rustix 0.38.31", "wasmtime-asm-macros", "wasmtime-versioned-export-macros", @@ -16482,7 +16528,7 @@ version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a9f93a3289057b26dc75eb84d6e60d7694f7d169c7c09597495de6e016a13ff" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "windows-sys 0.52.0", ] @@ -16495,7 +16541,7 @@ checksum = "c6332a2b0af4224c3ea57c857ad39acd2780ccc2b0c99ba1baa01864d90d7c94" dependencies = [ "anyhow", "cc", - "cfg-if", + "cfg-if 1.0.0", "encoding_rs", "indexmap 2.2.5", "libc", @@ -16636,6 +16682,18 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + [[package]] name = "which" version = "4.4.2" @@ -17015,7 +17073,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "windows-sys 0.48.0", ] @@ -17025,7 +17083,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "windows-sys 0.48.0", ] diff --git a/Cargo.toml b/Cargo.toml index 7a7a92fa9148..5a204ecef057 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -290,6 +290,7 @@ parquet = { version = "52", features = ["async"] } paste = "1.0.15" # TODO: let's use native tls instead. poem = { version = "3.0", features = ["openssl-tls", "multipart", "compression"] } +proj4rs = { version = "0.1.3", features = ["geo-types", "crs-definitions"] } prometheus-client = "0.22" prost = { version = "0.12.1" } prost-build = { version = "0.12.1" } diff --git a/src/query/functions/Cargo.toml b/src/query/functions/Cargo.toml index e550dd203076..5195a0f29a11 100644 --- a/src/query/functions/Cargo.toml +++ b/src/query/functions/Cargo.toml @@ -51,6 +51,7 @@ ordered-float = { workspace = true, features = [ "serde", "rand", ] } +proj4rs = { workspace = true } rand = { workspace = true } regex = { workspace = true } roaring = "0.10.1" diff --git a/src/query/functions/src/scalars/geometry.rs b/src/query/functions/src/scalars/geometry.rs index 48d047697b11..e6bc2147b83b 100644 --- a/src/query/functions/src/scalars/geometry.rs +++ b/src/query/functions/src/scalars/geometry.rs @@ -25,6 +25,7 @@ use databend_common_expression::types::VariantType; use databend_common_expression::types::F64; use databend_common_expression::vectorize_with_builder_1_arg; use databend_common_expression::vectorize_with_builder_2_arg; +use databend_common_expression::vectorize_with_builder_3_arg; use databend_common_expression::vectorize_with_builder_4_arg; use databend_common_expression::FunctionDomain; use databend_common_expression::FunctionRegistry; @@ -42,6 +43,9 @@ use geo::EuclideanLength; use geo::HasDimensions; use geo::HaversineDistance; use geo::Point; +use geo::ToDegrees; +use geo::ToRadians; +use geo_types::coord; use geo_types::Polygon; use geohash::decode_bbox; use geohash::encode; @@ -62,6 +66,8 @@ use geozero::ToWkt; use jsonb::parse_value; use jsonb::to_string; use num_traits::AsPrimitive; +use proj4rs::transform::transform; +use proj4rs::Proj; pub fn register(registry: &mut FunctionRegistry) { // aliases @@ -1502,109 +1508,112 @@ pub fn register(registry: &mut FunctionRegistry) { ), ); - // registry.register_passthrough_nullable_2_arg::( - // "st_transform", - // |_, _, _| FunctionDomain::MayThrow, - // vectorize_with_builder_2_arg::( - // |original, srid, builder, ctx| { - // if let Some(validity) = &ctx.validity { - // if !validity.get_bit(builder.len()) { - // builder.commit_row(); - // return; - // } - // } - // - // #[allow(unused_assignments)] - // let mut from_srid = 0; - // - // // All representations of the geo types supported by crates under the GeoRust organization, have not implemented srid(). - // // Currently, the srid() of all types returns the default value `None`, so we need to parse it manually here. - // match read_ewkb_srid(&mut std::io::Cursor::new(original)) { - // Ok(srid) if srid.is_some() => from_srid = srid.unwrap(), - // _ => { - // ctx.set_error( - // builder.len(), - // ErrorCode::GeometryError(" input geometry must has the correct SRID") - // .to_string(), - // ); - // builder.commit_row(); - // return; - // } - // } - // - // let result = { - // Ewkb(original).to_geo().map_err(ErrorCode::from).and_then( - // |mut geom: Geometry| { - // Proj::new_known_crs(&make_crs(from_srid), &make_crs(srid), None) - // .map_err(|e| ErrorCode::GeometryError(e.to_string())) - // .and_then(|proj| { - // geom.transform(&proj) - // .map_err(|e| ErrorCode::GeometryError(e.to_string())) - // .and_then(|_| { - // geom.to_ewkb(geom.dims(), Some(srid)) - // .map_err(ErrorCode::from) - // }) - // }) - // }, - // ) - // }; - // - // match result { - // Ok(data) => { - // builder.put_slice(data.as_slice()); - // } - // Err(e) => { - // ctx.set_error(builder.len(), e.to_string()); - // } - // } - // - // builder.commit_row(); - // }, - // ), - // ); - // - // registry.register_passthrough_nullable_3_arg::( - // "st_transform", - // |_, _, _,_| FunctionDomain::MayThrow, - // vectorize_with_builder_3_arg::( - // |original, from_srid, to_srid, builder, ctx| { - // if let Some(validity) = &ctx.validity { - // if !validity.get_bit(builder.len()) { - // builder.commit_row(); - // return; - // } - // } - // - // let result = { - // Proj::new_known_crs(&make_crs(from_srid), &make_crs(to_srid), None) - // .map_err(|e| ErrorCode::GeometryError(e.to_string())) - // .and_then(|proj| { - // let old = Ewkb(original.to_vec()); - // Ewkb(old.to_ewkb(old.dims(), Some(from_srid)).unwrap()).to_geo().map_err(ErrorCode::from).and_then(|mut geom| { - // geom.transform(&proj).map_err(|e|ErrorCode::GeometryError(e.to_string())).and_then(|_| { - // geom.to_ewkb(old.dims(), Some(to_srid)).map_err(ErrorCode::from) - // }) - // }) - // }) - // }; - // match result { - // Ok(data) => { - // builder.put_slice(data.as_slice()); - // } - // Err(e) => { - // ctx.set_error(builder.len(), e.to_string()); - // } - // } - // - // builder.commit_row(); - // }, - // ), - // ); + registry.register_passthrough_nullable_2_arg::( + "st_transform", + |_, _, _| FunctionDomain::MayThrow, + vectorize_with_builder_2_arg::( + |original, to_srid, builder, ctx| { + if let Some(validity) = &ctx.validity { + if !validity.get_bit(builder.len()) { + builder.commit_row(); + return; + } + } + + // All representations of the geo types supported by crates under the GeoRust organization, have not implemented srid(). + // Currently, the srid() of all types returns the default value `None`, so we need to parse it manually here. + let from_srid = match Ewkb(original).to_geos().unwrap().srid() { + Some(srid) => srid, + _ => { + ctx.set_error( + builder.len(), + ErrorCode::GeometryError("input geometry must has the correct SRID") + .to_string(), + ); + builder.commit_row(); + return; + } + }; + + match st_transform_impl(original, from_srid, to_srid) { + Ok(data) => { + builder.put_slice(data.as_slice()); + } + Err(e) => { + ctx.set_error(builder.len(), e.to_string()); + } + } + + builder.commit_row(); + }, + ), + ); + + registry.register_passthrough_nullable_3_arg::( + "st_transform", + |_, _, _,_| FunctionDomain::MayThrow, + vectorize_with_builder_3_arg::( + |original, from_srid, to_srid, builder, ctx| { + if let Some(validity) = &ctx.validity { + if !validity.get_bit(builder.len()) { + builder.commit_row(); + return; + } + } + + match st_transform_impl(original, from_srid, to_srid) { + Ok(data) => { + builder.put_slice(data.as_slice()); + } + Err(e) => { + ctx.set_error(builder.len(), e.to_string()); + } + } + + builder.commit_row(); + }, + ), + ); } -// fn make_crs(srid: i32) -> String { -// format!("EPSG:{}", srid) -// } +fn st_transform_impl( + original: &[u8], + from_srid: i32, + to_srid: i32, +) -> databend_common_exception::Result> { + let from_proj = Proj::from_epsg_code( + u16::try_from(from_srid).map_err(|_| ErrorCode::GeometryError("invalid from srid"))?, + ) + .map_err(|_| ErrorCode::GeometryError("invalid from srid"))?; + let to_proj = Proj::from_epsg_code( + u16::try_from(to_srid).map_err(|_| ErrorCode::GeometryError("invalid to srid"))?, + ) + .map_err(|_| ErrorCode::GeometryError("invalid to srid"))?; + + let old = Ewkb(original.to_vec()); + Ewkb(old.to_ewkb(old.dims(), Some(from_srid)).unwrap()) + .to_geo() + .map_err(ErrorCode::from) + .and_then(|mut geom| { + // EPSG:4326 WGS84 in proj4rs is in radians, not degrees. + if from_srid == 4326 { + geom.to_radians_in_place(); + } + transform(&from_proj, &to_proj, &mut geom).map_err(|_| { + ErrorCode::GeometryError(format!( + "transform from {} to {} failed", + from_srid, to_srid + )) + })?; + if to_srid == 4326 { + geom.to_degrees_in_place(); + } + let round_geom = round_geometry_coordinates(geom); + round_geom + .to_ewkb(round_geom.dims(), Some(to_srid)) + .map_err(ErrorCode::from) + }) +} #[inline] fn get_shared_srid(geometries: &Vec) -> Result, String> { @@ -1895,3 +1904,121 @@ fn count_points(geom: &geo_types::Geometry) -> usize { geo_types::Geometry::Triangle(_) => 4, } } + +/// The last three decimal places of the f64 type are inconsistent between aarch64 and x86 platforms, +/// causing unit test results to fail. We will only retain six decimal places. +fn round_geometry_coordinates(geom: geo::Geometry) -> geo::Geometry { + fn round_coordinate(coord: f64) -> f64 { + (coord * 1_000_000.0).round() / 1_000_000.0 + } + + match geom { + geo::Geometry::Point(point) => geo::Geometry::Point(Point::new( + round_coordinate(point.x()), + round_coordinate(point.y()), + )), + geo::Geometry::LineString(linestring) => geo::Geometry::LineString( + linestring + .into_iter() + .map(|coord| coord!(x:round_coordinate(coord.x), y:round_coordinate(coord.y))) + .collect(), + ), + geo::Geometry::Polygon(polygon) => { + let outer_ring = polygon.exterior(); + let mut rounded_inner_rings = Vec::new(); + + for inner_ring in polygon.interiors() { + let rounded_coords: Vec> = inner_ring + .into_iter() + .map( + |coord| coord!( x: round_coordinate(coord.x), y: round_coordinate(coord.y)), + ) + .collect(); + rounded_inner_rings.push(LineString(rounded_coords)); + } + + let rounded_polygon = Polygon::new( + LineString( + outer_ring + .into_iter() + .map(|coord| coord!( x:round_coordinate(coord.x), y:round_coordinate(coord.y))) + .collect(), + ), + rounded_inner_rings, + ); + + geo::Geometry::Polygon(rounded_polygon) + } + geo::Geometry::MultiPoint(multipoint) => geo::Geometry::MultiPoint( + multipoint + .into_iter() + .map(|point| Point::new(round_coordinate(point.x()), round_coordinate(point.y()))) + .collect(), + ), + geo::Geometry::MultiLineString(multilinestring) => { + let rounded_lines: Vec> = multilinestring + .into_iter() + .map(|linestring| { + LineString( + linestring + .into_iter() + .map(|coord| coord!(x: round_coordinate(coord.x), y: round_coordinate(coord.y))) + .collect(), + ) + }) + .collect(); + + geo::Geometry::MultiLineString(geo::MultiLineString::new(rounded_lines)) + } + geo::Geometry::MultiPolygon(multipolygon) => { + let rounded_polygons: Vec> = multipolygon + .into_iter() + .map(|polygon| { + let outer_ring = polygon.exterior().into_iter() + .map(|coord| coord!( x:round_coordinate(coord.x), y:round_coordinate(coord.y))) + .collect::>>(); + + let mut rounded_inner_rings = Vec::new(); + for inner_ring in polygon.interiors() { + let rounded_coords: Vec> = inner_ring + .into_iter() + .map(|coord| coord!( x:round_coordinate(coord.x), y: coord.y)) + .collect(); + rounded_inner_rings.push(LineString(rounded_coords)); + } + + Polygon::new(LineString(outer_ring), rounded_inner_rings) + }) + .collect(); + geo::Geometry::MultiPolygon(geo::MultiPolygon::new(rounded_polygons)) + } + geo::Geometry::GeometryCollection(geometrycollection) => geo::Geometry::GeometryCollection( + geometrycollection + .into_iter() + .map(round_geometry_coordinates) + .collect(), + ), + geo::Geometry::Line(line) => geo::Geometry::Line(geo::Line::new( + Point::new( + round_coordinate(line.start.x), + round_coordinate(line.start.y), + ), + Point::new(round_coordinate(line.end.x), round_coordinate(line.end.y)), + )), + geo::Geometry::Rect(rect) => geo::Geometry::Rect(geo::Rect::new( + Point::new( + round_coordinate(rect.min().x), + round_coordinate(rect.min().y), + ), + Point::new( + round_coordinate(rect.max().x), + round_coordinate(rect.max().y), + ), + )), + geo::Geometry::Triangle(triangle) => geo::Geometry::Triangle(geo::Triangle::new( + coord!(x: round_coordinate(triangle.0.x), y: round_coordinate(triangle.0.y)), + coord!(x: round_coordinate(triangle.1.x), y: round_coordinate(triangle.1.y)), + coord!(x: round_coordinate(triangle.2.x), y: round_coordinate(triangle.2.y)), + )), + } +} diff --git a/src/query/functions/tests/it/scalars/geometry.rs b/src/query/functions/tests/it/scalars/geometry.rs index cd64ad365c89..8572dde9e86d 100644 --- a/src/query/functions/tests/it/scalars/geometry.rs +++ b/src/query/functions/tests/it/scalars/geometry.rs @@ -59,7 +59,7 @@ fn test_geometry() { test_st_xmin(file); test_st_ymax(file); test_st_ymin(file); - // test_st_transform(file); + test_st_transform(file); } fn test_haversine(file: &mut impl Write) { @@ -646,36 +646,36 @@ fn test_st_setsrid(file: &mut impl Write) { run_ast(file, "st_setsrid(to_geometry('POINT(13 51)'), 4326)", &[]); } -// fn test_st_transform(file: &mut impl Write) { -// // just to_srid -// run_ast( -// file, -// "st_transform(st_geomfromwkt('POINT(389866.35 5819003.03)', 32633), 3857)", -// &[], -// ); -// -// run_ast(file, "st_transform(st_geomfromwkt(a, b), c)", &[ -// ( -// "a", -// StringType::from_data(vec!["POINT(389866.35 5819003.03)"]), -// ), -// ("b", Int32Type::from_data(vec![32633])), -// ("c", Int32Type::from_data(vec![3857])), -// ]); -// -// // from_srid and to_srid -// run_ast( -// file, -// "st_transform(st_geomfromwkt('POINT(4.500212 52.161170)'), 4326, 28992)", -// &[], -// ); -// -// run_ast(file, "st_transform(st_geomfromwkt(a), b, c)", &[ -// ( -// "a", -// StringType::from_data(vec!["POINT(4.500212 52.161170)"]), -// ), -// ("b", Int32Type::from_data(vec![4326])), -// ("c", Int32Type::from_data(vec![28992])), -// ]); -// } +fn test_st_transform(file: &mut impl Write) { + // just to_srid + run_ast( + file, + "st_transform(st_geomfromwkt('POINT(389866.35 5819003.03)', 32633), 3857)", + &[], + ); + + run_ast(file, "st_transform(st_geomfromwkt(a, b), c)", &[ + ( + "a", + StringType::from_data(vec!["POINT(389866.35 5819003.03)"]), + ), + ("b", Int32Type::from_data(vec![32633])), + ("c", Int32Type::from_data(vec![3857])), + ]); + + // from_srid and to_srid + run_ast( + file, + "st_transform(st_geomfromwkt('POINT(4.500212 52.161170)'), 4326, 28992)", + &[], + ); + + run_ast(file, "st_transform(st_geomfromwkt(a), b, c)", &[ + ( + "a", + StringType::from_data(vec!["POINT(4.500212 52.161170)"]), + ), + ("b", Int32Type::from_data(vec![4326])), + ("c", Int32Type::from_data(vec![28992])), + ]); +} diff --git a/src/query/functions/tests/it/scalars/testdata/function_list.txt b/src/query/functions/tests/it/scalars/testdata/function_list.txt index cf418d948afb..6667a5055a4b 100644 --- a/src/query/functions/tests/it/scalars/testdata/function_list.txt +++ b/src/query/functions/tests/it/scalars/testdata/function_list.txt @@ -3599,6 +3599,10 @@ Functions overloads: 1 st_srid(Geometry NULL) :: Int32 NULL 0 st_startpoint(Geometry) :: Geometry 1 st_startpoint(Geometry NULL) :: Geometry NULL +0 st_transform(Geometry, Int32) :: Geometry +1 st_transform(Geometry NULL, Int32 NULL) :: Geometry NULL +2 st_transform(Geometry, Int32, Int32) :: Geometry +3 st_transform(Geometry NULL, Int32 NULL, Int32 NULL) :: Geometry NULL 0 st_x(Geometry) :: Float64 NULL 1 st_x(Geometry NULL) :: Float64 NULL 0 st_xmax(Geometry) :: Float64 NULL diff --git a/src/query/functions/tests/it/scalars/testdata/geometry.txt b/src/query/functions/tests/it/scalars/testdata/geometry.txt index f21534e60a90..96871e00103a 100644 --- a/src/query/functions/tests/it/scalars/testdata/geometry.txt +++ b/src/query/functions/tests/it/scalars/testdata/geometry.txt @@ -1189,3 +1189,67 @@ output domain : {10..=10} output : 10 +ast : st_transform(st_geomfromwkt('POINT(389866.35 5819003.03)', 32633), 3857) +raw expr : st_transform(st_geomfromwkt('POINT(389866.35 5819003.03)', 32633), 3857) +checked expr : st_transform(st_geometryfromwkt("POINT(389866.35 5819003.03)", to_int32(32633_u16)), to_int32(3857_u16)) +optimized expr : "SRID=3857;POINT(1489140.093766 6892872.19868)" +output type : Geometry +output domain : Undefined +output : 'SRID=3857;POINT(1489140.093766 6892872.19868)' + + +ast : st_transform(st_geomfromwkt(a, b), c) +raw expr : st_transform(st_geomfromwkt(a::String, b::Int32), c::Int32) +checked expr : st_transform(st_geometryfromwkt(a, b), c) +optimized expr : "SRID=3857;POINT(1489140.093766 6892872.19868)" +evaluation: ++--------+-----------------------------------------------------------------+-----------------+---------------+-------------------------------------------------+ +| | a | b | c | Output | ++--------+-----------------------------------------------------------------+-----------------+---------------+-------------------------------------------------+ +| Type | String | Int32 | Int32 | Geometry | +| Domain | {"POINT(389866.35 5819003.03)"..="POINT(389866.35 5819003.03)"} | {32633..=32633} | {3857..=3857} | Undefined | +| Row 0 | 'POINT(389866.35 5819003.03)' | 32633 | 3857 | 'SRID=3857;POINT(1489140.093766 6892872.19868)' | ++--------+-----------------------------------------------------------------+-----------------+---------------+-------------------------------------------------+ +evaluation (internal): ++--------+---------------------------------------------------------------------------------------------------+ +| Column | Data | ++--------+---------------------------------------------------------------------------------------------------+ +| a | StringColumn { data: 0x504f494e54283338393836362e333520353831393030332e303329, offsets: [0, 27] } | +| b | Int32([32633]) | +| c | Int32([3857]) | +| Output | BinaryColumn { data: 0x0101000020110f00006f0c0118f4b83641522cb70c524b5a41, offsets: [0, 25] } | ++--------+---------------------------------------------------------------------------------------------------+ + + +ast : st_transform(st_geomfromwkt('POINT(4.500212 52.161170)'), 4326, 28992) +raw expr : st_transform(st_geomfromwkt('POINT(4.500212 52.161170)'), 4326, 28992) +checked expr : st_transform(st_geometryfromwkt("POINT(4.500212 52.161170)"), to_int32(4326_u16), to_int32(28992_u16)) +optimized expr : "SRID=28992;POINT(94308.670475 464038.168827)" +output type : Geometry +output domain : Undefined +output : 'SRID=28992;POINT(94308.670475 464038.168827)' + + +ast : st_transform(st_geomfromwkt(a), b, c) +raw expr : st_transform(st_geomfromwkt(a::String), b::Int32, c::Int32) +checked expr : st_transform(st_geometryfromwkt(a), b, c) +optimized expr : "SRID=28992;POINT(94308.670475 464038.168827)" +evaluation: ++--------+-------------------------------------------------------------+---------------+-----------------+------------------------------------------------+ +| | a | b | c | Output | ++--------+-------------------------------------------------------------+---------------+-----------------+------------------------------------------------+ +| Type | String | Int32 | Int32 | Geometry | +| Domain | {"POINT(4.500212 52.161170)"..="POINT(4.500212 52.161170)"} | {4326..=4326} | {28992..=28992} | Undefined | +| Row 0 | 'POINT(4.500212 52.161170)' | 4326 | 28992 | 'SRID=28992;POINT(94308.670475 464038.168827)' | ++--------+-------------------------------------------------------------+---------------+-----------------+------------------------------------------------+ +evaluation (internal): ++--------+-----------------------------------------------------------------------------------------------+ +| Column | Data | ++--------+-----------------------------------------------------------------------------------------------+ +| a | StringColumn { data: 0x504f494e5428342e3530303231322035322e31363131373029, offsets: [0, 25] } | +| b | Int32([4326]) | +| c | Int32([28992]) | +| Output | BinaryColumn { data: 0x0101000020407100005dfe43ba4a06f7402ffce0ac98521c41, offsets: [0, 25] } | ++--------+-----------------------------------------------------------------------------------------------+ + + diff --git a/tests/sqllogictests/suites/query/functions/02_0060_function_geometry.test b/tests/sqllogictests/suites/query/functions/02_0060_function_geometry.test index b938e9e300fc..9ee64e8ac500 100644 --- a/tests/sqllogictests/suites/query/functions/02_0060_function_geometry.test +++ b/tests/sqllogictests/suites/query/functions/02_0060_function_geometry.test @@ -91,11 +91,21 @@ SELECT a, to_string(g) FROM t1 1 SRID=32633;POINT(389866.35 5819003.03) 2 SRID=4326;POINT(4.500212 52.16117) -#query T -#SELECT ST_TRANSFORM(g, 3857) AS transformed_geom FROM t1 -#---- -#SRID=3857;POINT(1489140.0937656453 6892872.198680114) -#SRID=3857;POINT(500961.30830177927 6829319.683153116) +query T +SELECT to_string(ST_TRANSFORM(g, 3857)) AS transformed_geom FROM t1 +---- +SRID=3857;POINT(1489140.093766 6892872.19868) +SRID=3857;POINT(500961.308302 6829319.683153) + +query T +SELECT to_string(ST_TRANSFORM(ST_GEOMFROMWKT('POINT(389866.35 5819003.03)', 32633), 32633, 3857)); +---- +SRID=3857;POINT(1489140.093766 6892872.19868) + +query T +SELECT to_string(ST_TRANSFORM(ST_GEOMFROMWKT('POINT(4.500212 52.161170)', 4326), 4326, 3857)); +---- +SRID=3857;POINT(500961.308302 6829319.683153) statement ok DROP TABLE IF EXISTS t1