鑑於我有一張表格,其中包含機場列表及其關聯的緯度和長度座標,我將如何着手獲取距另一座標100英里內的機場列表?我的最終目標是按城市搜索用戶,並在距城市經緯度100英里範圍內找到機場。我擁有的所有數據都不知道從哪裏開始。在半徑範圍內計算100英里
我的數據在SQL Server中。
鑑於我有一張表格,其中包含機場列表及其關聯的緯度和長度座標,我將如何着手獲取距另一座標100英里內的機場列表?我的最終目標是按城市搜索用戶,並在距城市經緯度100英里範圍內找到機場。我擁有的所有數據都不知道從哪裏開始。在半徑範圍內計算100英里
我的數據在SQL Server中。
create function dbo.F_GREAT_CIRCLE_DISTANCE
(
@Latitude1 float,
@Longitude1 float,
@Latitude2 float,
@Longitude2 float
)
returns float as
begin
declare @radius float
declare @lon1 float
declare @lon2 float
declare @lat1 float
declare @lat2 float
declare @a float
declare @distance float
-- Sets average radius of Earth in Miles
set @radius = 3956
-- Convert degrees to radians
set @lon1 = radians(@Longitude1)
set @lon2 = radians(@Longitude2)
set @lat1 = radians(@Latitude1)
set @lat2 = radians(@Latitude2)
set @a = sqrt(square(sin((@[email protected])/2.0E)) + (cos(@lat1) * cos(@lat2) * square(sin((@[email protected])/2.0E))))
set @distance = @radius * (2.0E *asin(case when 1.0E < @a then 1.0E else @a end))
return @distance
end
萬一你的機場在0,0, 30英里範圍內的所有機場應該在一個圓圈內。 測試如果點是一個圓內,則需要測試每個正方形方程: SQRT(X * X + Y * Y)< R, 其中X,Y - 各自增寬的位置,R =100英里
您可以使用System.Device.Location.GeoCoordinate
類
GeoCoordinate city = ....;
double distance = .......;
List<GeoCoordinate> airports = .......; //load from db.
var found = airports.Where(c=>c.GetDistanceTo(city) < distance);
編輯
對於那些誰可能有興趣在實際工作代碼
var airports1 = Airports.Search(51, 0, 100).ToList(); //~London
var airports2 = Airports.Search(40.714623, -74.006605,100).ToList(); //~NY
public class Airports
{
public class Airport
{
public string Name;
public GeoCoordinate Location;
public override string ToString()
{
return Name;
}
}
static Lazy<List<Airport>> _Airports = new Lazy<List<Airport>>(() =>
{
using (var wc = new WebClient())
{
var json = wc.DownloadString("http://www.flightradar24.com/AirportDataService2.php");
var jObj = new JavaScriptSerializer().Deserialize<Dictionary<string,string[]>>(json);
return jObj.Values
.Select(j => new Airport
{
Name = (string)j[2],
Location = new GeoCoordinate(double.Parse(j[3].ToString(), CultureInfo.InvariantCulture),double.Parse(j[4].ToString(), CultureInfo.InvariantCulture))
})
.ToList();
}
}, true);
public static IEnumerable<Airport> Search(double lat,double lon, double distInMiles)
{
var loc = new GeoCoordinate(lat, lon);
return _Airports.Value.Where(c => c.Location.GetDistanceTo(loc) < distInMiles * 1609.344);
}
}
我認爲OP正在T-SQL中尋求解決方案。 – Codeman
@ Pheonixblade9可能是這樣,但它已被C#標記。 –
你可以做這樣的事情:
--SELECT Points closer than @radius
select * from #Points p
WHERE power(p.x - @locX, 2) + POWER(p.y - @locY, 2) < POWER(@radius,2)
(這已被無恥地從http://www.sqlservercentral.com/Forums/Topic1228111-8-1.aspx#bm1229043撕開,通過谷歌搜索SQL + Pyhtagoras找到)。
不幸的是,兩條經度線之間的距離因緯度而異,所以這種解決方案在實踐中根本不起作用。 –
另外,不要忘記,地球表面的距離測量的是地球的曲線*的距離*,而不是兩點間的距離*。如果你直接去中國,到中國的速度要快很多,但挖掘這條隧道將會是一些工作。 –
下面是「爲烏鴉兩點之間飛行距離下式: 半正矢
formula: a = sin²(Δφ/2) + cos(φ1).cos(φ2).sin²(Δλ/2)
c = 2.atan2(√a, √(1−a))
d = R.c
其中φ是緯度,λ是經度,R是地球的半徑(平均半徑=6371公里) 音符角度需要以弧度傳遞以觸發函數!
您可以將該代碼轉換成SQL
JavaScript:
var R = 6371; // km
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad();
var lat1 = lat1.toRad();
var lat2 = lat2.toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
這裏的T-SQL頁面的鏈接數學函數: http://msdn.microsoft.com/en-us/library/ms188919.aspx
多少英里是一個緯度和經度之間?這就是你需要找出 –
你正在使用什麼版本的SQL服務器?如果您擁有SQL Server 2008,則可以使用GeoCoordinates。 –
http://stackoverflow.com/questions/862856/storing-and-querying-gps-coordinates-effectively也包含一些很好的信息。 –