1. <legend id='Keq8T'><style id='Keq8T'><dir id='Keq8T'><q id='Keq8T'></q></dir></style></legend>

    <i id='Keq8T'><tr id='Keq8T'><dt id='Keq8T'><q id='Keq8T'><span id='Keq8T'><b id='Keq8T'><form id='Keq8T'><ins id='Keq8T'></ins><ul id='Keq8T'></ul><sub id='Keq8T'></sub></form><legend id='Keq8T'></legend><bdo id='Keq8T'><pre id='Keq8T'><center id='Keq8T'></center></pre></bdo></b><th id='Keq8T'></th></span></q></dt></tr></i><div id='Keq8T'><tfoot id='Keq8T'></tfoot><dl id='Keq8T'><fieldset id='Keq8T'></fieldset></dl></div>
  2. <small id='Keq8T'></small><noframes id='Keq8T'>

      • <bdo id='Keq8T'></bdo><ul id='Keq8T'></ul>
    1. <tfoot id='Keq8T'></tfoot>

    2. 用 SQLite 计算大圆距离

      时间:2023-10-05
    3. <i id='E7ACZ'><tr id='E7ACZ'><dt id='E7ACZ'><q id='E7ACZ'><span id='E7ACZ'><b id='E7ACZ'><form id='E7ACZ'><ins id='E7ACZ'></ins><ul id='E7ACZ'></ul><sub id='E7ACZ'></sub></form><legend id='E7ACZ'></legend><bdo id='E7ACZ'><pre id='E7ACZ'><center id='E7ACZ'></center></pre></bdo></b><th id='E7ACZ'></th></span></q></dt></tr></i><div id='E7ACZ'><tfoot id='E7ACZ'></tfoot><dl id='E7ACZ'><fieldset id='E7ACZ'></fieldset></dl></div>
      • <bdo id='E7ACZ'></bdo><ul id='E7ACZ'></ul>
        <tfoot id='E7ACZ'></tfoot>
          <tbody id='E7ACZ'></tbody>
        <legend id='E7ACZ'><style id='E7ACZ'><dir id='E7ACZ'><q id='E7ACZ'></q></dir></style></legend>

          1. <small id='E7ACZ'></small><noframes id='E7ACZ'>

                本文介绍了用 SQLite 计算大圆距离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                这是我的问题,我有一个包含位置和纬度/经度的 SQLite 表.基本上我需要:

                Here is my problem, I have a SQLite table with locations and latitudes / longitudes. Basically I need to:

                SELECT location, HAVERSINE(lat, lon) AS distance FROM location ORDER BY distance ASC;
                

                HAVERSINE() 是一个 PHP 函数,它应该返回 大圆距离(以英里或公里为单位)给定一对纬度和经度值.其中一对应由 PHP 提供,另一对应由 locations 表中的每个纬度/经度行提供.

                HAVERSINE() is a PHP function that should return the Great-Circle Distance (in miles or km) given a pair of latitude and longitude values. One of these pairs should be provided by PHP and the other pair should be provided by each latitude / longitude row available in the locations table.

                因为 SQLite 没有任何地理空间扩展 (AFAIK SpatiaLite 存在,但仍然......) 我猜最好的方法是将自定义函数与 PDO 方法之一一起使用:

                Since SQLite doesn't has any Geo Spatial extension (AFAIK SpatiaLite exists but still...) I'm guessing the best approach would be to use a custom function with either one of the PDO methods:

                • PDO::sqliteCreateFunction()
                • PDO::sqliteCreateAggregate()

                我认为对于这种情况 PDO::sqliteCreateFunction() 就足够了,但是我对这个函数的有限经验可以简化为类似于 PHP 手册中提供的用例:

                I think for this case PDO::sqliteCreateFunction() would be enough, however my limited experience with this function can be reduced to usage cases similar to the one provided in the PHP Manual:

                $db = new PDO('sqlite:geo.db');
                
                function md5_and_reverse($string) { return strrev(md5($string)); }
                
                $db->sqliteCreateFunction('md5rev', 'md5_and_reverse', 1);
                $rows = $db->query('SELECT md5rev(filename) FROM files')->fetchAll();
                

                我在弄清楚如何让 SQLite 用户定义函数同时处理来自 PHP 和表数据的数据时遇到了一些麻烦,如果有人能帮我解决这个问题,我将不胜感激问题,同时也更好地理解 SQLite UDF(SQLite IMO 的一大胜利).

                I'm having some trouble figuring out how can I get an SQLite user defined function to process data from PHP and table data at the same time and I would appreciate if someone could help me solve this problem while also understanding SQLite UDFs (a big win of SQLite IMO) a little bit better.

                提前致谢!

                推荐答案

                来自您的有趣链接".

                function sqlite3_distance_func($lat1,$lon1,$lat2,$lon2) {
                    // convert lat1 and lat2 into radians now, to avoid doing it twice below
                    $lat1rad = deg2rad($lat1);
                    $lat2rad = deg2rad($lat2);
                    // apply the spherical law of cosines to our latitudes and longitudes, and set the result appropriately
                    // 6378.1 is the approximate radius of the earth in kilometres
                    return acos( sin($lat1rad) * sin($lat2rad) + cos($lat1rad) * cos($lat2rad) * cos( deg2rad($lon2) - deg2rad($lon1) ) ) * 6378.1;
                }
                
                $db->sqliteCreateFunction('DISTANCE', 'sqlite3_distance_func', 4);
                

                然后进行查询:

                "SELECT * FROM location ORDER BY distance(latitude,longitude,{$lat},{$lon}) LIMIT 1"
                

                <小时>

                编辑(按 QOP):我终于再次需要这个,这个解决方案效果很好,我只是稍微修改了代码,让它不那么冗长,并且可以处理非数字值优雅地,这里是:


                EDIT (by QOP): I finally needed this again and this solution worked out great, I just ended up modifying the code a bit to it is a bit less verbose and handles non-numeric values gracefully, here it is:

                $db->sqliteCreateFunction('distance', function () {
                    if (count($geo = array_map('deg2rad', array_filter(func_get_args(), 'is_numeric'))) == 4) {
                        return round(acos(sin($geo[0]) * sin($geo[2]) + cos($geo[0]) * cos($geo[2]) * cos($geo[1] - $geo[3])) * 6378.14, 3);
                    }
                
                    return null;
                }, 4);
                

                这篇关于用 SQLite 计算大圆距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:使用 PDO 创建表 下一篇:使用 PHP/PDO 检查数据库表是否存在

                相关文章

                最新文章

                  <small id='iQSVk'></small><noframes id='iQSVk'>

                  • <bdo id='iQSVk'></bdo><ul id='iQSVk'></ul>
                  <tfoot id='iQSVk'></tfoot>
                    <legend id='iQSVk'><style id='iQSVk'><dir id='iQSVk'><q id='iQSVk'></q></dir></style></legend>
                    <i id='iQSVk'><tr id='iQSVk'><dt id='iQSVk'><q id='iQSVk'><span id='iQSVk'><b id='iQSVk'><form id='iQSVk'><ins id='iQSVk'></ins><ul id='iQSVk'></ul><sub id='iQSVk'></sub></form><legend id='iQSVk'></legend><bdo id='iQSVk'><pre id='iQSVk'><center id='iQSVk'></center></pre></bdo></b><th id='iQSVk'></th></span></q></dt></tr></i><div id='iQSVk'><tfoot id='iQSVk'></tfoot><dl id='iQSVk'><fieldset id='iQSVk'></fieldset></dl></div>