LocationUtil.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package com.ylx.massage.utils;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import com.ylx.common.core.domain.R;
  4. import com.ylx.massage.domain.Location;
  5. import com.ylx.massage.domain.TJs;
  6. import org.apache.commons.compress.utils.Lists;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.data.geo.*;
  9. import org.springframework.data.redis.connection.RedisGeoCommands;
  10. import org.springframework.data.redis.core.BoundGeoOperations;
  11. import org.springframework.data.redis.core.GeoOperations;
  12. import org.springframework.data.redis.core.RedisTemplate;
  13. import org.springframework.stereotype.Component;
  14. import org.springframework.web.bind.annotation.RequestBody;
  15. import java.math.BigDecimal;
  16. import java.util.*;
  17. /**
  18. * @author jianlong
  19. * @date 2024-04-07 15:49
  20. */
  21. @Component
  22. public class LocationUtil {
  23. @Autowired
  24. private RedisTemplate<String, String> redisTemplate;
  25. /**
  26. * 作为存储经纬度列表的key值
  27. */
  28. private static final String GEO_KEY = "JS_POSITION";
  29. /**
  30. * 将经纬度信息添加到redis中
  31. *
  32. * @param certId 标识
  33. * @param longitude 经度
  34. * @param latitude 纬度
  35. */
  36. public void geoAdd(String certId, double longitude, double latitude) {
  37. GeoOperations geoOperations = redisTemplate.opsForGeo();
  38. Point point = new Point(longitude, latitude);
  39. RedisGeoCommands.GeoLocation geoLocation = new RedisGeoCommands.GeoLocation(certId, point);
  40. geoOperations.add(GEO_KEY, geoLocation);
  41. }
  42. /**
  43. * 两个人之间的距离
  44. *
  45. * @param certId1
  46. * @param certId2
  47. * @return
  48. */
  49. public double distanceBetween(String certId1, String certId2) {
  50. GeoOperations geoOperations = redisTemplate.opsForGeo();
  51. Distance distance = geoOperations.distance(GEO_KEY, certId1, certId2);
  52. return distance.getValue();
  53. }
  54. /**
  55. * 查询距离某个人指定范围内的人,包括距离多少米
  56. *
  57. * @param certId
  58. * @param distance
  59. * @return
  60. */
  61. public Map<String, Double> distanceInclude(String certId, double distance) {
  62. Map<String, Double> map = new LinkedHashMap<>();
  63. GeoOperations geoOperations = redisTemplate.opsForGeo();
  64. RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
  65. GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = geoOperations.radius(GEO_KEY, certId, new Distance(distance), geoRadiusCommandArgs.includeDistance());
  66. if (geoResults != null) {
  67. Iterator<GeoResult<RedisGeoCommands.GeoLocation<String>>> iterator = geoResults.iterator();
  68. while (iterator.hasNext()) {
  69. GeoResult<RedisGeoCommands.GeoLocation<String>> geoResult = iterator.next();
  70. // 与目标点相距的距离信息
  71. Distance geoResultDistance = geoResult.getDistance();
  72. // 该点的信息
  73. RedisGeoCommands.GeoLocation<String> geoResultContent = geoResult.getContent();
  74. map.put(geoResultContent.getName(), geoResultDistance.getValue());
  75. }
  76. }
  77. return map;
  78. }
  79. public List<TJs> dis(Location locationBo) {
  80. ArrayList<TJs> js = Lists.newArrayList();
  81. //设置当前位置
  82. Point point = new Point(locationBo.getLongitude(), locationBo.getLatitude());
  83. //设置半径范围
  84. Metric metric = RedisGeoCommands.DistanceUnit.METERS;
  85. Distance distance = new Distance(locationBo.getRadius(), metric);
  86. Circle circle = new Circle(point, distance);
  87. //设置参数 包括距离、坐标、条数
  88. RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands
  89. .GeoRadiusCommandArgs
  90. .newGeoRadiusArgs()
  91. .includeDistance()
  92. .includeCoordinates()
  93. .sortAscending()
  94. .limit(locationBo.getLimit());
  95. BoundGeoOperations<String, String> stringStringBoundGeoOperations = redisTemplate.boundGeoOps(GEO_KEY);
  96. GeoResults<RedisGeoCommands.GeoLocation<String>> radius = stringStringBoundGeoOperations.radius(circle, args);
  97. if (radius == null || CollectionUtil.isEmpty(radius.getContent())) {
  98. return null;
  99. }
  100. radius.forEach(content -> {
  101. TJs tJs = new TJs();
  102. tJs.setcOpenId(content.getContent().getName());
  103. tJs.setDistance(BigDecimal.valueOf(content.getDistance().getValue()));
  104. js.add(tJs);
  105. });
  106. return js;
  107. }
  108. }