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)))
def test_grid_formatting(): assert osgb.format_grid(osgb.parse_grid('NM975948')) == 'NM 975 948' assert osgb.format_grid(osgb.parse_grid('NH073060')) == 'NH 073 060' assert osgb.format_grid(osgb.parse_grid('SX700682')) == 'SX 700 682' assert osgb.format_grid(osgb.parse_grid('TQ103606')) == 'TQ 103 606' assert osgb.format_grid(osgb.parse_grid('HY 554 300')) == 'HY 554 300' assert osgb.format_grid(osgb.parse_grid('40/975948')) == 'NM 975 948'
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)
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)
# create sqlalchemy engine to connect to db, note you will need to enter credentials in config.py # With setting Echo=True, engine will log every query conn_str = f"postgresql://{user}:{password}@{host}/{database}" engine = create_engine(conn_str, echo=True) connection = engine.connect() # read in dataframe to be uploaded as pandas dataframe, no dtypes declared df = pd.read_csv(sys.argv[1], encoding='cp1252') # drop 'Unnamed' columns and set column names to lower case for usability in postgres df = df.drop([i for i in df.columns if 'Unnamed' in i], axis=1) df = df.rename(columns=str.lower) df.columns = df.columns.str.replace(' ', '_') # convert gridref column to string, remove white space df = df[~df['grid_reference'].isnull()] df = df[~df['uid'].isnull()] df = df.astype({'grid_reference': 'string'}) df['grid_reference'] = df['grid_reference'].str.replace(' ', '') # use parse_grid to convert osgr to easting/northing, null for values that don't match regex df['easting'] = df['grid_reference'].apply(lambda x: osgb.parse_grid(x)[0] if re.match(r'[a-zA-Z]{2}\d{6,10}', str(x)) is not None else np.nan) df['northing'] = df['grid_reference'].apply(lambda x: osgb.parse_grid(x)[1] if re.match(r'[a-zA-Z]{2}\d{6,10}', str(x)) is not None else np.nan) # convert dataframe to geodataframe with geom column gdf = gpd.GeoDataFrame(df, geometry= gpd.points_from_xy(df.easting, df.northing), crs='EPSG:27700') gdf = gdf[~gdf.geometry.is_empty] # export to database using gpd.to_postgis, note this will drop existing table and replace gdf.to_postgis(name='site_summary', schema='public', con=engine, if_exists='replace')
if hemi == 'W': 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)'
def test_bad_sheet(): with pytest.raises(osgb.gridder.UndefinedSheetError): _ = osgb.parse_grid(9999, 789, 234)
def test_wrong_sheet(): with pytest.raises(osgb.gridder.SheetMismatchError): _ = osgb.parse_grid(195, 789, 234)
def test_junk(): with pytest.raises(osgb.gridder.GarbageError): _ = osgb.parse_grid("This is not a grid ref")