@@ -2924,6 +2924,136 @@ def _georadiusgeneric(self, command, *args, **kwargs):
2924
2924
2925
2925
return self .execute_command (command , * pieces , ** kwargs )
2926
2926
2927
+ def geosearch (self , name , member = None , longitude = None , latitude = None ,
2928
+ unit = 'm' , radius = None , width = None , height = None , sort = None ,
2929
+ count = None , any = False , withcoord = False ,
2930
+ withdist = False , withhash = False ):
2931
+ """
2932
+ Return the members of specified key identified by the
2933
+ ``name`` argument, which are within the borders of the
2934
+ area specified by a given shape. This command extends the
2935
+ GEORADIUS command, so in addition to searching within circular
2936
+ areas, it supports searching within rectangular areas.
2937
+ This command should be used in place of the deprecated
2938
+ GEORADIUS and GEORADIUSBYMEMBER commands.
2939
+ ``member`` Use the position of the given existing
2940
+ member in the sorted set. Can't be given with ``longitude``
2941
+ and ``latitude``.
2942
+ ``longitude`` and ``latitude`` Use the position given by
2943
+ this coordinates. Can't be given with ``member``
2944
+ ``radius`` Similar to GEORADIUS, search inside circular
2945
+ area according the given radius. Can't be given with
2946
+ ``height`` and ``width``.
2947
+ ``height`` and ``width`` Search inside an axis-aligned
2948
+ rectangle, determined by the given height and width.
2949
+ Can't be given with ``radius``
2950
+ ``unit`` must be one of the following : m, km, mi, ft.
2951
+ `m` for meters (the default value), `km` for kilometers,
2952
+ `mi` for miles and `ft` for feet.
2953
+ ``sort`` indicates to return the places in a sorted way,
2954
+ ASC for nearest to farest and DESC for farest to nearest.
2955
+ ``count`` limit the results to the first count matching items.
2956
+ ``any`` is set to True, the command will return as soon as
2957
+ enough matches are found. Can't be provided without ``count``
2958
+ ``withdist`` indicates to return the distances of each place.
2959
+ ``withcoord`` indicates to return the latitude and longitude of
2960
+ each place.
2961
+ ``withhash`` indicates to return the geohash string of each place.
2962
+ """
2963
+
2964
+ return self ._geosearchgeneric ('GEOSEARCH' ,
2965
+ name , member = member , longitude = longitude ,
2966
+ latitude = latitude , unit = unit ,
2967
+ radius = radius , width = width ,
2968
+ height = height , sort = sort , count = count ,
2969
+ any = any , withcoord = withcoord ,
2970
+ withdist = withdist , withhash = withhash ,
2971
+ store = None , store_dist = None )
2972
+
2973
+ def geosearchstore (self , dest , name , member = None , longitude = None ,
2974
+ latitude = None , unit = 'm' , radius = None , width = None ,
2975
+ height = None , sort = None , count = None , any = False ,
2976
+ storedist = False ):
2977
+ """
2978
+ This command is like GEOSEARCH, but stores the result in
2979
+ ``dest``. By default, it stores the results in the destination
2980
+ sorted set with their geospatial information.
2981
+ if ``store_dist`` set to True, the command will stores the
2982
+ items in a sorted set populated with their distance from the
2983
+ center of the circle or box, as a floating-point number.
2984
+ """
2985
+ return self ._geosearchgeneric ('GEOSEARCHSTORE' ,
2986
+ dest , name , member = member ,
2987
+ longitude = longitude , latitude = latitude ,
2988
+ unit = unit , radius = radius , width = width ,
2989
+ height = height , sort = sort , count = count ,
2990
+ any = any , withcoord = None ,
2991
+ withdist = None , withhash = None ,
2992
+ store = None , store_dist = storedist )
2993
+
2994
+ def _geosearchgeneric (self , command , * args , ** kwargs ):
2995
+ pieces = list (args )
2996
+
2997
+ # FROMMEMBER or FROMLONLAT
2998
+ if kwargs ['member' ] is None :
2999
+ if kwargs ['longitude' ] is None or kwargs ['latitude' ] is None :
3000
+ raise DataError ("GEOSEARCH must have member or"
3001
+ " longitude and latitude" )
3002
+ if kwargs ['member' ]:
3003
+ if kwargs ['longitude' ] or kwargs ['latitude' ]:
3004
+ raise DataError ("GEOSEARCH member and longitude or latitude"
3005
+ " cant be set together" )
3006
+ pieces .extend ([b'FROMMEMBER' , kwargs ['member' ]])
3007
+ if kwargs ['longitude' ] and kwargs ['latitude' ]:
3008
+ pieces .extend ([b'FROMLONLAT' ,
3009
+ kwargs ['longitude' ], kwargs ['latitude' ]])
3010
+
3011
+ # BYRADIUS or BYBOX
3012
+ if kwargs ['radius' ] is None :
3013
+ if kwargs ['width' ] is None or kwargs ['height' ] is None :
3014
+ raise DataError ("GEOSEARCH must have radius or"
3015
+ " width and height" )
3016
+ if kwargs ['unit' ] is None :
3017
+ raise DataError ("GEOSEARCH must have unit" )
3018
+ if kwargs ['unit' ].lower () not in ('m' , 'km' , 'mi' , 'ft' ):
3019
+ raise DataError ("GEOSEARCH invalid unit" )
3020
+ if kwargs ['radius' ]:
3021
+ if kwargs ['width' ] or kwargs ['height' ]:
3022
+ raise DataError ("GEOSEARCH radius and width or height"
3023
+ " cant be set together" )
3024
+ pieces .extend ([b'BYRADIUS' , kwargs ['radius' ], kwargs ['unit' ]])
3025
+ if kwargs ['width' ] and kwargs ['height' ]:
3026
+ pieces .extend ([b'BYBOX' ,
3027
+ kwargs ['width' ], kwargs ['height' ], kwargs ['unit' ]])
3028
+
3029
+ # sort
3030
+ if kwargs ['sort' ]:
3031
+ if kwargs ['sort' ].upper () == 'ASC' :
3032
+ pieces .append (b'ASC' )
3033
+ elif kwargs ['sort' ].upper () == 'DESC' :
3034
+ pieces .append (b'DESC' )
3035
+ else :
3036
+ raise DataError ("GEOSEARCH invalid sort" )
3037
+
3038
+ # count any
3039
+ if kwargs ['count' ]:
3040
+ pieces .extend ([b'COUNT' , kwargs ['count' ]])
3041
+ if kwargs ['any' ]:
3042
+ pieces .append (b'ANY' )
3043
+ elif kwargs ['any' ]:
3044
+ raise DataError ("GEOSEARCH any can't be provided without count" )
3045
+
3046
+ # other properties
3047
+ for arg_name , byte_repr in (
3048
+ ('withdist' , b'WITHDIST' ),
3049
+ ('withcoord' , b'WITHCOORD' ),
3050
+ ('withhash' , b'WITHHASH' ),
3051
+ ('store_dist' , b'STOREDIST' )):
3052
+ if kwargs [arg_name ]:
3053
+ pieces .append (byte_repr )
3054
+
3055
+ return self .execute_command (command , * pieces , ** kwargs )
3056
+
2927
3057
# MODULE COMMANDS
2928
3058
def module_load (self , path ):
2929
3059
"""
0 commit comments