php根据经纬度排序,根据经纬度筛选距离段
SQL 语句:select location.* from (select *,round(6378.138*2*asin(sqrt(pow(sin( (36.668530*pi()/180-px_lat*pi()/180)/2),2)+cos(36.668530*pi()/180)*cos(px_lat*pi()/180)* pow(sin( (117.020359*pi()/180-px_lon*pi()/180)/2),2)))*1000) as distance from bsx_training where (px_state = 1) and (type_id != '') and (((px_lat >= 27.683290277922) and (px_lat <= 45.653769722078)) and ((px_lon >= 105.81826766053) and (px_lon <= 128.22245033947))) order by distance limit 0,10) location where (1=1) and (location.distance <= 500)
先忽略上面这条SQL语句。一一解释
根据SQL排序的SQl语句
// lon1当前用户经度 lat1当前用户纬度,lon2 sql的经度字段 lat sql的纬度字段
function distance_sql($lon1,$lat1,$lon2,$lat2)
{
$sql = "round(6378.138*2*asin(sqrt(pow(sin( ({$lat1}*pi()/180-{$lat2}*pi()/180)/2),2)+cos({$lat1}*pi()/180)*cos({$lat2}*pi()/180)* pow(sin( ({$lon1}*pi()/180-{$lon2}*pi()/180)/2),2)))*1000) ";
return $sql;
}
这是一个生成根据SQL排序函数代码
接下来下面是设置经纬度范围内的数据
// 当前登录用户经纬度
if(I("post.location")){
// 用户经纬度
$location = explode(",",I("post.location"));
$userLon = $location[0];
$userLat = $location[1];
// 经纬距离筛选筛选
$location = getAround($userLat,$userLon,1000000);
$wheres1.=" and (((px_lat >= {$location["minLat"]}) and (px_lat <= {$location['maxLat']})) and ((px_lon >= {$location['minLng']}) and (px_lon <= {$location['maxLng']})))";
// 经纬度距离优先排序,距离最近优先显示
if(I("post.distance_sort")){
$distanceSql = ",".distance_sql($userLon,$userLat,"px_lon","px_lat")." as distance";
$orderBy = " distance";
}
if(I("post.km")){
$kmStr = I("post.km");
// 距离 1千米-1万米之前
// $kmStr = "1000,10000";
// 距离小于1千米
//$kmStr = "<1000";
//距离大于1千米
//$kmStr = ">1000";
if(strpos($kmStr,"<") !== false){
$km = explode("<",$kmStr);
$wheres2 .= " and (location.distance <= {$km[1]})";
}else if(strpos($kmStr,"-") !== false){
$km = explode("-",$kmStr);
$wheres2 .= " and ((location.distance >= {$km[0]}) and (location.distance <= {$km[1]}))";
}else if(strpos($kmStr,">") !== false){
$km = explode(">",$kmStr);
$wheres2 .= " and (location.distance >= {$km[1]})";
}
}
}
下面算出经纬度范围内的数据控制函数
/**
*
* @param $latitude 纬度
* @param $longitude 经度
* @param $raidus 半径范围(单位:米)
* @return multitype:number
*/
function getAround($latitude,$longitude,$raidus)
{
$PI = 3.14159265;
$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 array (minLat=>$minLat, maxLat=>$maxLat, minLng=>$minLng, maxLng=>$maxLng);
}
要实现根据经纬度排序
就直接调用distance_sql(lon1,lat1,lon2,lat2)传入参数 并且as 一个别名例如 as distance, 然后sql语句中 order by 排序 根据 distance排序
如果筛选距离段 1000米-2000米的数据
那就sql语句嵌套sql
select *.loation from (select *,round(6378.138*2*asin(sqrt(pow(sin( (36.668530*pi()/180-px_lat*pi()/180)/2),2)+cos(36.668530*pi()/180)*cos(px_lat*pi()/180)* pow(sin( (117.020359*pi()/180-px_lon*pi()/180)/2),2)))*1000) as distance) from table location where (location.distance >= 1000) and (location.distance <= 2000))
如果实现根据最近位置排序sql
select *,round(6378.138*2*asin(sqrt(pow(sin( (36.668530*pi()/180-px_lat*pi()/180)/2),2)+cos(36.668530*pi()/180)*cos(px_lat*pi()/180)* pow(sin( (117.020359*pi()/180-px_lon*pi()/180)/2),2)))*1000) as distance order by distance
public function training_list()
{
$wheres1 = "(px_state = 1)";
$wheres2 = " where (1=1)"; $orderBy = " px_id desc";
if(I("post.location")){
// 用户经纬度
$location = explode(",",I("post.location"));
$userLon = $location[0];
$userLat = $location[1];
// 经纬度筛选
$location = getAround($userLat,$userLon,1000000);
$wheres1.=" and (((px_lat >= {$location["minLat"]}) and (px_lat <= {$location['maxLat']})) and ((px_lon >= {$location['minLng']}) and (px_lon <= {$location['maxLng']})))";
// 经纬度距离筛选
if(I("post.distance_sort")){
$distanceSql = ",".distance_sql($userLon,$userLat,"px_lon","px_lat")." as distance";
$orderBy = " distance";
}
if(I("post.km")){
$kmStr = htmlspecialchars_decode(I("post.km"));
if(strpos($kmStr,"<") !== false){
$km = explode("<",$kmStr);
$wheres2 .= " and (location.distance <= {$km[1]})";
}else if(strpos($kmStr,"-") !== false){
$km = explode("-",$kmStr);
$wheres2 .= " and ((location.distance >= {$km[0]}) and (location.distance <= {$km[1]}))";
}else if(strpos($kmStr,">") !== false){
$km = explode(">",$kmStr);
$wheres2 .= " and (location.distance >= {$km[1]})";
}
}
} $showNum = 10;
if(I("post.page")){
$page = I("post.page");
}else{
$page = 1;
}
$n = ($page-1)*$showNum;
$field = "*{$distanceSql}";
$sql = "select location.* from (select {$field} from bsx_training where {$wheres1} order by {$orderBy} limit {$n},{$showNum}) location {$wheres2}";
$training = M()->query($sql); dump(M()->getlastsql());die; }
php根据经纬度排序,根据经纬度筛选距离段的更多相关文章
- sql server2008根据经纬度计算两点之间的距离
--通过经纬度计算两点之间的距离 create FUNCTION [dbo].[fnGetDistanceNew] --LatBegin 开始经度 --LngBegin 开始维度 --29.49029 ...
- C# JackLib系列之如何获取地球上两经纬度坐标点间的距离
获取地球上两经纬度坐标点间的距离,利用[大圆距离公式] A diagram illustrating great-circle distance (drawn in red) between tw ...
- TSQL 根据经纬度计算两点间的距离;返回米(m)
-- ============================================= -- Author:Forrest -- Create date: 2013-07-16 -- Des ...
- php根据地球上任意两点的经纬度计算两点间的距离 原理
地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为6356.755千米,平均半径6371.004千米.如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R.如 ...
- java 根据经纬度坐标计算两点的距离算法
/** * @Desc 根据经纬度坐标计算两点的距离算法<br> * @Author yangzhenlong <br> * @Data 2018/5/9 18:38 */ p ...
- 获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)
如何获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等) 目标:使用百度定位sdk开发实时移动距离计算功能,根据经纬度的定位,计算行驶公里数并实时刷新界面显示.大家 ...
- 百度地图Api之自定义标注:(获得标注的经纬度和中心经纬度即缩放度)
百度地图Api之自定义标注:(获得标注的经纬度和中心经纬度即缩放度) <%@ Page Language="C#" AutoEventWireup="true&qu ...
- 百度经纬度和google经纬度互转
原文:百度经纬度和google经纬度互转 百度地图的坐标转换,由于百度地图在GCJ02协议的基础上又做了一次处理,变为 BD09协议的坐标,以下是坐标的转化方式,可以方便和其他平台转化 private ...
- 经纬度计算两点间的距离,根据距离排序SQL
#java的Utilspublic class DistanceUtil { // 地球平均半径 private static final double EARTH_RADIUS = 6378137; ...
随机推荐
- Python 开发学习路线
第一阶段:Python 语言基础 数据类型 流程控制 常用模块 函数.迭代器.装饰器 递归.迭代.反射 面向对象编程 购物车程序 计算器程序开发 模拟人生游戏开发 第二阶段:网络编程 Socket c ...
- 逆向破解之160个CrackMe —— 016
CrackMe —— 016 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...
- idea打开eclipse项目并部署至tomcat
前言:因为遇到了用idea打开eclipse项目并配置外置tomact的场景,经过实验也成功了,所以特地来记录一下. 导入eclipse项目 这里我们导入的eclipse下开发的maven项目,直接点 ...
- 合并多个jar包,并通过私服依赖
背景:许多jar包在maven仓库中没有,项目如果添加了许多的本地jar包,别人拿到代码也无法编译 需求:将本地jar包上传至私服并设置依赖,如果jar包较多,但都从属于同一功能,需要合并为一个jar ...
- 小白学习day2------比较运算
1 算术运算 加+ 2+3=5 减 - 3-2=1 乘 * 2*3=6 除 / 6/2=3 取膜 % 余数 幂 ** 2**3=8 整除 // 9//4=2 2 比较运算 == 判断是否等于 != , ...
- Java 并发:学习Thread 类
Java 中 Thread类 的各种操作与线程的生命周期密不可分,了解线程的生命周期有助于对Thread类中的各方法的理解.一般来说,线程从最初的创建到最终的消亡,要经历创建.就绪.运行.阻塞 和 消 ...
- Codeforces 1009G
题意略. 思路: 首先是贪心, 我们从前往后依次从小到大考虑放哪个字符, 重点是判断放了这个字符后, 对于剩下的后缀是否存在合法解. 考虑每个位置的允许放的字符集合只有2 ^ 6种, 我们预处理一个后 ...
- Leetcode之深度优先搜索(DFS)专题-329. 矩阵中的最长递增路径(Longest Increasing Path in a Matrix)
Leetcode之深度优先搜索(DFS)专题-329. 矩阵中的最长递增路径(Longest Increasing Path in a Matrix) 深度优先搜索的解题详细介绍,点击 给定一个整数矩 ...
- JUC包Lock机制的支持--AQS
在上一次总结中,提到了JUC包下使用Lock接口实现同步的方法,以及和Synchronized关键字的一些比较,那么使用Lock完成锁机制的底层支持又是什么呢?总结如下: 1 AQS是什么 AQS是一 ...
- 【qt】【QString的诸多操作】
前言: qt的数据处理莫过于QString,QString对于字符串的操作多的数不胜数.下面博主就将常用的罗列出来,一起分享. 正文: 下面的操作具体为:追加,查找,删除,提取,分割,各种转换等等. ...