日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring计算方圆300km内其它城市(附完整代码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近工作需要,頁面展示某個城市附近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緩存

  • 在項目啟動時,spring緩存所有的城市信息
  • 遍歷城市集合,判斷每個城市是否在范圍內
  • 然后返回頁面展示
  • 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 密碼:j2qv *?BasicInfoService緩存也可以換成redis和memcache等主流的nosql數據庫管理,這里主要是為了方便演示
    • 參考內容1:百度百科-球面距離
    • 參考內容2:百度百科-地球半徑
    • 地球是一個兩極稍扁、赤道略鼓的不規則球體,平均半徑6371千米,這只是近似計算

    轉載于:https://juejin.im/post/5a34e6bef265da432f3130e2

    總結

    以上是生活随笔為你收集整理的spring计算方圆300km内其它城市(附完整代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。