`
1028826685
  • 浏览: 938913 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类

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

阅读更多

最近给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 }; 
    }

 

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

代码如下

 

@RequestMapping(params = "doGetQuserNearList")
@ResponseBody
public JSONObject doGetQuserNearList( HttpServletRequest request) {
    JSONObject jsonObject=new JSONObject();
    String km=request.getParameter("km");//搜索范围  这里以米为单位
    String useridString=request.getParameter("userid");
    String precision=request.getParameter("precision");
    String latitude=request.getParameter("latitude");
    String rows=request.getParameter("rows");
    String page=request.getParameter("page");
    try {
       
        if("".equals(useridString)||useridString==null){
            jsonObject.put("status", "0");
            jsonObject.put("msg", "用户id不能为空");
            return jsonObject;
        }
       
        Session session= memberService.getSession();
        Query query=null;
     
     org.hibernate.SQLQuery sqlQuery= session.createSQLQuery("select * from q_member  where latitude <> 0 "
                + "and _precision > :left_lat "
                + "and _precision < :right_lat "
                + "and latitude > :down_lon  "
                + "and latitude < :top_lon  "
                + "and id <> :userid "
                +" order by ACOS(SIN((:lat * 3.1415) / 180 ) * SIN((latitude * 3.1415) / 180 )+COS((:lat * 3.1415) / 180 )*COS((latitude * 3.1415) / 180 )*COS((:lon * 3.1415) / 180 - (_precision * 3.1415) / 180 ) ) * 6380 asc limit :start,:size");
         double[] lalon=Location.getAround(Double.valueOf(latitude), Double.valueOf(precision), Integer.valueOf(km));
       
         sqlQuery.setParameter("left_lat", lalon[1]);   
         sqlQuery.setParameter("right_lat", lalon[3]);
         sqlQuery.setParameter("down_lon", lalon[0]);
         sqlQuery.setParameter("top_lon", lalon[2]);
         
         sqlQuery.setParameter("lat", latitude);
         sqlQuery.setParameter("lon", precision);
         sqlQuery.setParameter("start", Integer.valueOf(page)-1);
         sqlQuery.setParameter("size", Integer.valueOf(rows));
         sqlQuery.setParameter("userid", useridString);
         
            java.util.List<MemberEntity> memberEntities=sqlQuery.addEntity(MemberEntity.class).list();
        
        //循环计算相对距离
        for(MemberEntity memberEntity:memberEntities){
       
            memberEntity.setDistance(Location.distance(Double.valueOf(latitude), Double.valueOf(precision), Double.valueOf(memberEntity.getLatitude()), Double.valueOf(memberEntity.getPrecision())));
        }
       
    
        jsonObject.put("status", "1");
        jsonObject.put("msg", memberEntities);
       
    } catch (Exception e) {
        e.printStackTrace();
        message = "获取失败";
        jsonObject.put("status", "0");
        jsonObject.put("msg", message);
        throw new BusinessException(e.getMessage());
    }
   
    return jsonObject;
}

 

我用的是Hibernate框架,  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)); 
    }

 

这样既实现了分页处理,又实现了每条数据的经纬度与中心经纬度的直线距离(以米为单位)。   
 

 

 

分享到:
评论

相关推荐

    Android+仿微信实现搜索附近的人功能源码

    在Android开发中,仿微信实现搜索附近的人功能是一项常见的需求,尤其在社交应用中非常普遍。这个源码项目提供了一个基础的实现方案,通过获取用户的GPS坐标并上传,然后展示附近的用户信息。以下是对这个功能的详细...

    QQ微信附近好友雷达扫描

    【QQ微信附近好友雷达扫描】是一个仿制QQ和微信中“附近的人”功能的应用程序,其核心在于模拟雷达扫描的效果,让用户能够在一定范围内发现并连接附近的其他用户。这个功能在社交应用中非常常见,旨在帮助用户拓展...

    考拉开源仿微信uniapp前端+JAVA后端IM即时通讯

    在这个项目中,uniapp被用于构建用户界面,实现聊天窗口、联系人列表、消息发送接收等功能,确保在不同设备上都能获得一致的用户体验。 1. 组件化开发:uniapp采用组件化开发模式,每个功能模块都可以封装为一个...

    类似微信的联系人根据字母排列查询

    在Android开发中,实现“类似微信的联系人根据字母排列查询”的功能是一项常见的需求,它涉及到用户界面(UI)的设计、数据结构的处理以及搜索算法的实现。这一功能的目的是为了方便用户快速查找和筛选联系人,提高...

    微信通讯录朋友列表.zip

    本项目聚焦于实现微信通讯录朋友列表的功能,通过分析给出的代码,我们可以深入理解如何在应用程序中处理和展示联系人信息。"微信通讯录朋友列表.zip"包含了实现这一功能的源代码,方便开发者学习和参考。 首先,...

    仿微信联系人DEMO

    在IT行业中,开发类似微信的联系人功能是常见的应用场景,特别是在构建社交软件或者即时通讯工具时。本DEMO,名为“仿微信联系人DEMO”,旨在实现与微信类似的联系人查询和展示功能,特别是强调了根据联系人首字母...

    Android-仿微信通讯录的实现联系人按字母分组显示右侧添加快速索引条

    总的来说,实现“Android-仿微信通讯录的实现联系人按字母分组显示右侧添加快速索引条”涉及到Android界面设计、数据结构、排序算法以及事件监听等多个知识点,是一个综合性的开发任务。通过这样的实践,开发者可以...

    用Recycleview实现仿微信通讯录的右侧索引

    本教程将详细介绍如何利用Recycleview实现一个仿微信通讯录的右侧索引功能,这个功能通常被称为字母侧滑栏或者快速索引栏,它允许用户通过点击字母快速定位到联系人。 首先,我们需要理解Recycleview的基本工作原理...

    仿微信联系人按字母顺序排序的ListView

    这个“仿微信联系人按字母顺序排序的ListView”示例就是一个很好的学习点,它展示了如何利用自定义控件来实现这一功能。 首先,我们需要理解ListView的基本原理。ListView是Android中用于显示大量数据的视图组件,...

    基于微信小程序的食疗微信小程序的设计与实现(java).zip

    本资源介绍了一个基于微信小程序的食疗微信小程序的设计与实现。该小程序旨在帮助用户了解食物与健康之间的关系,提供个性化的饮食建议,以达到改善身体健康的目的。设计方面,我们采用了简洁明了的用户界面,方便...

    android listview仿照微信联系人字母排序

    总的来说,"android listview仿照微信联系人字母排序"涉及到的主要知识点包括:ListView的使用、Adapter模式、数据排序算法、字母导航实现、搜索功能的集成以及性能优化。通过这个项目,开发者不仅可以深入理解...

    仿钉钉、微信选择联系人,支持搜索框和a-z选择

    在IT行业中,构建类似钉钉或微信的联系人选择功能是一项常见的需求,它涉及到用户界面设计、数据管理和搜索算法等多个方面。"仿钉钉、微信选择联系人"这个标题所指的就是开发一个与这两个流行应用类似的联系人选框,...

    使用wx-java-miniapp-spring-boot-starter开发的微信小程序演示demo.zip

    其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始...

    微信电话簿.zip

    在本压缩包“微信电话簿.zip”中,包含了一个实现微信电话簿功能的代码示例。这个项目的主要目的是为了帮助开发者理解和构建类似微信的通讯录功能。通过分析和学习这段代码,我们可以掌握一些重要的IT知识点,特别是...

    [JavaApk.com]高仿微信.rar

    1. **用户界面(UI)**:源码中将包含各种布局文件(XML)和对应的Activity或Fragment,用于实现微信的各个界面,如登录页面、聊天界面、联系人列表等。开发者可能会使用Android Studio中的布局设计工具来创建这些UI...

    仿微信6.0界面

    在这里,我们将深入探讨“仿微信6.0界面”的核心设计理念、功能特点以及实现这些界面元素的技术手段。 首先,微信6.0的界面设计遵循了简洁明了的原则,旨在提供更加直观、高效的沟通体验。设计师们采用了清晰的图标...

    微信开发众筹项目视频教学小程序+java后端开发+mysql数据库

    在本微信开发众筹项目的视频教学中,我们将深入探讨如何利用HBuilder X开发微信小程序,并结合Java后端开发和MySQL数据库构建完整的众筹平台。这个项目涵盖了多个关键知识点,旨在帮助开发者全面掌握微信小程序的...

    Java项目基于SSM实现的跳蚤市场微信小程序

    基于SSM(Spring、SpringMVC、MyBatis)框架实现的跳蚤市场微信小程序,为用户提供了一个便捷、灵活的二手商品交易平台。主要功能包括: 商品浏览与搜索:用户可以在小程序中浏览各种二手商品,如书籍、衣物、电子...

    java项目之基于微信小程序的零食盒子设计与实现(源码+说明文档).zip

    这个项目适合于毕业设计或课程设计,提供完整的源码和说明文档,帮助学习者理解和实践Java后端开发以及微信小程序的前端实现。 1. **微信小程序**:微信小程序是一种轻量级的应用开发平台,无需下载安装即可使用,...

Global site tag (gtag.js) - Google Analytics