/// <summary> /// Расчет растояния между данной и точкой назначения /// </summary> /// <param name="dest_node">Координаты назначения</param> /// <param name="sour_node">Координаты источника</param> /// <returns>Возвращает длину в метрах</returns> static private double calculationCost(GrafNodeParam dest_node, GrafNodeParam sour_node) { double return_value; double sin_delt_Longitude = Math.Sin(dest_node.coord_Longitude_radian - sour_node.coord_Longitude_radian); double cos_delt_Longitude = Math.Cos(dest_node.coord_Longitude_radian - sour_node.coord_Longitude_radian); double y = Math.Sqrt(Math.Pow(dest_node.cos_coord_Latitude_radian * sin_delt_Longitude, 2) + Math.Pow(sour_node.cos_coord_Latitude_radian * dest_node.sin_coord_Latitude_radian - sour_node.sin_coord_Latitude_radian * dest_node.cos_coord_Latitude_radian * cos_delt_Longitude, 2)); double x = sour_node.sin_coord_Latitude_radian * dest_node.sin_coord_Latitude_radian + sour_node.cos_coord_Latitude_radian * dest_node.cos_coord_Latitude_radian * cos_delt_Longitude; return_value = Math.Atan2(y, x) * 6372795; return(return_value); }
/// <summary> /// Расчитывает растояния до смежных вершин /// </summary> /// <param name="GNFtemp">Файл приближенный к формату GNF</param> /// <param name="GNF">Файл вывода</param> public static void setDistansInFile(string GNFtemp, string GNF, char dataseparator = '/') { Dictionary <long, GrafNodeParam> node_param = new Dictionary <long, GrafNodeParam>(); Dictionary <long, long[]> node_neighbors = new Dictionary <long, long[]>(); using (StreamReader read = new StreamReader(GNFtemp)) { while (!read.EndOfStream) { string temp = read.ReadLine(); if (temp.Contains("<node>")) { temp = read.ReadLine(); long index = Convert.ToInt64(temp.Split(new char[] { '>' }, StringSplitOptions.RemoveEmptyEntries)[1].Split(new char[] { '<' }, StringSplitOptions.RemoveEmptyEntries)[0]); temp = read.ReadLine(); string[] param_string = temp.Split(new char[] { '>' }, StringSplitOptions.RemoveEmptyEntries)[1].Split(new char[] { '<' }, StringSplitOptions.RemoveEmptyEntries)[0].Split(';'); for (int i = 0; i < param_string.Length; i++) { param_string[i] = param_string[i].Replace('.', ','); } GrafNodeParam param = new GrafNodeParam(Convert.ToDouble(param_string[0]), Convert.ToDouble(param_string[1]), 1); temp = read.ReadLine(); string[] param_string_next = temp.Split(new char[] { '>' }, StringSplitOptions.RemoveEmptyEntries)[1].Split(new char[] { '<' }, StringSplitOptions.RemoveEmptyEntries)[0].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); List <long> temp_neighbors = new List <long>(); for (int i = 0; i < param_string_next.Length; i++) { long temp_index_neig = Convert.ToInt64(param_string_next[i]); if (!temp_neighbors.Contains(temp_index_neig)) { temp_neighbors.Add(temp_index_neig); } } long[] neighbors = new long[temp_neighbors.Count]; temp_neighbors.CopyTo(neighbors); if (!node_param.ContainsKey(index)) { node_param.Add(index, param); node_neighbors.Add(index, neighbors); } } } } Console.WriteLine("Вершины загруженны"); using (StreamWriter write = new StreamWriter(GNF)) { foreach (var item in node_neighbors) { string data = "<node v=\""; data += item.Key + "" + dataseparator; for (int i = 0; i < item.Value.Length; i++) { if (node_param.ContainsKey(item.Value[i])) { data += item.Value[i] + ";"; } } data = data.Remove(data.Length - 1) + dataseparator; for (int i = 0; i < item.Value.Length; i++) { if (node_param.ContainsKey(item.Value[i])) { data += calculationCost(node_param[item.Key], node_param[item.Value[i]]) + ";"; } } data = data.Remove(data.Length - 1) + dataseparator; data += node_param[item.Key].latittude + ";" + node_param[item.Key].longitude + ";1\"/>"; if (data.Contains(";0;")) { data.Replace(";0;", ";0,0000;"); } if (data.Contains("/0;")) { data.Replace("/0;", "/0,0000;"); } write.WriteLine(data); } } Console.WriteLine("Файл " + GNF + " успешно заполнен"); }