Beispiel #1
0
        /// <summary>
        /// Converts the value of the current ZonePoint object to
        /// its equivalent string representation in the specified unit,
        /// using the specified formatting.
        /// </summary>
        /// <returns>A string representing the current coordinate in
        /// the WGS84 system, using the specified unit and formatting.</returns>
        public string ToString(GeoCoordinateUnit unit, GeoCoordinateFormat format)
        {
            // Creates a builder to make the main string.
            StringBuilder sBuilder = new StringBuilder();

            /// 1. Latitude component.
            double lat       = DataContainer.GetDouble("latitude").Value;
            bool   isDmOrDms = unit == GeoCoordinateUnit.DegreesMinutes ||
                               unit == GeoCoordinateUnit.DegreesMinutesSeconds;

            // DM and DMS output cardinal directions, others don't.
            if (isDmOrDms)
            {
                sBuilder.Append(lat >= 0 ? format.NorthSymbol : format.SouthSymbol);
                sBuilder.Append(format.CardinalPointSeparator);
            }

            // Computes and adds the main latitude component.
            sBuilder.Append(GetConvertedCoordinate(lat, 2, unit, format));

            // Adds the eventual separator.
            sBuilder.Append(format.ComponentSeparator);

            /// 2. Longitude component.
            double lon = DataContainer.GetDouble("longitude").Value;

            // DM and DMS output cardinal directions, others don't.
            if (isDmOrDms)
            {
                sBuilder.Append(lon >= 0 ? format.EastSymbol : format.WestSymbol);
                sBuilder.Append(format.CardinalPointSeparator);
            }

            // Computes and adds the main latitude component.
            sBuilder.Append(GetConvertedCoordinate(lon, 3, unit, format));

            // Returns the coordinates.
            return(sBuilder.ToString());
        }
Beispiel #2
0
        private string GetConvertedCoordinate(double value, int maxIntPartDigits, GeoCoordinateUnit unit, GeoCoordinateFormat format)
        {
            // DD : DD.DDD°
            // DM : DD° MM.MMM'
            // DMS : DD° MM' SS.SSS"

            StringBuilder coordBuilder = new StringBuilder(); // Builder for the final coordinates.
            
            bool isDmOrDms = unit == GeoCoordinateUnit.DegreesMinutes
                || unit == GeoCoordinateUnit.DegreesMinutesSeconds;

            /// 1. Creates the two format strings for decimal and floats.
            StringBuilder formatBuilder = new StringBuilder();

            // Heading zeroes:
            // All digits except the last one are optional if TrimIntegralZeroes is true.
            formatBuilder.Append(format.TrimIntegralZeroes ? '#' : '0', maxIntPartDigits - 1); // e.g. ##

            // The last digit of the integral part is non-optional.
            formatBuilder.Append('0'); // e.g. ##0

            // This so far gives the first format string.
            string fmtTruncatedInteger = formatBuilder.ToString(); // e.g. ##0

            // Adds the precision digits.
            if (format.PrecisionDigits > 0)
            {
                formatBuilder.Append('.'); // Floating part separator.
                formatBuilder.Append('0'); // First digit is non-optional. // e.g. ##0.0

                if (format.PrecisionDigits > 1)
                {
                    formatBuilder.Append(
                        format.TrimPrecisionZeroes ? '#' : '0', 
                        format.PrecisionDigits - 1); // Additional optional digits. // e.g. ##0.0###
                }
            }

            // This so far gives the second format string.
            string fmtFloatingNumber = formatBuilder.ToString();

            // Let's remove the first character if maxIntPartDigits is 3.
            // This makes two format strings for subcomponents whose integral
            // parts have only 2 digits.
            int startDigit = maxIntPartDigits - 2;
            string fmtFloatingNumberMax2 = fmtFloatingNumber.Substring(startDigit); // e.g. #0.0###
            string fmtTruncatedIntegerMax2 = fmtTruncatedInteger.Substring(startDigit); // e.g. #0

            /// 2. First subcomponent format: (D)DD° or (D)DD.DDD°
            formatBuilder.Clear();
            if (isDmOrDms)
            {
                // DM and DMS: Only uses the integral part.
                formatBuilder.Append(fmtTruncatedInteger);
            }
            else if (unit == GeoCoordinateUnit.DecimalDegrees)
            {
                // DD: Uses the whole number format.
                formatBuilder.Append(fmtFloatingNumber); // e.g. ##0.0###
            }

            // Computes and appends the first subcomponent.
            double degrees = isDmOrDms ? Math.Floor(Math.Abs(value)) : value;
            coordBuilder.Append(degrees.ToString(formatBuilder.ToString(), format.NumberFormat));

            // Adds the symbols.
            if (format.ShowSymbols)
            {
		        coordBuilder.Append(format.DegreesSymbol);
            }

            // Adds separators.
            if (isDmOrDms)
            {
                // DM and DMS: Adds a subcomponent separator.
                coordBuilder.Append(format.SubComponentSeparator);
                // e.g. ##0°,
            }

            // DD can return now.
            if (unit == GeoCoordinateUnit.DecimalDegrees)
            {
                return coordBuilder.ToString();
            }

            /// 3. Second subcomponent: MM' or MM.MMM'
            formatBuilder.Clear();
            if (isDmOrDms)
            {
                // DMS uses the integral format, DM the whole format.
                formatBuilder.Append(unit == GeoCoordinateUnit.DegreesMinutesSeconds 
                    ? fmtTruncatedIntegerMax2 
                    : fmtFloatingNumberMax2);
            }

            // Computes and appends the second subcomponent.
            double minutes = (Math.Abs(value) * 60) % 60;
            coordBuilder.Append(minutes.ToString(formatBuilder.ToString(), format.NumberFormat));

            // Adds symbol and separator.
            if (isDmOrDms)
            {
                // Adds the symbol.
                if (format.ShowSymbols)
                {
                    coordBuilder.Append(format.MinutesSymbol);
                }

                // DMS: Adds subcomponent separator.
                if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
                {
                    coordBuilder.Append(format.SubComponentSeparator);
                }
            }

            // DM can return now.
            if (unit == GeoCoordinateUnit.DegreesMinutes)
            {
                return coordBuilder.ToString();
            }

            /// 4. Third subcomponent : SS.SSS"
            formatBuilder.Clear();
            if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
            {
                // DMS: Uses the whole format.
                formatBuilder.Append(fmtFloatingNumberMax2);
            }

            // Computes and appends the third subcomponent.
            double seconds = (Math.Abs(value) * 3600) % 60;
            coordBuilder.Append(seconds.ToString(formatBuilder.ToString(), format.NumberFormat));

            // Adds symbol.
            if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
            {
                // DMS: Adds the symbol.
                if (format.ShowSymbols)
                {
                    coordBuilder.Append(format.SecondsSymbol);
                }
            }

            // DMS can return now.
            if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
            {
                return coordBuilder.ToString();
            }
            
            // Makes sure we're not doing something unexpected.
            throw new InvalidOperationException("Unexpected unit: " + unit.ToString());
           
        }
