1. 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语句
  1. // lon1当前用户经度 lat1当前用户纬度,lon2 sql的经度字段 lat sql的纬度字段
    function distance_sql($lon1,$lat1,$lon2,$lat2)
  2. {
  3. $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) ";
  4. return $sql;
  5. }

这是一个生成根据SQL排序函数代码

接下来下面是设置经纬度范围内的数据

  1. // 当前登录用户经纬度
    if(I("post.location")){
  2. // 用户经纬度
  3. $location = explode(",",I("post.location"));
  4. $userLon = $location[0];
  5. $userLat = $location[1];
  6. // 经纬距离筛选筛选
  7. $location = getAround($userLat,$userLon,1000000);
  8. $wheres1.=" and (((px_lat >= {$location["minLat"]}) and (px_lat <= {$location['maxLat']})) and ((px_lon >= {$location['minLng']}) and (px_lon <= {$location['maxLng']})))";
  9. // 经纬度距离优先排序,距离最近优先显示
  10. if(I("post.distance_sort")){
  11. $distanceSql = ",".distance_sql($userLon,$userLat,"px_lon","px_lat")." as distance";
  12. $orderBy = " distance";
  13. }
  14. if(I("post.km")){
            $kmStr = I("post.km");
            // 距离 1千米-1万米之前
  15. // $kmStr = "1000,10000";
            
            // 距离小于1千米
              //$kmStr = "<1000";
               //距离大于1千米
            //$kmStr = ">1000";
  16. if(strpos($kmStr,"<") !== false){
  17. $km = explode("<",$kmStr);
  18. $wheres2 .= " and (location.distance <= {$km[1]})";
  19. }else if(strpos($kmStr,"-") !== false){
  20. $km = explode("-",$kmStr);
  21. $wheres2 .= " and ((location.distance >= {$km[0]}) and (location.distance <= {$km[1]}))";
  22. }else if(strpos($kmStr,">") !== false){
  23. $km = explode(">",$kmStr);
  24. $wheres2 .= " and (location.distance >= {$km[1]})";
  25. }
  26. }
  27. }

下面算出经纬度范围内的数据控制函数

  1. /**
  2. *
  3. * @param $latitude 纬度
  4. * @param $longitude 经度
  5. * @param $raidus 半径范围(单位:米)
  6. * @return multitype:number
  7. */
  8. function getAround($latitude,$longitude,$raidus)
  9. {
  10. $PI = 3.14159265;
  11. $degree = (24901*1609)/360.0;
  12. $dpmLat = 1/$degree;
  13. $radiusLat = $dpmLat*$raidus;
  14. $minLat = $latitude - $radiusLat;
  15. $maxLat = $latitude + $radiusLat;
  16. $mpdLng = $degree*cos($latitude * ($PI/180));
  17. $dpmLng = 1 / $mpdLng;
  18. $radiusLng = $dpmLng*$raidus;
  19. $minLng = $longitude - $radiusLng;
  20. $maxLng = $longitude + $radiusLng;
  21. return array (minLat=>$minLat, maxLat=>$maxLat, minLng=>$minLng, maxLng=>$maxLng);
  22. }

要实现根据经纬度排序

就直接调用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

  1. public function training_list()
  2. {
  3. $wheres1 = "(px_state = 1)";
  4. $wheres2 = " where (1=1)";
  5.  
  6. $orderBy = " px_id desc";
  7. if(I("post.location")){
  8. // 用户经纬度
  9. $location = explode(",",I("post.location"));
  10. $userLon = $location[0];
  11. $userLat = $location[1];
  12. // 经纬度筛选
  13. $location = getAround($userLat,$userLon,1000000);
  14. $wheres1.=" and (((px_lat >= {$location["minLat"]}) and (px_lat <= {$location['maxLat']})) and ((px_lon >= {$location['minLng']}) and (px_lon <= {$location['maxLng']})))";
  15. // 经纬度距离筛选
  16. if(I("post.distance_sort")){
  17. $distanceSql = ",".distance_sql($userLon,$userLat,"px_lon","px_lat")." as distance";
  18. $orderBy = " distance";
  19. }
  20. if(I("post.km")){
  21. $kmStr = htmlspecialchars_decode(I("post.km"));
  22. if(strpos($kmStr,"<") !== false){
  23. $km = explode("<",$kmStr);
  24. $wheres2 .= " and (location.distance <= {$km[1]})";
  25. }else if(strpos($kmStr,"-") !== false){
  26. $km = explode("-",$kmStr);
  27. $wheres2 .= " and ((location.distance >= {$km[0]}) and (location.distance <= {$km[1]}))";
  28. }else if(strpos($kmStr,">") !== false){
  29. $km = explode(">",$kmStr);
  30. $wheres2 .= " and (location.distance >= {$km[1]})";
  31. }
  32. }
  33. }
  34.  
  35. $showNum = 10;
  36. if(I("post.page")){
  37. $page = I("post.page");
  38. }else{
  39. $page = 1;
  40. }
  41. $n = ($page-1)*$showNum;
  42. $field = "*{$distanceSql}";
  43. $sql = "select location.* from (select {$field} from bsx_training where {$wheres1} order by {$orderBy} limit {$n},{$showNum}) location {$wheres2}";
  44. $training = M()->query($sql);
  45.  
  46. dump(M()->getlastsql());die;
  47.  
  48. }

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. net必问的面试题系列之基本概念和语法

    上个月离职了,这几天整理了一些常见的面试题,整理成一个系列给大家分享一下,机会是给有准备的人,面试造火箭,工作拧螺丝,不慌,共勉. 1.net必问的面试题系列之基本概念和语法 2.net必问的面试题系 ...

  2. 再见 Spring Boot 1.X ,Spring Boot 2.X 走向舞台中心

    2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束. 其实早在2018年7月30号,Spring 官方就已经 ...

  3. ES6之模块化导入导出

    1.概述 在js的历史上一直没有模块(module)体系,无法将一个大程序拆分成相互依赖的小文件,再用简单的方法拼装起来,这对开发大型的.复杂的项目形成了巨大障碍. 在 ES6 之前,社区制定了一些模 ...

  4. Node开发知识概括

    一. javascript高级话题(面向对象,作用域,闭包,设计模式等) 1. 常用js类定义的方法有哪些? 参考答案:主要有构造函数原型和对象创建两种方法.原型法是通用老方法,对象创建是ES5推荐使 ...

  5. 2018 Petrozavodsk Winter Camp, Yandex Cup

    A. Ability Draft solved by RDC 60min start, 148 min AC, 1Y 题意:两只 Dota 队伍,每队 \(n\) 个英雄,英雄一开始无技能,他们需要按 ...

  6. HDU 4396More lumber is required 过至少K条边的最短路

    /* ** 题目要求过最少k条边的最短路 */ #include <iostream> #include <cstdio> #include <cstring> # ...

  7. springboot使用Jpa连接数据库

    springboot使用Jpa连接数据库 1.pom.xml: <?xml version="1.0" encoding="UTF-8"?> < ...

  8. Spring Cloud官方文档中文版-Spring Cloud Config(上)-服务端(配置中心)

    官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...

  9. eclipse中注释模板使用

    步骤: Window -->Preferences-->Java-->Code Style -->Code Templates-->Comments 1.Files可对整 ...

  10. Elasticsearch(7) --- 复合查询

    Elasticsearch(7) ---复合查询 复合查询有:bool query(布尔查询).boosting query(提高查询).constant_score(固定分数查询).dis_max( ...