Java实现Redis中的GEO数据结构
- 手机
- 2025-09-08 14:33:02

Java 实现 Redis中的GEO数据结构
LBS (基于位置信息服务(Location-Based Service,LBS))应用访问的数据是和人
或物关联的一组经纬度信息,而且要能查询相邻的经纬度范围,GEO 就非常适合应用在
LBS 服务的场景中
import java.util.ArrayList; import java.util.List; // 定义一个表示地理位置的类,用于存储地理位置的相关信息 public class GeoLocation { // 成员名称,用于标识这个地理位置,比如某个地点的名称 private String member; // 地理位置的经度 private double longitude; // 地理位置的纬度 private double latitude; // 构造函数,用于初始化 GeoLocation 对象 // 参数 member 为成员名称,longitude 为经度,latitude 为纬度 public GeoLocation(String member, double longitude, double latitude) { this.member = member; this.longitude = longitude; this.latitude = latitude; } // 获取成员名称的方法 public String getMember() { return member; } // 获取经度的方法 public double getLongitude() { return longitude; } // 获取纬度的方法 public double getLatitude() { return latitude; } } // 定义一个用于计算两个地理位置之间距离的工具类 class GeoDistanceCalculator { // 地球的平均半径,单位为千米,在计算距离时会用到 private static final int EARTH_RADIUS = 6371; // 静态方法,使用 Haversine 公式计算两个经纬度之间的距离 // 参数 lat1 和 lon1 是第一个地点的纬度和经度 // 参数 lat2 和 lon2 是第二个地点的纬度和经度 public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) { // 计算两个纬度之间差值的弧度 double dLat = Math.toRadians(lat2 - lat1); // 计算两个经度之间差值的弧度 double dLon = Math.toRadians(lon2 - lon1); // 将第一个地点的纬度转换为弧度 lat1 = Math.toRadians(lat1); // 将第二个地点的纬度转换为弧度 lat2 = Math.toRadians(lat2); // Haversine 公式的一部分,用于计算球面距离 double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); // 计算反三角函数,得到球面距离的弧度值 double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); // 最终距离等于地球半径乘以弧度值 return EARTH_RADIUS * c; } } // 定义一个模拟 Redis Geo 数据结构的类,用于管理地理位置信息 class GeoDataStructure { // 用于存储所有地理位置信息的列表 private List<GeoLocation> locations; // 构造函数,初始化存储地理位置信息的列表 public GeoDataStructure() { this.locations = new ArrayList<>(); } // 向数据结构中添加一个新的地理位置信息 // 参数 member 为成员名称,longitude 为经度,latitude 为纬度 public void addLocation(String member, double longitude, double latitude) { // 创建一个新的 GeoLocation 对象 GeoLocation location = new GeoLocation(member, longitude, latitude); // 将新的地理位置信息添加到列表中 locations.add(location); } // 根据给定的经纬度和距离范围,查找附近的成员 // 参数 longitude 和 latitude 是查询的中心点的经度和纬度 // 参数 distance 是查询的距离范围,单位为千米 public List<String> findNearbyMembers(double longitude, double latitude, double distance) { // 用于存储附近成员名称的列表 List<String> nearbyMembers = new ArrayList<>(); // 遍历所有存储的地理位置信息 for (GeoLocation location : locations) { // 计算当前地理位置与查询中心点之间的距离 double dist = GeoDistanceCalculator.calculateDistance(latitude, longitude, location.getLatitude(), location.getLongitude()); // 如果计算出的距离小于等于查询的距离范围 if (dist <= distance) { // 将该地理位置的成员名称添加到附近成员列表中 nearbyMembers.add(location.getMember()); } } // 返回附近成员列表 return nearbyMembers; } } // 测试 GeoDataStructure 类功能的测试类 class GeoDataStructureTest { public static void main(String[] args) { // 创建一个 GeoDataStructure 对象,用于管理地理位置信息 GeoDataStructure geoData = new GeoDataStructure(); // 向 GeoDataStructure 对象中添加一些地理位置信息 // 这里添加了三个地点,分别是 place1、place2 和 place3 geoData.addLocation("place1", 116.4074, 39.9042); geoData.addLocation("place2", 121.4737, 31.2304); geoData.addLocation("place3", 113.2644, 23.1291); // 定义查询的中心点的经度 double targetLongitude = 116.4074; // 定义查询的中心点的纬度 double targetLatitude = 39.9042; // 定义查询的距离范围,单位为千米 double searchDistance = 10000; // 调用 findNearbyMembers 方法,查找附近的成员 List<String> nearbyMembers = geoData.findNearbyMembers(targetLongitude, targetLatitude, searchDistance); // 输出附近的成员名称列表 System.out.println("附近的地点: " + nearbyMembers); } }Java实现Redis中的GEO数据结构由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java实现Redis中的GEO数据结构”