Tọa độ Kinh vỹ trong HYPACK
Ứng dụng Tạo khung bản đồ của AJS hỗ trợ hệ tọa độ trong HYPACK, VN2000 và WGS-84
Liên hệ hotline: 0382.77.44.57 để biết thêm chi tiết...
1 Thêm class AJS_Mercator.lsp
Lưu mã sau dưới dạng tệp tin AJS_Mercator.cs
Code:
using Autodesk.AutoCAD.Geometry;
using lhBasic;
using System;
using System.Windows.Forms;
namespace TKBD
{
    internal static class Mercator
    {
        private const double A = 6378137.0; // Semi-major axis
        private const double F = 1.0 / 298.257223563; // Flattening
        private const double B = A * (1 - F); // Semi-minor axis
        private const double E_SQUARED = F * (2.0 - F); // First eccentricity squared
        private static double E = Math.Sqrt(E_SQUARED); // First eccentricity
        public static Point3d MercatorToWGSLatLong(this Point3d from_lat_long, bool rbXYtoBL, string txtFalseEasting = "500000.0", string txtScaleFactor = "1.0")
        {
            var txtCenterMeridian = lhBasic.Regs.Get(Defs.kpath, "OverwrideNaturalLong", 106.0);
            var standardParallel = lhBasic.Regs.Get(Defs.kpath, "OverwrideNaturalLat", 16.0);
            double lambda0, fe, k0Input;
            try
            {
                lambda0 = txtCenterMeridian;
                fe = double.Parse(txtFalseEasting);
                k0Input = double.Parse(txtScaleFactor);
                //k0Input = 0.9999;
                if (standardParallel < -90 || standardParallel > 90)
                {
                    MessageBox.Show("Standard parallel must be between -90 and 90 degrees.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return Point3d.Origin;
                }
            }
            catch (FormatException)
            {
                MessageBox.Show("Parameters must be valid numbers. Check 'Center Meridian', 'False Easting', 'Scale Factor', and 'Standard Parallel'.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return Point3d.Origin;
            }
            if (k0Input <= 0) k0Input = 0;
            string mode = rbXYtoBL ? "xy2bl" : "bl2xy";
            double lambda0Rad = lambda0.ToRadian();
            double k0Effective;
            bool standardParallelHasval = true;
            if (standardParallelHasval)
            {
                double standardParallelRad = standardParallel.ToRadian();
                double sinStandardParallel = Math.Sin(standardParallelRad);
                k0Effective = k0Input * Math.Cos(standardParallelRad) / Math.Sqrt(1 - E_SQUARED * sinStandardParallel * sinStandardParallel);
            }
            else
            {
                k0Effective = k0Input;
            }
            if (k0Effective <= 0)
            {
                MessageBox.Show("Effective scale factor (k₀ effective) must be positive. Check parameters.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return Point3d.Origin;
            }
            var (lat, lon) = rbXYtoBL ? MercatorToLatLonEllipsoidal(from_lat_long.X, from_lat_long.Y, lambda0Rad, k0Effective, fe)
                : LatLonToMercatorEllipsoidal(from_lat_long.X, from_lat_long.Y, lambda0Rad, k0Effective, fe, 0);
            return new Point3d(lat, lon, 0);
        }
        public static (double lat, double lon) MercatorToLatLonEllipsoidal(double x, double y, double lambda0Rad, double k0Effective, double fe)
        {
            double lonRad = (x - fe) / (A * k0Effective) + lambda0Rad;
            double t = Math.Exp(-y / (A * k0Effective));
            double latRadPrev = Math.PI / 2 - 2 * Math.Atan(t);
            for (int i = 0; i < 20; i++)
            {
                double sinLatPrev = Math.Sin(latRadPrev);
                double newLatRad = Math.PI / 2 - 2 * Math.Atan(t * Math.Pow((1 - E * sinLatPrev) / (1 + E * sinLatPrev), E / 2));
                if (Math.Abs(newLatRad - latRadPrev) < 1e-12)
                {
                    latRadPrev = newLatRad;
                    break;
                }
                latRadPrev = newLatRad;
            }
            return (latRadPrev.ToDegree(), lonRad.ToDegree());
        }
        public static (double x, double y) LatLonToMercatorEllipsoidal(double lat, double lon, double lambda0Rad, double k0Effective, double fe, double de = -1)
        {
            double latRad = (lat + de / (10.0 * 3600.0)).ToRadian();
            double lonRad = lon.ToRadian();
            double sinLat = Math.Sin(latRad);
            double term1 = Math.Tan(Math.PI / 4.0 + latRad / 2.0);
            double term2 = Math.Pow(Math.Tan(Math.PI / 4.0 + E * sinLat / 2.0), E);
            if (term1 <= 0 || term2 <= 0)
                throw new ArgumentException("Error calculating isometric latitude: invalid log value.");
            double meridianArc = Math.Log(term1 / term2);
            double x = A * (lonRad - lambda0Rad) * k0Effective + fe;
            double y = A * meridianArc * k0Effective;
            return (x, y);
        }
    }
}Link tải (MediaFire)
---------------------------------------------------------------------------------------------
Mọi thông tin xin liên hệ Fanpage AutoLISP Thật là đơn giản!
Cảm ơn bạn đã theo dõi!

 
 
Không có nhận xét nào:
Đăng nhận xét