i have a mysql table structured as per the example below:
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
now what i am trying to do is create a query that will select results within selected kilometers of a searched location
so lets say they search for "grey river" and select "find all results within 20 kilometers"
it should obviously select "grey river", but it should also select all locations within 20 kilometers of gr开发者_如何学运维ey river based on the latitudes and longitudes.
i really have no idea how to do this. i've read up on the haversine formula but have no idea how to apply this to a mysql SELECT.
any help would be much appreciated.
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'
If your table is MyISAM
you may want to store your points in a native geometry format and create a SPATIAL
index on it:
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
This query works for me to get all the lat,long between 12 km distance.I have mst_suburbs
is may table which having the lat
and long
column.$lat
and $long
are my two php variable .and I am passing the desired lat,long to get the nearest 12km lat long list from the mst_suburb
. You just need to change the name of the column according to your table and pass the lat,long to query.
It's a little complicated algorithm, but here's a link to one solution
You simply take your haversine formula and apply it like this:
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
Replace $lat1
and $lon1
with the latitude and longitude you want to compare against.
精彩评论