package com.ylx.massage.utils; import cn.hutool.core.collection.CollectionUtil; import com.ylx.common.core.domain.R; import com.ylx.massage.domain.Location; import com.ylx.massage.domain.TJs; import org.apache.commons.compress.utils.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.geo.*; import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.data.redis.core.BoundGeoOperations; import org.springframework.data.redis.core.GeoOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestBody; import java.math.BigDecimal; import java.util.*; /** * @author jianlong * @date 2024-04-07 15:49 */ @Component public class LocationUtil { @Autowired private RedisTemplate redisTemplate; /** * 作为存储经纬度列表的key值 */ private static final String GEO_KEY = "JS_POSITION"; /** * 将经纬度信息添加到redis中 * * @param certId 标识 * @param longitude 经度 * @param latitude 纬度 */ public void geoAdd(String certId, double longitude, double latitude) { GeoOperations geoOperations = redisTemplate.opsForGeo(); Point point = new Point(longitude, latitude); RedisGeoCommands.GeoLocation geoLocation = new RedisGeoCommands.GeoLocation(certId, point); geoOperations.add(GEO_KEY, geoLocation); } /** * 两个人之间的距离 * * @param certId1 * @param certId2 * @return */ public double distanceBetween(String certId1, String certId2) { GeoOperations geoOperations = redisTemplate.opsForGeo(); Distance distance = geoOperations.distance(GEO_KEY, certId1, certId2); return distance.getValue(); } /** * 查询距离某个人指定范围内的人,包括距离多少米 * * @param certId * @param distance * @return */ public Map distanceInclude(String certId, double distance) { Map map = new LinkedHashMap<>(); GeoOperations geoOperations = redisTemplate.opsForGeo(); RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs(); GeoResults> geoResults = geoOperations.radius(GEO_KEY, certId, new Distance(distance), geoRadiusCommandArgs.includeDistance()); if (geoResults != null) { Iterator>> iterator = geoResults.iterator(); while (iterator.hasNext()) { GeoResult> geoResult = iterator.next(); // 与目标点相距的距离信息 Distance geoResultDistance = geoResult.getDistance(); // 该点的信息 RedisGeoCommands.GeoLocation geoResultContent = geoResult.getContent(); map.put(geoResultContent.getName(), geoResultDistance.getValue()); } } return map; } public List dis(Location locationBo) { ArrayList js = Lists.newArrayList(); //设置当前位置 Point point = new Point(locationBo.getLongitude(), locationBo.getLatitude()); //设置半径范围 Metric metric = RedisGeoCommands.DistanceUnit.METERS; Distance distance = new Distance(locationBo.getRadius(), metric); Circle circle = new Circle(point, distance); //设置参数 包括距离、坐标、条数 RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands .GeoRadiusCommandArgs .newGeoRadiusArgs() .includeDistance() .includeCoordinates() .sortAscending() .limit(locationBo.getLimit()); BoundGeoOperations stringStringBoundGeoOperations = redisTemplate.boundGeoOps(GEO_KEY); GeoResults> radius = stringStringBoundGeoOperations.radius(circle, args); if (radius == null || CollectionUtil.isEmpty(radius.getContent())) { return null; } radius.forEach(content -> { TJs tJs = new TJs(); tJs.setcOpenId(content.getContent().getName()); tJs.setDistance(BigDecimal.valueOf(content.getDistance().getValue())); js.add(tJs); }); return js; } }