网站想做个链接怎么做asp.net 3.5网站开发全程解析
news/
2025/9/23 19:18:58/
文章来源:
网站想做个链接怎么做,asp.net 3.5网站开发全程解析 ,虚拟主机做多个网站,制作网站的步骤和方法目录 引言
Redis GEO命令概述
什么是GEO命令#xff1f;
主要命令详解
命令应用示例
添加地点信息
查询两地距离
查询附近的城市
实现查找附近的人功能
功能需求与实现思路
基本需求
实现思路
命令实现方案
存储用户位置
查询附近的用户
Java代码实…目录 引言
Redis GEO命令概述
什么是GEO命令
主要命令详解
命令应用示例
添加地点信息
查询两地距离
查询附近的城市
实现查找附近的人功能
功能需求与实现思路
基本需求
实现思路
命令实现方案
存储用户位置
查询附近的用户
Java代码实现详解
使用Redis GEO的优势与注意事项
优势
注意事项 引言 在移动互联网时代基于地理位置的服务已成为众多应用的标配功能。无论是打车软件、外卖平台还是社交应用附近的XX功能几乎无处不在。这类功能的核心技术挑战在于如何高效存储地理位置数据并进行快速检索Redis 3.2版本引入的GEO地理空间命令集完美解决了这一问题为开发者提供了简单高效的地理位置数据处理方案。 本文将深入浅出地介绍Redis GEO命令及其工作原理通过实际案例和代码示例帮助你轻松实现查找附近的人等地理位置相关功能。无论你是Redis新手还是有经验的开发者都能从中获取有价值的信息。 Redis GEO命令概述
什么是GEO命令 GEO是Geolocation地理定位的简写Redis GEO是Redis专门为地理位置信息存储和检索设计的命令集。它允许我们将经纬度坐标存储到Redis数据库中并支持按距离查询、计算两点间距离等多种地理空间操作。 底层实现上Redis GEO使用了地理空间索引算法Geohash将二维的经纬度转换为一维的字符串并通过Redis的有序集合(Sorted Set)来存储这使得地理位置的存取和计算变得非常高效。
主要命令详解
Redis GEO主要提供了以下几个核心命令
GEOADD: 添加地理空间信息
# 将指定的地理空间位置经度、纬度、名称添加到指定的key中
# 可以一次添加多个位置
GEOADD key longitude latitude member [longitude latitude member ...]
GEODIST: 计算两点间距离
# 返回两个给定位置之间的距离
# unit参数指定返回值的单位可以是m米、km千米、mi英里或ft英尺
GEODIST key member1 member2 [unit]
GEOHASH: 获取经纬度的Geohash表示
# 返回一个或多个位置元素的Geohash表示
# Geohash是一种将经纬度编码为字符串的方法
GEOHASH key member [member ...]
GEOHASH: 获取经纬度的Geohash表示
# 返回一个或多个位置元素的Geohash表示
# Geohash是一种将经纬度编码为字符串的方法
GEOHASH key member [member ...]
GEOPOS: 获取位置的经纬度
# 返回指定名称位置的经纬度坐标
GEOPOS key member [member ...]
GEORADIUS: 查找指定半径内的成员
# 以给定的经纬度为中心返回键中包含的位置元素当中与中心的距离不超过给定半径的所有位置元素
GEORADIUS key longitude latitude radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] WITHDIST: 在返回位置元素的同时将位置元素与中心之间的距离也一并返回 WITHCOORD: 将位置元素的经度和纬度也一并返回 WITHHASH: 以52位无符号整数的形式返回位置元素的geohash值主要用于调试 COUNT n: 限定返回的记录数量 ASC|DESC: 根据中心的位置按照从近到远ASC或从远到近DESC的顺序返回位置元素 GEOSEARCH: 在指定范围内搜索
# 在指定范围内搜索范围可以是圆形或矩形
GEOSEARCH key [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius unit] [BYBOX width height unit] [WITHDIST] [WITHCOORD] [WITHHASH] [COUNT count] [ASC|DESC]
GEOSEARCHSTORE: 在指定范围内搜索并将结果存储
# 与GEOSEARCH功能相同但可以将结果存储到指定的key中
GEOSEARCHSTORE destination key [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius unit] [BYBOX width height unit] [WITHDIST] [WITHCOORD] [WITHHASH] [COUNT count] [ASC|DESC]
这些命令共同构成了一个完整的地理空间数据处理工具集能够满足大多数基于位置的服务需求。
命令应用示例
让我们通过一个具体的例子来理解GEO命令的使用
添加地点信息
# 上述命令将东京和吉隆坡两个城市的经纬度信息添加到名为locations的地理空间集合中。
GEOADD locations 139.781210 35.774426 东京 101.653962 5.205122 吉隆坡
查询两地距离
# 这个命令会返回东京和吉隆坡之间的距离单位公里。
GEODIST locations 东京 吉隆坡 km
查询附近的城市
# 这个命令会查找距离指定坐标点经度139.0纬度35.01000公里范围内的所有城市并同时返回它们与中心点的距离。
GEORADIUS locations 139.0 35.0 1000 km WITHDIST
实现查找附近的人功能 查找附近的人是移动应用中的常见功能下面我们将详细讲解如何使用Redis GEO命令来实现。
功能需求与实现思路
基本需求
存储每个用户的地理位置信息经纬度能够查询指定用户周围一定范围内的其他用户返回的用户列表按照距离排序
实现思路
使用GEOADD命令将用户ID及其经纬度信息存储在Redis中当需要查询附近的人时使用GEORADIUS命令以查询用户的位置为中心指定半径范围进行搜索
命令实现方案
假设我们正在开发一个社交应用需要实现广州市用户查找1000公里范围内其他用户的功能
存储用户位置
GEOADD user_location 113.267548 23.142979 user1
GEOADD user_location 113.300000 23.150000 user2
GEOADD user_location 114.057868 22.543099 user3
查询附近的用户
# 命令会返回距离广州市指定坐标1000公里范围内的所有用户并显示他们与查询点的具体距离。
GEORADIUS user_location 113.254325 23.144043 1000 km WITHDIST
Java代码实现详解
下面是使用Java语言和Jedis客户端实现查找附近的人功能的代码示例
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.GeoRadiusParam;import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Collectors;/*** Redis GEO功能示例实现附近的人功能* * author Muller*/
public class RedisGeoDemo {private static final String USER_LOCATION_KEY user_location;/*** 存储用户地理位置信息* * param userId 用户ID* param longitude 经度* param latitude 纬度* param jedis Redis连接* return 添加成功的数量*/public static Long saveUserLocation(String userId, double longitude, double latitude, Jedis jedis) {try {return jedis.geoadd(USER_LOCATION_KEY, longitude, latitude, userId);} catch (Exception e) {System.err.println(保存用户位置信息失败: e.getMessage());return 0L;}}/*** 批量存储多个用户的地理位置信息* * param userLocations 用户位置Mapkey为用户IDvalue为经纬度坐标* param jedis Redis连接* return 添加成功的数量*/public static Long saveUserLocations(MapString, double[] userLocations, Jedis jedis) {try {MapString, GeoCoordinate memberCoordinateMap new HashMap();for (Map.EntryString, double[] entry : userLocations.entrySet()) {String userId entry.getKey();double[] coordinates entry.getValue();memberCoordinateMap.put(userId, new GeoCoordinate(coordinates[0], coordinates[1]));}return jedis.geoadd(USER_LOCATION_KEY, memberCoordinateMap);} catch (Exception e) {System.err.println(批量保存用户位置信息失败: e.getMessage());return 0L;}}/*** 查询附近的人* * param longitude 经度* param latitude 纬度* param radius 半径* param jedis Redis连接* return 附近用户ID列表*/public static ListString getNearbyUsers(double longitude, double latitude, double radius, Jedis jedis) {try {ListGeoRadiusResponse responses jedis.georadius(USER_LOCATION_KEY, longitude, latitude, radius, GeoUnit.KM, GeoRadiusParam.geoRadiusParam().withDist().sortAscending());return responses.stream().map(GeoRadiusResponse::getMemberByString).collect(Collectors.toList());} catch (Exception e) {System.err.println(查询附近用户失败: e.getMessage());return List.of();}}/*** 获取用户详细地理信息包含距离* * param longitude 经度* param latitude 纬度* param radius 半径* param jedis Redis连接* return 附近用户详细信息列表*/public static ListUserGeoInfo getNearbyUsersWithDistance(double longitude, double latitude, double radius, Jedis jedis) {try {ListGeoRadiusResponse responses jedis.georadius(USER_LOCATION_KEY, longitude, latitude, radius, GeoUnit.KM, GeoRadiusParam.geoRadiusParam().withDist().withCoord().sortAscending());return responses.stream().map(response - new UserGeoInfo(response.getMemberByString(),response.getDistance(),response.getCoordinate().getLongitude(),response.getCoordinate().getLatitude())).collect(Collectors.toList());} catch (Exception e) {System.err.println(查询附近用户详细信息失败: e.getMessage());return List.of();}}/*** 计算两个用户之间的距离* * param userId1 用户1的ID* param userId2 用户2的ID* param jedis Redis连接* return 两用户间距离单位公里如果计算失败返回-1*/public static double getDistanceBetweenUsers(String userId1, String userId2, Jedis jedis) {try {Double distance jedis.geodist(USER_LOCATION_KEY, userId1, userId2, GeoUnit.KM);return distance ! null ? distance : -1;} catch (Exception e) {System.err.println(计算用户距离失败: e.getMessage());return -1;}}/*** 获取用户的地理坐标* * param userId 用户ID* param jedis Redis连接* return 用户坐标[经度,纬度]如果不存在返回null*/public static double[] getUserPosition(String userId, Jedis jedis) {try {ListGeoCoordinate positions jedis.geopos(USER_LOCATION_KEY, userId);if (positions ! null !positions.isEmpty() positions.get(0) ! null) {GeoCoordinate pos positions.get(0);return new double[] { pos.getLongitude(), pos.getLatitude() };}return null;} catch (Exception e) {System.err.println(获取用户坐标失败: e.getMessage());return null;}}/*** 用户地理信息包装类*/public static class UserGeoInfo {private String userId;private double distance;private double longitude;private double latitude;public UserGeoInfo(String userId, double distance, double longitude, double latitude) {this.userId userId;this.distance distance;this.longitude longitude;this.latitude latitude;}public String getUserId() {return userId;}public double getDistance() {return distance;}public double getLongitude() {return longitude;}public double getLatitude() {return latitude;}Overridepublic String toString() {return 用户ID: userId , 距离: String.format(%.2f, distance) 公里 , 坐标: [ longitude , latitude ];}}/*** 示例用法*/public static void main(String[] args) {// 这里仅用于演示实际使用应通过连接池获取Jedis实例try (Jedis jedis new Jedis(localhost, 6379)) {// 清除之前可能存在的测试数据jedis.del(USER_LOCATION_KEY);// 存储几个测试用户的位置广州及周边城市的坐标saveUserLocation(user1, 113.267548, 23.142979, jedis); // 广州saveUserLocation(user2, 114.057868, 22.543099, jedis); // 深圳saveUserLocation(user3, 113.030396, 22.938259, jedis); // 佛山saveUserLocation(user4, 116.397128, 39.916527, jedis); // 北京System.out.println( 查询广州周边1000公里范围内的用户 );ListString nearbyUsers getNearbyUsers(113.267548, 23.142979, 1000, jedis);System.out.println(附近的用户: nearbyUsers);System.out.println(\n 查询广州周边1000公里范围内的用户包含距离信息 );ListUserGeoInfo nearbyUsersWithDist getNearbyUsersWithDistance(113.267548, 23.142979, 1000, jedis);nearbyUsersWithDist.forEach(System.out::println);System.out.println(\n 计算用户间距离 );double distance getDistanceBetweenUsers(user1, user2, jedis);System.out.println(广州(user1)到深圳(user2)的距离: String.format(%.2f, distance) 公里);distance getDistanceBetweenUsers(user1, user4, jedis);System.out.println(广州(user1)到北京(user4)的距离: String.format(%.2f, distance) 公里);System.out.println(\n 获取用户坐标 );double[] pos getUserPosition(user1, jedis);if (pos ! null) {System.out.println(用户user1的坐标: [ pos[0] , pos[1] ]);}}}
}
使用Redis GEO的优势与注意事项
优势
性能高效Redis基于内存操作地理位置查询性能极高使用简单GEO命令集设计直观容易上手功能完善提供了从添加、查询到计算距离的完整功能集可扩展性好可以轻松处理百万级别的POI兴趣点数据与Redis其他功能协同可以结合Redis的缓存、事务等功能
注意事项
精度限制GEO命令的精度受到Geohash算法的限制对于需要极高精度的应用场景如军事可能不适用内存消耗大量GEO数据会占用较多内存需要合理规划Redis服务器资源经纬度范围Redis GEO只接受有效的经纬度范围经度-180到180纬度-85.05112878到85.05112878数据持久化使用AOF持久化模式可能会导致重启时间延长需权衡数据安全性和重启速度适用场景最适合附近的XX这类不需要复杂地理形状计算的场景如需多边形区域计算等高级地理信息功能可能需要专业GIS系统
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/913603.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!