Objective
Most apps now have the ability to find nearby features, simply have to find the surrounding sports venues, complex with drops, and worship to find the vehicles around. This paper mainly describes the general implementation of locating nearby locations. Searching for nearby people is the same idea.
Scenario Comparison
Scenario 1 (performance is good)
Database directly to the latitude and longitude, and then calculate the rectangle boundary value, walk index query
Scenario 2 (not yet tried)
Convert the latitude and longitude to a value and then compare the query Genhash
http://blog.csdn.net/newjueqi/article/details/18989867
Scenario 3 (said to be high-performance, how is performance? Pending test)
MongoDB geography Type, high performance http://www.tuicool.com/articles/Jfu6fy
SQL Server Geographic Data geography https://msdn.microsoft.com/en-us/library/ff929109.aspx
Implementation of Scenario 1 (This article mainly describes this scenario)
Implementation environment: Java+mysql
Scene Simulation: Zhang San users in Chengdu Tianfu Five Street to inquire about the location within 10 km
1. First establish the latitude data, such as the common location of the latitude and longitude database, I am here to download an online Shop_area table data, which contains some common locations of latitude and longitude, such as
2. Then, according to the latitude and longitude of the Zhang San user, and the distance he wants to query 10 km, get the four vertices of the query range rectangle, such as:
Calculate the MyBatis SQL for these four points:
<select id= "Getcurrentlocationrectangle" parametertype= "Locationfilter" resulttype= "LocationFilter" > SELECT #{mylongitude}-#{distance}/ABS (COS (RADIANS (#{mylatitude}) *) as Longitudemin, #{mylongitude} + #{ Distance}/ABS (COS (RADIANS (#{mylatitude})) * For Longitudemax, #{mylatitude}-(#{distance}/) as Latitude Min, #{mylatitude} + (#{distance}/) as latitudemax</select>
3. The value of the rectangle four points just obtained into the following SQL for latitude and longitude query filtering, remember latitude and longitude fields to be indexed
MyBatis sql:
<select id= "getusernearbyarealist" parametertype= "Com.anuo.app.modules.coach.entity.CoachFilter" resulttype= " Shoparea "> select * from ( select a.*, getdistance (#{mylatitude}, #{mylongitude}, A.lat, A.LNG) as distance from Shop_area a WHERE A.lat between #{latitudemin} and #{latitudemax} and a.lng Between #{longitudemin} and #{longitudemax} ) z <where> <if test= "distance > 0" > < z.distance #{distance} </if> </where> ORDER by z.distance LIMIT #{pagestart},#{pagesize}< /select>
Because the longitude and latitude data filtered by the index at four points, the efficiency is greatly improved. And we want to the 10 km range of latitude and longitude data filtered out, although more query the point data (see four fork), see the fourth step below, remove the superfluous
4. and z.distance in SQL above < #{distance} that is, and z.distance is less than the specified distance #{distance}, is the cross-fork part of the latitude and longitude data culling, the data is redundant, because we want to query the circle of data
Here is a MySQL getdistance function, the code is as follows
DELIMITER $ $USE ' Anuoapp ' $$DROP FUNCTIONIFEXISTS' Getdistance ' $$CREATE definer=' Root ' @' localhost ' FUNCTION ' getdistance ' (mylatitude decimal ( 11,8), #我当前位置的纬度 mylongitude DECIMAL (11,8), #我当前位置的经度 latitude DECIMAL (11,8), longitude DECIMAL ( 11,8)) RETURNS doublebegin RETURN (6371 * ACOS (cos (RADIANS (mylatitude)) * cos (RADIANS (latitude)) * cos (RADIANS (longitude)-RADIANS (mylongitude)) + SIN (RADIANS ( mylatitude)) * SIN (RADIANS (latitude))); end$ $DELIMITER;
Finally find out the location of Zhang San within 10 km of Tianfu Five street, Chengdu
Request Url:http://localhost:8080/v1/apigetusernearbyarea
Request Body:
{ "Token ":"6850d1c361e9478ca1e94496ec6b27f9", "Version ":"1.8.0", "Entities ":[ { "Mylatitude ":30.54286, "Mylongitude ":104.075569, "Distance ":10, "PageSize ":10, "pagenumber": 1}", "ismobile": < Span class= "hljs-literal" >true, "pageindex": 1," isinnertest ": True, "isgetip": false, "pagesize ": 38," Isencrypt ": true," Parameters ": {}} /span>
Response:
{ "Success ":True, "TotalRow ":11, "Entities ":[ { "ID ":"510122004", "AreaName ":"Middle and street", "ParentID ":510122, "ShortName ":"Middle and street", "LNG ":"104.082375", "Lat ":"30.559141", "Level ":True, "Position ":"Tr_0 tr_510000 tr_510100 tr_510122", "Sort ":25, "Distance ":1.9241037391984028}, {"ID ":"510107063", "AreaName ":"Stone Sheep Farm Street", "ParentID ":510107, "ShortName ":"Stone Sheep Farm Street", "LNG ":"104.048271", "Lat ":"30.590687", "Level ":True, "Position ":"Tr_0 tr_510000 tr_510100 tr_510107", "Sort ":12, "Distance ":5.925643914100619}, {"ID ":"510122122", "AreaName ":"Wan ' an town", "ParentID ":510122, "ShortName ":"Wan ' an town", "LNG ":"104.112701", "Lat ":"30.487444", "Level ":True, "Position ":"Tr_0 tr_510000 tr_510100 tr_510122", "Sort ":18, "Distance ":7.114938271111233}, {"ID ":"510122120", "AreaName ":"New Town", "ParentID ":510122, "ShortName ":"New Town", "LNG ":"104.149757", "Lat ":"30.52656", "Level ":True, "Position ":"Tr_0 tr_510000 tr_510100 tr_510122", "Sort ":21, "Distance ":7.332851650201873}, {"ID ":"510107007", "AreaName ":"South train Station Street", "parentid ": 510107," shortname": "South Train Station Street", " LNG ": " 104.082924 "," lat ": "30.619801", "level": true, "position": " tr_0 tr_510000 tr_510100 tr_510107 "," sort ": Span class= "Hljs-value" >7, "distance": 8.5843717771867}]}
Full source See:
Https://gitee.com/anuo/anuoapp
Search the Apigetusernearbyarea interface in this project to locate
For a complete database, see:
Https://pan.baidu.com/s/1o9lUJMU
Java implementation search for nearby locations or people's functions