Created
March 29, 2012 20:39
-
-
Save JeffJacobson/2243571 to your computer and use it in GitHub Desktop.
WA State Route related extension methods for .NET
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Jeff Jacobson, CGIS, ITS3 | |
* 2008-09 | |
*/ | |
using System.Text.RegularExpressions; | |
using System; | |
namespace Wsdot.Cgis.Extensions | |
{ | |
/// <summary> | |
/// This <see langword="static"/> <see langword="class"/> provides extension methods for dealing with State Route ID strings. | |
/// </summary> | |
public static class RouteExtensions | |
{ | |
private const string | |
////_SRID_PATTERN = @"(?in)(?<sr>\d{3})(?:(?<rrt>[A-Za-z0-9]{2})(?<rrq>[A-Za-z0-9]{0,6}))?", | |
// A regular expression matching a valid state route identifier. | |
_SRID_PATTERN = | |
@"(?inx) | |
(?<sr>\d{3}) | |
( | |
(?<rrt> | |
(AR)|(CO)|(C[DI])|(F[DI])|(LX)|(ML)|(RL)|(SP)|(TB)|(TR)|(PR)|(FU) | |
# If a value is capture in the ramp group, we know it is a ramp. | |
|(?<ramp>[PQRS][\dU]) | |
# A capture in the incOnly group indicates an RRT that only occurs in the increase layer. | |
# All others (excluding ramps) occur in both increasing and decreasing layers. (Based on info provided by Masao Matsuoka and Eric Jackson.) | |
|(?<incOnly>H[ID]) | |
# A capture in this group means a ferry RRT. | |
|(?<ferry>F[ST]) | |
) | |
(?<rrq>[A-Za-z0-9]{0,6}) | |
)?"; | |
private const string | |
_RAMP_RRT_PATTERN = @"(?i)[PQRS][\dU]", | |
////_DEC_RRT_PATTERN = @"(?in)(AR)|(CO)|(F[DI])|(FU)|(LX)|(RL)|(SP)", | |
////_INC_RRT_PATTERN = @"(?n)(AR)|(CO)|(F[DI])|(FU)|(H[DI])|(LX)|(RL)|(SP)"; | |
_INC_ONLY_RRT_PATTERN = @"H[ID]"; | |
private static readonly Regex | |
_srIdRegex = new Regex(_SRID_PATTERN), | |
_rampRrtRegex = new Regex(_RAMP_RRT_PATTERN); | |
/// <summary> | |
/// Attempts to split a state route string into its component SR, RRT, and RRQ parts. | |
/// </summary> | |
/// <param name="srid">A state route identifier string.</param> | |
/// <param name="sr">Output: The three digit route identifier.</param> | |
/// <param name="rrt">Output: The two character related route type (RRT) string, if applicable; otherwise, <see cref="string.Empty"/>.</param> | |
/// <param name="rrq">Output: The Related Roadway Qualifier string, if applicable; <see cref="string.Empty"/> otherwise.</param> | |
/// <returns> | |
/// Returns <see langword="true"/> if <paramref name="srid"/> is a properly formatted state route identifier. | |
/// Returns <see langword="false"/> otherwise. | |
/// </returns> | |
/// <remarks> | |
/// Note that this method does not check against all possible RRTs and RRQs; only the format of these strings is checked. | |
/// I.e., SR must be three digit characters, RRT (if provided) must consist of two digit or letter characters, RRQ (if RRT provided) must be between 0-6 digit or letter characters long. | |
/// </remarks> | |
public static bool TrySplitSRId(this string srid, out string sr, out string rrt, out string rrq) | |
{ | |
sr = rrt = rrq = null; | |
bool output = false; | |
// We already know that the input is not valid if it is null or empty. | |
if (!string.IsNullOrEmpty(srid)) | |
{ | |
// Use the regex to see if the SRID is valid. | |
Match srMatch = _srIdRegex.Match(srid); | |
if (srMatch.Success) | |
{ | |
GroupCollection groups = srMatch.Groups; | |
sr = groups["sr"].Value; | |
rrt = groups["rrt"].Value; | |
rrq = groups["rrq"].Value; | |
output = true; | |
} | |
} | |
return output; | |
} | |
public static bool IsValidSRId(this string srid) | |
{ | |
if (string.IsNullOrEmpty(srid)) return false; | |
return _srIdRegex.IsMatch(srid); | |
} | |
public static bool isRampSRId(this string srId) | |
{ | |
if (string.IsNullOrEmpty(srId)) return false; | |
Match m = _srIdRegex.Match(srId); | |
if (m.Success) | |
{ | |
Group rampGroup = m.Groups["ramp"]; | |
if (rampGroup.Success && rampGroup.Length > 0) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
public static bool IsRampRrt(this string rrt) | |
{ | |
if (string.IsNullOrEmpty(rrt)) return false; | |
return _rampRrtRegex.IsMatch(rrt); | |
} | |
public static char GetRouteType(this string srId, bool decrease) | |
{ | |
const char RAMP = 'R', INC = 'I', DEC = 'D'; | |
if (string.IsNullOrEmpty(srId)) throw new ArgumentException("Invalid SRID. SRID cannot be null or empty.", "srId"); | |
Match m = _srIdRegex.Match(srId); | |
if (string.IsNullOrEmpty(srId)) throw new ArgumentException("Invalid SRID.", "srId"); | |
GroupCollection groups = m.Groups; | |
// If the RRT indicates a ramp... | |
Group rampGroup = groups["ramp"]; | |
if (rampGroup.Success && rampGroup.Length > 0) | |
{ | |
return RAMP; | |
} | |
// If the RRT is only in the INC layer, or the user specified increase, return INC. Otherwise return DEC. | |
Group incOnlyGroup = groups["incOnly"]; | |
if ((incOnlyGroup.Success && incOnlyGroup.Length > 0) || !decrease) | |
{ | |
return INC; | |
} | |
else | |
{ | |
return DEC; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment