Beispiel #1
0
        /// <summary>
        /// Shortens the full code by removing four or six digits, depending on the provided reference point
        /// </summary>
        /// <param name="latitude">Reference location latitude</param>
        /// <param name="longitude">Reference location longitude</param>
        /// <returns>Returns a new Open Location Code with less digits</returns>
        public static OpenLocationCode Shorten(this OpenLocationCode code, double latitude, double longitude)
        {
            if (!code.IsFull)
            {
                throw new InvalidOperationException("Can only shorten a full Open Location Code.");
            }

            if (code.IsPadded)
            {
                throw new InvalidOperationException("Can only shorten an Open Location Code that isn't padded.");
            }

            Bounds bounds = code.Decode();

            double latitudeDiff  = Math.Abs(latitude - bounds.CenterLatitude);
            double longitudeDiff = Math.Abs(longitude - bounds.CenterLongitude);

            if (latitudeDiff < Constants.LatitudePrecision8Digits && longitudeDiff < Constants.LatitudePrecision8Digits)
            {
                return(new OpenLocationCode(code.Code.Substring(8)));
            }
            else if (latitudeDiff < Constants.LatitudePrecision6Digits && longitudeDiff < Constants.LatitudePrecision6Digits)
            {
                return(new OpenLocationCode(code.Code.Substring(6)));
            }
            else if (latitudeDiff < Constants.LatitudePrecision4Digits && longitudeDiff < Constants.LatitudePrecision4Digits)
            {
                return(new OpenLocationCode(code.Code.Substring(4)));
            }

            throw new ArgumentException("Location is too far from the Open Location Code center.");
        }
        public static OpenLocationCode Recover(this OpenLocationCode code, double latitude, double longitude)
        {
            if (code.IsFull)
            {
                return(code);
            }

            latitude  = Builder.ClipLatitude(latitude);
            longitude = Builder.NormalizeLongitude(longitude);

            int    digitsToRecover = 8 - code.Code.IndexOf(Constants.Separator);
            double paddedArea      = Math.Pow(20, 2 - (digitsToRecover / 2));

            // use reference location to pad the supplied code
            string prefix = OpenLocationCode.Encode(latitude, longitude)
                            .Substring(0, digitsToRecover);

            var recoveredCode       = new OpenLocationCode(prefix + code.Code);
            var recoveredCodeBounds = recoveredCode.Decode();

            double recoveredLatitude  = recoveredCodeBounds.CenterLatitude;
            double recoveredLongitude = recoveredCodeBounds.CenterLongitude;

            // adjust latitude resolution
            double latitudeDiff = recoveredLatitude - latitude;

            if (latitudeDiff > (paddedArea / 2))
            {
                recoveredLatitude -= paddedArea;
            }
            else if (latitudeDiff < (-paddedArea / 2))
            {
                recoveredLatitude += paddedArea;
            }

            // adjust longitude resolution
            double longitudeDiff = recoveredLongitude - longitude;

            if (longitudeDiff > (paddedArea / 2))
            {
                recoveredLongitude -= paddedArea;
            }
            else if (longitudeDiff < (-paddedArea / 2))
            {
                recoveredLongitude += paddedArea;
            }

            return(new OpenLocationCode(recoveredLatitude, recoveredLongitude, recoveredCode.Code.Length - 1));
        }