Example #1
0
def osgb_to_lonlat(osgb_str, model='OSGB36'):
    """
    Convert an Ordinance Survey reference to a longitude and latitude.

    :Parameters:
            osgb_str
                    An Ordnance Survey grid reference in "letter-number" format.
                    Case and spaces are cleaned up by this function, and resolution
                    automatically detected, so that so that ``TM114 525``, ``TM114525``,
                    and ``TM 11400 52500`` are all recognised and identical.

            model
                    'OSGB36' or 'WGS84'.  Default 'OSGB36'.

    :Returns:
            The longitude and latitude of the grid reference, according to the chosen model.

    For example::

            # just outside Ipswich, about 1.088975 52.129892
            >>> osgb_to_lonlat('TM114 525')
            (1.088975, 52.129892)

            # accepts poor formating
            >>> osgb_to_lonlat(' TM 114525 ')
            (1.088975, 52.129892)

            # accepts higher resolution
            >>> osgb_to_lonlat('TM1140052500')
            (1.088975, 52.129892)

    """
    return tuple(
        reversed(osgb.grid_to_ll(osgb.parse_grid(osgb_str), model=model)))
Example #2
0
def osgb_to_lonlat(osgb_str, model='OSGB36'):
    """
    Convert an Ordinance Survey reference to a longitude and latitude.
    
    :Parameters:
            osgb_str
                    An Ordnance Survey grid reference in "letter-number" format.
                    Case and spaces are cleaned up by this function, and resolution
                    automatically detected, so that so that ``TM114 525``, ``TM114525``,
                    and ``TM 11400 52500`` are all recognised and identical. 

            model   
                    OSGB36 or WGS84
    
    :Returns:
            The longitude and latitude of the grid reference, according to the chosen model.
            
    For example::
    
            # just outside Ipswich, about 1.088975 52.129892
            >>> lon1, lat1 = osgb_to_lonlat ('TM114 525')
            >>> 1.0889 < lon1 < 1.0890
            True
            >>> 52.1298 < lat1 < 52.1299
            True
            >>> (round(lon1, 14), round(lat1, 14))
            (1.08897495610794, 52.12989202825308)

            
            # accepts poor formating
            >>> lon2, lat2 = osgb_to_lonlat (' TM 114525 ')
            >>> lon2 == lon1
            True
            >>> lat2 == lat1
            True
            
            # accepts higher resolution
            >>> lon3, lat3 = osgb_to_lonlat ('TM1140052500')
            >>> 1.0889 < lon3 < 1.0890
            True
            >>> 52.1298 < lat3 < 52.1299
            True
            >>> (round(lon3, 14), round(lat3, 14))
            (1.08897495610794, 52.12989202825308)


    
    """
    (e, n) = osgb.parse_grid(osgb_str)
    (lat, lon) = osgb.grid_to_ll(e, n, model=model)
    return (lon, lat)
Example #3
0
def osgb_to_lonlat(osgb_str, model='OSGB36'):
    """
    Convert an Ordinance Survey reference to a longitude and latitude.
    
    :Parameters:
            osgb_str
                    An Ordnance Survey grid reference in "letter-number" format.
                    Case and spaces are cleaned up by this function, and resolution
                    automatically detected, so that so that ``TM114 525``, ``TM114525``,
                    and ``TM 11400 52500`` are all recognised and identical. 

            model   
                    'OSGB36' or 'WGS84'.  Default 'OSGB36'.
    
    :Returns:
            The longitude and latitude of the grid reference, according to the chosen model.
            
    For example::
    
            # just outside Ipswich, about 1.088975 52.129892
            >>> lon1, lat1 = osgb_to_lonlat('TM114 525')
            >>> 1.0889 < lon1 < 1.0890
            True
            >>> 52.1298 < lat1 < 52.1299
            True
            >>> (round(lon1, 14), round(lat1, 14))
            (1.08897495610794, 52.12989202825308)

            
            # accepts poor formating
            >>> lon2, lat2 = osgb_to_lonlat(' TM 114525 ')
            >>> lon2 == lon1
            True
            >>> lat2 == lat1
            True
            
            # accepts higher resolution
            >>> lon3, lat3 = osgb_to_lonlat('TM1140052500')
            >>> 1.0889 < lon3 < 1.0890
            True
            >>> 52.1298 < lat3 < 52.1299
            True
            >>> (round(lon3, 14), round(lat3, 14))
            (1.08897495610794, 52.12989202825308)


    
    """
    (e, n) = osgb.parse_grid(osgb_str)
    (lat, lon) = osgb.grid_to_ll(e, n, model=model)
    return (lon, lat)
