文档章节

java 实现微信搜索附近人功能

凯文加内特
 凯文加内特
发布于 2015/09/08 17:31
字数 829
阅读 396
收藏 21

最近给andorid做后台查询数据功能,有一个需求是模仿微信的查找附近人功能。 数据库中存储每个用户的经纬度信息及用户信息,通过当前用户传递过来的经纬度查询这个用户半径N公里以内的用户信息。   

数据库表结构:

表信息

表名 Mobile_User

mu_id 自增,主键

mu_u_id 用户表的ID 外键

mu_longitud 精度

mu_latitude 纬度 (还有其他的一些信息,这里就列举4个字段足矣)

首先需要一个方法,是把传递过来的经纬度按照半径N公里扩散,找出距离中心经纬度N公里的上下左右经纬度值。效果如图


尴尬 随手画的  勿喷


以中心生成经纬度时 正上方和正下方的精度是不变的,只有纬度变化。 生成左右时道理一样,只有精度变化,纬度是不变的。

所以只需要生成上下的纬度,左右的精度就可以了。

参考了网上的文章,http://digdeeply.info/archives/06152067.html 这篇文章是用PHP实现的经纬度查询。修改成java的 代码如下

/** 
     * 生成以中心点为中心的四方形经纬度 
     *  
     * @param lat 纬度 
     * @param lon 精度 
     * @param raidus 半径(以米为单位) 
     * @return 
     */  
    public static double[] getAround(double lat, double lon, int raidus) {  
  
        Double latitude = lat;  
        Double longitude = lon;  
  
        Double degree = (24901 * 1609) / 360.0;  
        double raidusMile = raidus;  
  
        Double dpmLat = 1 / degree;  
        Double radiusLat = dpmLat * raidusMile;  
        Double minLat = latitude - radiusLat;  
        Double maxLat = latitude + radiusLat;  
  
        Double mpdLng = degree * Math.cos(latitude * (Math.PI / 180));  
        Double dpmLng = 1 / mpdLng;               
        Double radiusLng = dpmLng * raidusMile;   
        Double minLng = longitude - radiusLng;    
        Double maxLng = longitude + radiusLng;    
        return new double[] { minLat, minLng, maxLat, maxLng };  
    }

这样四周的经纬度都已经生成了。    
下一步是查询数据库中和四周经纬度匹配的数据。 如果数据量很大的话会很耗时间,而且会很消耗流量。所以需要用到分页查询 

代码如下 

select * from mobile_user 
			where mu_latitude <> 0
			and mu_longitud > #left_lat#
			and mu_longitud < #right_lat#
			and mu_latitude > #down_lon#
			and mu_latitude < #top_lon#
			and mu_u_id <> #uid#
			order by ACOS(SIN((#lat# * 3.1415) / 180 ) * SIN((mu_latitude * 3.1415) / 180 ) 
			+COS((#lat# * 3.1415) / 180 ) * COS((mu_latitude * 3.1415) / 180 ) 
			*COS((#lon# * 3.1415) / 180 - (mu_longitud * 3.1415) / 180 ) ) 
			* 6380 asc limit #start#,#end#

我用的是ibatis框架,sql里以#开始并结束的 是我传递过来的参数。  sql语句计算了每条数据和中心经纬度的距离并且以最近进行排序。  sql语句是根据下面的方法演变而来
方法是计算两个经纬度之间的直线距离。

/** 
     * 计算中心经纬度与目标经纬度的距离(米) 
     *  
     * @param centerLon 
     *            中心精度 
     * @param centerLan 
     *            中心纬度 
     * @param targetLon 
     *            需要计算的精度 
     * @param targetLan 
     *            需要计算的纬度 
     * @return 米 
     */  
    private static double distance(double centerLon, double centerLat, double targetLon, double targetLat) {  
  
        double jl_jd = 102834.74258026089786013677476285;// 每经度单位米;  
        double jl_wd = 111712.69150641055729984301412873;// 每纬度单位米;  
        double b = Math.abs((centerLat - targetLat) * jl_jd);  
        double a = Math.abs((centerLon - targetLon) * jl_wd);  
        return Math.sqrt((a * a + b * b));  
    }

这样既实现了分页处理,又实现了每条数据的经纬度与中心经纬度的直线距离(以米为单位)。   
最后就是组成json数组返回给android使用了。  
做个笔记,欢迎补充。

思考:

数据量大了,需要按照经纬度进行分表

鉴于一些网站采集本blog的文章,  本站原创。  http://blog.csdn.net/qq7342272   转载请注明出处。


本文转载自:http://blog.csdn.net/qq7342272/article/details/7991714

凯文加内特
粉丝 341
博文 701
码字总数 110786
作品 0
青岛
后端工程师
私信 提问
加载中

评论(2)

凯文加内特
凯文加内特 博主

引用来自“12叔”的评论

mongodb 不是有么。
谢谢
12叔
12叔
mongodb 不是有么。
Java实现搜索附近人功能

想用Java实现如微信一样查找附近人功能,查了一些资料大致是通过客户端传过来的经纬度进行查询,还想大家讨论一下给出具体实现。一起完善成一个高效的实现。谢谢

隋济远
2014/03/31
3.9K
5
Java实现QQ微信轰炸机1.0(乞丐版)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/xiaoxiaob/article/details/93619747 9.1更新了: Java实现QQ微信轰炸...

Ben_小b
09/01
0
0
Java实现QQ微信轰炸机1.2(斗图乞丐版)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/xiaoxiaob/article/details/95601038 之前有小可爱评论可以实现斗图的...

Ben_小b
09/01
0
0
Java微信开发_00_资源汇总贴

1.微信公众平台技术文档(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432) 2.微信企业号开发接口文档(http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E......

rayner
2017/08/07
0
0
Java虚拟机JVM内部体系结构

Java虚拟机JVM内部体系结构 易百教程移动端:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"教程" 选择相关教程阅读或直接访问:http://m.yiibai.com 。 JVM(Java虚拟机)是一个抽象...

LYQ1990
2018/07/18
289
0

没有更多内容

加载失败,请刷新页面

加载更多

MySQL左连接问题,右表做筛选,左表列依然在

两张表,一张user表,一张user_log表 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFA......

bengozhong
27分钟前
5
0
重新开始学Java——多线程基础

多线程 进程 主流计算机操作系统都支持同时运行多个任务 , 每个任务通常就是一个程序 , 每个运行中的程序就是一个进程或者多个进程 。 进程的特点 独立性 进程是系统中独立存在的实体 可以...

大家都是低调来的
28分钟前
7
0
注解在Java中是如何工作的?

> 来一点咖啡,准备好进入注解的世界。 注解一直是 Java 的一个非常重要的部分,它从 J2SE 5.0 开始就已经存在了。在我们的应用程序代码中,经常看到 @Override 和 @Deprecated 这样的注解。...

liululee
30分钟前
18
0
Docker 容器连接

Docker 容器连接 容器间的链接有两种方法,你选择其一即可 网络端口映射 docker run -d -P docker run -d -p-P :是容器内部端口随机映射到主机的高端口。-p : 是容器内部端口绑定到指定...

测者陈磊
33分钟前
9
0
车载导航应用中基于Sketch UI主题定制方案的实现

1.导读 关于应用的主题定制,相信大家或多或少都有接触,基本上,实现思路可以分为两类: 内置主题(应用内自定义style) 外部加载方式(资源apk形式、压缩资源、插件等) 其实,针对不同的主题...

阿里云官方博客
38分钟前
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部