Is Valid GB Grid Reference
Although there are parts of Northern Ireland that fall within the GB Grid, Northern Ireland
Grid References should relate one of the Irish Grid reference systems.
Public Shared Function IsValidOs(EN As EastNorth) As Boolean
If EN.East <= 2 OrElse EN.East >= 699999 OrElse EN.North < 2 OrElse EN.North >= 1249999 Then Return False
' technically, the grid is 0-700000 by 0-1250000 (inclusive) however Northern Ireland should use Irish Grid
' and there is no other land on extreme edges of grid. Values within 2m of edges can cause problems in some programs.
Return True
End Function
Is Valid OS "Square" Reference
Private Function Square_IsValid(sq As String) As Boolean
' Square references should have 2 chars & 10 digits
' If you encounter less than 10 digits, it may be an approximate reference
' squares never contain the letter I
Dim ea, no As Integer
Dim s1, s2 As Char
sq = sq.ToUpper.Replace(" ", String.Empty)
If sq.Length <> 12 Then Return False
If sq.Contains("."c) Then Return False
If Not Integer.TryParse(Mid(sq, 3, 5), ea) Then Return False
If Not Integer.TryParse(Mid(sq, 8, 5), no) Then Return False
s1 = CChar(Mid(sq, 1, 1))
s2 = CChar(Mid(sq, 2, 1))
Select Case s1
Case "H"
If Not "LMNOPQRSTUVWXYZ".Contains(s2) Then Return False
If no > 500000 Then Return False
Case "J"
If Not "LMQRVW".Contains(s2) Then Return False
If no > 500000 Then Return False
Case "N", "S"
If Not "ABCDEFGHJKLMNOPQRSTUVWXYZ".Contains(s2) Then Return False
Case "O", "T"
If Not "ABFGLMQRVW".Contains(s2) Then Return False
Case Else
Return False
End Select
Return True
End Function
Convert Easting/Northing to 12 Figure Grid Reference
Private Function EastNorth_To_12Figure(EN As EastNorth) As String
' Although this type of grid reference is called 12 figure, North Scotland locations may require a 13th digit
' Leading zeros (if present) MUST be included in 12 figure grid references
' Always round down to integer when converting from easting/northing to 12 figure (bottom left od square containing reference)
' When converting 12 figure to easting/northing add 0.5 toshow middle of square containing reference
' Eastings and Northings can be accurate to 1mm, however, 12 figure refrences are only accutate to 1m
' The space is optional but recommended when reference is being used in a spreadsheet. (Space discourages spreadesheet removal of leading zeros.)
Dim ea, no As Integer
ea = Math.Floor(EN.East)
no = Math.Floor(EN.North)
Return ea.ToString("000000") & " " & no.ToString("#000000").Trim
End Function
Convert 12 Figure Grid Reference To Eating/Northing
Private Function Figure12_To_EastNorth(fig12 As String) As EastNorth
Dim ret As EastNorth
Dim eInteger, nInteger As Integer
Dim eString, nString As String
ret.East = 0 : ret.North = 0 ' default value indicating invalid fig12 value
fig12 = fig12.Replace(" "c, String.Empty)
If fig12.Length < 12 OrElse fig12.Length > 13 Then Return ret
eString = Mid(fig12, 1, 6)
nString = Mid(fig12, 7)
If Not Integer.TryParse(eString, eInteger) Then Return ret
If Not Integer.TryParse(nString, nInteger) Then Return ret
If eInteger <= 0 OrElse eInteger >= 700 Then Return ret
If nInteger <= 0 OrElse nInteger >= 1250 Then Return ret
ret.East = eInteger + 0.5
ret.North = nInteger + 0.5
Return ret
End Function
Convert Easting/Northing To 12 Figure Reference
Private Function EastNorth_To_Square(en As EastNorth) As String
' Square references (with 1m accuracy) are always two letters followed by 10 digits
' All digits (including leading zeros must be included
' Optional spaces allowed before first digit and between 5th/6th digit
' when the easting or northing is invalid,function will return an empty string
Dim eInteger As Integer = Math.Floor(en.East)
Dim nInteger As Integer = Math.Floor(en.North)
If eInteger <= 0 OrElse eInteger >= 700000 Then Return String.Empty
If nInteger <= 0 OrElse nInteger >= 1250000 Then Return String.Empty
Dim eSquare As Integer = eInteger \ 100000
eInteger = eInteger Mod 100000
Dim nSquare As Integer = nInteger \ 100000
nInteger = nInteger Mod 100000
Dim sq1, sq2 As Char
If eSquare < 5 Then
Select Case nSquare
Case < 5 : sq1 = "S"c
Case >= 5 < 10 : sq1 = "N"c
Case Else : sq1 = "H"c
End Select
Else
Select Case nSquare
Case < 5 : sq1 = "T"c
Case >= 5 < 10 : sq1 = "O"c
Case Else : sq1 = "J"c
End Select
End If
Dim eSqMod5 As Integer = eSquare Mod 5
Dim nSqMod5 As Integer = nSquare Mod 5
Dim alpha As String = "VWXYZQRSTULMNOPFGHJKABCDE"
sq2 = CChar(Mid(alpha, eSqMod5 + (nSqMod5 * 5) + 1, 1))
Return sq1 & sq2 & " " & eInteger.ToString("00000") & " " & nInteger.ToString("00000")
End Function
Convert Square Reference to Easting/Northing
Private Function Square_To_EastNorth(sq As String) As EastNorth
' Will return East=0,North=0 for an Invalid square reference
Dim ea, no As Integer
Dim err, ret As EastNorth : err.East = 0 : err.North = 0
sq = sq.ToUpper.Replace(" "c, String.Empty)
If sq.Length <> 12 Then Return err
If Not Integer.TryParse(Mid(sq, 3, 5), ea) Then Return err
If Not Integer.TryParse(Mid(sq, 8, 5), no) Then Return err
Select Case Mid(sq, 1, 1)
Case "S" : ea += 0 : no += 0
Case "N" : ea += 0 : no += 500000
Case "H" : ea += 0 : no += 1000000
Case "T" : ea += 500000 : no += 0
Case "O" : ea += 500000 : no += 500000
Case "J" : ea += 500000 : no += 1000000
Case Else : Return err
End Select
Select Case Mid(sq, 2, 1)
Case "V", "Q", "L", "F", "A" : ea += 0
Case "W", "R", "M", "G", "B" : ea += 100000
Case "X", "S", "N", "H", "C" : ea += 200000
Case "Y", "T", "O", "J", "D" : ea += 300000
Case "Z", "U", "P", "K", "E" : ea += 400000
Case Else : Return err
End Select
Select Case Mid(sq, 2, 1)
Case "V", "W", "X", "Y", "Z" : no += 0
Case "Q", "R", "S", "T", "U" : no += 100000
Case "L", "M", "N", "O", "P" : no += 200000
Case "F", "G", "H", "J", "K" : no += 300000
Case "A", "B", "C", "D", "E" : no += 400000
Case Else : Return err
End Select
ret.East = ea + 0.5
ret.North = no + 0.5
Return ret
End Function
Convert Short Square Reference to Square Reference
Private Function ShortSquare_To_Square(sSq As String) As String
' Short square references should be avoided because they are only approximations
' 2 letters 10 digits = accuracy 1m = normal square reference
' 2 letters 8 digits = accuracy 10m
' 2 letters 6 digits = accuracy 100m
' 2 letters 4 digits = accuracy 1km
' 2 letters 2 digits = accuracy 10km
' 2 letters 0 digits = accuracy 100km
' Function will return string.empty when ShortSquare reference is invalid
' When using reduced accuracy, try to point to middle of posible region
Dim ret As String
Dim err As String = String.Empty
sSq = sSq.ToUpper.Replace(" ", String.Empty)
Dim ea, no As Integer
If sSq.Contains("."c) Then Return err
Select Case sSq.Length
Case 12
If Not Integer.TryParse(Mid(sSq, 3, 5), ea) Then Return err
If Not Integer.TryParse(Mid(sSq, 8, 5), no) Then Return err
Case 10
If Not Integer.TryParse(Mid(sSq, 3, 4), ea) Then Return err
If Not Integer.TryParse(Mid(sSq, 7, 4), no) Then Return err
Case 8
If Not Integer.TryParse(Mid(sSq, 3, 3), ea) Then Return err
If Not Integer.TryParse(Mid(sSq, 6, 3), no) Then Return err
Case 6
If Not Integer.TryParse(Mid(sSq, 3, 2), ea) Then Return err
If Not Integer.TryParse(Mid(sSq, 5, 2), no) Then Return err
Case 4
If Not Integer.TryParse(Mid(sSq, 3, 1), ea) Then Return err
If Not Integer.TryParse(Mid(sSq, 4, 1), no) Then Return err
Case 2
ea = 0
no = 0
Case Else
Return err
End Select
ret = Mid(sSq, 1, 2) & " " & ea.ToString("00000") & " " & no.ToString("00000")
If Not Square_IsValid(ret) Then Return err
Return ret
End Function
DigitalDan.co.uk