码迷,mamicode.com
首页 > 其他好文 > 详细

关于经纬度得到的多边形面积。

时间:2016-06-29 13:17:26      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:

  天干物燥,小心火烛,看了唐家三少的一篇自述,突然觉得我们和人家相比起来差距太大了,人家从小语文不好,虽然我们程序员半路出家的比较多,但是我还是觉得三少不错,如果不看网络小说,你们应该不晓得这个人的。

  一个很简单的APP,但是真心五脏俱全呀,数据库就用了七个,还有莫名的爬虫(老大为了省钱,爬的免费的天气数据),新来的CTO看不下去了,当然,我也是新来的,鄙人到这家公司是今年三月份,CTO到这家公司是今年二月份,其实呢,看不下去也是有原因的,一个APP,就五六十张表,结果呢,整了七个数据库,请注意,是七个数据库,真心觉得没有什么必要,于是乎,开始了混混烈烈的重构,原来的是用的ModelFirst,然后因为用了很多的数据库访问,所以呢,全部依赖注入,然后各种强关联,其实这个是我最受不了的,因为我们做的这玩意很金融没有关系呀,你还是全强关联,真心有点受不了,强关联就强关联吧,数据还全部是真删除,我去,我也是服了,然后呢,一条数据的生成过程也没有,虽然我们查询某些特定的存储过程,可以得到某些需要的数据,但是呀,真心不想说什么了。

  然后这个任务就交给了宝宝,说心里话,宝宝也是处呀,宝宝怎么知道搭建什么框架,最后采取了各种建议,宝宝决定,框架复杂了就好么?No,解决问题才是根本,于是乎,就开始了一个简单工厂,完了之后加了一个缓存这就是现在的项目的基本框架,可能有些人任务宝宝是不是太随意了,但是我看了重构与模式那本书之后,反正现在的我就认为简单和复杂都是相对的,只有解决问题,这才是根本。反正一个工厂,谁负责接口,谁负责实现,这些都没有问题,然后呢,访问数据,因为个人能力的问题,也没有想那么多,反正数据太多的时候就分表呗,至少宝宝是这么认为的。

  额,好像扯远了,直接上代码(两个点)半正矢公式 计算(Haversine formula)

技术分享

