This page contains some of the co-ordinate systems commonly used in radiocommunications work.
It is assumed the concept of Latitude and Longitude are understood. Even so, there are several ways of expressing a location on the surface of the earth and latitude and longitude are not all that useful when using a map. Co-ordinate systems have been invented to try and make things easier to understand. The sitedata programme in the software section will convert between systems for you.
The Maidenhead System The maidenhead locator was invented to provide a worldwide simple to
use locator based on latitude and longitude. The picture below generated by the excellent AZ_Proj utility gives the idea.
|
The OSGB system The UK NGR is based on a projection of an ellipsoid to allow a curved surface to be represented on a flat map. It is only valid for the UK. The ellipsoid used in the OSGB36 datum which was invented in 1830 by the Astronomer Royal, Sir George Airy. The caluclations in this programme are fairly detailed and should give results accurate to a few metres. Beware of Ellipsoids. GPS data is often based on WGS84. Using the incorrect ellipsoid can result in errors of several 100m. The UK national grid reference should be written as a two letter plus 4 digit, 6 digit or 8 digit locator. E.g. SU59, SU500900, SU50009000 The more digits the higher the accuracy - 8 is generally more than enough resolution unless you are into surveying. These locators are commonly printed as a grid on UK Ordanance Survey maps. The grid covering the UK is 700km by 1300km. The lettters indicate the large square, the first letter represents a 500x500km square and can be S,T, N, O, H or J. Placed over the UK as below, with North being at the top. H J The second letter represents a 100kmx100km square within the 500km squares. It can be any letter except I. The format is: A B C D E The numbers are then the range East and North of the bottom left corner of the square. With 2 digits, the first is East and the next is North. Naturally, the digit is in units of 10km. With 2 digits, the first 2 are East and the next 2 North in units of 1km and so on for increasing numbers of digits. Not all grid squares contain land and as there is a false zero, the easiest way to picture it is as an image.
It is also possible to avoid all these complicated letters and numbers and simply quote two numbers, the distance East and distance North of the reference point, which is at the bottom left of the map. The distance is usually expressed in metres. |
Code - C++. No promises it will be suitable for purpose etc.
Lat-Long & Maidenhead
const double FIELD_WIDTH = 20.0; AnsiString DegToMaidenhead(double lat, double lon) // Returns Maidenhead Locator { AnsiString locator; latitude += 90.0; char ilong = char(longitude / FIELD_WIDTH); char ilat = char(latitude / FIELD_HEIGHT); ilong = char(longitude / SQUARE_WIDTH); ilat = char(latitude / SQUARE_HEIGHT); ilong = char(longitude / SUB_WIDTH); ilat = char(latitude / SUB_HEIGHT); ilong = char(longitude / SUB_SUB_WIDTH); ilat = char(latitude / SUB_SUB_HEIGHT); locator.printf("%s",buff); MaidenheadToDeg(AnsiString locator, double &latitude,
double &longitude) locator = locator.UpperCase(); if (locator.Length() == 4) if (locator.Length() != 6 && locator.Length()
!= 8) if (locator[1] < 'A' || locator[1] > 'R' || if (locator.Length() == 8 && longitude = -180.0 + FIELD_WIDTH * (locator[1] - 'A')
+ latitude = -90.0 + FIELD_HEIGHT * (locator[2] - 'A')
+ if (locator.Length() == 8) { |
OSGB Conversions - written by Chuck Gantz - chuck.gantz@globalstar.com
void OSGBtoLL(const
double OSGBNorthing, const double OSGBEasting, const char* OSGBZone, double&
Lat, double& Long )
double eccSquared =
(majoraxis * majoraxis - minoraxis * minoraxis) / (majoraxis * majoraxis); //only calculate M0 once since it is based on the origin of the OSGB projection, which is fixed static double M0 =
a*((1 - eccSquared/4 - 3*eccSquared*eccSquared/64 - 5*eccSquared*eccSquared*eccSquared/256)*LatOriginRad
OSGBSquareToRefCoords(OSGBZone, RefEasting, RefNorthing);
phi1Rad = mu + (3*e1/2-27*e1*e1*e1/32)*sin(2*mu) + (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu) +(151*e1*e1*e1/96)*sin(6*mu);
int LLtoOSGB(const double
Lat, const double Long, long &OSGBEasting, long &OSGBNorthing,
char OSGBGridSquare[3]) // Fast sanity check
- are we anywhere near the UK double a; double majoraxis =
a = 6377563.396;//Airy eccSquared = (majoraxis
* majoraxis - minoraxis * minoraxis) / (majoraxis * majoraxis); //only
calculate M0 once since it is based on the origin eccPrimeSquared = (eccSquared)/(1-eccSquared);
// Sanity check CoordsToOSGBSquare(easting, northing, OSGBGridSquare, OSGBEasting, OSGBNorthing); return(1); // Valid
location void OSGBSquareToRefCoords(const
char* OSGBGridSquare, long &RefEasting, long &RefNorthing) //find 500km offset //find 100km offset
and add to 500km offset to get coordinate of } void CoordsToOSGBSquare(double
easting, double northing, char OSGBGridSquare[3], long &OSGBEasting,
long &OSGBNorthing) OSGBEasting = long(easting
+ 0.5); //round to nearest int //find correct 500km
square //find correct 100km
square OSGBGridSquare[2] = '\0';//terminate grid ref string with null //remainder is northing
and easting OSGBEasting = OSGBEasting
% 500000L;
|
© Mike Willis 8th April 2005