@@ -2637,6 +2637,188 @@ func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse {
2637
2637
2638
2638
//------------------------------------------------------------------------------
2639
2639
2640
+ // GeoSearchQuery is used for GEOSearch/GEOSearchStore command query.
2641
+ type GeoSearchQuery struct {
2642
+ Member string
2643
+
2644
+ // Latitude and Longitude when using FromLonLat option.
2645
+ Longitude float64
2646
+ Latitude float64
2647
+
2648
+ // Distance and unit when using ByRadius option.
2649
+ // Can use m, km, ft, or mi. Default is km.
2650
+ Radius float64
2651
+ RadiusUnit string
2652
+
2653
+ // Height, width and unit when using ByBox option.
2654
+ // Can be m, km, ft, or mi. Default is km.
2655
+ BoxWidth float64
2656
+ BoxHeight float64
2657
+ BoxUnit string
2658
+
2659
+ // Can be ASC or DESC. Default is no sort order.
2660
+ Sort string
2661
+ Count int
2662
+ CountAny bool
2663
+ }
2664
+
2665
+ type GeoSearchLocationQuery struct {
2666
+ GeoSearchQuery
2667
+
2668
+ WithCoord bool
2669
+ WithDist bool
2670
+ WithHash bool
2671
+ }
2672
+
2673
+ type GeoSearchStoreQuery struct {
2674
+ GeoSearchQuery
2675
+
2676
+ // When using the StoreDist option, the command stores the items in a
2677
+ // sorted set populated with their distance from the center of the circle or box,
2678
+ // as a floating-point number, in the same unit specified for that shape.
2679
+ StoreDist bool
2680
+ }
2681
+
2682
+ func geoSearchLocationArgs (q * GeoSearchLocationQuery , args []interface {}) []interface {} {
2683
+ args = geoSearchArgs (& q .GeoSearchQuery , args )
2684
+
2685
+ if q .WithCoord {
2686
+ args = append (args , "withcoord" )
2687
+ }
2688
+ if q .WithDist {
2689
+ args = append (args , "withdist" )
2690
+ }
2691
+ if q .WithHash {
2692
+ args = append (args , "withhash" )
2693
+ }
2694
+
2695
+ return args
2696
+ }
2697
+
2698
+ func geoSearchArgs (q * GeoSearchQuery , args []interface {}) []interface {} {
2699
+ if q .Member != "" {
2700
+ args = append (args , "frommember" , q .Member )
2701
+ } else {
2702
+ args = append (args , "fromlonlat" , q .Longitude , q .Latitude )
2703
+ }
2704
+
2705
+ if q .Radius > 0 {
2706
+ if q .RadiusUnit == "" {
2707
+ q .RadiusUnit = "km"
2708
+ }
2709
+ args = append (args , "byradius" , q .Radius , q .RadiusUnit )
2710
+ } else {
2711
+ if q .BoxUnit == "" {
2712
+ q .BoxUnit = "km"
2713
+ }
2714
+ args = append (args , "bybox" , q .BoxWidth , q .BoxHeight , q .BoxUnit )
2715
+ }
2716
+
2717
+ if q .Sort != "" {
2718
+ args = append (args , q .Sort )
2719
+ }
2720
+
2721
+ if q .Count > 0 {
2722
+ args = append (args , "count" , q .Count )
2723
+ if q .CountAny {
2724
+ args = append (args , "any" )
2725
+ }
2726
+ }
2727
+
2728
+ return args
2729
+ }
2730
+
2731
+ type GeoSearchLocationCmd struct {
2732
+ baseCmd
2733
+
2734
+ opt * GeoSearchLocationQuery
2735
+ val []GeoLocation
2736
+ }
2737
+
2738
+ var _ Cmder = (* GeoSearchLocationCmd )(nil )
2739
+
2740
+ func NewGeoSearchLocationCmd (
2741
+ ctx context.Context , opt * GeoSearchLocationQuery , args ... interface {},
2742
+ ) * GeoSearchLocationCmd {
2743
+ return & GeoSearchLocationCmd {
2744
+ baseCmd : baseCmd {
2745
+ ctx : ctx ,
2746
+ args : args ,
2747
+ },
2748
+ opt : opt ,
2749
+ }
2750
+ }
2751
+
2752
+ func (cmd * GeoSearchLocationCmd ) Val () []GeoLocation {
2753
+ return cmd .val
2754
+ }
2755
+
2756
+ func (cmd * GeoSearchLocationCmd ) Result () ([]GeoLocation , error ) {
2757
+ return cmd .val , cmd .err
2758
+ }
2759
+
2760
+ func (cmd * GeoSearchLocationCmd ) String () string {
2761
+ return cmdString (cmd , cmd .val )
2762
+ }
2763
+
2764
+ func (cmd * GeoSearchLocationCmd ) readReply (rd * proto.Reader ) error {
2765
+ n , err := rd .ReadArrayLen ()
2766
+ if err != nil {
2767
+ return err
2768
+ }
2769
+
2770
+ cmd .val = make ([]GeoLocation , n )
2771
+ for i := 0 ; i < n ; i ++ {
2772
+ _ , err = rd .ReadArrayLen ()
2773
+ if err != nil {
2774
+ return err
2775
+ }
2776
+
2777
+ var loc GeoLocation
2778
+
2779
+ loc .Name , err = rd .ReadString ()
2780
+ if err != nil {
2781
+ return err
2782
+ }
2783
+ if cmd .opt .WithDist {
2784
+ loc .Dist , err = rd .ReadFloatReply ()
2785
+ if err != nil {
2786
+ return err
2787
+ }
2788
+ }
2789
+ if cmd .opt .WithHash {
2790
+ loc .GeoHash , err = rd .ReadIntReply ()
2791
+ if err != nil {
2792
+ return err
2793
+ }
2794
+ }
2795
+ if cmd .opt .WithCoord {
2796
+ nn , err := rd .ReadArrayLen ()
2797
+ if err != nil {
2798
+ return err
2799
+ }
2800
+ if nn != 2 {
2801
+ return fmt .Errorf ("got %d coordinates, expected 2" , nn )
2802
+ }
2803
+
2804
+ loc .Longitude , err = rd .ReadFloatReply ()
2805
+ if err != nil {
2806
+ return err
2807
+ }
2808
+ loc .Latitude , err = rd .ReadFloatReply ()
2809
+ if err != nil {
2810
+ return err
2811
+ }
2812
+ }
2813
+
2814
+ cmd .val [i ] = loc
2815
+ }
2816
+
2817
+ return nil
2818
+ }
2819
+
2820
+ //------------------------------------------------------------------------------
2821
+
2640
2822
type GeoPos struct {
2641
2823
Longitude , Latitude float64
2642
2824
}
0 commit comments