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

毕业生就业网站开发项目禁用wordpress默认编辑器

毕业生就业网站开发项目,禁用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/a/568829.html

相关文章:

  • 服务器数据恢复—raid5阵列硬盘离线搞崩溃,分区数据恢复案例来袭
  • 基于springboot的新闻资讯系统
  • H3C AC+AP本地转发二层组网
  • JavaEE 进阶第五期:Maven 之道,项目的依赖艺术与构建哲学
  • Linux:五种IO模型与非阻塞IO
  • unity hub在ubuntu 22.0.4上启动卡住
  • 自己做个网站需要什么网页设计尺寸用怎么量
  • 青建设厅官方网站申请域名后怎样建设网站
  • 安装Conda并配置PX4无人机仿真环境
  • 微信小程序全局配置分享功能
  • Spring Boot3零基础教程,StreamAPI 更多用法,笔记100
  • Unity UGC IDE实现深度解析(六):子图系统与模块化设计
  • 嵌入式Linux新手入门:北京迅为3568开发板驱动开发第二章helloworld 驱动实验
  • 动态背景网站邗江区做网站
  • Milvus:向现有Collections更改和添加字段(十一)
  • ESP32C3开发指南(基于IDF):console控制台命令行交互功能
  • harmonyos的鸿蒙的跳转页面的部署参数传递
  • Git 简介和基础使用
  • HarmonyOS Marquee组件深度解析:构建高性能滚动视觉效果
  • 网站建设绿茶科技zencart 网站建设
  • vscode arm交叉编译 中 cmakeTools 编译器设置
  • 全自动化立体仓库巷道堆垛机使用西门子1500PLC通过EtherCAT主站转Profinet实现与EtherCAT协议的伺服进行通讯方案案例
  • MAC M1系统用pyinstaller分别打包支持ARM系统的app和支持Inter系统的APP
  • MTK平台详解`adb devices`输出的序列号组成
  • uniapp实现的Tab 选项卡组件模板
  • 学习Linux——网络基础管理
  • 杭州做网站比较出名的公司有哪些网站 内容建设存在的问题
  • C# ASP.NET MVC Model 分类:数据传输对象(DTO)—— 跨层传数的 “精简快递“
  • Elasticsearch 7.0 介绍与配置详解
  • 如何理解前端开发中框架一词及其优点?