|  | @@ -1,3 +1,4 @@
 | 
	
		
			
				|  |  | +using System;
 | 
	
		
			
				|  |  |  using System.Collections;
 | 
	
		
			
				|  |  |  using System.Collections.Generic;
 | 
	
		
			
				|  |  |  using UnityEngine;
 | 
	
	
		
			
				|  | @@ -102,4 +103,80 @@ public static class CoordinateConverter
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          return (latitude, longitude);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const double PI = Math.PI;
 | 
	
		
			
				|  |  | +    const double AXIS = 6378245.0;   // a
 | 
	
		
			
				|  |  | +    const double EE = 0.00669342162296594323; // e^2
 | 
	
		
			
				|  |  | +    const double EARTH_RADIUS = 20037508.34;  // 墨卡托投影最大值
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /// <summary>
 | 
	
		
			
				|  |  | +    /// 判断是否在中国范围外
 | 
	
		
			
				|  |  | +    /// </summary>
 | 
	
		
			
				|  |  | +    static bool OutOfChina(double lon, double lat)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        return (lon < 72.004 || lon > 137.8347 || lat < 0.8293 || lat > 55.8271);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    static double TransformLat(double x, double y)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y
 | 
	
		
			
				|  |  | +                   + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));
 | 
	
		
			
				|  |  | +        ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
 | 
	
		
			
				|  |  | +        ret += (20.0 * Math.Sin(y * PI) + 40.0 * Math.Sin(y / 3.0 * PI)) * 2.0 / 3.0;
 | 
	
		
			
				|  |  | +        ret += (160.0 * Math.Sin(y / 12.0 * PI) + 320 * Math.Sin(y * PI / 30.0)) * 2.0 / 3.0;
 | 
	
		
			
				|  |  | +        return ret;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    static double TransformLon(double x, double y)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x
 | 
	
		
			
				|  |  | +                   + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));
 | 
	
		
			
				|  |  | +        ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
 | 
	
		
			
				|  |  | +        ret += (20.0 * Math.Sin(x * PI) + 40.0 * Math.Sin(x / 3.0 * PI)) * 2.0 / 3.0;
 | 
	
		
			
				|  |  | +        ret += (150.0 * Math.Sin(x / 12.0 * PI) + 300.0 * Math.Sin(x / 30.0 * PI)) * 2.0 / 3.0;
 | 
	
		
			
				|  |  | +        return ret;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /// <summary>
 | 
	
		
			
				|  |  | +    /// GCJ-02(火星坐标,高德坐标) → WGS84
 | 
	
		
			
				|  |  | +    /// </summary>
 | 
	
		
			
				|  |  | +    public static Vector2 GCJ02ToWGS84(double lon, double lat)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        if (OutOfChina(lon, lat))
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            return new Vector2((float)lon, (float)lat);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        double dLat = TransformLat(lon - 105.0, lat - 35.0);
 | 
	
		
			
				|  |  | +        double dLon = TransformLon(lon - 105.0, lat - 35.0);
 | 
	
		
			
				|  |  | +        double radLat = lat / 180.0 * PI;
 | 
	
		
			
				|  |  | +        double magic = Math.Sin(radLat);
 | 
	
		
			
				|  |  | +        magic = 1 - EE * magic * magic;
 | 
	
		
			
				|  |  | +        double sqrtMagic = Math.Sqrt(magic);
 | 
	
		
			
				|  |  | +        dLat = (dLat * 180.0) / ((AXIS * (1 - EE)) / (magic * sqrtMagic) * PI);
 | 
	
		
			
				|  |  | +        dLon = (dLon * 180.0) / (AXIS / sqrtMagic * Math.Cos(radLat) * PI);
 | 
	
		
			
				|  |  | +        double mgLat = lat + dLat;
 | 
	
		
			
				|  |  | +        double mgLon = lon + dLon;
 | 
	
		
			
				|  |  | +        return new Vector2((float)(lon * 2 - mgLon), (float)(lat * 2 - mgLat));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /// <summary>
 | 
	
		
			
				|  |  | +    /// WGS84 → WebMercator (EPSG:3857)
 | 
	
		
			
				|  |  | +    /// </summary>
 | 
	
		
			
				|  |  | +    public static Vector2 WGS84ToWebMercator(double lon, double lat)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        double x = lon * EARTH_RADIUS / 180.0;
 | 
	
		
			
				|  |  | +        double y = Math.Log(Math.Tan((90.0 + lat) * PI / 360.0)) / (PI / 180.0);
 | 
	
		
			
				|  |  | +        y = y * EARTH_RADIUS / 180.0;
 | 
	
		
			
				|  |  | +        return new Vector2((float)x, (float)y);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /// <summary>
 | 
	
		
			
				|  |  | +    /// 一步到位: GCJ-02 → WebMercator
 | 
	
		
			
				|  |  | +    /// </summary>
 | 
	
		
			
				|  |  | +    public static Vector2 GCJ02ToWebMercator(double lon, double lat)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        Vector2 wgs84 = GCJ02ToWGS84(lon, lat);
 | 
	
		
			
				|  |  | +        return WGS84ToWebMercator(wgs84.x, wgs84.y);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |