1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
use log::warn; use geo_types; use crate::{features, nominatim, operations}; #[derive(Debug, Clone)] pub enum Location { Coordinates { latitude: f64, longitude: f64 }, Center } #[derive(Debug, Clone)] pub struct OSMGeoMapper { pub data_structure: features::GeoTilesDataStructure, pub coordinates: geo_types::Coordinate<i32>, pub radius: u32 } impl OSMGeoMapper { pub fn from_geojson_file_with_radius(geojson_file: String, radius: u32, location: Option<Location>) -> Result<OSMGeoMapper, Box<dyn std::error::Error>> { let geojson = operations::parse_geojson_file(&geojson_file); let data_structure = operations::process_geojson(&geojson); let coordinates = match location { Some(Location::Coordinates { latitude, longitude }) => { geo_types::Coordinate { x: operations::to_tile_scale(longitude), y: operations::to_tile_scale(latitude) } }, Some(Location::Center) => { warn!("Finding center location of geojson file not supported yet"); geo_types::Coordinate { x: 0, y: 0 } }, None => geo_types::Coordinate { x: 0, y: 0 } }; Ok(OSMGeoMapper { data_structure, coordinates, radius }) } pub fn from_geojson_file(geojson_file: String, location: Option<Location>) -> Result<OSMGeoMapper, Box<dyn std::error::Error>> { OSMGeoMapper::from_geojson_file_with_radius(geojson_file, 0, location) } pub fn from_address(address: String, radius: Option<u32>) -> Result<OSMGeoMapper, Box<dyn std::error::Error>> { let (latitude, longitude) = nominatim::get_address_lat_lon(address)?; OSMGeoMapper::from_lat_lon(latitude, longitude, radius) } pub fn from_lat_lon(latitude: f64, longitude: f64, radius: Option<u32>) -> Result<OSMGeoMapper, Box<dyn std::error::Error>> { let rad = radius.unwrap_or(200); let radiusf = operations::from_tile_scale(rad as i32); let geojson_file = operations::get_geojson_file_by_lat_lon(latitude, longitude, radiusf)?; OSMGeoMapper::from_geojson_file_with_radius( geojson_file, rad, Some( Location::Coordinates { latitude, longitude } ) ) } pub fn load_more_from_lat_lon(&mut self, latitude: f64, longitude: f64, radius: Option<u32>) -> Result<(), Box<dyn std::error::Error>> { let radiusf = operations::from_tile_scale(radius.unwrap_or(200) as i32); let geojson_file = operations::get_geojson_file_by_lat_lon(latitude, longitude, radiusf)?; let geojson = operations::parse_geojson_file(&geojson_file.to_string()); operations::process_geojson_with_data_structure(&geojson, self.data_structure.clone()); Ok(()) } pub fn load_more_from_address(&mut self, address: String, radius: Option<u32>) -> Result<(), Box<dyn std::error::Error>> { let (latitude, longitude) = nominatim::get_address_lat_lon(address)?; self.load_more_from_lat_lon(latitude, longitude, radius) } pub fn load_more_from_geojson_file(&mut self, geojson_file: String) -> Result<(), Box<dyn std::error::Error>> { let geojson = operations::parse_geojson_file(&geojson_file.to_string()); operations::process_geojson_with_data_structure(&geojson, self.data_structure.clone()); Ok(()) } pub fn get(&self, lat: i32, lon: i32) -> Option<features::GeoTile> { let locked_data_structure = self.data_structure.read().unwrap(); let option_arc_geo_tile = locked_data_structure.get(&geo_types::Coordinate { x: lon, y: lat }); if let Some(arc_geo_tile) = option_arc_geo_tile { Some(arc_geo_tile.as_ref().clone()) } else { None } } pub fn get_real(&self, lat: f64, lon: f64) -> Option<features::GeoTile> { let lat = operations::to_tile_scale(lat); let lon = operations::to_tile_scale(lon); self.get(lat, lon) } pub fn atomic_clone(&self) -> OSMGeoMapper { OSMGeoMapper { data_structure: self.data_structure.clone(), coordinates: self.coordinates, radius: self.radius, } } }