C#实现墨卡托投影坐标系经纬度与米制单位之间的互转

在做WebAPI时,暴露给接口调用方的坐标常是经纬度,而在GIS数据建库时单位常是米。WGS1984坐标下,墨卡托投影的坐标经纬度与米之间的常用转换如下:

using System;
using GeoJSON.Net.Geometry;

namespace GISWebService.Common
{
    /// <summary>
    /// 墨卡托坐标转换(经纬度与米之间互转)
    /// </summary>
    public class MercatorCoordinatesConverter
    {
        /// <summary>
        /// 经纬度转Web墨卡托(单位:米)
        /// </summary>
        /// <param name="longitude">经度</param>
        /// <param name="latitude">纬度</param>
        /// <returns>转换后的位置</returns>
        public static Position Degree2WebMercatorMeter(double longitude, double latitude)
        {
            var xValue = longitude * 20037508.34 / 180;
            var y = Math.Log(Math.Tan((90 + latitude) * Math.PI / 360)) / (Math.PI / 180);
            var yValue = y * 20037508.34 / 180;
            return new Position(xValue, yValue);
        }

        /// <summary>
        /// 经纬度转World墨卡托(单位:米)
        /// </summary>
        /// <param name="longitude">经度</param>
        /// <param name="latitude">纬度</param>
        /// <returns>转换后的位置</returns>
        public static Position Degree2WorldMercatorMeter(double longitude, double latitude)
        {
            const int radius = 6378137;
            const double minorRadius = 6356752.314245179;

            const double d = Math.PI / 180;
            const double r = radius;
            var y = latitude * d;
            const double tmp = minorRadius / r;
            double e = Math.Sqrt(1 - tmp * tmp),
                con = e * Math.Sin(y);

            var ts = Math.Tan(Math.PI / 4 - y / 2) / Math.Pow((1 - con) / (1 + con), e / 2);
            y = -r * Math.Log(Math.Max(ts, 1E-10));

            var xValue = longitude * d * r;
            var yValue = y;

            return new Position(xValue, yValue);
        }

        /// <summary>
        /// Web墨卡托转经纬度
        /// </summary>
        /// <param name="x">X坐标值(单位:米)</param>
        /// <param name="y">Y坐标值(单位:米)</param>
        /// <returns>转换后的位置</returns>
        public static Position WebMercatorMeter2Degree(double x, double y)
        {
            var xValue = x / 20037508.34 * 180;
            var yValue = y / 20037508.34 * 180;
            yValue = 180 / Math.PI * (2 * Math.Atan(Math.Exp(yValue * Math.PI / 180)) - Math.PI / 2);
            var longitude = xValue;
            var latitude = yValue;
            return new Position(longitude, latitude);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/a_dev/article/details/80990492