Как найти ближайшие города в заданном радиусе? - PullRequest
9 голосов
/ 12 марта 2009

Знаете ли вы какую-нибудь утилиту или веб-сайт, где я могу указать в качестве входных данных город, штат и радиальное расстояние США в миль, и он вернет мне все города в этом радиусе?

Спасибо!

Ответы [ 6 ]

5 голосов
/ 12 марта 2009

Вот как я это делаю.

Вы можете получить список городов, улиц, почтовых индексов и их широт и долгот. (Я не могу вспомнить, с какой стороны мы взяли нашу голову)

редактировать: http://geonames.usgs.gov/domestic/download_data.htm как кто-то, упомянутый выше, вероятно, будет работать.

Затем вы можете написать метод для расчета минимальной и максимальной широты и долготы на основе радиуса и запросить все города между этими минимальными и максимальными значениями. Затем выполните цикл и рассчитайте расстояние и удалите все, которые не находятся в радиусе

double latitude1 = Double.parseDouble(zipCodes.getLatitude().toString());
double longitude1 = Double.parseDouble(zipCodes.getLongitude().toString());

//Upper reaches of possible boundaries
double upperLatBound = latitude1 + Double.parseDouble(distance)/40.0;
double lowerLatBound = latitude1 - Double.parseDouble(distance)/40.0;

double upperLongBound = longitude1 + Double.parseDouble(distance)/40.0;
double lowerLongBound = longitude1 - Double.parseDouble(distance)/40.0;

//pull back possible matches
SimpleCriteria zipCriteria = new SimpleCriteria();
zipCriteria.isBetween(ZipCodesPeer.LONGITUDE, lowerLongBound, upperLongBound);
zipCriteria.isBetween(ZipCodesPeer.LATITUDE, lowerLatBound, upperLatBound);
List zipList = ZipCodesPeer.doSelect(zipCriteria);
ArrayList acceptList = new ArrayList();

if(zipList != null)
{
    for(int i = 0; i < zipList.size(); i++)
    {
        ZipCodes tempZip = (ZipCodes)zipList.get(i);
        double tempLat = new Double(tempZip.getLatitude().toString()).doubleValue();
        double tempLon = new Double(tempZip.getLongitude().toString()).doubleValue();
        double d = 3963.0 * Math.acos(Math.sin(latitude1 * Math.PI/180) * Math.sin(tempLat * Math.PI/180) + Math.cos(latitude1 * Math.PI/180) * Math.cos(tempLat * Math.PI/180) *  Math.cos(tempLon*Math.PI/180 -longitude1 * Math.PI/180));

        if(d < Double.parseDouble(distance))
        {
            acceptList.add(((ZipCodes)zipList.get(i)).getZipCd());  
        }
    }
}

Вот выдержка из моего кода, надеюсь, вы сможете увидеть, что происходит. Я начинаю с одного ZipCodes (таблицы в моей БД), затем откатываю возможные совпадения и, наконец, отсеиваю тех, кто не в радиусе.

4 голосов
/ 12 марта 2009

Oracle, PostGIS, mysql с расширениями ГИС, sqlite с расширениями ГИС - все поддерживают такие запросы

Если у вас нет набора данных, посмотрите:

http://www.geonames.org/

2 голосов
/ 12 марта 2009

Вы можете получить довольно хорошую базу данных географических названий городов / мест из http://geonames.usgs.gov - найдите соответствующий дамп базы данных, импортируйте его в свою БД, и выполнить запрос, который вам нужен, довольно просто, особенно если ваш СУБД поддерживает некоторые пространственные запросы (например, Oracle Spatial , MySQL Spatial Extensions , PostGIS или SQLServer 2008 )

См. Также: как выполнить поиск по местоположению

2 голосов
/ 12 марта 2009

Взгляните на этот веб-сервис, рекламируемый на xmethods.net. Для реального использования требуется подписка, но она заявляет, что делает то, что вам нужно.

Рекламируемый метод в описании вопроса:

GetPlacesWithin Возвращает список гео места в пределах указанного расстояния с данного места. Параметры: место - название места (не более 65 символов), штат - двухбуквенный код штата (не требуется для почтовые индексы), расстояние - расстояние в мили, placeTypeToFind - тип места искать: ZipCode или City (включая любые деревни, города и т. д.).

http://xmethods.net/ve2/ViewListing.po?key=uuid:5428B3DD-C7C6-E1A8-87D6-461729AF02C0

0 голосов
/ 01 июня 2016

Может быть, это может помочь. Проект настроен в километрах, хотя. Вы можете изменить их в 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 \ resources \ json \ towns.json" содержит все города из Бельгии. Вы можете удалить или создать записи, если вы тоже хотите. Пока вы не измените имена и / или структуру, никакие изменения кода не требуются.

Обязательно прочтите README https://github.com/GlennVanSchil/LocationFinder

0 голосов
/ 12 марта 2009

У меня нет веб-сайта, но мы реализовали это как в Oracle в качестве функции базы данных, так и в SAS в качестве макроса статистики. Требуется только база данных со всеми городами и их широтой и продолжительностью.

...