public static GeoHashQuery queryForGeoHash(GeoHash geohash, int bits)
        {
            string hash      = geohash.getGeoHashString();
            int    precision = (int)Math.Ceiling((double)bits / Base32Utils.BITS_PER_BASE32_CHAR);

            if (hash.Length < precision)
            {
                return(new GeoHashQuery(hash, hash + "~"));
            }
            hash = hash.Substring(0, precision);
            string baseS           = hash.Substring(0, hash.Length - 1);
            int    lastValue       = Base32Utils.base32CharToValue(hash[(hash.Length - 1)]);
            int    significantBits = bits - (baseS.Length * Base32Utils.BITS_PER_BASE32_CHAR);
            int    unusedBits      = (Base32Utils.BITS_PER_BASE32_CHAR - significantBits);
            // delete unused bits
            int    startValue = (lastValue >> unusedBits) << unusedBits;
            int    endValue   = startValue + (1 << unusedBits);
            string startHash  = baseS + Base32Utils.valueToBase32Char(startValue);
            string endHash;

            if (endValue > 31)
            {
                endHash = baseS + "~";
            }
            else
            {
                endHash = baseS + Base32Utils.valueToBase32Char(endValue);
            }
            return(new GeoHashQuery(startHash, endHash));
        }
Exemple #2
0
        public override bool Equals(object o)
        {
            if (this == o)
            {
                return(true);
            }
            if (o == null || GetType() != o.GetType())
            {
                return(false);
            }

            GeoHash other = (GeoHash)o;

            return(this.geoHash.Equals(other.geoHash));
        }
        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 containsGeoHash(GeoHash hash)
        {
            string hashStr = hash.getGeoHashString();

            return(this.startValue.CompareTo(hashStr) <= 0 && this.endValue.CompareTo(hashStr) > 0);
        }