最近工作需要,页面展示某个城市附近300km范围内所有的其它城市。找了半天也没有合适的方法,这里给出一种解决方法,如果有更好的,请不吝赐教。

一、准备工作

问题抽象: 求城市300km范围内所有的其它城市,可以抽象为球面上两个点的距离是否在一定的范围内

球面距离: 球面上两点之间的最短连线的长度,就是经过这两点的大圆在这两点间的一段劣弧的长度。(大圆就是经过球心的平面截球面所得的圆)

球面距离计算公式: 设两点A、B的经、纬度分别为(jA,wA)(jB,wB),则半径为R的球面上两点间的最短距离(大圆弧)为:弧AB=R*arccos[sin(wA)sin(wB)+cos(wA)cos(wB)*cos(jA-jB)

地球半径: 地球的平均半径6371.393千米

表结构:

二、sql计算

SELECT province, city FROM city WHERE city != "苏州" and
6371.393* ACOS
(SIN(31.30703 * PI() / 180) * SIN(latitude * PI() / 180)+COS(31.30703 * PI() / 180) * COS(latitude * PI() / 180) * COS(120.591431 * PI() / 180-longitude * PI() / 180)
) <= 300
复制代码

使用sql计算直接给出结果,但是sql计算会占用较多cpu资源,如果并发量较高,不建议使用。

三、使用spring缓存

  1. 在项目启动时,spring缓存所有的城市信息
  2. 遍历城市集合,判断每个城市是否在范围内
  3. 然后返回页面展示

1. 代码展示

  • controller

    • url要符合restful风格,不建议使用中文,这里是为了演示方便
@RequestMapping("/aroundCity/{cityName:[\u4E00-\u9FFF]+}") // 汉字正则表达式
public String aroundCityMapping(Model model, @PathVariable String cityName) {List<City> listAroundcities = aroundCityService.listAroundcities(cityName, distance);if (listAroundcities != null && listAroundcities.size() > 0) {model.addAttribute("listAroundcities", listAroundcities);model.addAttribute("distance", distance);model.addAttribute("cityName", cityName);}return "aroundCity";
}复制代码
  • service

    • dao层使用mybatis的逆向工程生成(逆向工程及mybatis语法以后单独总结一份)
public List<City> listAroundcities(String cityName, int distance) {List<City> cityList = basicInfoService.getCityList();CityExample cityExample = new CityExample();Criteria criteria = cityExample.createCriteria();criteria.andCityEqualTo(cityName);List<City> cities = cityMapper.selectByExample(cityExample);City city = null;if (cities == null || cities.size() < 1) {return null;}city = cities.get(0);List<City> aroundCitiesByDistance = addAroundCitiesByDistance(city, cityList, distance);return aroundCitiesByDistance;
}
复制代码
/*** 添加当前城市x公里内的所有城市*/
private List<City> addAroundCitiesByDistance(City localCity, List<City> cityList, int distance) {List<City> aroundCityList = new ArrayList<City>(); // 周围城市列表for (City city : cityList) {Float lat = city.getLatitude();Float lng = city.getLongitude();if (!Objects.equals(city.getCity(), localCity.getCity()) && withinRange(localCity.getLatitude(), localCity.getLongitude(), lat, lng, distance)) {aroundCityList.add(city);}}return aroundCityList;
}
复制代码
/*** 判断两个经纬坐标之间的距离是否在distance km内*/
private boolean withinRange(float lat1, float lng1, float lat2, float lng2, int distance) {double exp1 = Math.sin(lat1 * Math.PI / 180) * Math.sin(lat2 * Math.PI / 180);double exp2 = Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180)* Math.cos(lng1 * Math.PI / 180 - lng2 * Math.PI / 180);return EARTH_RADIUS * Math.acos(exp1 + exp2) <= distance;
}
复制代码
  • BasicInfoService

    • 使用@PostConstruct注解,可以在项目启动时执行
    • 获取所有的城市信息,并交给spring管理
    • spring默认是单例模式,而且List集合不是线程安全的,所有不要提供setter方法
private List<City> cityList;@PostConstruct
public void init() {cityList = cityMapper.selectByExample(new CityExample());
}public List<City> getCityList() {return cityList;
}
复制代码
  • view

    • freemarker作为视图
    • 多视图配置详见共享代码(下方有百度云地址)
    • freemarker的语法及使用技巧,以后总结
<table><tr><td>ID</td><td>省份</td><td>城市</td><td>经度</td><td>纬度</td></tr><#list listAroundcities as city><tr><td>${city.id}</td><td>${city.province}</td><td>${city.city}</td><td>${city.longitude}</td><td>${city.latitude}</td></tr></#list>
</table>
复制代码

2. 测试

url:http://localhost:8090/aroundCity/aroundCity/苏州;

3. 结果

4. 验证

使用百度地图的测距功能逐个验证

总结

  • 想了解更详细的内容可以直接下载代码:链接:http://pan.baidu.com/s/1ge5fMxX 密码:j2qvBasicInfoService缓存也可以换成redismemcache等主流的nosql数据库管理,这里主要是为了方便演示
  • 参考内容1:百度百科-球面距离
  • 参考内容2:百度百科-地球半径
  • 地球是一个两极稍扁、赤道略鼓的不规则球体,平均半径6371千米,这只是近似计算

