Try to evaluate a geo/spatial function. Returns `Some(result)` if the function name matched, `None` if unrecognized (caller falls through).
(name: &str, args: &[Value])
| 11 | /// Try to evaluate a geo/spatial function. Returns `Some(result)` if the |
| 12 | /// function name matched, `None` if unrecognized (caller falls through). |
| 13 | pub fn eval_geo_function(name: &str, args: &[Value]) -> Option<Value> { |
| 14 | let result = match name { |
| 15 | "geo_distance" | "haversine_distance" => { |
| 16 | let lng1 = num_arg(args, 0).unwrap_or(0.0); |
| 17 | let lat1 = num_arg(args, 1).unwrap_or(0.0); |
| 18 | let lng2 = num_arg(args, 2).unwrap_or(0.0); |
| 19 | let lat2 = num_arg(args, 3).unwrap_or(0.0); |
| 20 | to_value_number(nodedb_types::geometry::haversine_distance( |
| 21 | lng1, lat1, lng2, lat2, |
| 22 | )) |
| 23 | } |
| 24 | "geo_bearing" | "haversine_bearing" => { |
| 25 | let lng1 = num_arg(args, 0).unwrap_or(0.0); |
| 26 | let lat1 = num_arg(args, 1).unwrap_or(0.0); |
| 27 | let lng2 = num_arg(args, 2).unwrap_or(0.0); |
| 28 | let lat2 = num_arg(args, 3).unwrap_or(0.0); |
| 29 | to_value_number(nodedb_types::geometry::haversine_bearing( |
| 30 | lng1, lat1, lng2, lat2, |
| 31 | )) |
| 32 | } |
| 33 | "geo_point" | "st_point" => { |
| 34 | let lng = num_arg(args, 0).unwrap_or(0.0); |
| 35 | let lat = num_arg(args, 1).unwrap_or(0.0); |
| 36 | Value::Geometry(nodedb_types::geometry::Geometry::point(lng, lat)) |
| 37 | } |
| 38 | "geo_geohash" => { |
| 39 | let lng = num_arg(args, 0).unwrap_or(0.0); |
| 40 | let lat = num_arg(args, 1).unwrap_or(0.0); |
| 41 | let precision = num_arg(args, 2).unwrap_or(6.0) as u8; |
| 42 | Value::String(nodedb_spatial::geohash_encode(lng, lat, precision)) |
| 43 | } |
| 44 | "geo_geohash_decode" => { |
| 45 | let hash = str_arg(args, 0).unwrap_or_default(); |
| 46 | match nodedb_spatial::geohash_decode(&hash) { |
| 47 | Some(bb) => { |
| 48 | let mut map = std::collections::HashMap::new(); |
| 49 | map.insert("min_lng".to_string(), Value::Float(bb.min_lng)); |
| 50 | map.insert("min_lat".to_string(), Value::Float(bb.min_lat)); |
| 51 | map.insert("max_lng".to_string(), Value::Float(bb.max_lng)); |
| 52 | map.insert("max_lat".to_string(), Value::Float(bb.max_lat)); |
| 53 | Value::Object(map) |
| 54 | } |
| 55 | None => Value::Null, |
| 56 | } |
| 57 | } |
| 58 | "geo_geohash_neighbors" => { |
| 59 | let hash = str_arg(args, 0).unwrap_or_default(); |
| 60 | let neighbors = nodedb_spatial::geohash_neighbors(&hash); |
| 61 | let arr: Vec<Value> = neighbors |
| 62 | .into_iter() |
| 63 | .map(|(dir, h)| { |
| 64 | let mut map = std::collections::HashMap::new(); |
| 65 | map.insert("direction".to_string(), Value::String(format!("{dir:?}"))); |
| 66 | map.insert("hash".to_string(), Value::String(h)); |
| 67 | Value::Object(map) |
| 68 | }) |
| 69 | .collect(); |
| 70 | Value::Array(arr) |
no test coverage detected