public static class AreaOfTwoPoint
	{
		private static double EARTH_RADIUS = 6370996.81;

		public static double AreaOfPoint(List<Point> list)
		{
			double result;
			if (list.Count<Point>() == 2)
			{
				double lat = list[0].lat;
				double lat2 = list[0].lat;
				double lon = list[1].lon;
				double lon2 = list[1].lon;
				double num = AreaOfTwoPoint.Distance(lat, lon , lat2, lon2);
				result = 3.1415926535897931 * Math.Pow(num / 2.0, 2.0);
			}
			else
			{
				result = 0.0;
			}
			return result;
		}

		private static double HvaerSin(double thera)
		{
			double num = Math.Sin(thera / 2.0);
			return num * num;
		}

		private static double Distance(double lat1, double lon1, double lat2, double lon2)
		{
			lat1 = AreaOfTwoPoint.ConvertDegreesToRadians(lat1);
			lon1 = AreaOfTwoPoint.ConvertDegreesToRadians(lon1);
			lat2 = AreaOfTwoPoint.ConvertDegreesToRadians(lat2);
			lon2 = AreaOfTwoPoint.ConvertDegreesToRadians(lon2);
			double thera = Math.Abs(lon1 - lon2);
			double thera2 = Math.Abs(lat1 - lat2);
			double d = AreaOfTwoPoint.HvaerSin(thera2) + Math.Cos(lat1) * Math.Cos(lat2) * AreaOfTwoPoint.HvaerSin(thera);
			return 2.0 * AreaOfTwoPoint.EARTH_RADIUS * Math.Asin(Math.Sqrt(d));
		}

		private static double ConvertDegreesToRadians(double degrees)
		{
			return degrees * 3.1415926535897931 / 180.0;
		}
	}

  具体请参考:https://en.wikipedia.org/wiki/Haversine_formula

  多个点,宝宝没本事,没有办法,只能就说按照多边形的投影走了,就是得到多边形,然后切割成N-2个小三角。然后计算面积。

  在这里必须要提醒的是,在处理的时候,有时候当三个点在经纬度上面显示出来约等于一条直线的时候,因为小数问题,可能会被计算机识别为一条直线,那么,此时,得到的面积就会无穷大,所以,在实际运用过程中,请注意,每个点之间的对应的投影点,及时做好处理。

 private double CalcArea(List<Points> list)
        {
            var count = list.Count;
            if (count > 2)
            {
                //数组中的元素值
                double mtotalArea = 0;
                double LowX = 0.0;
                double LowY = 0.0;
                double MiddleX = 0.0;
                double MiddleY = 0.0;
                double HighX = 0.0;
                double HighY = 0.0;

                //三角形的边
                double AM = 0.0, BM = 0.0, CM = 0.0;
                double AL = 0.0, BL = 0.0, CL = 0.0;
                double AH = 0.0, BH = 0.0, CH = 0.0;

                double CoefficientL = 0.0, CoefficientH = 0.0;

                double ALtangent = 0.0, BLtangent = 0.0, CLtangent = 0.0;

                double AHtangent = 0.0, BHtangent = 0.0, CHtangent = 0.0;

                double ANormalLine = 0.0, BNormalLine = 0.0, CNormalLine = 0.0;

                //定位置
                double OrientationValue = 0.0;
                //余弦函数
                double AngleCos = 0.0;

                double Sum1 = 0.0, Sum2 = 0.0;
                double Count1 = 0,Count2 = 0;


                double Sum = 0.0;
                double Radius = 6370996.81;//地球半径
                for (int i = 0; i < count; i++)
                {
                    //坐标系中,一般X代表纬度(Lon),Y代表经度(Lat)
                    if (i == 0)
                    {
                        LowX = (list[count - 1].Lon) * Math.PI / 180;
                        LowY = (list[count - 1].Lat) * Math.PI / 180;
                        MiddleX = (list[0].Lon) * Math.PI / 180;
                        MiddleY = (list[0].Lat) * Math.PI / 180;
                        HighX = (list[1].Lon) * Math.PI / 180;
                        HighY = (list[1].Lat) * Math.PI / 180;
                    }
                    else if (i == count - 1)
                    {
                        LowX = (list[count-2].Lon) * Math.PI / 180;
                        LowY = (list[count-2].Lat) * Math.PI / 180;
                        MiddleX = (list[count - 1].Lon) * Math.PI / 180;
                        MiddleY = (list[count - 1].Lat) * Math.PI / 180;
                        HighX = (list[0].Lon) * Math.PI / 180;
                        HighY = (list[0].Lat) * Math.PI / 180;
                    }
                    else
                    {
                        LowX = (list[i-1].Lon) * Math.PI / 180;
                        LowY = (list[i - 1].Lat) * Math.PI / 180;
                        MiddleX = (list[i].Lon) * Math.PI / 180;
                        MiddleY = (list[i].Lat) * Math.PI / 180;
                        HighX = (list[i+1].Lon) * Math.PI / 180;
                        HighY = (list[i+1].Lat) * Math.PI / 180;
                    }

                    AM = Math.Cos(MiddleY) * Math.Cos(MiddleX);
                    BM = Math.Cos(MiddleY) * Math.Sin(MiddleX);
                    CM = Math.Sin(MiddleY);
                    AL = Math.Cos(LowY) * Math.Cos(LowX);
                    BL = Math.Cos(LowY) * Math.Sin(LowX);
                    CL = Math.Sin(LowY);
                    AH = Math.Cos(HighY) * Math.Cos(HighX);
                    BH = Math.Cos(HighY) * Math.Sin(HighX);
                    CH = Math.Sin(HighY);

                    CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);
                    CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);

                    ALtangent = CoefficientL * AL - AM;
                    BLtangent = CoefficientL * BL - BM;
                    CLtangent = CoefficientL * CL - CM;
                    AHtangent = CoefficientH * AH - AM;
                    BHtangent = CoefficientH * BH - BM;
                    CHtangent = CoefficientH * CH - CM;
                    AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.Sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent) * Math.Sqrt(ALtangent * ALtangent + BLtangent * BLtangent + CLtangent * CLtangent));
                    AngleCos = Math.Acos(AngleCos);//余弦角度
                    ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;
                    BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);
                    CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;

                    if (AM != 0)
                        OrientationValue = ANormalLine / AM;
                    else if (BM != 0)
                        OrientationValue = BNormalLine / BM;
                    else
                        OrientationValue = CNormalLine / CM;
                    if (OrientationValue > 0)
                    {
                        Sum1 += AngleCos;
                        Count1++;
                    }
                    else
                    {
                        Sum2 += AngleCos;
                        Count2++;
                    }
                }
                if (Sum1 > Sum2)
                {
                    Sum = Sum1 + (2 * Math.PI * Count2 - Sum2);
                }
                else
                {
                    Sum = (2 * Math.PI * Count1 - Sum1) + Sum2;
                }
                return Math.Abs((Sum - (count - 2) * Math.PI) * Radius * Radius);
            }
            return 0;
        }

   如有侵权,请联系本人,谢谢。

关于经纬度得到的多边形面积。

标签:

原文地址:http://www.cnblogs.com/JeffController/p/5618742.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!