[1].[代码] [PHP]代码跳至[1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
$uid
=
$_POST
[uid];
if
(
$uid
>0)
{
$re
=mysql_query(
"select `lat`,`long` from pre_common_member where uid='$uid'"
)
or
die
(mysql_error());
$row
=mysql_fetch_assoc(
$re
);
if
(!
empty
(
$row
[lat])
and
!
empty
(
$row
[long]))
{
$re0
=mysql_query(
"select `username`,`lat`,`long` from pre_common_member where uid!='$uid'"
);
while
(
$row0
=mysql_fetch_assoc(
$re0
))
{
$distance
= getDistanceBetweenPointsNew(
$row
[
'lat'
],
$row
[
'long'
],
$row0
[
'lat'
],
$row0
[
'long'
]);
$row0
[meter]=
$distance
[meters];
$arr
[]=
$row0
;
}
$arr
=array_sort(
$arr
,
'meter'
);
$arr
=
array_slice
(
$arr
,0,10);
$data
=json_encode(
$arr
);
$s
=mysql_errno();
//echo $data;
echo
"{\"s\":$s,\"data\":$data}"
;
}
}
// 比较两个地点的距离
function
getDistanceBetweenPointsNew(
$latitude1
,
$longitude1
,
$latitude2
,
$longitude2
)
{
$theta
=
$longitude1
-
$longitude2
;
$miles
= (sin(
deg2rad
(
$latitude1
)) * sin(
deg2rad
(
$latitude2
))) + (
cos
(
deg2rad
(
$latitude1
)) *
cos
(
deg2rad
(
$latitude2
)) *
cos
(
deg2rad
(
$theta
)));
$miles
=
acos
(
$miles
);
$miles
= rad2deg(
$miles
);
$miles
=
$miles
* 60 * 1.1515;
$feet
=
$miles
* 5280;
$yards
=
$feet
/ 3;
$kilometers
=
$miles
* 1.609344;
$meters
=
$kilometers
* 1000;
return
compact(
'miles'
,
'feet'
,
'yards'
,
'kilometers'
,
'meters'
);
}
// 二维数组按某个key排序
function
array_sort(
$arr
,
$keys
,
$type
=
'asc'
)
{
$keysvalue
=
$new_array
=
array
();
foreach
(
$arr
as
$k
=>
$v
){
$keysvalue
[
$k
] =
$v
[
$keys
];
}
if
(
$type
==
'asc'
){
asort(
$keysvalue
);
}
else
{
arsort(
$keysvalue
);
}
reset(
$keysvalue
);
foreach
(
$keysvalue
as
$k
=>
$v
){
$new_array
[
$k
] =
$arr
[
$k
];
}
return
$new_array
;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
define(EARTH_RADIUS, 6371);//地球半径,平均半径为6371km
/** *计算某个经纬度的周围某段距离的正方形的四个点 * *@param lng float 经度 *@param lat float 纬度 *@param distance float 该点所在圆的半径,该圆与此正方形内切,默认值为0.5千米 *@return array 正方形的四个点的经纬度坐标 */ function returnSquarePoint($lng, $lat,$distance = 0.5){ $dlng = 2 * asin(sin($distance / (2 * EARTH_RADIUS)) / cos(deg2rad($lat))); $dlng = rad2deg($dlng); $dlat = $distance/EARTH_RADIUS; $dlat = rad2deg($dlat); return array( 'left-top'=>array('lat'=>$lat + $dlat,'lng'=>$lng-$dlng), 'right-top'=>array('lat'=>$lat + $dlat, 'lng'=>$lng + $dlng), 'left-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng - $dlng), 'right-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng + $dlng) ); } //使用此函数计算得到结果后,带入sql查询。 $squares = returnSquarePoint($lng, $lat); $info_sql = "select id,locateinfo,lat,lng from `lbs_info` where lat<>0 and lat>{$squares['right-bottom']['lat']} and lat<{$squares['left-top']['lat']} and lng>{$squares['left-top']['lng']} and lng<{$squares['right-bottom']['lng']} ";
目前的工作是需要对用户的一些数据进行分析,每个用户都有若干条记录,每条记录中有用户的一个位置,是用经度和纬度表示的。
参考wiki百科上的一些球面计算公式: 假设已知点的经纬度分别为$lng, $lat //$lat 已知点的纬度 $dlng = 2 * asin(sin($distance / (2 * EARTH_RADIUS)) / cos(deg2rad($lat))); $dlng = rad2deg($dlng);//转换弧度 然后是纬度范围的查询, $dlat = $distance/EARTH_RADIUS;//EARTH_RADIUS地球半径 $dlat = rad2deg($dlat);//转换弧度 最后,就可以得出四个点的坐标: 我把以上方法写成了一个函数,综合起来就是: define(EARTH_RADIUS, 6371);//地球半径,平均半径为6371km /** *计算某个经纬度的周围某段距离的正方形的四个点 * *@param lng float 经度 *@param lat float 纬度 *@param distance float 该点所在圆的半径,该圆与此正方形内切,默认值为0.5千米 *@return array 正方形的四个点的经纬度坐标 */ function returnSquarePoint($lng, $lat,$distance = 0.5){ $dlng = 2 * asin(sin($distance / (2 * EARTH_RADIUS)) / cos(deg2rad($lat))); $dlng = rad2deg($dlng); $dlat = $distance/EARTH_RADIUS; $dlat = rad2deg($dlat); return array( 'left-top'=>array('lat'=>$lat + $dlat,'lng'=>$lng-$dlng), 'right-top'=>array('lat'=>$lat + $dlat, 'lng'=>$lng + $dlng), 'left-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng - $dlng), 'right-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng + $dlng) ); } //使用此函数计算得到结果后,带入sql查询。 $squares = returnSquarePoint($lng, $lat); $info_sql = "select id,locateinfo,lat,lng from `lbs_info` where lat<>0 and lat>{$squares['right-bottom']['lat']} and lat<{$squares['left-top']['lat']} and lng>{$squares['left-top']['lng']} and lng<{$squares['right-bottom']['lng']} "; 在lat和lng上建立一个联合索引后,使用此项查询,每条记录的查询消耗平均为0.8毫秒,相比以前的1700ms,真的是天壤之别啊。效率真真的是以前的2125倍~~ 总结:这应该也不是效率最好的办法,但是效率比以前确实有明显的提升。请记住,总有办法更好的。 |