寒窗轩,寒川的个人网络博客,记录互联网事,学习网络编程、分享工作经验、人生感悟,包括但不限于程序代码、数据库、Office办公、随笔等内容。

PHP+MySQL基于地理位置信息的附近交友的实现

老早就想总结这篇《PHP+MySQL基于地理位置信息的附近好友交友的实现》的文章了,受限于工作时间问题,今天把它写出来,起个抛砖引玉的作用。我们都知道,基于地理位置信息的APP有很多,例如微信、陌陌等等,本文以小白的视野来探究其功能用PHP+MySQL是怎么实现的?

在开始这个功能实现过程前,本人对微信、陌陌的附近好友功能也进行了一翻研究,其基本原理大致如下:


GPS.png

图1 基于地理位置信息的附近交友的实现原理图


从上图可以看出,用户要获取附近用户列表,需要先获取自生的GPS信息,再把GPS信息提交给WEB服务器,WEB服务器到数据库中查询附近的人,再返回用户列表给用户,这是基本原理。至于如何数据库查询实现基于地理位置信息的附近交友,下面重点讲解。

首先,建议数据库,结构如下:

CREATE TABLE IF NOT EXISTS `nearby` (
  `id` int(11) unsigned NOT NULL,
  `name` varchar(40) NOT NULL COMMENT '用户名',
  `longitude` varchar(10) NOT NULL COMMENT '经度',
  `latitude` varchar(10) NOT NULL COMMENT '纬度'
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

--
-- 转存表中的数据 `nearby`
--

INSERT INTO `nearby` (`id`, `name`, `longitude`, `latitude`) VALUES
(1, 'demo', '12.2222544', '65.54451'),
(2, 'demo1', '12.2222844', '65.54751'),
(3, 'demo2', '12.5222844', '65.55751'),
(4, 'demo3', '12.5226844', '65.58751');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `nearby`
--
ALTER TABLE `nearby`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `nearby`
--
ALTER TABLE `nearby`
  MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5;

为方便说明,本文以轻量级的PHP数据库框架Medoo为数据库链接,安装如下:

composer require catfan/Medoo

安装完成后就开始以PHP编写API了,代码如下:

<?php
require 'vendor/autoload.php';
use Medoo\Medoo;
$database = new Medoo([
    'type' => 'mysql',
    'host' => 'localhost',
    'database' => 'data',
    'username' => 'root',
    'password' => 'password'
]);
//为方便编写,用户ID直接前台传来,实际开发过程中建议使用session或cookie或其它用户验证
$id =isset($_GET['id'])?$_GET['id']:0;
//获取经纬度
$longitude = isset($_GET['longitude'])?$_GET['longitude']:0;
$latitude = isset($_GET['latitude'])?$_GET['latitude']:0;
//更新户自己的GPS信息
$database->update("nearby", [
"longitude" => $longitude,
"latitude" => $latitude
], [
"id" =>$id
]);
//访问以下地址获取附近用户
http://xxx.com/?id=1&longitude=12.2222544&latitude=65.54451
$longitudeAndLatitude = getAround($longitude, $latitude, '100');
$datas = $database->select("account", [
    "user_name",
    "email"
], [
    "user_id[>]" => 100
]);
$list = $database->query("SELECT *,(st_distance(point(longitude,latitude),point('{$longitude}','{$latitude}'))*95000/1000) as distance FROM nearby WHERE id != '{$id}' AND longitude >= '{$longitudeAndLatitude['minLng']}' AND longitude <= '{$longitudeAndLatitude['maxLng']}' AND latitude >= '{$longitudeAndLatitude['minLat']}' AND latitude <= '{$longitudeAndLatitude['maxLat']}' ORDER BY distance ASC limit 10")
->fetchAll();
print_r($database->log());
print_r($list);
/**
*
* 函数:根据经纬度及半径范围(单位:千米)返回坐标
* @param  string $longitude   经度
* @param  string $latitude 纬度
* @param  string $raidus 范围,千米
*
**/
function getAround($longitude, $latitude, $raidus)
{
    $PI = pi();
    $raidus = $raidus*1000;
    $degree = (24901*1609)/360.0;
    $dpmLat = 1/$degree;
    $radiusLat = $dpmLat*$raidus;
    $minLat = $latitude - $radiusLat;
    $maxLat = $latitude + $radiusLat;
    $mpdLng = $degree*cos($latitude * ($PI/180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng*$raidus;
    $minLng = $longitude - $radiusLng;
    $maxLng = $longitude + $radiusLng;
    return ['minLat'=>$minLat, 'maxLat'=>$maxLat, 'minLng'=>$minLng, 'maxLng'=>$maxLng];
}


文章写得不错?我是土豪我要在线打赏!
在线打赏

昵称:

验证码:验证码

评论:

文章分类
系统
程序
数据
Office
随笔
热门文章
Excel文件内容很少,但文件很大,打开很慢、很卡怎么办?
Excel动态引用各表格指定单元格数据
开篇第一章
Excel文件内容很少,但文件很大,打开很慢怎么办?
如何利用python修改文件的创建时间,修改时间,访问时间
发现一个好网站——春燕文档
Ubuntu22.04中用thunar替换默认文件管理器,提示无法启动“TerminalEmulator“的首选应用程序
MySQL如何按每个分类查询10条数据,即MySQL如何每个分类查询10条数据
文章推荐
请不要奇怪,为什么最近博客的文章是几年前的内容
免责声明
关于博主
开篇第一章
随机推荐
摸死你个性签名集合
人成熟的四个标准
asp+access+wml网页编程:asp读取access数据分页输出到手机客户端
强悍的图片搜索引擎,以图搜图
网站模板调试,本地浏览正常,但上传后在IE6中是乱的
富士康第十跳诞生,工作压力大还是承受能力小?
两天整了份简报。。。。
PHP 获取系统信息,PHP 获取服务器详细信息
PHP7报错:Call to undefined function mysql_connect(),如何兼容mysql_connect函数
php curl利用嘀咕、搜狐微博API发布微博
友情连接
春燕网络
春燕文档
谢润的博客