Вот как я это делаю.
Вы можете получить список городов, улиц, почтовых индексов и их широт и долгот.
(Я не могу вспомнить, с какой стороны мы взяли нашу голову)
редактировать: 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 (таблицы в моей БД), затем откатываю возможные совпадения и, наконец, отсеиваю тех, кто не в радиусе.