Intereting Posts

выберите в пределах 20 километров в зависимости от широты / долготы

У меня есть таблица mysql, структурированная в соответствии с приведенным ниже примером:

POSTAL_CODE_ID|PostalCode|City|Province|ProvinceCode|CityType|Latitude|Longitude 7|A0N 2J0|Ramea|Newfoundland|NL|D|48.625599999999999|-58.9758 8|A0N 2K0|Francois|Newfoundland|NL|D|48.625599999999999|-58.9758 9|A0N 2L0|Grey River|Newfoundland|NL|D|48.625599999999999|-58.9758 

теперь то, что я пытаюсь сделать, это создать запрос, который будет выбирать результаты в выбранных километрах искомого местоположения

поэтому скажем, что они ищут «серая река» и выбирают «найти все результаты в пределах 20 километров»,

он должен, очевидно, выбрать «серая река», но он также должен выбрать все места в пределах 20 километров серой реки, основанные на широтах и ​​долготах.

я действительно не знаю, как это сделать. Я прочитал формулу haversine, но понятия не имею, как применить это к SELECT.

Любая помощь приветствуется.

 SELECT * FROM mytable m JOIN mytable mn ON ACOS(COS(RADIANS(m.latitude)) * COS(RADIANS(mn.latitude)) * COS(RADIANS(mn.longitude) - RADIANS(m.longitude)) + SIN(RADIANS(m.latitude)) * SIN(radians(mn.latitude))) <= 20 / 6371.0 WHERE m.name = 'grey river' 

Если ваша таблица MyISAM вы можете захотеть сохранить свои точки в формате собственной геометрии и создать на ней индекс SPATIAL :

 ALTER TABLE mytable ADD position POINT; UPDATE mytable SET position = POINT(latitude, longitude); ALTER TABLE mytable MODIFY position NOT NULL; CREATE SPATIAL INDEX sx_mytable_position ON mytable (position); SELECT * FROM mytable m JOIN mytable mn ON MBRContains ( LineString ( Point ( X(m.position) - 0.009 * 20, Y(m.position) - 0.009 * 20 / COS(RADIANS(X(m.position))) ), Point ( X(m.position) + 0.009 * 20, Y(m.position) + 0.009 * 20 / COS(RADIANS(X(m.position)) ) ), mn.position ) AND ACOS(COS(RADIANS(m.latitude)) * COS(RADIANS(mn.latitude)) * COS(RADIANS(mn.longitude) - RADIANS(m.longitude)) + SIN(RADIANS(m.latitude)) * SIN(radians(mn.latitude))) <= 20 / 6371.0 WHERE m.name = 'grey river' 
 SELECT `s`.suburb_id,`s`.suburb_name,`s`.lat,`s`.long, (((acos(sin(($lat*pi()/180)) * sin((s.lat*pi()/180))+cos(($lat*pi()/180)) * cos((s.lat*pi()/180)) * cos((($long - s.long)*pi()/180))))*180/pi())*60*1.1515*1.609344) AS distance FROM (`mst_suburbs` as s) HAVING distance <= 20 ORDER BY `s`.suburb_id DESC 

Этот запрос работает для меня, чтобы получить все mst_suburbs , длинные между 12-километровым расстоянием. У меня есть mst_suburbs , может быть таблица, имеющая lat и long столбец. $lat и $long – это моя вторая переменная php. И я передаю желаемый лат, чтобы получить ближайший 12-километровый длинный список из mst_suburb . Вам просто нужно изменить имя столбца в соответствии с вашей таблицей и передать lat, долгое время запрашивать.

Это немного сложный алгоритм, но вот ссылка на одно решение

Вы просто принимаете формулу haversine и применяете ее следующим образом:

 SELECT *, 6371 * ACOS(SIN(RADIANS( $lat1 )) * SIN(RADIANS(`Latitude`)) + COS(RADIANS( $lat1 )) * COS(RADIANS(`Latitude`)) * COS(RADIANS(`Longitude`) - RADIANS( $lon1 ))) AS `distance` FROM `table` WHERE `distance` <= 20 ORDER BY `distance` ASC 

Замените $lat1 и $lon1 на широту и долготу, с которыми вы хотите сравнить.