如何找到给定半径内最近的城市?

发布于 2024-07-14 18:58:32 字数 83 浏览 10 评论 0原文

您是否知道一些实用程序或网站,我可以在其中输入美国城市、州和以英里为单位的径向距离作为输入,然后它会返回该半径内的所有城市?

谢谢!

Do you know some utility or a web site where I can give US city,state and radial distance in miles as input and it would return me all the cities within that radius?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

囚你心 2024-07-21 18:58:32

我是这样做的。

您可以获得城市、街道、邮政编码及其纬度和经度的列表。
(我记不起我们从哪里得到的)

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

这是我的代码的摘录,希望您能看到发生了什么。 我从一个邮政编码(数据库中的一张表)开始,然后拉回可能的匹配项,最后剔除那些不在半径内的人。

Here is how I do it.

You can obtain a list of city, st, zip codes and their latitudes and longitudes.
(I can't recall off the top of my head where we got ours)

edit: http://geonames.usgs.gov/domestic/download_data.htm
like someone mentioned above would probably work.

Then you can write a method to calculate the min and max latitude and longitudes based on a radius, and query for all cities between those min and max. Then loop through and calculate the distance and remove any that are not in the radius

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

There's an excerpt of my code, hopefully you can see what's happening. I start out with one ZipCodes( a table in my DB), then I pull back possible matches, and finally I weed out those who are not in the radius.

陌生 2024-07-21 18:58:32

Oracle、PostGIS、带有GIS扩展的mysql、带有GIS扩展的sqlite都支持这种查询。

如果您没有数据集,请查看:

http://www.geonames.org/

Oracle, PostGIS, mysql with GIS extensions, sqlite with GIS extensions all support this kind of queries.

If you don't have the dataset look at:

http://www.geonames.org/

相思碎 2024-07-21 18:58:32

看一下 xmethods.net 上广告的此 Web 服务。 它需要订阅才能实际使用,但声称可以满足您的需要。

问题描述中所宣传的方法:

GetPlacesWithin 返回地理列表
指定距离内的地点
从一个给定的地方。 参数:地点
- 地名(最多 65 个字符)、州 - 2 个字母的州代码(不需要
邮政编码),距离 - 距离
英里,placeTypeToFind - 地点类型
寻找:邮政编码或城市
(包括任何村庄、城镇等)。

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

Take a look at this web service advertised on xmethods.net. It requires a subscription to actually use, but claims to do what you need.

The advertised method in question's description:

GetPlacesWithin Returns a list of geo
places within a specified distance
from a given place. Parameters: place
- place name (65 char max), state - 2 letter state code (not required for
zip codes), distance - distance in
miles, placeTypeToFind - type of place
to look for: ZipCode or City
(including any villages, towns, etc).

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

风轻花落早 2024-07-21 18:58:32

您可以从 http://geonames.usgs.gov 获取一个非常好的地理定位城市/地名数据库 - find一个适当的数据库转储,将其导入到您的数据库中,然后执行您需要的查询类型非常简单,特别是如果您的 DBMS 支持某种空间查询(例如 Oracle Spatial, MySQL 空间扩展PostGISSQLServer 2008)

另请参阅:如何进行基于位置的搜索

You can obtain a pretty good database of geolocated cities/placenames from http://geonames.usgs.gov - find an appropriate database dump, import it into your DB, and performing the kind of query your need is pretty straightforward, particularly if your DBMS supports some kind of spatial queries (e.g. like Oracle Spatial, MySQL Spatial Extensions, PostGIS or SQLServer 2008)

See also: how to do location based search

霊感 2024-07-21 18:58:32

我没有网站,但我们已在 Oracle 中将其实现为数据库功能,并在 SAS 中将其实现为统计宏。 它只需要一个包含所有城市及其经纬度的数据库。

I do not have a website, but we have implemented this both in Oracle as a database function and in SAS as a statistics macro. It only requires a database with all cities and their lat and long.

如梦 2024-07-21 18:58:32

也许这会有所帮助。 该项目的配置单位是公里。 您可以在 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\cities.json”文件包含比利时的所有城市。 如果您愿意,也可以删除或创建条目。 只要不更改名称和/或结构,就不需要更改代码。

请务必阅读自述文件 https://github.com/GlennVanSchil/LocationFinder

Maybe this can help. The project is configured in kilometers though. You can modify these 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;
}

The "LocationFinder\src\main\resources\json\cities.json" file contains all cities from Belgium. You can delete or create entries if you want too. As long as you don't change the names and/or structure, no code changes are required.

Make sure to read the README https://github.com/GlennVanSchil/LocationFinder

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文