Code Monkey home page Code Monkey logo

Comments (7)

stevegoddard avatar stevegoddard commented on June 19, 2024 1

Glad it works James. Take a look at the image at the top of this page:

http://www.record-lrc.co.uk/c2.aspx?Mod=Article&ArticleID=GridRefs_Main

Hopefully explains how the letters work!

Steve

from phpcoord.

stevegoddard avatar stevegoddard commented on June 19, 2024

Just convert the grid ref to eastings/northing first. Then use:

$OSRef = new OSRef(500000, 200000); //Easting, Northing
$LatLng = $OSRef->toLatLng();

The conversion from grid ref to easting/northing is easy enough and you can decide if you want it centred or bottom left corner. I have a function that does this - it's pretty old code but still works ok. Happy to share if it helps.

Steve

from phpcoord.

imbeingfollowed avatar imbeingfollowed commented on June 19, 2024

Thanks for looking into this for me Steve.

I couldn't find a routine here to convert the 10 figure grid ref into an easting and northing, could you point me in the right direction?

Centering the result does sound good too. Any code you can share at all would be much appreciated.

Cheers,

James

from phpcoord.

stevegoddard avatar stevegoddard commented on June 19, 2024

Hi James,
Here you go. I did write this a long time ago - it could probably be simplified a lot. But it's fairly well commented.

Hope it helps. It doesn't do any centering - but that would be easy to add as you have the resolution - so just add half the resolution meters to easting and northing.

Steve

========================================

