|
@@ -0,0 +1,100 @@
|
|
|
+package locaxis
|
|
|
+
|
|
|
+import (
|
|
|
+ "math"
|
|
|
+)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const (
|
|
|
+ XPi = math.Pi * 3000.0 / 180.0
|
|
|
+ OFFSET = 0.00669342162296594323
|
|
|
+ AXIS = 6378245.0
|
|
|
+)
|
|
|
+
|
|
|
+
|
|
|
+func BD2GCJ(lon float64, lat float64) (float64, float64) {
|
|
|
+ x := lon - 0.0065
|
|
|
+ y := lat - 0.006
|
|
|
+
|
|
|
+ z := math.Sqrt(x*x+y*y) - 0.00002*math.Sin(y*XPi)
|
|
|
+ theta := math.Atan2(y, x) - 0.000003*math.Cos(x*XPi)
|
|
|
+
|
|
|
+ return z * math.Cos(theta), z * math.Sin(theta)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func GCJ2BD(lon, lat float64) (float64, float64) {
|
|
|
+ z := math.Sqrt(lon*lon+lat*lat) + 0.00002*math.Sin(lat*XPi)
|
|
|
+ theta := math.Atan2(lat, lon) + 0.000003*math.Cos(lon*XPi)
|
|
|
+
|
|
|
+ return z*math.Cos(theta) + 0.0065, z*math.Sin(theta) + 0.006
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func WGS2GCJ(lon float64, lat float64) (float64, float64) {
|
|
|
+ if isOutOfChina(lon, lat) {
|
|
|
+ return lon, lat
|
|
|
+ }
|
|
|
+
|
|
|
+ return delta(lon, lat)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func GCJ2WGS(lon float64, lat float64) (float64, float64) {
|
|
|
+ if isOutOfChina(lon, lat) {
|
|
|
+ return lon, lat
|
|
|
+ }
|
|
|
+
|
|
|
+ mgLon, mgLat := delta(lon, lat)
|
|
|
+ return lon*2 - mgLon, lat*2 - mgLat
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func BD2WGS(lon float64, lat float64) (float64, float64) {
|
|
|
+ lon, lat = BD2GCJ(lon, lat)
|
|
|
+ return GCJ2WGS(lon, lat)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func WGS2BD(lon float64, lat float64) (float64, float64) {
|
|
|
+ lon, lat = WGS2GCJ(lon, lat)
|
|
|
+ return GCJ2BD(lon, lat)
|
|
|
+}
|
|
|
+
|
|
|
+func delta(lon float64, lat float64) (float64, float64) {
|
|
|
+ dLat := transformLat(lon-105.0, lat-35.0)
|
|
|
+ dLon := transformLng(lon-105.0, lat-35.0)
|
|
|
+
|
|
|
+ radLat := lat / 180.0 * math.Pi
|
|
|
+ magic := math.Sin(radLat)
|
|
|
+ magic = 1 - OFFSET*magic*magic
|
|
|
+ sqrtMagic := math.Sqrt(magic)
|
|
|
+
|
|
|
+ dLat = (dLat * 180.0) / ((AXIS * (1 - OFFSET)) / (magic * sqrtMagic) * math.Pi)
|
|
|
+ dLon = (dLon * 180.0) / (AXIS / sqrtMagic * math.Cos(radLat) * math.Pi)
|
|
|
+
|
|
|
+ return lon + dLon, lat + dLat
|
|
|
+}
|
|
|
+
|
|
|
+func transformLat(lon float64, lat float64) float64 {
|
|
|
+ var ret = -100.0 + 2.0*lon + 3.0*lat + 0.2*lat*lat + 0.1*lon*lat + 0.2*math.Sqrt(math.Abs(lon))
|
|
|
+ ret += (20.0*math.Sin(6.0*lon*math.Pi) + 20.0*math.Sin(2.0*lon*math.Pi)) * 2.0 / 3.0
|
|
|
+ ret += (20.0*math.Sin(lat*math.Pi) + 40.0*math.Sin(lat/3.0*math.Pi)) * 2.0 / 3.0
|
|
|
+ ret += (160.0*math.Sin(lat/12.0*math.Pi) + 320*math.Sin(lat*math.Pi/30.0)) * 2.0 / 3.0
|
|
|
+ return ret
|
|
|
+}
|
|
|
+
|
|
|
+func transformLng(lon float64, lat float64) float64 {
|
|
|
+ var ret = 300.0 + lon + 2.0*lat + 0.1*lon*lon + 0.1*lon*lat + 0.1*math.Sqrt(math.Abs(lon))
|
|
|
+ ret += (20.0*math.Sin(6.0*lon*math.Pi) + 20.0*math.Sin(2.0*lon*math.Pi)) * 2.0 / 3.0
|
|
|
+ ret += (20.0*math.Sin(lon*math.Pi) + 40.0*math.Sin(lon/3.0*math.Pi)) * 2.0 / 3.0
|
|
|
+ ret += (150.0*math.Sin(lon/12.0*math.Pi) + 300.0*math.Sin(lon/30.0*math.Pi)) * 2.0 / 3.0
|
|
|
+ return ret
|
|
|
+}
|
|
|
+
|
|
|
+func isOutOfChina(lon float64, lat float64) bool {
|
|
|
+ return !(lon > 73.66 && lon < 135.05 && lat > 3.86 && lat < 53.55)
|
|
|
+}
|