/// <summary>
        /// Here is supposed that easting and northing are integers, e.g. 33T 4498003N; 674582E, but not 33T 4498003.123N; 674582.3542E
        /// </summary>
        /// <param name="utmCoordinatesMatch">Regex.Match object to match the coordinate parts. Should have named groups "zone", "easting", and "northing".</param>
        /// <param name="latitude">ICoordinatePart object for the latitude coordinate part.</param>
        /// <param name="longitude">ICoordinatePart object for the longitude coordinate part.</param>
        /// <returns>The Success value of the <paramref name="utmCoordinatesMatch"/> match.</returns>
        private bool ProcessIntegerUTMCoordinate(Match utmCoordinatesMatch, ICoordinatePart latitude, ICoordinatePart longitude)
        {
            if (utmCoordinatesMatch.Success)
            {
                // Add tailing zeros
                var utmEastingString  = utmCoordinatesMatch.Groups[UtmEastingValue].Value.Trim().PadRight(6, '0');
                var utmNorthingString = utmCoordinatesMatch.Groups[UtmNorthingValue].Value.Trim().PadRight(7, '0');

                var utmZone     = utmCoordinatesMatch.Groups[UtmZoneValue].Value.Trim();
                var utmEasting  = double.Parse(utmEastingString);
                var utmNorthing = double.Parse(utmNorthingString);

                var point = this.utmCoordianesTransformer.TransformUtm2Decimal(utmEasting, utmNorthing, utmZone);

                latitude.DecimalValue  = point[0];
                latitude.Type          = CoordinatePartType.Latitude;
                latitude.PartIsPresent = true;

                longitude.DecimalValue  = point[1];
                longitude.Type          = CoordinatePartType.Longitude;
                longitude.PartIsPresent = true;

                return(true);
            }

            return(false);
        }
        private void ParseCoordinateObject(ICoordinatePart latitude, ICoordinatePart longitude, Coordinate coordinate)
        {
            this.ParseSinglePartTypeCoordinate(
                coordinate.Latitude,
                latitude,
                LatitudeMatchPattern);

            this.ParseSinglePartTypeCoordinate(
                coordinate.Longitude,
                longitude,
                LongitudeMatchPattern);
        }
        private void ParseGeneralTypeCoordinate(string coordinateText, ICoordinatePart latitude, ICoordinatePart longitude)
        {
            var coordinate = new Coordinate();

            {
                string leftPart  = Regex.Replace(coordinateText, CoordinateParsePattern, "$1");
                string rightPart = Regex.Replace(coordinateText, CoordinateParsePattern, "$16");

                this.DetermineLatitudeAndLongitudePartsFromTwoPartSeparableCoordinateString(coordinate, leftPart, rightPart);
            }

            this.ParseCoordinateObject(latitude, longitude, coordinate);
        }
        private void ProcessCoordinateNodeWithDeterminedLatitudeAndLongitudeStringParts(
            string latitudeString,
            string longitudeString,
            ICoordinatePart latitude,
            ICoordinatePart longitude)
        {
            var coordinate = new Coordinate
            {
                Latitude  = latitudeString,
                Longitude = longitudeString
            };

            this.ParseCoordinateObject(latitude, longitude, coordinate);
        }
        private bool ProcessSimpleSphericalCoordinate(Match match, ICoordinatePart latitude, ICoordinatePart longitude)
        {
            if (match.Success)
            {
                var latitudeString  = match.Groups[LatitudeTypeValue].Value.Trim();
                var longitudeString = match.Groups[LongitudeTypeValue].Value.Trim();

                this.ProcessCoordinateNodeWithDeterminedLatitudeAndLongitudeStringParts(
                    latitudeString,
                    longitudeString,
                    latitude,
                    longitude);

                return(true);
            }

            return(false);
        }
        private void ParseSinglePartTypeCoordinate(string coordinateText, ICoordinatePart coordinatePart, string matchPartPattern)
        {
            Match matchPart = Regex.Match(coordinateText, matchPartPattern);

            coordinatePart.PartIsPresent = matchPart.Success;

            if (coordinatePart.PartIsPresent)
            {
                if (matchPart.NextMatch().Success)
                {
                    throw new ApplicationException($"Multiple matches of {coordinatePart.Type}");
                }
                else
                {
                    coordinatePart.CoordinatePartString = coordinatePart.PartIsPresent ? matchPart.Value : string.Empty;
                    coordinatePart.Parse();
                    //// this.logger?.Log("{0} =\t{1}", coordinatePart.Type, coordinatePart.CoordinatePartString);
                }
            }
        }
