2009-03-12 9 views
9

Kennen Sie ein Dienstprogramm oder eine Website, auf der ich die Stadt, den Bundesstaat und die Radialentfernung in Meilen als Eingabe angeben kann und mir alle Städte innerhalb dieses Radius zurückgeben würde?Wie findet man die nächstgelegenen Städte in einem bestimmten Radius?

Danke!

+0

Vielleicht bearbeiten Sie könnten lesen und eine bessere Definition von „Städten“ geben? Meinst du nur Ortsnamen oder meinst du Ballungszentren? –

+0

Probieren Sie es aus: http://www.cityradius.com/ Die Radien sind begrenzt, aber es ist trotzdem ziemlich cool. Ich habe das auch schon gesehen: http://www.zip-codes.com/free-zip-code-tools.asp#radius –

Antwort

0

Ich habe keine Website, aber wir haben dies sowohl in Oracle als Datenbankfunktion als auch in SAS als Statistikmakro implementiert. Es benötigt nur eine Datenbank mit allen Städten und deren Lat und Long.

2

Werfen Sie einen Blick auf diesen Web-Service, der auf xmethods.net beworben wird. Es erfordert ein Abonnement, um tatsächlich zu verwenden, aber Ansprüche zu tun, was Sie brauchen.

Das angekündigte Verfahren in der Beschreibung der Frage:

GetPlacesWithin Gibt eine Liste von Geo Orten innerhalb einer bestimmten Entfernung von einem bestimmten Ort. Parameter: Ort - Ortsname (65 Zeichen max), Zustand - 2 Buchstaben Statuscode (nicht für Postleitzahlen erforderlich), Entfernung - Entfernung in Meilen, placeTypeToFind - Art des Orts zu suchen: PLZ oder Stadt (einschließlich irgendwelcher Dörfer, Städte usw.).

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

4

Oracle, PostGIS, mysql mit GIS-Erweiterungen, sqlite mit GIS-Erweiterungen unterstützen alle diese Art von Abfragen.

Wenn Sie nicht das Aussehen Dataset an:

http://www.geonames.org/

5

Hier ist, wie ich es tun.

Sie können eine Liste von Städten, Städten, Postleitzahlen und deren Breiten und Längen erhalten. (Ich kann die Spitze von meinem Kopf erinnern, wo wir uns vor)

edit: http://geonames.usgs.gov/domestic/download_data.htm wie jemand oben erwähnt würde wahrscheinlich funktionieren.

Dann können Sie eine Methode schreiben, um den minimalen und maximalen Breiten- und Längengrad basierend auf einem Radius zu berechnen, und alle Städte zwischen diesen Min- und Max-Werten abfragen. Dann durch die Schleife und den Abstand berechnen und entfernen Sie alle, die nicht im Radius sind

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

Es ist ein Auszug aus meinem Code, hoffentlich können Sie sehen, was passiert. Ich beginne mit einem ZipCodes (eine Tabelle in meiner DB), dann ziehe ich mögliche Streichhölzer zurück und schließlich wähle ich diejenigen aus, die nicht im Radius sind.

0

Vielleicht kann dies helfen. Das Projekt wird jedoch in Kilometern konfiguriert. Sie können diese in 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; 
} 

Das "Locationfinder \ src \ main \ resources \ json \ cities.json" ändern Datei, die alle Städte von Belgien enthält. Sie können Einträge löschen oder erstellen, wenn Sie auch möchten. Solange Sie die Namen und/oder Struktur nicht ändern, sind keine Codeänderungen erforderlich.

Achten Sie auf die Readme https://github.com/GlennVanSchil/LocationFinder

Verwandte Themen