转载于:https://juejin.im/post/5a34e6bef265da432f3130e2

spring计算方圆300km内其它城市(附完整代码)相关推荐

  1. Python(numpy):垂向涡度计算(二维速度,附完整代码)

    最近写代码的时候遇到了需要用速度计算涡度的问题,在网上搜了一下,发现不知道为什么,能找到的代码源都无比复杂,难道是简单到大家都不屑于写了吗hhh 涉及到处理数据,如果你的数据来源是nc文件,并使用xa ...

  2. Spring MVC+Spring+Mybatis实现支付宝支付功能(附完整代码)

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:https://urlify.cn/aYrmIr 前言 本教 ...

  3. OpenCV计算时刻calculate moments的实例(附完整代码)

    OpenCV计算时刻calculate moments的实例 OpenCV计算时刻calculate moments的实例 OpenCV计算时刻calculate moments的实例 #includ ...

  4. 前后端分离的用户验证原理及Spring Boot + JWT的框架搭建(附完整的框架代码)之二

    本篇承接上一篇,关于Session以及JWT Token参考: 前后端分离的用户验证原理及Spring Boot + JWT的框架搭建(附完整的框架代码)之一 框架整体描述 框架使用Spring Bo ...

  5. CV项目肢体动作识别(三)内附完整代码和详细讲解

    CV项目肢体动作识别(三)内附完整代码和详细讲解 首先我还是给出完整的代码,然后再进行详细的讲解.这一次我们用模块化的思想,把一个功能模块化(moudle),这种思想在工程中非常常见,在分工中你需要做 ...

  6. 五子棋java百度文库_JAVA课程设计 五子棋(内附完整代码).doc

    JAVA课程设计 五子棋(内附完整代码) JAVA课程设计 设计题目:五子棋游戏 简要的介绍五子棋 五子棋的起源 五子棋,又被称为"连五子.五子连.串珠.五目.五目碰.五格.五石.五法.五联 ...

  7. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一) 本文目录: 一.[旋转的精灵女孩]案例运行效果 二.Three.js简介 三.Three.js代码正常运行显示条件 (1)不载入 ...

  8. 对“科大讯飞2021丨广告点击率预估挑战赛 Top1方案(附完整代码)_Jack_Yang的博客-CSDN博客”的补充。

    这篇文章的初衷是针对科大讯飞2021丨广告点击率预估挑战赛 Top1方案(附完整代码)_Jack_Yang的博客-CSDN博客进行补充. 博客的信息量很少,对任务背景的介绍也不太对,说实话令人费解.我 ...

  9. PCL提取3D点云模型特征(3.0 FPFH快速点特征直方图)附完整代码

    一.概述 上一篇博客解释了PFH是什么以及如何利用PFH来提取点云的特征,那么讲了PFH(PCL提取3D点云模型特征(2.0 PFH点特征直方图 )附完整代码)之后肯定是要接着说FPFH的.本来想着把 ...

最新文章

  1. 第十一章 异常,日志,断言和调试
  2. Python教学与学习过程中应注意的九句话
  3. 使用docker优雅的部署你的nuxtjs项目
  4. Android_View,ViewGroup,Window之间的关系
  5. linux xftp,xshell免费下载
  6. 解决办法:Centos 7 SSH连接超时自动断开
  7. eclipse使用maven教程
  8. android gps测速代码,【GPS测速仪】GPS测速仪 GPS speedometer 1.6.0下载_安卓(android)软件下载-魅族溜...
  9. 短视频解析 MD5修改 ,为什么要修改MD5
  10. 博客迁移到sunface.io
  11. 光纤交换机与普通交换机的区别
  12. 开灯问题~有n盏灯,编号为1~n。1号将灯全部打开,2将按下所有为2的倍数的开关,(这些灯将被关掉)第3个人按下所有编号为3的倍数的开关(该灯如为打开的, 则将它关闭;如关闭的,则将它打开)。
  13. Logstash:使用 mutate 过滤器
  14. easyui ValidateBox validType验证规则
  15. tc ebpf sample - tethering offload on linux pc
  16. 家谱二叉树c语言程序,家谱图-二叉树
  17. 再见,Python正则表达式!
  18. glob模块中的glob.glob和golb.iglob
  19. 周庄王,姬佗(公元前696年—公元前682年在位)
  20. NLP-文本处理:词性标注【使用成熟的第三方工具包:中文(哈工大LTP)、英文()】【对分词后得到的“词语列表”进行词性标注,词性标注的结果用于依存句法分析、语义角色标注】

热门文章

  1. bzoj1131: [POI2008]Sta
  2. spoj Longest Common Substring II
  3. ubuntu下eclipse新建项目没有java project的解决办法
  4. 关于获取各种浏览器可见窗口大小(转载)
  5. Null reference pointer was passed to the stub when not debugging with IE
  6. 如何移动SQL SERVER的系统数据库
  7. 创业?你还差一位合格的产品经理
  8. 艾媒报告丨2017年全球移动社交市场研究报告
  9. Docker镜像与容器命令
  10. python中的浅拷贝和深拷贝