/// <summary> /// Генерує сітку /// </summary> public static List <double[]> generateGrid( double cellSize, out int outColumns, out int outRows, double coLatitudeBound = 0, double coLatitudeBound2 = 180, double LongitudeBoundW = 0, double LongitudeBoundE = 360, AngleType resType = AngleType.Radians ) { if (coLatitudeBound > 90 || coLatitudeBound < 0) { throw new Exception("coLatitudeBound повинна бути: 0 <= coLatitude <= 90"); } if (LongitudeBoundW >= 360 || LongitudeBoundW < 0 || LongitudeBoundE > 360 || LongitudeBoundE <= 0) { throw new Exception("LongitudeBounds must be 0<=LongitudeBound<360"); } if (LongitudeBoundW > LongitudeBoundE) { throw new Exception("West longituge bound повинна бути менша за East longituge"); } double gridRows = (180 - coLatitudeBound - (180 - coLatitudeBound2)) / cellSize; double gridColumns = (360 - LongitudeBoundW - (360 - LongitudeBoundE)) / cellSize; int addRow = 0, addCol = 0; if ((Math.Round(gridRows) - gridRows) < 0) { addRow = 1; } if ((Math.Round(gridColumns) - gridColumns) < 0) { addCol = 1; } gridColumns = (int)gridColumns + addCol; outColumns = (int)gridColumns; gridRows = (int)gridRows + addRow; outRows = (int)gridRows; int gridCells = (int)(gridColumns * gridRows); List <double[]> greed = new List <double[]>(gridCells); double coLatitudeStart = coLatitudeBound + (cellSize / 2D); double LongStart = deg2rad(LongitudeBoundW); #region ifRadians if (resType == AngleType.Radians) { MathFunc.deg2rad(ref cellSize); MathFunc.deg2rad(ref coLatitudeStart); } #endregion for (int r = 0; r < gridRows; r++) { for (int c = 0; c < gridColumns; c++) { greed.Add(new double[] { coLatitudeStart + r * cellSize, LongStart + cellSize * (0.5 + c) }); } } return(greed); }
//Зчитування даних з файлу .SGG public static double[][] read_SGG_data(string folder, MainForm.setProgressDel d) { System.IO.FileInfo fi = new FileInfo(folder); folder = fi.DirectoryName; List <string> files = new List <string>(); foreach (var file in System.IO.Directory.GetFiles(folder)) { var f = new FileInfo(file); if (f.Extension.Equals(".SGG", System.StringComparison.CurrentCultureIgnoreCase)) { files.Add(file); } ; } List <double[]> myList = new List <double[]>(getLines(files[0])); if (files.Count > 0) { foreach (string filename in files) { string[] lines = System.IO.File.ReadAllLines(filename); var x = Parallel.For(0, lines.Length, (i) => { double[] temp = null; double lat = 0; int l = 0; string[] line = null; lock (lines) { line = lines[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); } if (line.Length > 20) { lat = double.Parse(line[3]); //if (lat < 0) lat += 360; lat = MathFunc.deg2rad(lat); temp = new double[] { double.Parse(line[1]), MathFunc.deg2rad(90 - double.Parse(line[2])), lat, double.Parse(line[6]) }; if (Math.Abs(temp[1]) < Math.PI && Math.Abs(temp[2]) < 2D * Math.PI) { lock (myList) { myList.Add(temp); } } else { System.Windows.Forms.MessageBox.Show("Помилка в лінії номер " + i.ToString()); } l++; if (Math.Round(l / 20000D) == (double)l / 20000D) { d.Invoke(l / lines.Length, 1, "Обробка файлу вимірюваннь"); } ; } }); } } ; return(myList.ToArray()); }
/// <summary> /// Визначає, до якої клітинки сітки відноситься кожен результат. Кожен елемент List() відповідає елементу Greed, і є масивом номерів точок з pointsData /// </summary> /// <param name="rs">Референсна система</param> /// <param name="pointsData">Масив точок типу: {radius,coLatitude,Longitude,Gradient}</param> /// <param name="greed">Масив з клітинками сітки типу: {{colat,long},{colat,long},{colat,long}...}</param> /// <param name="rowCount">Кількість рядків сітки</param> /// <param name="colsCount">Кількість стовпчиків сітки</param> /// <returns>Повертає масив з номерами точок з масиву pointsData</returns> public static List <int>[] getMappingOfPoints(ReferenceSystem rs, double[][] pointsData, double[][] greed, int rowCount, int colsCount, double avgRadius) { List <int>[] map = new List <int> [greed.Length]; for (int i = 0; i < map.Length; i++) { map[i] = new List <int>(); } double cellSize = MathFunc.deg2rad(rs.gridParameters.cellSize); double zero = greed[0][0] - cellSize / 2D; double l_zero = greed[0][1] - cellSize / 2d; Parallel.For(0, pointsData.Length, (i) => { double fi, lambda, r; lock (pointsData) { fi = pointsData[i][1]; lambda = pointsData[i][2]; r = pointsData[i][0]; } if (fi >= greed[0][0] && fi <= greed[greed.Length - 1][0] && lambda >= greed[0][1] && lambda <= greed[greed.Length - 1][1] && Math.Abs(r - avgRadius) < 10000d) { fi = fi - (zero); lambda = lambda - l_zero; int n = (int)Math.Floor(fi / cellSize); int m = (int)Math.Floor(lambda / cellSize); int index = (colsCount * n) + m; lock (map) { var x1 = cellSize / 2D - Math.Abs(greed[index][0] - zero - fi); var x2 = cellSize / 2D - Math.Abs(greed[index][1] - l_zero - lambda); if (x1 < 0 || x2 < 0) { System.Windows.Forms.MessageBox.Show("getMappingOfPoints: неправильна визначена клітинка точки " + i.ToString()); } else { map[index].Add(i); } } } ; }); return(map); }
/// <summary> /// Обчислення градієнту V_zz для заданих координат по моделі "in_model" /// </summary> public static double getGradient(ReferenceSystem rs, GravityModel in_model, double coLat, double longit, MathFunc.AngleType angType = MathFunc.AngleType.Radians) { GravityModel gm; if (in_model.model_a != rs.a || in_model.model_GM != rs.GM) { gm = in_model.rescaleModel(rs); } else { gm = new GravityModel(in_model); }; if (angType == MathFunc.AngleType.Degrees) { MathFunc.deg2rad(ref longit); } double grad = 0; double tmp = 0, sum_tmp = 0, sum_tmp_2 = 0; double[] legendrePolynoms = null; MathFunc.getLegendre(rs.maxDegree, coLat, out legendrePolynoms, angType); for (int i = 0; i <= rs.maxDegree; i++) { int n = MathFunc.getArraySize(i - 1) - 1; sum_tmp_2 = 0; sum_tmp = (i + 1) * (i + 2) * Math.Pow(rs.a / rs.satelliteSphere, i + 3); for (int m = 0; m < gm.c_coef[i].Length; m++) { double a1 = legendrePolynoms[n + m + 1], a2 = gm.c_coef[i][m] * Math.Cos(m * longit), a3 = gm.s_coef[i][m] * Math.Sin(m * longit); double x = a1 * (a2 + a3); sum_tmp_2 += x; } tmp += sum_tmp * sum_tmp_2; } grad = rs.GM / Math.Pow(rs.a, 3D) * tmp; return(grad); }