Ejemplo n.º 1
0
        /// <returns>
        /// A new OpenLocationCode instance representing a full Open Location Code from this
        /// (short) Open Location Code, given the reference location
        /// </returns>
        /// <param name="referenceLatitude">The reference latitude in decimal degrees.</param>
        /// <param name="referenceLongitude">The reference longitude in decimal degrees.</param>
        public OpenLocationCode Recover(double referenceLatitude, double referenceLongitude)
        {
            if (IsFull())
            {
                // Note: each code is either full xor short, no other option.
                return(this);
            }
            referenceLatitude  = ClipLatitude(referenceLatitude);
            referenceLongitude = NormalizeLongitude(referenceLongitude);

            int digitsToRecover = SeparatorPosition - Code.IndexOf(Separator);
            // The precision (height and width) of the missing prefix in degrees.
            double prefixPrecision = Math.Pow(EncodingBase, 2 - (digitsToRecover / 2));

            // Use the reference location to generate the prefix.
            string recoveredPrefix =
                new OpenLocationCode(referenceLatitude, referenceLongitude).Code.Substring(0, digitsToRecover);
            // Combine the prefix with the short code and decode it.
            OpenLocationCode recovered         = new OpenLocationCode(recoveredPrefix + Code);
            CodeArea         recoveredCodeArea = recovered.Decode();
            // Work out whether the new code area is too far from the reference location. If it is, we
            // move it. It can only be out by a single precision step.
            double recoveredLatitude  = recoveredCodeArea.CenterLatitude;
            double recoveredLongitude = recoveredCodeArea.CenterLongitude;

            // Move the recovered latitude by one precision up or down if it is too far from the reference,
            // unless doing so would lead to an invalid latitude.
            double latitudeDiff = recoveredLatitude - referenceLatitude;

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

            // Move the recovered longitude by one precision up or down if it is too far from the
            // reference.
            double longitudeDiff = recoveredCodeArea.CenterLongitude - referenceLongitude;

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

            return(new OpenLocationCode(recoveredLatitude, recoveredLongitude, recovered.Code.Length - 1));
        }
Ejemplo n.º 2
0
            private static OpenLocationCode RecoverNearestValid(string shortCode, double referenceLatitude, double referenceLongitude)
            {
                referenceLatitude  = ClipLatitude(referenceLatitude);
                referenceLongitude = NormalizeLongitude(referenceLongitude);

                int digitsToRecover = SeparatorPosition - shortCode.IndexOf(SeparatorCharacter);
                // The precision (height and width) of the missing prefix in degrees.
                double prefixPrecision = Math.Pow(EncodingBase, 2 - (digitsToRecover / 2));

                // Use the reference location to generate the prefix.
                string recoveredPrefix =
                    new OpenLocationCode(referenceLatitude, referenceLongitude).Code.Substring(0, digitsToRecover);
                // Combine the prefix with the short code and decode it.
                OpenLocationCode recovered = new OpenLocationCode(recoveredPrefix + shortCode);
                GeoPoint         recoveredCodeAreaCenter = recovered.Decode().Center;
                // Work out whether the new code area is too far from the reference location. If it is, we
                // move it. It can only be out by a single precision step.
                double recoveredLatitude  = recoveredCodeAreaCenter.Latitude;
                double recoveredLongitude = recoveredCodeAreaCenter.Longitude;

                // Move the recovered latitude by one precision up or down if it is too far from the reference,
                // unless doing so would lead to an invalid latitude.
                double latitudeDiff = recoveredLatitude - referenceLatitude;

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

                // Move the recovered longitude by one precision up or down if it is too far from the reference.
                double longitudeDiff = recoveredCodeAreaCenter.Longitude - referenceLongitude;

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

                return(new OpenLocationCode(recoveredLatitude, recoveredLongitude, recovered.CodeDigits.Length));
            }