static bool IsRadiusIsEnough(RTree node, double x, double y, int radius) { double nearestX = x <node.xMin?node.xMin : x> node.xMax ? node.xMax : x; double nearestY = y <node.yMin?node.yMin : x> node.yMax ? node.yMax : y; double xCoef1 = 111 * Math.Cos(y); double xCoef2 = 111 * Math.Cos(nearestY); double yCoef = 111; double xLength = ((nearestX - x) * xCoef1 + (nearestX - x) * xCoef2) / 2; double yLength = (nearestY - y) * yCoef; return(Math.Sqrt(Math.Pow(xLength, 2) + Math.Pow(yLength, 2)) <= radius); }
public static (Entity, double) FindNearestEntityBySubtype(RTree node, double x, double y, string subtype) { int radius = 10; List <Entity> entities = FindNearestEntities(node, x, y, radius, "all", subtype); while ((entities == null || entities.Count == 0) && radius < 1000) { radius *= 2; entities = FindNearestEntities(node, x, y, radius, "all", subtype); } if (entities == null) { return(null, -1); } return(FindNearestOfTheList(entities, x, y)); }
public static void FillRTree(ref RTree tree, string filename) { using (StreamReader sr = new(filename)) { for (int ctr = 0; !sr.EndOfStream; ctr++) { string str = sr.ReadLine(); if (str == null) { continue; } try { string[] items = str.Split(";"); if (items.Length < 6) { continue; } tree.Add(new Entity(double.Parse(items[0]), double.Parse(items[1]), items[2], items[3], items[4], items[5])); } catch (IndexOutOfRangeException) { Console.WriteLine($"Oops, damaged line {ctr} in file... Let`s skip it!"); } } } }
static void Main(string[] args) { long starttime = DateTime.Now.Ticks; string filename; double latitude = 0, longitude = 0; int radius = 0; string type, subtype; if (args.Length == 0) { Console.WriteLine("Enter args please:"); args = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); } if (args.Length < 4) { Console.WriteLine("Too few arguments!"); Environment.Exit(1); } filename = args[0]; if (!System.IO.File.Exists(filename)) { Console.WriteLine("Such file doesn't exist!"); Environment.Exit(1); } try { latitude = double.Parse(args[1]); longitude = double.Parse(args[2]); radius = int.Parse(args[3]); } catch (FormatException ex) { Console.WriteLine(ex.Message); Console.WriteLine("Incorrect input!"); Environment.Exit(2); } if (args.Length == 6) { type = args[4]; subtype = args[5]; } else if (args.Length == 5) { type = args[4]; subtype = "all"; } else { type = "all"; subtype = "all"; } RTree tree = RTreeFactory.FillRTree(filename); long searchtime, buildtime = DateTime.Now.Ticks; if (type == "find") { Entity nearestEntity; double distance; (nearestEntity, distance) = TreeProcessing.FindNearestEntityBySubtype(tree, longitude, latitude, subtype); searchtime = DateTime.Now.Ticks; if (nearestEntity != null) { Console.WriteLine($"We dound nearest entity of {subtype} subtype:"); Console.WriteLine($"(longitude: {nearestEntity.X}, latitude: {nearestEntity.Y}) - {distance * 1000}m"); } else { Console.WriteLine("We didn't found entites of this subtype in nearest 1000 km!"); } } else { List <Entity> nearest = TreeProcessing.FindNearestEntities(tree, longitude, latitude, radius, type, subtype); searchtime = DateTime.Now.Ticks; EntitiesOutput(nearest); } Console.WriteLine($"Tree build time: {new TimeSpan(buildtime-starttime).TotalSeconds} seconds.\n Search time: {new TimeSpan(searchtime-buildtime).TotalSeconds} seconds"); }