Экранные координаты в мировые - C#
Формулировка задачи:
Ребят всем доброго времени суток, подскажите как перевести координаты курсора т.е. (X и Y) в долготу и широту мировую куда копать что почитать? Может кто то делал и поделится. Я понимаю что нужно установить начальную точку в виде долготы и широты и от нее уже считать, только как считать не могу найти полезного ресурса что б изучить данный вопрос.
Всем спасибо!
Решение задачи: «Экранные координаты в мировые»
textual
Листинг программы
public class ClassGeoTransform : IClassGeoTransform { private const double M_PI = 3.14159265358979323846; private const double M_PI_2 = M_PI / 2.0; private const double D_R = (M_PI / 180.0); private const double R_D = (180.0 / M_PI); private const double R_MAJOR = 6378137.0; private const double R_MINOR = 6356752.3142; private static double R_MAJOR_POW_2 = System.Math.Pow(R_MAJOR, 2); private static double R_MINOR_POW_2 = System.Math.Pow(R_MINOR, 2); private const double RATIO = (R_MINOR / R_MAJOR); private static double ECCENT = (System.Math.Sqrt(1.0 - (RATIO * RATIO))); private double COM = (0.5 * ECCENT); //private const double SPHERICAL_A = 6378137; //private const double EQUATOR_R = 6378245.0; // Радиус по экватору //private const double MERIDIAN_R = 6356863.0; // Радиус по меридиану //#define min(a, b) (a <= b ? a : b) //#define max(a, b) (a >= b ? a : b) // Проекция Меркатора public ClassPointD MercatorTransform(double longitude, double latitude) { //auto lat = min(89.5, max(latitude, -89.5)); double lat = (89.5 <= ((latitude >= -89.5) ? latitude : -89.5)) ? 89.5 : ((latitude >= -89.5) ? latitude : -89.5); double phi = lat * D_R; double sin_phi = System.Math.Sin(phi); double con = ECCENT * sin_phi; con = System.Math.Pow((1.0 - con) / (1.0 + con), COM); double ts = System.Math.Tan(0.5 * (M_PI * 0.5 - phi)) / con; double y = 0 - R_MAJOR * System.Math.Log(ts); double x = R_MAJOR * longitude * D_R; return new ClassPointD(x, y); } // Преобразование коодинат из одной системы в другую с учетом поворота public ClassPointD VectorTransform(double csys1_ax1, double csys1_ay1, double csys1_ax2, double csys1_ay2, double csys1_bx2, double csys1_by2, double csys2_ax1, double csys2_ay1, double csys2_ax2, double csys2_ay2) { double ax = csys1_ax2 - csys1_ax1; double ay = csys1_ay2 - csys1_ay1; double cx = ay; double cy = -ax; double csys2_ax = csys2_ax2 - csys2_ax1; double csys2_ay = csys2_ay2 - csys2_ay1; // Знаки выставлены наоборот по сравнению с географическими координатами, т.к. оси OY расположена в противоположную сторону double csys2_cx = -csys2_ay; double csys2_cy = csys2_ax; double a_len_2 = ax * ax + ay * ay; double bx = csys1_bx2 - csys1_ax1; double by = csys1_by2 - csys1_ay1; double d = (ax * bx + ay * by) / a_len_2; double f = (cx * bx + cy * by) / a_len_2; return new ClassPointD(csys2_ax * d + csys2_cx * f + csys2_ax1, csys2_ay * d + csys2_cy * f + csys2_ay1); } // Обратная проекция Меркатора public ClassPointD RevertMercatorTransform(double x, double y) { double ts = System.Math.Exp(-y / R_MAJOR); double phi = M_PI_2 - 2.0 * System.Math.Atan(ts); double dphi = 1.0; for (int i = 0; System.Math.Abs(dphi) > 0.000000001 && i < 15; i++) { double con = ECCENT * System.Math.Sin(phi); dphi = M_PI_2 - 2 * System.Math.Atan(ts * System.Math.Pow((1.0 - con) / (1.0 + con), COM)) - phi; phi += dphi; } double latitude = phi * R_D; double longitude = x * R_D / R_MAJOR; return new ClassPointD(longitude, latitude); } // Пресчёт гео в относительные public ClassPointD GeoToRelative(double geo_coords_x, double geo_coords_y, anhorsPoins anh_points) { if (anh_points._Anchor_Longitude_1 == 0.0 || anh_points._Anchor_Latitude_1 == 0.0 || anh_points._Anchor_Longitude_2 == 0.0 || anh_points._Anchor_Latitude_2 == 0.0) return new ClassPointD(0.0, 0.0); if (anh_points._Anchor_X_1 == 0.0 || anh_points._Anchor_Y_1 == 0.0 || anh_points._Anchor_X_2 == 0.0 || anh_points._Anchor_Y_2 == 0.0) return new ClassPointD(0.0, 0.0); ClassPointD a1 = MercatorTransform(anh_points._Anchor_Longitude_1, anh_points._Anchor_Latitude_1); ClassPointD a2 = MercatorTransform(anh_points._Anchor_Longitude_2, anh_points._Anchor_Latitude_2); ClassPointD b2 = MercatorTransform(geo_coords_x, geo_coords_y); ClassPointD res = VectorTransform(a1._X, a1._Y, a2._X, a2._Y, b2._X, b2._Y, anh_points._Anchor_X_1, anh_points._Anchor_Y_1, anh_points._Anchor_X_2, anh_points._Anchor_Y_2); return res; } // Растояние между двумя точками public static ClassPointD GetDistanceBetweenTwoPoint(double longitude1, double latitude1, double longitude2, double latitude2) { if (longitude1 == 0.0 || latitude1 == 0.0 || longitude2 == 0.0 || latitude2 == 0.0) return null; //Вычисляем угол с учетом радиусов элипсоида double angle_1 = System.Math.Atan((R_MINOR_POW_2 / R_MAJOR_POW_2) * System.Math.Tan(M_PI / 180 * latitude1)); double angle_2 = System.Math.Atan((R_MINOR_POW_2 / R_MAJOR_POW_2) * System.Math.Tan(M_PI / 180 * latitude2)); //radius of small circle (radius between meridians) double point_radius1 = (1 / System.Math.Sqrt((System.Math.Pow(System.Math.Cos(angle_1), 2) / R_MAJOR_POW_2) + (System.Math.Pow(System.Math.Sin(angle_1), 2) / R_MINOR_POW_2))); //+ высота точки; double point_radius2 = (1 / System.Math.Sqrt((System.Math.Pow(System.Math.Cos(angle_2), 2) / R_MAJOR_POW_2) + (System.Math.Pow(System.Math.Sin(angle_2), 2) / R_MINOR_POW_2))); //+ высота точки; double earth_point_1_x = point_radius1 * System.Math.Cos(angle_1); double earth_point_1_y = point_radius1 * System.Math.Sin(angle_1); double earth_point_2_x = point_radius2 * System.Math.Cos(angle_2); double earth_point_2_y = point_radius2 * System.Math.Sin(angle_2); double x = System.Math.Sqrt(System.Math.Pow((earth_point_1_x - earth_point_2_x), 2) + System.Math.Pow((earth_point_1_y - earth_point_2_y), 2)); double y = M_PI * ((earth_point_1_x + earth_point_2_x) / 360) * (longitude1 - longitude2); return new ClassPointD(x, y); } // Относительные координаты в гео public ClassPointD RelativeToGeo(anhorsPoins anh_points, double X_rel, double Y_rel) { ClassPointD a1 = MercatorTransform(anh_points._Anchor_Longitude_1, anh_points._Anchor_Latitude_1); ClassPointD a2 = MercatorTransform(anh_points._Anchor_Longitude_2, anh_points._Anchor_Latitude_2); ClassPointD metric_coords = VectorTransform(anh_points._Anchor_X_1, anh_points._Anchor_Y_1, anh_points._Anchor_X_2, anh_points._Anchor_Y_2, X_rel, Y_rel, a1._X, a1._Y, a2._X, a2._Y); ClassPointD res = RevertMercatorTransform(metric_coords._X, metric_coords._Y); return new ClassPointD(res._X, res._Y); } // Угол между точками public int GetAngelTwoPoint(double longitude1, double latitude1, double longitude2, double latitude2) { // Результат int angel_res = 0; bool chetvertUP; bool chetvertRIGHT; // Точки ClassPointD p_1 = new ClassPointD(longitude1, latitude1); // точка старта ClassPointD p_2 = new ClassPointD(longitude2, latitude2); // текущая точка ClassPointD range = ClassGeoTransform.GetDistanceBetweenTwoPoint(p_1._X, p_1._Y, p_2._X, p_2._Y); // Длины сторон треугольника double distance = (Math.Sqrt(Math.Pow(range._X, 2) + Math.Pow(range._Y, 2))); double distanceX = range._X; double distanceY = range._Y; // Найдём углы треугольник const int angel_distanceX_distanceY_GRAD = 90; int angel_distance_distanceX_GRAD = (int)((double)angel_distanceX_distanceY_GRAD * distanceX / distance); int angel_distance_distanceY_GRAD = 180 - angel_distanceX_distanceY_GRAD - angel_distance_distanceX_GRAD; // Определим в какой мы четверти if ((p_1._Y - p_2._Y) <= 0) chetvertUP = true; else chetvertUP = false; if ((p_1._X - p_2._X) <= 0) chetvertRIGHT = true; else chetvertRIGHT = false; // if (chetvertUP && chetvertRIGHT) angel_res = angel_distance_distanceX_GRAD + angel_distanceX_distanceY_GRAD; else if (!chetvertUP && chetvertRIGHT) angel_res = angel_distance_distanceY_GRAD; else if (!chetvertUP && !chetvertRIGHT) angel_res = 270 + angel_distance_distanceX_GRAD; else if (chetvertUP && !chetvertRIGHT) angel_res = 180 + angel_distance_distanceY_GRAD; return angel_res; } // Расчет удаления от точки старта public int GetRangeTwoPoint(double longitude1, double latitude1, double longitude2, double latitude2) { int distance; ClassPointD p_1 = new ClassPointD(longitude1, latitude1); ClassPointD p_2 = new ClassPointD(longitude2, latitude2); ClassPointD range = ClassGeoTransform.GetDistanceBetweenTwoPoint(p_1._X, p_1._Y, p_2._X, p_2._Y); if (range != null) distance = (int)(Math.Sqrt(Math.Pow(range._X, 2) + Math.Pow(range._Y, 2))); else distance = 0; return distance; } } public class ClassPointD { public double _X; public double _Y; public ClassPointD() { _X = 0; _Y = 0; } public ClassPointD(double x, double y) { _X = x; _Y = y; } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д