Skip to content

Commit

Permalink
Truncate, don't round when calculating OS 6 figure references (fixes #1)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdoug committed Nov 19, 2014
1 parent 3d032ca commit 6ea75a2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 36 deletions.
50 changes: 20 additions & 30 deletions OSRef.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ class OSRef {
* object from the six-figure grid reference TG514131, the easting would
* be 651400 and the northing would be 313100.
*
* Grid references with accuracy greater than 1m can be represented
* using floating point values for the easting and northing. For example,
* a value representing an easting or northing accurate to 1mm would be
* given as 651400.0001.
*
* @param int $aEasting the easting of the reference (with 1m accuracy)
* @param int $aNorthing the northing of the reference (with 1m accuracy)
*/
Expand All @@ -67,41 +62,36 @@ public function __toString() {
* @return string
*/
public function toSixFigureString() {
$hundredkmE = floor($this->easting / 100000);
$hundredkmN = floor($this->northing / 100000);
$firstLetter = "";
if ($hundredkmN < 5) {
if ($hundredkmE < 5) {
$firstLetter = "S";
}
else {
$firstLetter = "T";
}

$easting = str_pad($this->easting, 6, 0, STR_PAD_LEFT);
$northing = str_pad($this->northing, 6, 0, STR_PAD_LEFT);

$hundredkmE = $easting[0];
$hundredkmN = $northing[0];

if ($hundredkmN < 5 && $hundredkmE < 5) {
$firstLetter = 'S';
}
else if ($hundredkmN < 10) {
if ($hundredkmE < 5) {
$firstLetter = "N";
}
else {
$firstLetter = "O";
}
else if ($hundredkmN < 5 && $hundredkmE >= 5) {
$firstLetter = 'T';
}
else if ($hundredkmN < 10 && $hundredkmE < 5) {
$firstLetter = 'N';
}
else if ($hundredkmN < 10 && $hundredkmE >= 5) {
$firstLetter = 'O';
}
else {
$firstLetter = "H";
$firstLetter = 'H';
}

$secondLetter = "";
$index = 65 + ((4 - ($hundredkmN % 5)) * 5) + ($hundredkmE % 5);
$ti = $index;
if ($index >= 73) {
if ($index >= 73) { //skip the letter I
$index++;
}
$secondLetter = chr($index);

$e = round(($this->easting - (100000 * $hundredkmE)) / 100);
$n = round(($this->northing - (100000 * $hundredkmN)) / 100);

return sprintf("%s%s%03d%03d", $firstLetter, $secondLetter, $e, $n);
return $firstLetter . $secondLetter . substr($easting, 1, 3) . substr($northing, 1, 3);
}


Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ Output of calculations have been changed from the original code in the following
* Eastings and northings are rounded to 1m, and lat/long to 5dp (approx 1m) to avoid any
misconceptions that precision is the same thing as accuracy
* When calculating surface distances, a more accurate mean radius is now used rather than
that derived from historical definitions of a nautical mile
that derived from historical definitions of a nautical mile
* Corrected calculation of OS 6-figure grid references (rounding instead of truncating meant the
grid square was sometimes off by 1)

Usage
-----
Expand Down
19 changes: 14 additions & 5 deletions tests/OSRefTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,20 @@ public function testLatLngOSWorkedExample() {
}

public function testToSixFigureString() {

$OSRef = new OSRef(530140, 184184);

$expected = 'TQ301842';


$OSRef = new OSRef(530140, 184184);

$expected = 'TQ301841';

self::assertEquals($expected, $OSRef->toSixFigureString());
}

public function testToSixFigureString2() {

$OSRef = new OSRef(439145, 274187);

$expected = 'SP391741';

self::assertEquals($expected, $OSRef->toSixFigureString());
}

Expand Down

0 comments on commit 6ea75a2

Please sign in to comment.