在另一个邮政编码的半径范围内查找列表的邮政编码/坐标

时间:2014-07-10 04:12:40

标签: php mysql math map zipcode

所以我正在创建一个搜索功能,我希望在邮政编码的任意半径范围内找到所有列表。例如距离90210英里10英里,距00603英里100英里。

因此,如果我距离90210有10英里,我想返回这10英里范围内的所有列表。列表也是邮政编码,所以我基本上想找到这10英里范围内的所有其他邮政编码。

我想一旦我收集了半径中的所有邮政编码,然后我将它们添加到一个数组中,然后做一个sql来查找所有在这个数组中都有邮政编码的列表。但是,我不确定这是否是最好的方式。

我曾尝试做研究,但对我来说这很复杂,我认为它可能与Great Circle有关。我一直在http://williams.best.vwh.net/avform.htm研究航空公式,但仍然无法解决问题。

我有一个邮政编码数据库,包含所有邮政编码的经度和纬度,以及城市和州信息。这足以满足我的需求。我想我只需要知道数学。我不想使用API​​。

我绝对迷失在这里,关于我如何计算这样的半径。非常感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

您可以通过调用以下api获取与输入的邮政编码对应的所有邮政编码列表: -

$zipcode=90210;
$distancekm=10;

$curl = curl_init();
   curl_setopt_array($curl, array( 
   CURLOPT_RETURNTRANSFER => 1,

   CURLOPT_URL => 
       'http://zipcodedistanceapi.redline13.com/rest/2odywUYrQJOEEO0vJdlcH5Qd8Lf6EGKG4YfBTd2JXQoCFo7pBsBiysvGdLNSsyzw/radius.json/'.$zipcode.'/'.$distancekm.'/mile'));

   $result = curl_exec($curl);

   $decoded_result = json_decode($result, true);

$ decoding_result会返回距离邮政编码90210近10英里的所有邮政编码。

这可能会对你有帮助。

答案 1 :(得分:0)

您提到了3个单独的问题:

  • “Miles”和“地理坐标”没有直接翻译。你可能已经听说过,地球并不平坦:-),这意味着在赤道和洛杉矶纬度的1º经度将会有不同的英里数。您链接的公式是spherical law of cosines的应用,它允许您以更快的近似值转换经度和纬度差异

  • 假设您可能有很多地址,那么您的第二个问题是常规MySQL索引(B-Trees)对于按最近坐标进行过滤效率非常低。一些数据库供应商(Oracle,Postgress)具有“GIS扩展”,允许对地理坐标执行快速查找。虽然MySQL具有这些特定的数据类型和功能,但早期版本的范围和性能非常有限。最新版本(5.6和5.7)在某种程度上有所改进,你可以在这里看到一个例子,你用MySQL做什么来过滤坐标附近的地方:

    http://mysqlserverteam.com/mysql-5-7-and-gis-an-example/

    它涉及使用边界框进行过滤,这使得MySQL功能变得更容易。 上一个链接在逐步指南中包含所有公式和查询。

  • 您打算执行点搜索,然后执行第二个查询以检索每个找到的位置的信息。这是不必要的,并且可能在网络带宽上效率低下,您可以通过执行自联接来完成单个查询中的所有操作(在表中搜索特定的邮政编码,搜索地理上接近的记录)。

    < / LI>

这是关于GIS和MySQL的另一个链接:http://www.slideshare.net/henrikingo/spatial-functions-in-mysql-56-mariadb-55-postgis-20-and-others

答案 2 :(得分:0)

也许这个Java项目可以提供帮助。该项目配置为公里。您可以在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;
}

&#34; LocationFinder \ src \ main \ resources \ json \ cities.json&#34;文件包含比利时的所有城市。您也可以删除或创建条目。只要您不更改名称和/或结构,就不需要更改代码。

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