private bool isSuperQuery(GeoHashQuery other)
        {
            int startCompare = other.startValue.CompareTo(this.startValue);

            if (startCompare <= 0)
            {
                return(other.endValue.CompareTo(this.endValue) >= 0);
            }
            else
            {
                return(false);
            }
        }
 public GeoHashQuery joinWith(GeoHashQuery other)
 {
     if (other.isPrefix(this))
     {
         return(new GeoHashQuery(this.startValue, other.endValue));
     }
     else if (this.isPrefix(other))
     {
         return(new GeoHashQuery(other.startValue, this.endValue));
     }
     else if (this.isSuperQuery(other))
     {
         return(other);
     }
     else if (other.isSuperQuery(this))
     {
         return(this);
     }
     else
     {
         throw new Exception("Can't join these 2 queries: " + this + ", " + other);
     }
 }
        public override bool Equals(object o)
        {
            if (this == o)
            {
                return(true);
            }
            if (o == null || GetType() != o.GetType())
            {
                return(false);
            }

            GeoHashQuery that = (GeoHashQuery)o;

            if (!endValue.Equals(that.endValue))
            {
                return(false);
            }
            if (!startValue.Equals(that.startValue))
            {
                return(false);
            }

            return(true);
        }
        public static HashSet <GeoHashQuery> queriesAtLocation(GeoLocation location, double radius)
        {
            int queryBits        = Math.Max(1, Utils.bitsForBoundingBox(location, radius));
            int geoHashPrecision = (int)(Math.Ceiling(((float)queryBits) / Base32Utils.BITS_PER_BASE32_CHAR));

            double latitude            = location.latitude;
            double longitude           = location.longitude;
            double latitudeDegrees     = radius / Constants.METERS_PER_DEGREE_LATITUDE;
            double latitudeNorth       = Math.Min(90, latitude + latitudeDegrees);
            double latitudeSouth       = Math.Max(-90, latitude - latitudeDegrees);
            double longitudeDeltaNorth = GeoUtils.distanceToLongitudeDegrees(radius, latitudeNorth);
            double longitudeDeltaSouth = GeoUtils.distanceToLongitudeDegrees(radius, latitudeSouth);
            double longitudeDelta      = Math.Max(longitudeDeltaNorth, longitudeDeltaSouth);

            HashSet <GeoHashQuery> queries = new HashSet <GeoHashQuery>();

            GeoHash geoHash  = new GeoHash(latitude, longitude, geoHashPrecision);
            GeoHash geoHashW = new GeoHash(latitude, GeoUtils.wrapLongitude(longitude - longitudeDelta), geoHashPrecision);
            GeoHash geoHashE = new GeoHash(latitude, GeoUtils.wrapLongitude(longitude + longitudeDelta), geoHashPrecision);

            GeoHash geoHashN  = new GeoHash(latitudeNorth, longitude, geoHashPrecision);
            GeoHash geoHashNW = new GeoHash(latitudeNorth, GeoUtils.wrapLongitude(longitude - longitudeDelta), geoHashPrecision);
            GeoHash geoHashNE = new GeoHash(latitudeNorth, GeoUtils.wrapLongitude(longitude + longitudeDelta), geoHashPrecision);

            GeoHash geoHashS  = new GeoHash(latitudeSouth, longitude, geoHashPrecision);
            GeoHash geoHashSW = new GeoHash(latitudeSouth, GeoUtils.wrapLongitude(longitude - longitudeDelta), geoHashPrecision);
            GeoHash geoHashSE = new GeoHash(latitudeSouth, GeoUtils.wrapLongitude(longitude + longitudeDelta), geoHashPrecision);

            queries.Add(queryForGeoHash(geoHash, queryBits));
            queries.Add(queryForGeoHash(geoHashE, queryBits));
            queries.Add(queryForGeoHash(geoHashW, queryBits));
            queries.Add(queryForGeoHash(geoHashN, queryBits));
            queries.Add(queryForGeoHash(geoHashNE, queryBits));
            queries.Add(queryForGeoHash(geoHashNW, queryBits));
            queries.Add(queryForGeoHash(geoHashS, queryBits));
            queries.Add(queryForGeoHash(geoHashSE, queryBits));
            queries.Add(queryForGeoHash(geoHashSW, queryBits));

            // Join queries
            bool didJoin;

            do
            {
                GeoHashQuery query1 = null;
                GeoHashQuery query2 = null;
                foreach (GeoHashQuery query in queries)
                {
                    foreach (GeoHashQuery other in queries)
                    {
                        if (query != other && query.canJoinWith(other))
                        {
                            query1 = query;
                            query2 = other;
                            break;
                        }
                    }
                }
                if (query1 != null && query2 != null)
                {
                    queries.Remove(query1);
                    queries.Remove(query2);
                    queries.Add(query1.joinWith(query2));
                    didJoin = true;
                }
                else
                {
                    didJoin = false;
                }
            } while (didJoin);

            return(queries);
        }
 public bool canJoinWith(GeoHashQuery other)
 {
     return(this.isPrefix(other) || other.isPrefix(this) || this.isSuperQuery(other) || other.isSuperQuery(this));
 }
 private bool isPrefix(GeoHashQuery other)
 {
     return((other.endValue.CompareTo(this.startValue) >= 0) &&
            (other.startValue.CompareTo(this.startValue) < 0) &&
            (other.endValue.CompareTo(this.endValue) < 0));
 }