1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Currently the only site accessible without internet access is the Royal
Greenwich Observatory, as an example (and for testing purposes). In future
releases, a canonical set of sites may be bundled into astropy for when the
online registry is unavailable.
Additions or corrections to the observatory list can be submitted via Pull
Request to the [astropy-data GitHub repository](https://github.com/astropy/astropy-data),
updating the ``location.json`` file.
"""
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import json
from difflib import get_close_matches
from collections import Mapping
from ..utils.data import get_pkg_data_contents, get_file_contents
from .earth import EarthLocation
from .errors import UnknownSiteException
from .. import units as u
class SiteRegistry(Mapping):
"""
A bare-bones registry of EarthLocation objects.
This acts as a mapping (dict-like object) but with the important caveat that
it's always transforms its inputs to lower-case. So keys are always all
lower-case, and even if you ask for something that's got mixed case, it will
be interpreted as the all lower-case version.
"""
def __init__(self):
# the keys to this are always lower-case
self._lowercase_names_to_locations = {}
# these can be whatever case is appropriate
self._names = []
def __getitem__(self, site_name):
"""
Returns an EarthLocation for a known site in this registry.
Parameters
----------
site_name : str
Name of the observatory (case-insensitive).
Returns
-------
site : `~astropy.coordinates.EarthLocation`
The location of the observatory.
"""
if site_name.lower() not in self._lowercase_names_to_locations:
# If site name not found, find close matches and suggest them in error
close_names = get_close_matches(site_name, self._lowercase_names_to_locations)
close_names = sorted(close_names, key=len)
raise UnknownSiteException(site_name, "the 'names' attribute", close_names=close_names)
return self._lowercase_names_to_locations[site_name.lower()]
def __len__(self):
return len(self._lowercase_names_to_locations)
def __iter__(self):
return iter(self._lowercase_names_to_locations)
def __contains__(self, site_name):
return site_name.lower() in self._lowercase_names_to_locations
@property
def names(self):
"""
The names in this registry. Note that these are *not* exactly the same
as the keys: keys are always lower-case, while `names` is what you
should use for the actual readable names (which may be case-sensitive)
Returns
-------
site : list of str
The names of the sites in this registry
"""
return sorted(self._names)
def add_site(self, names, locationobj):
"""
Adds a location to the registry.
Parameters
----------
names : list of str
All the names this site should go under
locationobj : `~astropy.coordinates.EarthLocation`
The actual site object
"""
for name in names:
self._lowercase_names_to_locations[name.lower()] = locationobj
self._names.append(name)
@classmethod
def from_json(cls, jsondb):
reg = cls()
for site in jsondb:
site_info = jsondb[site]
location = EarthLocation.from_geodetic(site_info['longitude'] * u.Unit(site_info['longitude_unit']),
site_info['latitude'] * u.Unit(site_info['latitude_unit']),
site_info['elevation'] * u.Unit(site_info['elevation_unit']))
location.info.name = site_info['name']
reg.add_site([site] + site_info['aliases'], location)
reg._loaded_jsondb = jsondb
return reg
def get_builtin_sites():
"""
Load observatory database from data/observatories.json and parse them into
a SiteRegistry.
"""
jsondb = json.loads(get_pkg_data_contents('data/sites.json'))
return SiteRegistry.from_json(jsondb)
def get_downloaded_sites(jsonurl='http://data.astropy.org/coordinates/sites.json'):
"""
Load observatory database from data.astropy.org and parse into a SiteRegistry
"""
jsondb = json.loads(get_file_contents(jsonurl, show_progress=False))
return SiteRegistry.from_json(jsondb)
|