Beispiel #3
0
        /// <summary>
        /// Converts the value of the current ZonePoint object to
        /// its equivalent string representation in the specified unit,
        /// using the specified formatting.
        /// </summary>
        /// <returns>A string representing the current coordinate in
        /// the WGS84 system, using the specified unit and formatting.</returns>
        public string ToString(GeoCoordinateUnit unit, GeoCoordinateFormat format)
        {
            // Creates a builder to make the main string.
            StringBuilder sBuilder = new StringBuilder();

            /// 1. Latitude component.
            double lat = DataContainer.GetDouble("latitude").Value;
            bool isDmOrDms = unit == GeoCoordinateUnit.DegreesMinutes
                || unit == GeoCoordinateUnit.DegreesMinutesSeconds;

            // DM and DMS output cardinal directions, others don't.
            if (isDmOrDms)
            {
                sBuilder.Append(lat >= 0 ? format.NorthSymbol : format.SouthSymbol);
                sBuilder.Append(format.CardinalPointSeparator);
            }
            
            // Computes and adds the main latitude component.
            sBuilder.Append(GetConvertedCoordinate(lat, 2, unit, format));

            // Adds the eventual separator.
            sBuilder.Append(format.ComponentSeparator);

            /// 2. Longitude component.
            double lon = DataContainer.GetDouble("longitude").Value;

            // DM and DMS output cardinal directions, others don't.
            if (isDmOrDms)
            {
                sBuilder.Append(lon >= 0 ? format.EastSymbol : format.WestSymbol);
                sBuilder.Append(format.CardinalPointSeparator);
            }

            // Computes and adds the main latitude component.
            sBuilder.Append(GetConvertedCoordinate(lon, 3, unit, format));

            // Returns the coordinates.
            return sBuilder.ToString();
        }
