redis+GEOhash地理位置

2023年5月17日10:08:57

   最近要做一个站点提醒的功能,找了很多资料,原来 redis里支持这种功能,简直是完美解决问题

先说原理 , GEOhash  原理就是把经纬度分别以二进制表示,再奇偶插入等到一个hash值,保存,相同的经纬度保存的地址相近,这样在取范围的时候,可以拿出相近的经纬度, 

  再就是边界问题, 因为是不断的划分区域,所以在边界查询的时候,会把上评级的四个区域都拿出来,所以本质也是个zset有序集合,

大家可以网上找些例子了解下,直接保存经纬代码

	//提供地图坐标GeoHash保存站点,redis支持的类型存储 
		@Override
		public boolean saveRedisGeo(JSONObject str) {
			 this.geoOperations = redisTemplate.opsForGeo();
			 this.zsetOperations = redisTemplate.opsForZSet();
			    List<Object> listsite =  str.getJSONArray("lineLoad");
				String  carId = str.getString("carID").trim();
				String geoKey="";
				 Map<String,Point> memberCoordinateMap = new HashMap<String, Point>();
				 Point geoCoordinate=null;
		    	  for(int i=0;i<listsite.size();i++){
		    		  JSONObject objsite = (JSONObject) listsite.get(i);
		    		  geoCoordinate = new Point(objsite.getDoubleValue("lng"), objsite.getDoubleValue("lat"));
		    		  geoKey = carId+"#"+objsite.getString("id")+"#"+objsite.getString("siteName")+"#"+objsite.getString("address")+"#"+str.getString("sendCarDate");
					  memberCoordinateMap.put(geoKey, geoCoordinate);
		    	  }
				 geoOperations.geoAdd("ELEF:SITE:"+carId, memberCoordinateMap);
				 zsetOperations.getOperations().expire("ELEF:SITE:"+carId,36L, TimeUnit.HOURS);
			return true;
		}

下面就是取出站点, 车子到哪里了, 然后传入经纬度,相应的距离计算得出

		/*     TMS系统地理坐标,附近站点,半径等  无需计算得到距离      */
		private void getGeohashSite(String carid,JSONObject message){
			  GeoRadiusCommandArgs geoRadiusArgs = GeoRadiusCommandArgs.newGeoRadiusArgs();  
		         geoRadiusArgs = geoRadiusArgs.includeCoordinates().includeDistance();//查询返回结果包括距离和坐标  
		         if (Direction.ASC.equals(Direction.ASC)) {//按查询出的坐标距离中心坐标的距离进行排序  
		             geoRadiusArgs.sortAscending();  
		         } else if (Direction.DESC.equals(Direction.DESC)) {  
		             geoRadiusArgs.sortDescending();  
		         }
		         geoRadiusArgs.limit(2);//限制查询数量    distance 距离
		         GeoResults<GeoLocation<String>> radiusGeo = geoOperations.geoRadius("ELEF:SITE:"+carid, new Circle(new Point(Double.parseDouble(message.getString("longitude")), Double.parseDouble(message.getString("latitude"))), new Distance(3, DistanceUnit.KILOMETERS)), geoRadiusArgs);  
		         Iterator<GeoResult<GeoLocation<String>>> result =radiusGeo.iterator();
		          while(result.hasNext()){
		        	  GeoResult<GeoLocation<String>> geoLocation = result.next();
		        	 // System.out.println(geoLocation.getDistance().getValue());
		        	 // System.out.println(geoLocation.getContent().getName());
		        	  String[]  sts = geoLocation.getContent().getName().split("#");//拼接拆开
		        	  if(sts[0].equals(carid) && geoLocation.getDistance().getValue()<1.5){
		        		 // geoSendMessage(sts[0],sts[2],sts[3],sts[4]);
		        		//  zsetOperations.remove("ELEF:SITE:"+carid, geoLocation.getContent().getName());
		        		  break;
		        	  }
		          }
		}
		

代码就这么多, 刚开始因为不懂这个功能,写了很多代码,还不如这几行代码简洁,

 

  • 作者:大树168
  • 原文链接:https://blog.csdn.net/limingcai168/article/details/82805594
    更新时间:2023年5月17日10:08:57 ,共 2406 字。