2009-03-12 11 views
9

Czy znasz jakieś narzędzie lub stronę internetową, na której mogę podać dystans miasta, stanu i odległości w milach jako dane wejściowe i czy zwrócą one wszystkie miasta w tym promieniu?Jak znaleźć najbliższe miasta w danym promieniu?

Dzięki!

+0

Być może można edytować i dać lepszą definicję „cities”? Czy chodzi ci tylko o nazwy miejsc, czy też o centra demograficzne? –

+0

Wypróbuj to: http://www.cityradius.com/ Promienie są ograniczone, ale mimo wszystko jest całkiem fajnie. Właśnie zobaczyłem to: http://www.zip-codes.com/free-zip-code-tools.asp#radius –

Odpowiedz

0

Nie mam strony internetowej, ale wdrożyliśmy ją zarówno w Oracle jako funkcję bazy danych, jak iw SAS jako makro statystyk. Wymaga tylko bazy danych ze wszystkimi miastami i ich latami i długimi.

2

Spójrz na tę usługę internetową reklamowaną na xmethods.net. Wymaga korzystania z subskrypcji, ale twierdzi, że robi to, czego potrzebujesz.

Reklamowane metoda w pytaniu opis:

GetPlacesWithin Zwraca listę geo miejsca w określonej odległości z danego miejsca. Parametry: miejsce - nazwa miejsca (maks. 65 znaków), stan - dwuliterowy kod stanu (nie jest wymagany dla kodów pocztowych ), odległość - odległość mil, placeTypeToFind - rodzaj miejsca , aby wyszukać: Kod pocztowy lub Miejscowość (w tym wszelkie wsie, miasta itp.).

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

4

Oracle, PostGIS, mysql z rozszerzeniami GIS, sqlite z rozszerzeniami GIS obsługują tego rodzaju zapytania.

Jeśli nie masz wygląd zestawu danych w:

http://www.geonames.org/

5

Oto jak to zrobić.

Możesz uzyskać listę kodów miast, ulic, zip oraz ich szerokości i długości. (nie pamiętam poza czubek mojej głowy, gdzie mamy nasze)

edit: http://geonames.usgs.gov/domestic/download_data.htm jak ktoś wspomniał powyżej będzie prawdopodobnie działać.

Następnie można napisać metodę obliczania minimalnej i maksymalnej szerokości i długości geograficznej na podstawie promienia oraz zapytania dla wszystkich miast między tymi górnymi i dolnymi. Następnie pętli i obliczyć odległość i usuń te, które nie znajdują się w promieniu

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()); 
     } 
    } 
} 

Jest fragment mojego kodu, mam nadzieję, że można zobaczyć, co się dzieje. Zaczynam z jednym ZipCodes (stolik w moim DB), potem wycofuję ewentualne mecze, a na koniec wypieram tych, którzy nie są w promieniu.

0

Może to pomoże. Projekt jest skonfigurowany w kilometrach. Można modyfikować je w 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; 
} 

W "LocationFinder \ src \ main \ Resources \ json \ cities.json" plik zawiera wszystkie miasta z Belgii. Możesz również usuwać lub tworzyć wpisy, jeśli chcesz. Dopóki nie zmienisz nazw i/lub struktury, zmiany kodu nie są wymagane.

Koniecznie przeczytaj README https://github.com/GlennVanSchil/LocationFinder

Powiązane problemy