|
|
@@ -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);
|
|
|
+ }
|
|
|
}
|