Чтобы сфокусироваться на (а):
В прошлом я предварительно вычислял части, сохраняя значения lat, long, xaxis, yaxis и zxais, где x, y & z определены как:
xaxis = cos(radians(Lat)) * cos(radians(Lon))
yaxis = cos(radians(Lat)) * sin(radians(Lon))
zaxis = sin(radians(Lat))
Затем расстояние можно вычислить с использованием SQL, например, (acos( xaxis * $xaxis + yaxis * $yaxis + zaxis * $zaxis ) * 6367.0 / 1.852)
(где значения, начинающиеся с $, предварительно вычисляются для рассматриваемой начальной точки таким же образом, как указано выше)
Предварительное вычисление таким образом переводит относительно дорогостоящий триггер в одноразовое событие и упрощает запрос.