Beispiel #4
0
        private string GetConvertedCoordinate(double value, int maxIntPartDigits, GeoCoordinateUnit unit, GeoCoordinateFormat format)
        {
            // DD : DD.DDD°
            // DM : DD° MM.MMM'
            // DMS : DD° MM' SS.SSS"

            StringBuilder coordBuilder = new StringBuilder(); // Builder for the final coordinates.

            bool isDmOrDms = unit == GeoCoordinateUnit.DegreesMinutes ||
                             unit == GeoCoordinateUnit.DegreesMinutesSeconds;

            /// 1. Creates the two format strings for decimal and floats.
            StringBuilder formatBuilder = new StringBuilder();

            // Heading zeroes:
            // All digits except the last one are optional if TrimIntegralZeroes is true.
            formatBuilder.Append(format.TrimIntegralZeroes ? '#' : '0', maxIntPartDigits - 1); // e.g. ##

            // The last digit of the integral part is non-optional.
            formatBuilder.Append('0'); // e.g. ##0

            // This so far gives the first format string.
            string fmtTruncatedInteger = formatBuilder.ToString(); // e.g. ##0

            // Adds the precision digits.
            if (format.PrecisionDigits > 0)
            {
                formatBuilder.Append('.'); // Floating part separator.
                formatBuilder.Append('0'); // First digit is non-optional. // e.g. ##0.0

                if (format.PrecisionDigits > 1)
                {
                    formatBuilder.Append(
                        format.TrimPrecisionZeroes ? '#' : '0',
                        format.PrecisionDigits - 1); // Additional optional digits. // e.g. ##0.0###
                }
            }

            // This so far gives the second format string.
            string fmtFloatingNumber = formatBuilder.ToString();

            // Let's remove the first character if maxIntPartDigits is 3.
            // This makes two format strings for subcomponents whose integral
            // parts have only 2 digits.
            int    startDigit              = maxIntPartDigits - 2;
            string fmtFloatingNumberMax2   = fmtFloatingNumber.Substring(startDigit);   // e.g. #0.0###
            string fmtTruncatedIntegerMax2 = fmtTruncatedInteger.Substring(startDigit); // e.g. #0

            /// 2. First subcomponent format: (D)DD° or (D)DD.DDD°
            formatBuilder.Clear();
            if (isDmOrDms)
            {
                // DM and DMS: Only uses the integral part.
                formatBuilder.Append(fmtTruncatedInteger);
            }
            else if (unit == GeoCoordinateUnit.DecimalDegrees)
            {
                // DD: Uses the whole number format.
                formatBuilder.Append(fmtFloatingNumber); // e.g. ##0.0###
            }

            // Computes and appends the first subcomponent.
            double degrees = isDmOrDms ? Math.Floor(Math.Abs(value)) : value;

            coordBuilder.Append(degrees.ToString(formatBuilder.ToString(), format.NumberFormat));

            // Adds the symbols.
            if (format.ShowSymbols)
            {
                coordBuilder.Append(format.DegreesSymbol);
            }

            // Adds separators.
            if (isDmOrDms)
            {
                // DM and DMS: Adds a subcomponent separator.
                coordBuilder.Append(format.SubComponentSeparator);
                // e.g. ##0°,
            }

            // DD can return now.
            if (unit == GeoCoordinateUnit.DecimalDegrees)
            {
                return(coordBuilder.ToString());
            }

            /// 3. Second subcomponent: MM' or MM.MMM'
            formatBuilder.Clear();
            if (isDmOrDms)
            {
                // DMS uses the integral format, DM the whole format.
                formatBuilder.Append(unit == GeoCoordinateUnit.DegreesMinutesSeconds
                    ? fmtTruncatedIntegerMax2
                    : fmtFloatingNumberMax2);
            }

            // Computes and appends the second subcomponent.
            double minutes = (Math.Abs(value) * 60) % 60;

            coordBuilder.Append(minutes.ToString(formatBuilder.ToString(), format.NumberFormat));

            // Adds symbol and separator.
            if (isDmOrDms)
            {
                // Adds the symbol.
                if (format.ShowSymbols)
                {
                    coordBuilder.Append(format.MinutesSymbol);
                }

                // DMS: Adds subcomponent separator.
                if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
                {
                    coordBuilder.Append(format.SubComponentSeparator);
                }
            }

            // DM can return now.
            if (unit == GeoCoordinateUnit.DegreesMinutes)
            {
                return(coordBuilder.ToString());
            }

            /// 4. Third subcomponent : SS.SSS"
            formatBuilder.Clear();
            if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
            {
                // DMS: Uses the whole format.
                formatBuilder.Append(fmtFloatingNumberMax2);
            }

            // Computes and appends the third subcomponent.
            double seconds = (Math.Abs(value) * 3600) % 60;

            coordBuilder.Append(seconds.ToString(formatBuilder.ToString(), format.NumberFormat));

            // Adds symbol.
            if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
            {
                // DMS: Adds the symbol.
                if (format.ShowSymbols)
                {
                    coordBuilder.Append(format.SecondsSymbol);
                }
            }

            // DMS can return now.
            if (unit == GeoCoordinateUnit.DegreesMinutesSeconds)
            {
                return(coordBuilder.ToString());
            }

            // Makes sure we're not doing something unexpected.
            throw new InvalidOperationException("Unexpected unit: " + unit.ToString());
        }