当前位置: 首页 > wzjs >正文

成都公司做网站找什么平台代写文章

成都公司做网站找什么平台,代写文章,wordpress 构建轻社区,wordpress开发登录插件目录 引言 Redis GEO命令概述 什么是GEO命令? 主要命令详解 命令应用示例 添加地点信息 查询两地距离 查询附近的城市 实现"查找附近的人"功能 功能需求与实现思路 基本需求 实现思路 命令实现方案 存储用户位置 查询附近的用户 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.0)1000公里范围内的所有城市,并同时返回它们与中心点的距离。
GEORADIUS locations 139.0 35.0 1000 km WITHDIST

实现"查找附近的人"功能

        "查找附近的人"是移动应用中的常见功能,下面我们将详细讲解如何使用Redis GEO命令来实现。

功能需求与实现思路

基本需求

  • 存储每个用户的地理位置信息(经纬度)
  • 能够查询指定用户周围一定范围内的其他用户
  • 返回的用户列表按照距离排序

实现思路

  1. 使用GEOADD命令将用户ID及其经纬度信息存储在Redis中
  2. 当需要查询"附近的人"时,使用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 用户位置Map,key为用户ID,value为经纬度坐标* @param jedis Redis连接* @return 添加成功的数量*/public static Long saveUserLocations(Map<String, double[]> userLocations, Jedis jedis) {try {Map<String, GeoCoordinate> memberCoordinateMap = new HashMap<>();for (Map.Entry<String, 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 List<String> getNearbyUsers(double longitude, double latitude, double radius, Jedis jedis) {try {List<GeoRadiusResponse> 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 List<UserGeoInfo> getNearbyUsersWithDistance(double longitude, double latitude, double radius, Jedis jedis) {try {List<GeoRadiusResponse> 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 {List<GeoCoordinate> 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公里范围内的用户 =====");List<String> nearbyUsers = getNearbyUsers(113.267548, 23.142979, 1000, jedis);System.out.println("附近的用户: " + nearbyUsers);System.out.println("\n===== 查询广州周边1000公里范围内的用户(包含距离信息) =====");List<UserGeoInfo> 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.dtcms.com/wzjs/813453.html

相关文章:

  • 做招商加盟网站怎么做网站建设基本概述
  • 临沂 网站建设由前台有后台的网站怎么做
  • 兴化网站开发深圳防疫政策最新
  • 深圳网站设计 工作室如何成功开展网络营销
  • 如何用云指做自己的网站校园网站建设详细的设计方案
  • 德清网站建设ps制作网页步骤
  • 广州建设工程合同备案系统网站丽水市做网站的
  • 中小学网站建设处理器优化软件
  • 手机站点图文设计
  • app和网站开发语言的区别做网站必须有云虚拟主机
  • 营销网站建设的公司叫什么h5制作软件免费 fou
  • 杭州 建设网站制作织梦网站怎么做404页面
  • 网站源码查看北京海淀建设部邮编
  • 网站开发课程培训游戏推广引流软件
  • 网站建设培训费用多少长治网站建设收费多少
  • 网站上的二维码怎么做手机网站关键词快速排名
  • 菜鸟教程网站做标书分享网站
  • 有什么网站做统计图的工业设计创意产品
  • 乔拓云智能建站平台物联网应用技术是干什么的
  • 网站域名有哪些网站设为主页功能怎么做
  • 做贺卡的网站wordpress按最后评论排序
  • 自己做轴承网站wordpress 笔记本主题下载失败
  • 泉州网站wordpress使用缩略
  • 外贸网站优化服务怎么删除安装wordpress
  • 建网站定制新农村基础设施建设网站
  • 做网站电脑配置要求个高吗中国企业网络营销现状
  • 广西网站建设设计php不用框架怎么做网站
  • python 做 网站wordpress快速网店主题
  • 长沙市做网站的好医生网站怎么做不了题目了
  • 济南住建局官方网站穿衣打扮 wordpress