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根据经纬度排序,根据经纬度筛选距离段的更多相关文章

  1. sql server2008根据经纬度计算两点之间的距离

    --通过经纬度计算两点之间的距离 create FUNCTION [dbo].[fnGetDistanceNew] --LatBegin 开始经度 --LngBegin 开始维度 --29.49029 ...

  2. C# JackLib系列之如何获取地球上两经纬度坐标点间的距离

    获取地球上两经纬度坐标点间的距离,利用[大圆距离公式]   A diagram illustrating great-circle distance (drawn in red) between tw ...

  3. TSQL 根据经纬度计算两点间的距离;返回米(m)

    -- ============================================= -- Author:Forrest -- Create date: 2013-07-16 -- Des ...

  4. php根据地球上任意两点的经纬度计算两点间的距离 原理

    地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为6356.755千米,平均半径6371.004千米.如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R.如 ...

  5. java 根据经纬度坐标计算两点的距离算法

    /** * @Desc 根据经纬度坐标计算两点的距离算法<br> * @Author yangzhenlong <br> * @Data 2018/5/9 18:38 */ p ...

  6. 获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)

    如何获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)  目标:使用百度定位sdk开发实时移动距离计算功能,根据经纬度的定位,计算行驶公里数并实时刷新界面显示.大家 ...

  7. 百度地图Api之自定义标注:(获得标注的经纬度和中心经纬度即缩放度)

    百度地图Api之自定义标注:(获得标注的经纬度和中心经纬度即缩放度) <%@ Page Language="C#" AutoEventWireup="true&qu ...

  8. 百度经纬度和google经纬度互转

    原文:百度经纬度和google经纬度互转 百度地图的坐标转换,由于百度地图在GCJ02协议的基础上又做了一次处理,变为 BD09协议的坐标,以下是坐标的转化方式,可以方便和其他平台转化 private ...

  9. 经纬度计算两点间的距离,根据距离排序SQL

    #java的Utilspublic class DistanceUtil { // 地球平均半径 private static final double EARTH_RADIUS = 6378137; ...

随机推荐

  1. go 学习笔记之是否支持以及如何实现继承

    熟悉面向对象的小伙伴们可能会知道封装,继承和多态是最主要的特性,为什么前辈们会如此看重这三种特性,真的那么重要吗? 什么是封装 什么是封装,封装有什么好处以及怎么实现封装? 相信大多数小伙伴们都有自己 ...

  2. Java 集合源码分析(一)HashMap

    目录 Java 集合源码分析(一)HashMap 1. 概要 2. JDK 7 的 HashMap 3. JDK 1.8 的 HashMap 4. Hashtable 5. JDK 1.7 的 Con ...

  3. 前端优化---回流 (reflow)与 重绘(repaint)

    回流(reflow):指的是网络浏览器为了重新渲染部分或全部的文档而重新计算文档中元素的位置和几何结构的过程. 页面上节点是以树的形式展现的,我们通过js将页面上的一个节点删除,此时为了不让剩下的节点 ...

  4. 使用node中mysql模块连接本地数据库

    连接数据库的方法迄今为止学了三种: cmd方式.可视化工具,今天记第三种----node端连接数据库. 一:mysql模块介绍与下载 1.mysql模块是node端专门连接数据库的第三方模块 2.下载 ...

  5. Socket(套接字)在服务器端和客户端之间的基本工作原理

    Socket之间的连接过程主要可以概括为以下三步: 服务器建立监听:客户端初始化Socket动态库后创建套接字,然后指定客户端Socket的地址,循环绑定Socket直至成功,然后开始建立监听,此时客 ...

  6. mysql中的截取函数及其实例

    一.mysql截取字符串函数 1.left(str,length) 从左边截取length 2.right(str,length)从右边截取length 3.substring(str,index)当 ...

  7. P2518 [HAOI2010]计数 类似数位dp

    题意 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数.比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等. 现 ...

  8. Docker详解(一)

    目录 Docker简介 Docker组成 永远的HelloWorld 序言:众所周知,近几年的互联网各项技术发展的如火如荼,敏捷开发模式越来越普及,"快"似乎成为了行业的标准,于是 ...

  9. Docker下使用disconf:细说demo开发

    Docker下的disconf实战全文链接 <Docker搭建disconf环境,三部曲之一:极速搭建disconf>: <Docker搭建disconf环境,三部曲之二:本地快速构 ...

  10. SpringBoot系列__01HelloWorld

    接触SpringBoot很久了,但是一直没有很深入的研究一下源码,最近重启了博客,顺便开始深入研究一下技术. 1.简介 参照官方文档的说法,SpringBoot的设计理念就是为了简化Java程序员搭建 ...