Учитывая координаты, как мне получить все почтовые индексы в радиусе 10 миль?
-
10-10-2019 - |
Вопрос
У меня есть местоположение (широта и долгота). Как я могу получить список Zipcodes, которые либо частично, либо полностью в радиусе 10 миль моего местоположения?
Решение может быть вызовом хорошо известной веб -службы (карты Google, Bing Maps и т. Д.) Или локальное решение базы данных (клиент имеет SQL Server 2005) или алгоритм.
Я видел несколько Подобный вопрос, но все ответы там в значительной степени относятся к использованию функциональности географии SQL Server 2008, которая для меня недоступна.
Решение
Во -первых, вам понадобится база данных всех Zipcodes, их соответствующие широты и долготы. В Австралии есть только несколько тысяч из них (и информация легко доступна), однако я предполагаю, что это, вероятно, более сложная задача в США.
Во -вторых, учитывая, что вы знаете, где вы находитесь, и вы знаете радиус, который ищете, вы можете посмотреть все Zipcodes, которые попадают в этот радиус. Что -то простое написано в PHP было бы следующим образом: (извиняюсь, что это не в C#)
function distanceFromTo($latitude1,$longitude1,$latitude2,$longitude2,$km){
$latitude1 = deg2rad($latitude1);
$longitude1 = deg2rad($longitude1);
$latitude2 = deg2rad($latitude2);
$longitude2 = deg2rad($longitude2);
$delta_latitude = $latitude2 - $latitude1;
$delta_longitude = $longitude2 - $longitude1;
$temp = pow(sin($delta_latitude/2.0),2) + cos($latitude1) * cos($latitude2) * pow(sin($delta_longitude/2.0),2);
$earth_radius = 3956;
$distance = $earth_radius * 2 * atan2(sqrt($temp),sqrt(1-$temp));
if ($km)
$distance = $distance * 1.609344;
return $distance;
}
Другие советы
Начните с базы данных почтового индекса, которая содержит zipcodes и их соответствующие координаты широты и долготы:
http://www.zipcodedownload.com/products/product/z5commercial/standard/overview/
Чтобы получить расстояние между широтой и долготой, вам понадобится хорошая формула расстояния. Этот сайт имеет пару вариаций:
http://www.meridianworlddata.com/distance-calculation/
Формула «Великого круга расстояния» немного экстремальна. Этот работает достаточно хорошо по моему опыту:
sqrt(x * x + y * y)
where x = 69.1 * (lat2 - lat1)
and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3)
Ваш запрос SQL будет выглядеть примерно так:
select zd.ZipCode
from ZipData zd
where
sqrt(
square(69.1 * (zd.Latitude - @Latitude)) +
square(69.1 * (zd.Longitude - @Longitude) * cos(@Latitude/57.3))
) < @Distance
Удачи!
Большинство поисков работают с центроидами. Чтобы работать с частичными Zipcodes, находящимися в пределах 10 миль, вам придется купить базу данных полигонов ZipCode (*). Затем реализуйте алгоритм, который проверяет на Zipcodes с вершинами в радиусе 10 миль. Чтобы быть сделанным правильно, вы используете формулу Haversine для измерения расстояния. С некоторыми умными структурами данных вы можете значительно сократить пространство поиска. Аналогичным образом, поиски могут быть значительно ускорены, сохраняя и первоначально сравнивая с экстентами Zipcoe (север, запад, восток, юг).
(*) Примечание: технически Zipcodes не полигоны! Я знаю, что мы все так думаем о них, но на самом деле это коллекции точек данных (уличные адреса), и именно так USPS действительно использует их. Это означает, что Zipcodes могут включать другие zipcodes; Zipcodes могут быть изготовлены из нескольких «многоугольников»; и Zipcodes могут перекрывать другие zipcodes. Большинство из этих ситуаций не должны быть проблемой, но вам придется обрабатывать zipcodes, которые могут быть определены как несколько многоугольников.