Экранные координаты в мировые - 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;
        }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.214 из 5
Похожие ответы