Esempio n. 7
0
        public void Intercept(IInvocation invocation)
        {
            if (invocation.Request.Target.GetType() == typeof(Coordinate2DParser))
            {
                if (invocation.Request.Arguments.Length != 4)
                {
                    throw new InvalidOperationException($"{nameof(LogParsedCoordinatesInterceptor)} requires invocation with 4 arguments");
                }

                string          coordinateString = (string)invocation.Request.Arguments[0];
                string          coordinateType   = (string)invocation.Request.Arguments[1];
                ICoordinatePart latitude         = (ICoordinatePart)invocation.Request.Arguments[2];
                ICoordinatePart longitude        = (ICoordinatePart)invocation.Request.Arguments[3];

                invocation.Proceed();

                this.logger?.Log("{2} =\t{0};\t{3} =\t{1}\n", latitude.Value, longitude.Value, latitude.Type, longitude.Type);
            }
            else
            {
                invocation.Proceed();
            }
        }
        public void ParseCoordinateString(string coordinateString, string coordinateType, ICoordinatePart latitude, ICoordinatePart longitude)
        {
            try
            {
                {
                    var integerUtmCoordinatesMatchPatterns = new string[]
                    {
                        // UTM WGS84: 33T 455.4683
                        @"\A(?:\s*UTM\s*[A-Z]+[0-9]+:?\s+)?(?<zone>[0-9]{1,2}[A-Z])\s+(?<easting>[0-9]{2,7})\.(?<northing>[0-9]{2,7})\s*\Z",

                        // UTM ED50: 33T 4498003N; 674582E
                        @"\A(?:\s*UTM\s*[A-Z]+[0-9]+:?\s+)?(?<zone>[0-9]{1,2}[A-Z])\s+(?<northing>[0-9]{2,7})N\W+(?<easting>[0-9]{2,7})E\s*\Z",

                        // UTM ED50: 33T 674582E; 4498003N
                        @"\A(?:\s*UTM\s*[A-Z]+[0-9]+:?\s+)?(?<zone>[0-9]{1,2}[A-Z])\s+(?<easting>[0-9]{2,7})E\W+(?<northing>[0-9]{2,7})N\s*\Z",

                        // 55G 595500 5371700
                        @"\A(?:\s*UTM\s*[A-Z]+[0-9]+:?\s+)?(?<zone>[0-9]{1,2}[A-Z])\s+(?<easting>[0-9]{2,6})\W+(?<northing>[0-9]{2,7})\s*\Z"
                    };

                    var integerUtmCoordinatesMatches = integerUtmCoordinatesMatchPatterns.Select(p => Regex.Match(coordinateString, p));
                    foreach (var match in integerUtmCoordinatesMatches)
                    {
                        if (this.ProcessIntegerUTMCoordinate(match, latitude, longitude))
                        {
                            return;
                        }
                    }
                }

                {
                    string coordinateText = coordinateString
                                            .RegexReplace("[–—−-]", "-")
                                            .RegexReplace(@"\s*:\s*", " ");

                    var simpleSphericalCoordinatesPatterns = new string[]
                    {
                        // 29.5423°, -86.1926°  /see test case/
                        @"\A(?<latitude>\-?[0-9]+\.[0-9]+\W?)[;,\s]+(?<longitude>\-?[0-9]+\.[0-9]+\W?)\Z",

                        // -31:34:55; 159:5:9 /see test case/
                        @"\A(?<latitude>\-?[0-9]+ [0-9]+ [0-9]+)[;,\s]+(?<longitude>\-?[0-9]+ [0-9]+ [0-9]+)\Z",
                    };

                    var simplesphericalCoordinatesMatches = simpleSphericalCoordinatesPatterns.Select(p => Regex.Match(coordinateText, p));
                    foreach (var match in simplesphericalCoordinatesMatches)
                    {
                        if (this.ProcessSimpleSphericalCoordinate(match, latitude, longitude))
                        {
                            return;
                        }
                    }
                }

                {
                    //// 03°14.78S, 72°54.61W /see test case/
                    //// 03°15’S 72°54’W /see test case/
                    //// 20°20.1N 74°33.6W /see test case/
                    //// 37°08'09.4"N, 8°23'04.2"W /see test case/
                    //// 08º48’23’’S, 115º56’24’’E /see test case/

                    string coordinateText = this.SimplifyCoordinateString(coordinateString);

                    if (string.IsNullOrWhiteSpace(coordinateType))
                    {
                        this.ParseGeneralTypeCoordinate(coordinateText, latitude, longitude);
                    }
                    else if (coordinateType == LatitudeTypeValue)
                    {
                        this.ParseLatitudeTypeCoordinate(coordinateText, latitude);
                    }
                    else if (coordinateType == LongitudeTypeValue)
                    {
                        this.ParseLongitudeTypeCoordinate(coordinateText, longitude);
                    }
                }
            }
            catch (ApplicationException)
            {
                string coordinateText  = this.SimplifyCoordinateString(coordinateString);
                var    latitudeString  = Regex.Replace(coordinateText, @"\A.*([NS])\W?(\d{1,3})\W{1,3}(\d{1,3})\W{1,3}(\d{1,3}).*\Z", "$1$2 $3 $4");
                var    longitudeString = Regex.Replace(coordinateText, @"\A.*([EW])\W?(\d{1,3})\W{1,3}(\d{1,3})\W{1,3}(\d{1,3}).*\Z", "$1$2 $3 $4");

                this.ProcessCoordinateNodeWithDeterminedLatitudeAndLongitudeStringParts(
                    latitudeString,
                    longitudeString,
                    latitude,
                    longitude);
            }
        }
 private void ParseLatitudeTypeCoordinate(string coordinateText, ICoordinatePart latitude)
 {
     this.ParseSinglePartTypeCoordinate(coordinateText, latitude, MatchLatitudePartPattern);
 }