LBS——地理圍欄(C#)
阿新 • • 發佈:2018-12-21
LBS GPS圍欄計算 點在圍欄內 點與圍欄的關係 點與多邊形的關係
圍欄計算(採用最小外包矩形法+暴力數學計演算法)
/// <summary>
/// 圍欄計算(點是否在圍欄內)
/// </summary>
/// <param name="latlon">單點座標</param>
/// <param name="APoints">座標集合</param>
/// <returns></returns>
public static bool MBR(Gps latlon, List<Gps> APoints)
{
if (MBR_zerOne(latlon, APoints))
{
return IsPtInPoly(latlon, APoints);//內判斷
}
else
{
return false;//外判斷
}
}
/// <summary>
/// 最小外包法
/// </summary>
/// <param name="latlon"></param>
/// <param name="APoints"></param>
/// <returns></returns>
private static bool MBR_zerOne(Gps latlon, List< Gps> APoints)
{
double max_lon = APoints.Max(x => x.getWgLon());
double max_lat = APoints.Max(x => x.getWgLat());
double min_lon = APoints.Min(x => x.getWgLon());
double min_lat = APoints.Min(x => x.getWgLat());
double aLon = latlon.getWgLon();
double aLat = latlon.getWgLat();
if (aLon >= max_lon || aLon <= min_lon || aLat >= max_lat || aLat <= min_lat)
{
return false;
}
else
{
return true;
}
}
/// <summary>
/// 點在圍欄內(數學計算方法)
/// </summary>
/// <param name="latlon">Gps座標</param>
/// <param name="APoints">Gps座標點集合</param>
/// <returns></returns>
private static bool IsPtInPoly(Gps latlon, List<Gps> APoints)
{
int iSum = 0, iCount;
double dLon1, dLon2, dLat1, dLat2, dLon;
double ALat = latlon.getWgLat();
double ALon = latlon.getWgLon();
if (APoints.Count < 3)
return false;
iCount = APoints.Count;
for (int i = 0; i < iCount; i++)
{
if (i == iCount - 1)
{
dLon1 = APoints[i].getWgLon();
dLat1 = APoints[i].getWgLat();
dLon2 = APoints[0].getWgLon();
dLat2 = APoints[0].getWgLat();
}
else
{
dLon1 = APoints[i].getWgLon();
dLat1 = APoints[i].getWgLat();
dLon2 = APoints[i + 1].getWgLon();
dLat2 = APoints[i + 1].getWgLat();
}
//以下語句判斷A點是否在邊的兩端點的水平平行線之間,在則可能有交點,開始判斷交點是否在左射線上
if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1)))
{
if (Math.Abs(dLat1 - dLat2) > 0)
{
//得到 A點向左射線與邊的交點的x座標:
dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat)) / (dLat1 - dLat2);
// 如果交點在A點左側(說明是做射線與 邊的交點),則射線與邊的全部交點數加一:
if (dLon < ALon)
iSum++;
}
}
}
if (iSum % 2 != 0)
return true;
return false;
}
GPS座標模型
/// <summary>
/// 座標模型
/// </summary>
public class Gps
{
/// <summary>
/// 緯度
/// </summary>
private double wgLat;
/// <summary>
/// 經度
/// </summary>
private double wgLon;
public Gps()
{
wgLat = 0;
wgLon = 0;
}
public Gps(double wgLat, double wgLon)
{
setWgLat(wgLat);
setWgLon(wgLon);
}
public double getWgLat()
{
return wgLat;
}
public void setWgLat(double wgLat)
{
this.wgLat = wgLat;
}
public double getWgLon()
{
return wgLon;
}
public void setWgLon(double wgLon)
{
this.wgLon = wgLon;
}
public String toString()
{
return wgLat + "," + wgLon;
}
}