Мой запрос для формулы haversine:
$query = "SELECT id,
( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance
FROM markers
HAVING distance < 25
ORDER BY distance
LIMIT 0 , 20;";
При использовании этой формулы возвращается пустой набор результатов. Результаты не найдены. Дайте мне знать правильное решение.
Также используйте
select * FROM (
SELECT *, ( 3959 * acos( cos( radians(37) ) * cos( radians( -33.898113 ) ) * cos( radians( 151.174469 ) - radians(-122) ) + sin( radians(37) ) * sin( radians( -33.898113 ) ) ) ) AS Distance FROM markers
) as T
WHERE T.Distance < 25
ORDER BY T.Distance
LIMIT 0 , 20
этот, но вернуть те же результаты.
У меня есть пара Stored Procedures
для поиска ближайших маркеров и т. д., которые, кажется, хорошо работают ~ Я попытался отредактировать один для ваших целей здесь — предположив, что два соответствующих столбца lat
а также lng
— возможно, это поможет
CREATE DEFINER=`root`@`localhost` PROCEDURE `spNearestMarkers`(
IN `p_lat` DOUBLE,
IN `p_lng` DOUBLE,
IN `p_rad` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
proc:begin
declare latitude double default 0;
declare longitude double default 0;
declare radius float default 0;
declare earth_radius integer default 0;
declare longitude_1 float;
declare latitude_1 float;
declare longitude_2 float;
declare latitude_2 float;set @latitude=p_lat;
set @longitude=p_lng;
set @radius=p_rad;set @earth_radius=3956;
set @longitude_1 = @longitude - @radius/abs( cos( radians(@latitude) ) * 69 );
set @longitude_2 = @longitude + @radius/abs( cos( radians(@latitude) ) * 69 );
set @latitude_1 = @latitude - (@radius/69);
set @latitude_2 = @latitude + (@radius/69);select distinct
*,
round( @earth_radius * 2 * asin( sqrt( power( sin( ( @latitude - m.`lat` ) * pi()/180 / 2 ), 2 ) + cos( @latitude * pi()/180 ) * cos( m.`lat` * pi()/180) *power( sin( ( @longitude - m.`lng`) * pi()/180 / 2 ), 2) ) ) , 2 ) as 'distance'
from `markers` m
where
( m.`lat` between @latitude_1 and @latitude_2 )
and
( m.`lng` between @longitude_1 and @longitude_2 )
group by m.`name`
having `distance` <= @radius
order by `distance`;
set @latitude=null;
set @longitude=null;
set @radius=null;
set @longitude_1 = null;
set @longitude_2 = null;
set @latitude1 = null;
set @latitude2 = null;
end
Чтобы вызвать процедуру в php
$lat=-33.74788;
$lng=151.23526;
$radius=10;
$sql="call `spNearestMarkers`('$lat','$lng','$radius');`";
Или вызвать процедуру в mysql (gui)
set @_lat=-33.74788;
set @_lng=151.23526;
set @_radius=10;
call `spNearestMarkers`(@_lat,@_lng,@_radius);
Вышеуказанное возвращает:
"id","name","address","lat","lng","distance",
"1","Heir Apparel","Crowea Pl, Frenchs Forest NSW 2086","-33.737885","151.235260","0.69",
"4","The Legacy","Charlotte Ln, Chatswood NSW 2067","-33.796669","151.183609","4.49",
"6","Trish & Tash","Lincoln St, Lane Cove West NSW 2066","-33.812222","151.143707","6.88",
"10","Moda Couture","Northcote Rd, Glebe NSW 2037","-33.873882","151.177460","9.31",
Предполагая, что в вашей базе данных есть столбцы latitude
а также longitude
и вы пытаетесь вызвать запрос SQL из PHP, то
/* the lat/lng of the location you are trying to find places nearby */
$lat=56.25;
$lng=-2.65;
$sql="SELECT id, ( 3959 * acos( cos( radians( $lat ) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians($lng) ) + sin( radians($lat) ) * sin( radians( latitude ) ) ) ) AS distance
FROM markers
HAVING distance < 25
ORDER BY distance
LIMIT 0,20;";
Других решений пока нет …