def test_all(chatty=False):
    for k in sorted(test_input):
        (lat, lon) = osgb.grid_to_ll(*test_input[k])
        phi = math.radians(lat)
        one_lat_in_mm = 111132954 - 559822 * math.cos(
            2 * phi) + 1175 * math.cos(4 * phi)
        one_lon_in_mm = 1000 * (3.141592653589793 / 180) * (6378137 * math.cos(
            phi)) / math.sqrt(1 - 0.006694380004260827 * math.sin(phi)**2)

        delta_lat = lat - expected_output[k][0]
        delta_lon = lon - expected_output[k][1]

        delta_lat_mm = delta_lat * one_lat_in_mm
        delta_lon_mm = delta_lon * one_lon_in_mm

        if chatty:
            print('Test point {}  dLat: {:+.3f} mm  dLon: {:+.3f} mm'.format(
                k, delta_lat_mm, delta_lon_mm))

        assert abs(delta_lat_mm) < acceptable_error_mm
        assert abs(delta_lon_mm) < acceptable_error_mm
Example #5
0
    # Starting making the MP file
    print(
        'prologues := 3; outputtemplate := "%j.eps"; beginfig(1); defaultfont := "phvr8r";',
        file=plotter)

    # sides and insets will have anything in if we chose one or more series
    for k in sides + insets:
        print("fill {} withcolor (0.98, 0.906, 0.71);".format(path_for[k]),
              file=plotter)

    if args.error:
        for x in range(70):
            e = x * 10000 + 5000
            for y in range(125):
                n = y * 10000 + 5000
                (ee, nn) = osgb.ll_to_grid(*osgb.grid_to_ll(e, n))
                h = math.sqrt((e - ee)**2 + (n - nn)**2)
                if h > 0:
                    print(
                        'drawdot ({:.1f}, {:.1f}) withpen pencircle scaled 4 withcolor {:.2f}[white, red];'
                        .format(e / scale, n / scale, h * 100),
                        file=plotter)

        print(
            'label.rt("Round trip error (mm)" infont defaultfont scaled 0.6, ({:.1f}, {:.1f}));'
            .format(-176500 / scale, 1255000 / scale),
            file=plotter)
        for i in range(6):
            e = -120000 - i * 10000
            n = 1245000
            print(
Example #6
0
#! /usr/bin/env python3

import argparse
import osgb


if __name__ == "__main__":

    expected = (52+39/60+27.2531/3600, 1+43/60+4.5177/3600)

    got = osgb.grid_to_ll(651409.903, 313177.270, 'OSGB36')

    print(expected)
    print(got)
    
Example #7
0
    # open a tempory file for MP
    plotter = tempfile.NamedTemporaryFile(mode='wt', prefix='plot_maps_', suffix='.mp', dir='.', delete=False)

    # Starting making the MP file
    print('prologues := 3; outputtemplate := "%j.eps"; beginfig(1); defaultfont := "phvr8r";', file=plotter)

    # sides and insets will have anything in if we chose one or more series
    for k in sides + insets:
        print("fill {} withcolor (0.98, 0.906, 0.71);".format(path_for[k]), file=plotter)

    if args.error:
        for x in range(70):
            e = x * 10000 + 5000
            for y in range(125):
                n = y * 10000 + 5000
                (ee, nn) = osgb.ll_to_grid(*osgb.grid_to_ll(e, n))
                h = math.sqrt((e-ee)**2+(n-nn)**2)
                if h > 0:
                    print('drawdot ({:.1f}, {:.1f}) withpen pencircle scaled 4 withcolor {:.2f}[white, red];'.format(e/scale, n/scale, h*100), file=plotter)

        print('label.rt("Round trip error (mm)" infont defaultfont scaled 0.6, ({:.1f}, {:.1f}));'.format(-176500/scale, 1255000/scale), file=plotter)
        for i in range(6):
            e = -120000 - i * 10000
            n = 1245000
            print('drawdot ({:.1f}, {:.1f}) withpen pencircle scaled 4 withcolor {:.2f}[white, red];'.format(e/scale, n/scale, i/5), file=plotter)
            print('label.bot("{}" infont defaultfont scaled 0.6, ({:.1f}, {:.1f}));'.format(2*i, e/scale, n/scale-2), file=plotter)

    if not args.nograt:
        print("drawoptions(withpen pencircle scaled 0.4);", file=plotter)
        for lon in range(-10, 3):
            points = []
Example #8
0
            latlon[1] = -latlon[1]
    else:
        latlon = list(get_likely_lon_lat(x) for x in agenda.split())

    # if the arguments consists of just two likely looking numbers...
    # You can't just say "all(floats)" because 0 is a valid Longitude
    if len(latlon) == 2 and all(x is not None for x in latlon):
        (lon, lat) = sorted(latlon)  # Lon is always less than Lat in OSGB
        (e, n) = osgb.ll_to_grid(lat, lon)
        (olat, olon) = (lat, lon)
        (oe, on) = osgb.ll_to_grid(lat, lon, 'OSGB36')

    else:
        print('>>', agenda)
        (e, n) = osgb.parse_grid(agenda)
        (lat, lon) = osgb.grid_to_ll(e, n)
        (oe, on) = (e, n)
        (olat, olon) = osgb.grid_to_ll(e, n, 'OSGB36')

    try:
        grid = osgb.format_grid(e, n)
        maps = osgb.sheet_keys(e, n)
    except osgb.gridder.Error:
        grid = '??'
        maps = None

    if maps:
        map_string = 'on sheets {}'.format(', '.join(maps))
    else:
        map_string = '(not covered by any OSGB map)'
Example #9
0
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--putsomethinghere")
    args = parser.parse_args()

    print('''
prologues := 3;
outputtemplate := "%j%c.eps";
beginfig(1);
''')

    
    for n in range(1200500, 500, -10000):
        for e in range(500, 700000, 10000):
            lat, lon = osgb.grid_to_ll(e, n)
            ee, nn = osgb.ll_to_grid(lat, lon)
            de = ee-e
            dn = nn-n
            hh = math.sqrt(de*de + dn*dn)

            #print('{:.3f}'.format(hh*100), end=' ')
            if hh > 0:
                print('drawdot ({}, {}) withpen pencircle scaled 4 withcolor {}[white, red];'.format(e/1000, n/1000, hh*100))
        print()


    for lat in range(50, 61):
        print('draw')
        for lon in range(-9, 2):
            (e, n) = osgb.ll_to_grid(lat, lon)
Example #10
0
        help="Which map series? A: Landranger, B: Explorer, C: One-inch, ...")
    args = parser.parse_args()

    jason = {
        'type': 'FeatureCollection',
        'features': [],
    }

    polygons = collections.defaultdict(list)
    titles = dict()

    # Note that contrary to ISO 6709 GeoJSON wants lon before lat

    for k, m in osgb.map_locker.items():
        if m.series == args.series:
            p = [list(reversed(osgb.grid_to_ll(e, n))) for e, n in m.polygon]
            polygons[m.number].append([p])
            if m.parent == '':
                titles[m.number] = m.title

    # Polygon is an array of linear ring arrays
    # first is the ccw container, second and any subsequent are the clockwise holes
    # for maps there are *no* holes, so all Polygons are an array of one array.

    # Multipolygons are an array of Polygons, we use them for sheets with more than
    # one sheet

    for k in sorted(polygons):
        p = polygons[k]

        if len(p) > 1:
Example #11
0
def test_wrong_model():
    with pytest.raises(osgb.convert.UndefinedModelError):
        _ = osgb.grid_to_ll(428765, 114567, 'EDM50')
Example #12
0
def test_no_northing():
    with pytest.raises(osgb.convert.MissingArgumentError):
        _ = osgb.grid_to_ll(428765, None)