//Function to convert a gridref to northing and easting.
function gridref_to_ne($var_grid_ref)
{

    //Allowed prefixes.
    $var_allowed_prefixes = ['HP', 'HT', 'HU', 'HW', 'HX', 'HY', 'HZ', 'NA', 'NB', 'NC', 'ND', 'NF', 'NG', 'NH', 'NJ', 'NK', 'NL', 'NM', 'NN', 'NO', 'NR', 'NS', 'NT', 'NU', 'NW', 'NX', 'NY', 'NZ', 'OV', 'SC', 'CD', 'CE', 'SH', 'SJ', 'SK', 'SM', 'SN', 'SO', 'SP', 'SR', 'SS', 'ST', 'SU', 'SV', 'SW', 'SX', 'SY', 'SZ', 'TA', 'TF', 'TG', 'TL', 'TM', 'TQ', 'TR', 'TV'];

    //Validation. Check length, prefix letters, and that at least the next 2 characters are numeric.
    if ((strlen($var_grid_ref) >= 4) && (strlen($var_grid_ref) <= 12) && (in_array(substr($var_grid_ref, 0, 2), $var_allowed_prefixes)) && (is_numeric(substr($var_grid_ref, 2, 2)))) {

        //Clean the string.
        $var_grid_ref = strtoupper(preg_replace("/[^a-zA-Z0-9]/", "", $var_grid_ref));

        //Find the length.
        $var_grid_ref_length = strlen($var_grid_ref);

        //Chop it up.
        $var_grid_ref_prefix_1 = substr($var_grid_ref, 0, 1); //Just the first letter.
        $var_grid_ref_prefix_2 = substr($var_grid_ref, 1, 1); //Just the second letter.
        if ($var_grid_ref_length == 5) {
            //Tetrad.
            $var_grid_ref_numbers = substr($var_grid_ref, 2, 2); //2 numbers after the prefix.
            $var_grid_ref_num_1 = substr($var_grid_ref, 2, 1); //Get the first number.
            $var_grid_ref_num_2 = substr($var_grid_ref, 3, 1); //Get the second number.
            $var_tetrad = strtoupper(substr($var_grid_ref, 4, 1));
        } else {
            //Normal.
            $var_grid_ref_numbers = substr($var_grid_ref, 2, ($var_grid_ref_length - 2)); //All the numbers after the prefix.
            $var_grid_ref_num_1 = substr($var_grid_ref, 2, (($var_grid_ref_length - 2) / 2)); //Get the first N characters.
            $var_grid_ref_num_2 = substr($var_grid_ref, (2 + (($var_grid_ref_length - 2) / 2)), (($var_grid_ref_length - 2) / 2)); //Get the last N characters.
            $var_tetrad = null;
        }

        //Create variables for eastings and northing.
        $var_easting = 0;
        $var_northing = 0;

        //Handle first letters.
        if ($var_grid_ref_prefix_1 == 'S') {
            $var_easting = 0;
            $var_northing = 0;
        } else if ($var_grid_ref_prefix_1 == 'N') {
            $var_easting = 0;
            $var_northing = 500000;
        } else if ($var_grid_ref_prefix_1 == 'H') {
            $var_easting = 0;
            $var_northing = 1000000;
        } else if ($var_grid_ref_prefix_1 == 'T') {
            $var_easting = 500000;
            $var_northing = 0;
        } else if ($var_grid_ref_prefix_1 == 'O') {
            $var_easting = 500000;
            $var_northing = 500000;
        } else {
            //Unrecognised grid ref.
        }

        //Build an array for the second letter - easting.
        $var_array_second_letter_easting_array_4 = ['E', 'K', 'P', 'U', 'Z']; //400000
        $var_array_second_letter_easting_array_3 = ['D', 'J', 'O', 'T', 'Y']; //300000
        $var_array_second_letter_easting_array_2 = ['C', 'H', 'N', 'S', 'X']; //200000
        $var_array_second_letter_easting_array_1 = ['B', 'G', 'M', 'R', 'W']; //100000
        $var_array_second_letter_easting_array_0 = ['A', 'F', 'L', 'Q', 'V']; //0

        //Find the number in the array.
        $var_easting_second = 0;
        if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_easting_array_4)) {
            $var_easting_second = 400000;
        } else if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_easting_array_3)) {
            $var_easting_second = 300000;
        } else if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_easting_array_2)) {
            $var_easting_second = 200000;
        } else if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_easting_array_1)) {
            $var_easting_second = 100000;
        }

        //Build an array for the second letter - northing.
        $var_array_second_letter_northing_array_4 = ['A', 'B', 'C', 'D', 'E']; //400000
        $var_array_second_letter_northing_array_3 = ['F', 'G', 'H', 'J', 'K']; //300000
        $var_array_second_letter_northing_array_2 = ['L', 'M', 'N', 'O', 'P']; //200000
        $var_array_second_letter_northing_array_1 = ['Q', 'R', 'S', 'T', 'U']; //100000
        $var_array_second_letter_northing_array_0 = ['V', 'W', 'X', 'Y', 'Z']; //0

        //Find the number in the array.
        $var_northing_second = 0;
        if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_northing_array_4)) {
            $var_northing_second = 400000;
        } else if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_northing_array_3)) {
            $var_northing_second = 300000;
        } else if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_northing_array_2)) {
            $var_northing_second = 200000;
        } else if (in_array($var_grid_ref_prefix_2, $var_array_second_letter_northing_array_1)) {
            $var_northing_second = 100000;
        }

        //Add them together.
        $var_easting = $var_easting + $var_easting_second;
        $var_northing = $var_northing + $var_northing_second;

        /**************************************************************/

        //Deal with possible tetrad first, then everything else.
        if ($var_grid_ref_length == 5) {
            //Tetrad.
            $var_resolution = '2km';

            $var_grid_ref_num_1 = $var_grid_ref_num_1 * 10000;
            $var_grid_ref_num_2 = $var_grid_ref_num_2 * 10000;

            //Now need to add on extra for tetrad - easting.
            $var_array_tetrad_easting_array_8k = array('V', 'W', 'X', 'Y', 'Z'); //8000
            $var_array_tetrad_easting_array_6k = array('Q', 'R', 'S', 'T', 'U'); //6000
            $var_array_tetrad_easting_array_4k = array('K', 'L', 'M', 'N', 'P'); //4000
            $var_array_tetrad_easting_array_2k = array('F', 'G', 'H', 'I', 'J'); //2000
            $var_array_tetrad_easting_array_0k = array('A', 'B', 'C', 'D', 'E'); //0

            if (in_array($var_tetrad, $var_array_tetrad_easting_array_8k)) {$var_grid_ref_num_1 = $var_grid_ref_num_1 + 8000;} else if (in_array($var_tetrad, $var_array_tetrad_easting_array_6k)) {$var_grid_ref_num_1 = $var_grid_ref_num_1 + 6000;} else if (in_array($var_tetrad, $var_array_tetrad_easting_array_4k)) {$var_grid_ref_num_1 = $var_grid_ref_num_1 + 4000;} else if (in_array($var_tetrad, $var_array_tetrad_easting_array_2k)) {$var_grid_ref_num_1 = $var_grid_ref_num_1 + 2000;} else if (in_array($var_tetrad, $var_array_tetrad_easting_array_0k)) {$var_grid_ref_num_1 = $var_grid_ref_num_1 + 0;}

            //Now need to add on extra for tetrad - northing.
            $var_array_tetrad_northing_array_8k = array('E', 'J', 'P', 'U', 'Z'); //8000
            $var_array_tetrad_northing_array_6k = array('D', 'I', 'N', 'T', 'Y'); //6000
            $var_array_tetrad_northing_array_4k = array('C', 'H', 'M', 'S', 'X'); //4000
            $var_array_tetrad_northing_array_2k = array('B', 'G', 'L', 'R', 'W'); //2000
            $var_array_tetrad_northing_array_0k = array('A', 'F', 'K', 'Q', 'V'); //0
            if (in_array($var_tetrad, $var_array_tetrad_northing_array_8k)) {$var_grid_ref_num_2 = $var_grid_ref_num_2 + 8000;} else if (in_array($var_tetrad, $var_array_tetrad_northing_array_6k)) {$var_grid_ref_num_2 = $var_grid_ref_num_2 + 6000;} else if (in_array($var_tetrad, $var_array_tetrad_northing_array_4k)) {$var_grid_ref_num_2 = $var_grid_ref_num_2 + 4000;} else if (in_array($var_tetrad, $var_array_tetrad_northing_array_2k)) {$var_grid_ref_num_2 = $var_grid_ref_num_2 + 2000;} else if (in_array($var_tetrad, $var_array_tetrad_northing_array_0k)) {$var_grid_ref_num_2 = $var_grid_ref_num_2 + 0;}

        } else if ($var_grid_ref_length == 4) {
            //2 figure grid ref.
            $var_resolution = '10km';
            $var_grid_ref_num_1 = $var_grid_ref_num_1 * 10000;
            $var_grid_ref_num_2 = $var_grid_ref_num_2 * 10000;
        } else if ($var_grid_ref_length == 6) {
            //4 figure grid ref plus letters.
            $var_resolution = '1km';
            $var_grid_ref_num_1 = $var_grid_ref_num_1 * 1000;
            $var_grid_ref_num_2 = $var_grid_ref_num_2 * 1000;
        } else if ($var_grid_ref_length == 8) {
            //6 figure grid ref plus letters.
            $var_resolution = '100m';
            $var_grid_ref_num_1 = $var_grid_ref_num_1 * 100;
            $var_grid_ref_num_2 = $var_grid_ref_num_2 * 100;
        } else if ($var_grid_ref_length == 10) {
            //8 figure grid ref plus letters.
            $var_resolution = '10m';
            $var_grid_ref_num_1 = $var_grid_ref_num_1 * 10;
            $var_grid_ref_num_2 = $var_grid_ref_num_2 * 10;
        } else if ($var_grid_ref_length == 12) {
            $var_resolution = '1m';
            //10 figure grid ref plus letters. No multiplication required.
            $var_grid_ref_num_1 = $var_grid_ref_num_1 * 1;
            $var_grid_ref_num_2 = $var_grid_ref_num_2 * 1;
        } else {
            //Odd length!
            $var_resolution = 'Unknown';
        }

        //Add it all together.
        $var_easting = $var_easting + $var_grid_ref_num_1;
        $var_northing = $var_northing + $var_grid_ref_num_2;

        //Return an array of the easting and northing.
        return [
            'status' => 'success',
            'gridref' => $var_grid_ref,
            'resolution' => $var_resolution,
            'tetrad' => $var_tetrad,
            'easting' => $var_easting,
            'northing' => $var_northing,
        ];

    } else {

        return [
            'status' => 'error',
            'message' => Lang::get('geom.invalid_gridref'),
        ];

    }

}

from phpcoord.

imbeingfollowed avatar imbeingfollowed commented on June 19, 2024

Cheers Steve.

The first two letter conversions go over my head but I can confirm your code does work well. I hope to study it soon!

Thanks again,
James

from phpcoord.

dvdoug avatar dvdoug commented on June 19, 2024

Hi @imbeingfollowed

Thanks for the suggestion, I've now added this and released it as a new version. The master branch had been updated to have a minimum PHP7.1 version since the last release of the library, so I have released this as v3.0.0 as there are a few API-incompatible changes in there due to e.g. use of stricter typing.

If you're using an older PHP version still and need me to backport to the v2 branch, please let me know, it would be pretty easy to do

from phpcoord.

imbeingfollowed avatar imbeingfollowed commented on June 19, 2024

That's a nice added bonus, Doug - cheers!

You are doing excellent work here.

James

from phpcoord.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.