判断点是否在区域内解决方案
判断点是否在区域内
从地图上取到点的经纬度和区域各顶点的经纬度,判断这个点是否在区域内。
例如:经度:118.891898,纬度:31.965411
区域各顶点的经纬度如下:118.89507293701172,31.965306481024427;118.89925718307495,31.964123212108052;118.89816284179687,31.96230276861502;118.89404296875,31.96361349156799
我用的算法如下:
因为经纬度是小数,而Point要求是整数,我试过PointF,不行。
我将经纬度和区域各顶点的经纬都乘以10000,然后再四舍五入为整数,再判断,点还是不在区域内,实际上那个点是在区域内的,可能小数点后位数较多,乘以10000,不够精确。
如果是一个较大的区域,乘以10000,再四舍五入为整数,用上面的算法能判断出在区域内,如果区域较小,就不在区域内,也就是不准确,请高手指教!
------解决方案--------------------
如果你是用float做的,那显然是不行的,float只能有6位有效数字。按你这个需求,用dobule就可以了。
把要找的那个坐标的所有位数扩大成整数,在附带给它后面加个0.
从地图上取到点的经纬度和区域各顶点的经纬度,判断这个点是否在区域内。
例如:经度:118.891898,纬度:31.965411
区域各顶点的经纬度如下:118.89507293701172,31.965306481024427;118.89925718307495,31.964123212108052;118.89816284179687,31.96230276861502;118.89404296875,31.96361349156799
我用的算法如下:
- C# code
using System.Drawing; private int IsLeft(Point P0, Point P1, Point P2) { int abc = 0; try { abc = ((P1.X - P0.X) * (P2.Y - P0.Y) - (P2.X - P0.X) * (P1.Y - P0.Y)); } catch (Exception ex) { Console.WriteLine("判断点是否在区域某顶点左边时出现异常:{0}", ex.ToString()); } return abc; } private bool PointInFences(Point pnt1, Point[] fencePnts) { int wn = 0, j = 0; //wn 计数器 j第二个点指针 try { for (int i = 0; i < fencePnts.Length; i++) {//开始循环 if (i == fencePnts.Length - 1) j = 0;//如果 循环到最后一点 第二个指针指向第一点 else j = j + 1; //如果不是 ,则找下一点 if (fencePnts[i].Y <= pnt1.Y) { // 如果多边形的点 小于等于 选定点的 Y 坐标 if (fencePnts[j].Y > pnt1.Y) { // 如果多边形的下一点 大于于 选定点的 Y 坐标 if (IsLeft(fencePnts[i], fencePnts[j], pnt1) > 0) { wn++; } } } else { if (fencePnts[j].Y <= pnt1.Y) { if (IsLeft(fencePnts[i], fencePnts[j], pnt1) < 0) { wn--; } } } } } catch (Exception ex) { Console.WriteLine("判断点和区域时出现异常:{0}", ex.ToString()); } if (wn == 0) return false; else return true; }
因为经纬度是小数,而Point要求是整数,我试过PointF,不行。
我将经纬度和区域各顶点的经纬都乘以10000,然后再四舍五入为整数,再判断,点还是不在区域内,实际上那个点是在区域内的,可能小数点后位数较多,乘以10000,不够精确。
如果是一个较大的区域,乘以10000,再四舍五入为整数,用上面的算法能判断出在区域内,如果区域较小,就不在区域内,也就是不准确,请高手指教!
------解决方案--------------------
如果你是用float做的,那显然是不行的,float只能有6位有效数字。按你这个需求,用dobule就可以了。
把要找的那个坐标的所有位数扩大成整数,在附带给它后面加个0.
- C/C++ code
double a = 118.8918980,b = 31.965411; CString astr; astr.Format("%lf",a); CString bstr; bstr.Format("%lf",b); int lena = astr.GetLength()-astr.Find("."); int lenb = bstr.GetLength()-bstr.Find("."); int len = max(lena,lenb); int N = pow(10,len); CPoint p(int(a*N),int(b*N));
------解决方案--------------------
判断的时候用double,要画的时候再转成PointF画出来就是了。
------解决方案--------------------
point 的点是INT,32位的,反正经纬度只有180大小,如果精度不够,你完全乘以1000000或者10000000,只要不溢出就可以了