花了几个小时把js的google计算地图面积的算法改成了c# 的。
class Program { static void Main(string[] args) { // a = new qq.maps.LatLng(39.93, 116.44004334); //b = new qq.maps.LatLng(39.93, 116.35421264); //c = new qq.maps.LatLng(39.896775, 116.35421264); //d = new qq.maps.LatLng(39.89, 116.44004334); //29869510.924133233平方米 List<LatLng> a = new List<LatLng>(); a.Add(new LatLng() { Latitude = 39.93, Longitude = 116.44004334 }); a.Add(new LatLng() { Latitude = 39.93, Longitude = 116.35421264 }); a.Add(new LatLng() { Latitude = 39.896775, Longitude = 116.35421264 }); a.Add(new LatLng() { Latitude = 39.89, Longitude = 116.44004334 }); double area = computeArea(a, 0); } static double computeArea(List<LatLng> x, double y) { return Math.Abs(computeSignedArea(x, y)); } static double computeSignedArea(List<LatLng> a, double b) { double c = 6378137; if (b > 0) { c = b; } double g = a.Count - 1; double e = 0; LatLng d = a[0]; for (int i = 1; i < g; i++) { e += Zm(d, a[i], a[i + 1]); } return e * c * c; } static double Zm(LatLng a, LatLng b, LatLng c) { return Tm(a, b, c) * Um(a, b, c); } static double Tm(LatLng a, LatLng b, LatLng c) { List<LatLng> d = new List<LatLng>() { a, b, c, a }; List<double> e = new List<double>(); double f = 0; for (int i = 0; i < d.Count - 1; i++) { e.Add(Uf(d[i], d[i + 1])); f += e[i]; } f /= 2; double g = Math.Tan(f / 2); for (int j = 0; j < d.Count - 1; j++) { g *= Math.Tan((f - e[j]) / 2); } return 4 * Math.Atan(Math.Sqrt(Math.Abs(g))); } static double Um(LatLng a, LatLng b, LatLng c) { List<LatLng> d = new List<LatLng>() { a, b, c }; double[,] e = new double[3, 3]; for (int i = 0; i < 3; i++) { LatLng f = d[i]; double f1 = re(f); double f2 = se(f); e[i, 0] = Math.Cos(f1) * Math.Cos(f2); e[i, 1] = Math.Cos(f1) * Math.Sin(f2); e[i, 2] = Math.Sin(f1); } return 0 < e[0, 0] * e[1, 1] * e[2, 2] + e[1, 0] * e[2, 1] * e[0, 2] + e[2, 0] * e[0, 1] * e[1, 2] - e[0, 0] * e[2, 1] * e[1, 2] - e[1, 0] * e[0, 1] * e[2, 2] - e[2, 0] * e[1, 1] * e[0, 2] ? 1 : -1; } static double Uf(LatLng a, LatLng b) { var c = re(a); var d = re(b); return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((c - d) / 2), 2) + Math.Cos(c) * Math.Cos(d) * Math.Pow(Math.Sin((se(a) - se(b)) / 2), 2))); } static double re(LatLng a) { return Rd(a.Latitude); } static double se(LatLng a) { return Rd(a.Longitude); } static double Rd(double a) { return Math.PI / 180 * a; } } partial struct LatLng { private double _Longitude; public double Longitude { get { return _Longitude; } set { _Longitude = value; } } private double _Latitude; public double Latitude { get { return _Latitude; } set { _Latitude = value; } } }
double computeDistanceBetween(LngLat a, LngLat b, double c) { return Uf(a, b) * c; } public double ComputeLength(List<LngLat> a, double b = 0) { if (a.Count < 2) { return 0; } double c = 6378137; if (b > 0) { c = b; } double g = a.Count - 1; double d = 0; for (var e = 0; e < g; ++e) { d += computeDistanceBetween(a[e], a[e + 1], c); } return d; }