Вот моя проблема, у меня есть таблица SQLite с местоположениями и широтами / долготы. В основном я должен:
SELECT location, HAVERSINE(lat, lon) AS distance FROM location ORDER BY distance ASC;
HAVERSINE()
функция PHP, которая должна возвратить Большое Круговое Расстояние (в милях или км), учитывая пару значений широты и долготы. Одна из этих пар должна быть обеспечена PHP, и другая пара должна быть обеспечена каждой широтой / строка долготы, доступная в locations
таблица.
Так как SQLite не делает имеет любое Гео-Пространственное расширение (AFAIK SpatiaLite существует, но все еще...), я предполагаю, что лучший подход должен был бы использовать пользовательскую функцию с любым из методов PDO:
Я думаю для этого случая PDO::sqliteCreateFunction()
был бы достаточно, однако мой ограниченный опыт с этой функцией может быть уменьшен до случаев использования, подобных тому, обеспеченному в Руководстве PHP:
$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 UDFs (большая победа SQLite IMO) немного лучше.
Заранее спасибо!
До сих пор я могу думать только об этом решении:
$db = new PDO('sqlite:geo.db');
$db->sqliteCreateFunction('ACOS', 'acos', 1);
$db->sqliteCreateFunction('COS', 'cos', 1);
$db->sqliteCreateFunction('RADIANS', 'deg2rad', 1);
$db->sqliteCreateFunction('SIN', 'sin', 1);
, а затем выполнить следующий длительный запрос:
SELECT "location",
(6371 * ACOS(COS(RADIANS($latitude)) * COS(RADIANS("latitude")) * COS(RADIANS("longitude") - RADIANS($longitude)) + SIN(RADIANS($latitude)) * SIN(RADIANS("latitude")))) AS "distance"
FROM "locations"
HAVING "distance" < $distance
ORDER BY "distance" ASC
LIMIT 10;
Если кто-то может придумать лучшее решение, пожалуйста, дайте мне знать.
Я просто нашел эту интересную ссылку , я попробую это завтра.
Если у вас есть:
listRubriques = null;
и нет других объектов, содержащих ссылки на listRubriques
или содержащие их объекты, это подходит для сбора мусора. Но нет никакой гарантии, когда JVM фактически запустит на нем сбор мусора и свободную память. Вы можете позвонить по телефону
System.gc();
, чтобы порекомендовать JVM, что вы считаете запуск сбора мусора в это время хорошей идеей. Но и тогда гарантии нет.
Также наличие
listRubriques.clear();
перед установкой listRubriques
в значение null
не требуется.
EDIT : Чтобы ответить на ваш вопрос о циклических ссылках, JVM достаточно умны, чтобы понять, что весь граф объектов отключен от любого активно работающего кода, и JVM правильно определит, что все они имеют право на вывоз мусора. Это всегда было верно даже в плохие старые дни отсчета. Современные JVM просто быстрее и эффективнее. Но они не собирают больше объектов, чем старые JVM.
-121--2695415-Можно обрабатывать несколько типов исключений с помощью одной попытки/цикла захвата. Но позаботьтесь о порядке, в котором вы собираетесь справиться с исключениями. Порядок блока исключений захвата имеет значение.
-121--3866415-Построение из ответа Аликса...
$db->sqliteCreateFunction('HAVERSINE', 'haversine', 2);
Я бы предположил, что это позволит сработать тому запросу, который вы указали в своем вопросе.