locaxis.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package locaxis
  2. import (
  3. "math"
  4. )
  5. // WGS84坐标系:即地球坐标系,国际上通用的坐标系。
  6. // GCJ02坐标系:即火星坐标系,WGS84坐标系经加密后的坐标系。Google Maps,高德在用。
  7. // BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系。
  8. const (
  9. XPi = math.Pi * 3000.0 / 180.0
  10. OFFSET = 0.00669342162296594323
  11. AXIS = 6378245.0
  12. )
  13. // BD2GCJ 百度坐标系->火星坐标系
  14. func BD2GCJ(lon float64, lat float64) (float64, float64) {
  15. x := lon - 0.0065
  16. y := lat - 0.006
  17. z := math.Sqrt(x*x+y*y) - 0.00002*math.Sin(y*XPi)
  18. theta := math.Atan2(y, x) - 0.000003*math.Cos(x*XPi)
  19. return z * math.Cos(theta), z * math.Sin(theta)
  20. }
  21. // GCJ2BD 火星坐标系->百度坐标系
  22. func GCJ2BD(lon, lat float64) (float64, float64) {
  23. z := math.Sqrt(lon*lon+lat*lat) + 0.00002*math.Sin(lat*XPi)
  24. theta := math.Atan2(lat, lon) + 0.000003*math.Cos(lon*XPi)
  25. return z*math.Cos(theta) + 0.0065, z*math.Sin(theta) + 0.006
  26. }
  27. // WGS2GCJ WGS84坐标系->火星坐标系
  28. func WGS2GCJ(lon float64, lat float64) (float64, float64) {
  29. if isOutOfChina(lon, lat) {
  30. return lon, lat
  31. }
  32. return delta(lon, lat)
  33. }
  34. // GCJ2WGS 火星坐标系->WGS84坐标系
  35. func GCJ2WGS(lon float64, lat float64) (float64, float64) {
  36. if isOutOfChina(lon, lat) {
  37. return lon, lat
  38. }
  39. mgLon, mgLat := delta(lon, lat)
  40. return lon*2 - mgLon, lat*2 - mgLat
  41. }
  42. // BD2WGS 百度坐标系->WGS84坐标系
  43. func BD2WGS(lon float64, lat float64) (float64, float64) {
  44. lon, lat = BD2GCJ(lon, lat)
  45. return GCJ2WGS(lon, lat)
  46. }
  47. // WGS2BD WGS84坐标系->百度坐标系
  48. func WGS2BD(lon float64, lat float64) (float64, float64) {
  49. lon, lat = WGS2GCJ(lon, lat)
  50. return GCJ2BD(lon, lat)
  51. }
  52. func delta(lon float64, lat float64) (float64, float64) {
  53. dLat := transformLat(lon-105.0, lat-35.0)
  54. dLon := transformLng(lon-105.0, lat-35.0)
  55. radLat := lat / 180.0 * math.Pi
  56. magic := math.Sin(radLat)
  57. magic = 1 - OFFSET*magic*magic
  58. sqrtMagic := math.Sqrt(magic)
  59. dLat = (dLat * 180.0) / ((AXIS * (1 - OFFSET)) / (magic * sqrtMagic) * math.Pi)
  60. dLon = (dLon * 180.0) / (AXIS / sqrtMagic * math.Cos(radLat) * math.Pi)
  61. return lon + dLon, lat + dLat
  62. }
  63. func transformLat(lon float64, lat float64) float64 {
  64. 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))
  65. ret += (20.0*math.Sin(6.0*lon*math.Pi) + 20.0*math.Sin(2.0*lon*math.Pi)) * 2.0 / 3.0
  66. ret += (20.0*math.Sin(lat*math.Pi) + 40.0*math.Sin(lat/3.0*math.Pi)) * 2.0 / 3.0
  67. ret += (160.0*math.Sin(lat/12.0*math.Pi) + 320*math.Sin(lat*math.Pi/30.0)) * 2.0 / 3.0
  68. return ret
  69. }
  70. func transformLng(lon float64, lat float64) float64 {
  71. var ret = 300.0 + lon + 2.0*lat + 0.1*lon*lon + 0.1*lon*lat + 0.1*math.Sqrt(math.Abs(lon))
  72. ret += (20.0*math.Sin(6.0*lon*math.Pi) + 20.0*math.Sin(2.0*lon*math.Pi)) * 2.0 / 3.0
  73. ret += (20.0*math.Sin(lon*math.Pi) + 40.0*math.Sin(lon/3.0*math.Pi)) * 2.0 / 3.0
  74. ret += (150.0*math.Sin(lon/12.0*math.Pi) + 300.0*math.Sin(lon/30.0*math.Pi)) * 2.0 / 3.0
  75. return ret
  76. }
  77. func isOutOfChina(lon float64, lat float64) bool {
  78. return !(lon > 73.66 && lon < 135.05 && lat > 3.86 && lat < 53.55)
  79. }