2013-04-16 3 views
2

Учитывая, что у меня есть таблица, которая содержит список аэропортов с соответствующими координатами лат и длинных координат, как я могу получить список аэропортов, находящихся в пределах 100 миль от другой координаты? Моя цель состоит в том, чтобы найти пользователя по городу и найти аэропорты в пределах 100 миль от этой широты и долготы города. У меня есть все данные, которые просто не знают, с чего начать.Расчет 100 миль в радиусе

Мои данные находятся на SQL Server.

+0

Сколько миль составляют от единиц широт и долгот? Вот что вам нужно выяснить –

+0

Какую версию SQL-Server вы используете? Если у вас есть SQL Server 2008, вы можете использовать GeoCoordinates. –

+0

http://stackoverflow.com/questions/862856/storing-and-querying-gps-coordinates-effectively содержит некоторую хорошую информацию. –

ответ

5
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

+1 Это замечательно – Brad

+0

Можем ли мы сделать это в MySQL? – LoneWOLFs

+0

@ Маркус - результат в Майлсе? – LoneWOLFs

0

в случае, если у вас есть аэропорт в точке 0,0, все аэропорты в радиусе 30 миль должны находиться внутри круга. , чтобы проверить, если точка находится внутри круга, вы должны проверить каждое квадратное уравнение: SQRT (X * X + Y * Y) < R, где X, Y - местоположение каждого Sity, R = 100 миль

4

Вы можете использовать System.Device.Location.GeoCoordinate класс

GeoCoordinate city = ....; 
double distance = .......; 
List<GeoCoordinate> airports = .......; //load from db. 

var found = airports.Where(c=>c.GetDistanceTo(city) < distance); 

EDIT

Для тех, кто может быть заинтересован в реальной рабочей код

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); 
    } 
} 
+1

Я думаю, что OP просит решения в T-SQL. – Codeman

+0

@ Pheonixblade9 Это может быть так, но его отметили C#. –

1

Вы могли бы сделать что-то вроде этого:

--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, найденный через Google Поиск по SQL + Pyhtagoras).

+0

К сожалению, расстояние между двумя линиями долготы отличается широтой, поэтому это решение просто не работает на практике. –

+0

Кроме того, не забывайте, что расстояния на поверхности земли измеряют расстояние * как кривые земли *, а не расстояние * прямо через землю * между двумя точками.Гораздо быстрее добраться до Китая, если вы поедете прямо, но копать этот туннель будет какой-то работой. –

0

Вот формула для «по прямой линии расстояния между двумя точками: гаверсинуса

formula:  a = sin²(Δφ/2) + cos(φ1).cos(φ2).sin²(Δλ/2) 
c = 2.atan2(√a, √(1−a)) 
d = R.c 

, где φ широта, λ долгота, R является радиусом Земли (средний радиус = 6,371km) примечание что углы должны быть в радианах, чтобы перейти к триггерным функциям!

Вы можете перевести этот код в 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

Смежные вопросы