Получение всех почтовых индексов в радиусе n миль
Вопрос
Как лучше всего заставить работать такую функцию:
def getNearest(zipCode, miles):
То есть, учитывая почтовый индекс (07024) и радиус, вернуть все почтовые индексы, находящиеся в этом радиусе?
Решение
На SourceForge есть проект, который может помочь в этом:
http://sourceforge.net/projects/zips/
Он предоставляет вам базу данных с почтовыми индексами и их широтой/долготой, а также примеры кодирования того, как вычислить расстояние между двумя наборами координат.Вероятно, существует лучший способ сделать это, но вы могли бы заставить свою функцию получать почтовый индекс и его координаты, а затем пошагово просматривать каждый почтовый индекс в списке и добавлять почтовый индекс в список, если он находится в пределах указанного количества миль.
Другие советы
Если вы хотите, чтобы это было точно, вы должны начать с данных о полигонах, которые включают расположение и форму каждого почтового индекса.У меня есть подобная база данных (раньше она публиковалась в рамках переписи населения США, но они больше этого не делают), и я построил на ее основе похожие вещи, но не тот точный запрос.
Если ты не заботишься о том, чтобы быть точный (чего, я думаю, у вас нет), вы можете получить таблицу центральных точек почтовых индексов и точек запроса, упорядоченную по большой круг расстояние. ПостГИС предоставляет отличные инструменты для этого, хотя вы можете создать запрос к другим базам данных, которые будут выполнять аналогичные задачи.
Альтернативный подход, который я использовал, состоит в том, чтобы построить блок, охватывающий нужный вам круг, выполнить запрос с предложением Between по долготе/широте, а затем выполнить большой круг в коде приложения.
Возможно, это может помочь.Однако проект настроен в километрах.Вы можете изменить их в CityDAO.java.
public List<City> findCityInRange(GeoPoint geoPoint, double distance) {
List<City> cities = new ArrayList<City>();
QueryBuilder queryBuilder = geoDistanceQuery("geoPoint")
.point(geoPoint.getLat(), geoPoint.getLon())
//.distance(distance, DistanceUnit.KILOMETERS) original
.distance(distance, DistanceUnit.MILES)
.optimizeBbox("memory")
.geoDistance(GeoDistance.ARC);
SearchRequestBuilder builder = esClient.getClient()
.prepareSearch(INDEX)
.setTypes("city")
.setSearchType(SearchType.QUERY_THEN_FETCH)
.setScroll(new TimeValue(60000))
.setSize(100).setExplain(true)
.setPostFilter(queryBuilder)
.addSort(SortBuilders.geoDistanceSort("geoPoint")
.order(SortOrder.ASC)
.point(geoPoint.getLat(), geoPoint.getLon())
//.unit(DistanceUnit.KILOMETERS)); Original
.unit(DistanceUnit.MILES));
SearchResponse response = builder
.execute()
.actionGet();
SearchHit[] hits = response.getHits().getHits();
scroll:
while (true) {
for (SearchHit hit : hits) {
Map<String, Object> result = hit.getSource();
cities.add(mapper.convertValue(result, City.class));
}
response = esClient.getClient().prepareSearchScroll(response.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
if (response.getHits().getHits().length == 0) {
break scroll;
}
}
return cities;
}
Файл LocationFinder\src\main esources\json\cities.json содержит все города Бельгии.Вы также можете удалять или создавать записи, если хотите.Пока вы не измените имена и/или структуру, никаких изменений кода не требуется.
Обязательно прочтите README https://github.com/GlennVanSchil/LocationFinder