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));
        }
Beispiel #2
0
        public GeoHash(double latitude, double longitude, int precision)
        {
            if (precision < 1)
            {
                throw new System.Exception("Precision of GeoHash must be larger than zero!");
            }
            if (precision > MAX_PRECISION)
            {
                throw new System.Exception("Precision of a GeoHash must be less than " + (MAX_PRECISION + 1) + "!");
            }
            if (!GeoLocation.coordinatesValid(latitude, longitude))
            {
                throw new System.Exception(string.Format("Not valid location coordinates: [{0}, {1}]", latitude, longitude));
            }
            double[] longitudeRange = { -180, 180 };
            double[] latitudeRange  = { -90, 90 };

            char[] buffer = new char[precision];

            for (int i = 0; i < precision; i++)
            {
                int hashValue = 0;
                for (int j = 0; j < Base32Utils.BITS_PER_BASE32_CHAR; j++)
                {
                    bool     even  = (((i * Base32Utils.BITS_PER_BASE32_CHAR) + j) % 2) == 0;
                    double   val   = even ? longitude : latitude;
                    double[] range = even ? longitudeRange : latitudeRange;
                    double   mid   = (range[0] + range[1]) / 2;
                    if (val > mid)
                    {
                        hashValue = (hashValue << 1) + 1;
                        range[0]  = mid;
                    }
                    else
                    {
                        hashValue = (hashValue << 1);
                        range[1]  = mid;
                    }
                }
                buffer[i] = Base32Utils.valueToBase32Char(hashValue);
            }
            this.geoHash = new string(buffer);
        }