31/07/2025

Tính toán tọa độ kinh vỹ độ trong HYPACK | Mercator to WGS84 Ellipsoid lat long | AutoLISP Reviewer

Ứng dụng được phát triển/Sưu tầm bởi đội ngũ AutoLISP Thật là đơn giản
   

Thông tin thêm: 👉👉👉

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)




---------------------------------------------------------------------------------------------
Ứng dụng được phát triển bởi đội ngũ AutoLISP Thật là đơn giản - Tác giả ứng dụng in D2P

    

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

Lisp chèn tọa độ đỉnh CTD | CTD Chèn tọa độ đỉnh trong AutoCAD | AutoLISP Reviewer

Ứng dụng được phát triển/Sưu tầm bởi đội ngũ AutoLISP Thật là đơn giản     Thông tin thêm: 👉👉👉