“附近的人”功能实现

来源:互联网 发布:网络电视打开u盘没内容 编辑:程序博客网 时间:2024/04/28 22:28


核心思想:

1.以当前登录用户为中心,向四个方向获取最近用户

2.汇总查询出的用户,计算当前用户与这些用户的精确距离

3.按最短距离排序


图例:


数据表sql:

CREATE TABLE IF NOT EXISTS `location` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `x` decimal(10,0) NOT NULL,  `y` decimal(10,0) NOT NULL,  `user` varchar(200) NOT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


程序1:创建n个用户

<?php$values = array();for ($i=0; $i<500; $i++){$x = rand(1, 1000);$y = rand(1, 1000);$values [] = "({$x}, {$y}, 'user_{$i}')" ;}$sql = 'insert into location(`x`, `y`, `user`) values'.implode(',', $values) ;$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'lixinxin') ;$db->query('set names utf8');$flag = $db->exec($sql);if($flag > 0){printf("insert ok \n");}?>


程序2:获取附近的人

<?php/** * 获取附近的人(8名) */$my_x = 200;$my_y = 100;$ulist = array();$limit = 8;$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'lixinxin') ;$db->query('set names utf8');$sqls[] = "select * from location where x>$my_x and y>$my_y order by x asc,y asc limit 8" ;//右上方向 x++ y++$sqls[] = "select * from location where x>$my_x and y<$my_y order by x asc,y desc limit 8" ;//右下方向 x++ y--$sqls[] = "select * from location where x<$my_x and y>$my_y order by x desc,y asc limit 8" ;//左上方向 x-- y++$sqls[] = "select * from location where x<$my_x and y<$my_y order by x desc,y desc limit 8" ;//左下方向 x-- y--foreach ($sqls as $sql){$query = $db->query($sql);if ($query){$data = $query->fetchAll(PDO::FETCH_ASSOC);if (is_array($data)){$ulist = array_merge($ulist, $data);}}}foreach ($ulist as $_key => $_val){$ulist[$_key]['distance'] = getDistance($my_x, $my_y, $_val['x'], $_val['y']);}usort($ulist, function($m, $n){if ($m['distance'] == $n['distance'])return 0;if ($m['distance'] > $n['distance'])return 1;return -1;}) ;$ulist = array_splice($ulist, 0, 8); // limit 8file_put_contents('./log.txt', var_export($ulist, true)); // debugfunction getDistance($x1, $y1, $x2, $y2){$line_a = abs($x1-$x2);$line_b = abs($y1-$y2);// C^2 = A^2 + B^2$line_c = pow(pow($line_a, 2) + pow($line_b, 2), 1/2);return intval($line_c);}?>






0 0