Esempio n. 1
0
        public GeoHash(double latitude, double longitude, int precision = DefaultPrecision)
        {
            if (precision < 1)
            {
                throw new ArgumentException("Precision of GeoHash must be larger than zero!");
            }
            if (precision > MaxPrecision)
            {
                throw new ArgumentException("Precision of a GeoHash must be less than " + (MaxPrecision + 1) + "!");
            }
            if (!GeoUtils.CoordinatesValid(latitude, longitude))
            {
                throw new ArgumentException(string.Format("Not valid location coordinates: [%f, %f]", latitude, longitude));
            }
            double[] longitudeRange = { -180, 180 };
            double[] latitudeRange  = { -90, 90 };

            var buffer = new char[precision];

            for (var i = 0; i < precision; i++)
            {
                var hashValue = 0;
                for (var j = 0; j < Base32Utils.BitsPerBase32Char; j++)
                {
                    var even  = (i * Base32Utils.BitsPerBase32Char + j) % 2 == 0;
                    var val   = even ? longitude : latitude;
                    var range = even ? longitudeRange : latitudeRange;
                    var mid   = (range[0] + range[1]) / 2;
                    if (val > mid)
                    {
                        hashValue = (hashValue << 1) + 1;
                        range[0]  = mid;
                    }
                    else
                    {
                        hashValue <<= 1;
                        range[1]    = mid;
                    }
                }
                buffer[i] = Base32Utils.ValueToBase32Char(hashValue);
            }
            _geoHash = new string(buffer);
        }
Esempio n. 2
0
        public static GeoHashQuery QueryForGeoHash(GeoHash geohash, int bits)
        {
            var hash      = geohash.GetGeoHashString();
            var precision = (int)Math.Ceiling((double)bits / Base32Utils.BitsPerBase32Char);

            if (hash.Length < precision)
            {
                return(new GeoHashQuery(hash, hash + "~"));
            }
            hash = hash.Substring(0, precision);
            var hashBase        = hash.Substring(0, hash.Length - 1);
            var lastValue       = Base32Utils.Base32CharToValue(hash[hash.Length - 1]);
            var significantBits = bits - hashBase.Length * Base32Utils.BitsPerBase32Char;
            var unusedBits      = Base32Utils.BitsPerBase32Char - significantBits;
            // delete unused bits
            var startValue = (lastValue >> unusedBits) << unusedBits;
            var endValue   = startValue + (1 << unusedBits);
            var startHash  = hashBase + Base32Utils.ValueToBase32Char(startValue);
            var endHash    = endValue > 31 ? hashBase + "~" : hashBase + Base32Utils.ValueToBase32Char(endValue);

            return(new GeoHashQuery(startHash, endHash));
        }