31/07/2025

Tính toán tọa độ kinh vỹ độ trong Hải đồ 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

Hàm COUNTIFS đếm theo nhiều điều kiện trong Excel | COUNTIFS, COUNTIF | AutoLISP Reviewer

Hàm COUNTIFS đếm theo nhiều điều kiện trong Excel Cuối tháng cần biết phòng Kế toán có bao nhiêu người đi làm đủ công, bao nhiêu đơn hàng ...