__filename__ = "maps.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.3.0" __maintainer__ = "Bob Mottram" __email__ = "bob@libreserver.org" __status__ = "Production" __module_group__ = "Core" import os from utils import is_float from utils import acct_dir from utils import load_json from utils import save_json def _geocoords_from_osm_link(url: str, osm_domain: str) -> (int, float, float): """Returns geocoordinates from an OSM map link """ if osm_domain + '/#map=' not in url: return None, None, None coords_str = url.split(osm_domain + '/#map=')[1] if '/' not in coords_str: return None, None, None coords = coords_str.split('/') if len(coords) != 3: return None, None, None zoom = coords[0] if not zoom.isdigit(): return None, None, None latitude = coords[1] if not is_float(latitude): return None, None, None longitude = coords[2] if not is_float(longitude): return None, None, None zoom = int(zoom) latitude = float(latitude) longitude = float(longitude) return zoom, latitude, longitude def _geocoords_from_gmaps_link(url: str) -> (int, float, float): """Returns geocoordinates from a Gmaps link """ if '/maps/' not in url: return None, None, None coords_str = url.split('/maps', 1)[1] if '/@' not in coords_str: return None, None, None coords_str = coords_str.split('/@', 1)[1] if 'z' not in coords_str: return None, None, None coords_str = coords_str.split('z', 1)[0] if ',' not in coords_str: return None, None, None coords = coords_str.split(',') if len(coords) != 3: return None, None, None zoom = coords[2] if not zoom.isdigit(): return None, None, None latitude = coords[0] if not is_float(latitude): return None, None, None longitude = coords[1] if not is_float(longitude): return None, None, None zoom = int(zoom) latitude = float(latitude) longitude = float(longitude) return zoom, latitude, longitude def _geocoords_from_bmaps_link(url: str) -> (int, float, float): """Returns geocoordinates from a bing map link """ prefixes = ('/maps?cp=', '/maps/directions?cp=') map_prefix = None for prefix in prefixes: if prefix in url: map_prefix = prefix break if not map_prefix: return None, None, None coords_str = url.split(map_prefix)[1] if '~' not in coords_str: return None, None, None orig_coords_str = coords_str if '&' in coords_str: coords_str = coords_str.split('&')[0] if ';' in coords_str: coords_str = coords_str.split(';')[0] coords = coords_str.split('~') if len(coords) != 2: return None, None, None latitude = coords[0] if not is_float(latitude): return None, None, None longitude = coords[1] if not is_float(longitude): return None, None, None zoom = 17 if 'lvl=' in orig_coords_str: zoom = orig_coords_str.split('lvl=')[1] if '&' in zoom: zoom = zoom.split('&')[0] if ';' in zoom: zoom = zoom.split(';')[0] if not zoom.isdigit(): return None, None, None zoom = int(zoom) latitude = float(latitude) longitude = float(longitude) return zoom, latitude, longitude def _geocoords_from_waze_link(url: str) -> (int, float, float): """Returns geocoordinates from a waze map link """ prefixes = ['/ul?ll='] map_prefix = None for prefix in prefixes: if prefix in url: map_prefix = prefix break if not map_prefix: return None, None, None coords_str = url.split(map_prefix)[1] orig_coords_str = coords_str if '&' in coords_str: coords_str = coords_str.split('&')[0] if '%2C' not in coords_str and ',' not in coords_str: return None, None, None if '%2C' in coords_str: coords = coords_str.split('%2C') else: coords = coords_str.split(',') if len(coords) != 2: return None, None, None latitude = coords[0] if not is_float(latitude): return None, None, None longitude = coords[1] if not is_float(longitude): return None, None, None zoom = 17 if 'zoom=' in orig_coords_str: zoom = orig_coords_str.split('zoom=')[1] if '&' in zoom: zoom = zoom.split('&')[0] if not zoom.isdigit(): return None, None, None zoom = int(zoom) latitude = float(latitude) longitude = float(longitude) return zoom, latitude, longitude def _geocoords_from_wego_link(url: str) -> (int, float, float): """Returns geocoordinates from a wego map link """ prefixes = ['/?map='] map_prefix = None for prefix in prefixes: if prefix in url: map_prefix = prefix break if not map_prefix: return None, None, None coords_str = url.split(map_prefix)[1] if ',' not in coords_str: return None, None, None coords = coords_str.split(',') if len(coords) < 3: return None, None, None latitude = coords[0] if not is_float(latitude): return None, None, None longitude = coords[1] if not is_float(longitude): return None, None, None zoom = coords[2] if not zoom.isdigit(): return None, None, None zoom = int(zoom) latitude = float(latitude) longitude = float(longitude) return zoom, latitude, longitude def geocoords_from_map_link(url: str, osm_domain: str = 'openstreetmap.org') -> (int, float, float): """Returns geocoordinates from a map link url """ if osm_domain in url: return _geocoords_from_osm_link(url, osm_domain) if '.google.co' in url: return _geocoords_from_gmaps_link(url) if '.bing.co' in url: return _geocoords_from_bmaps_link(url) if '.waze.co' in url: return _geocoords_from_waze_link(url) if 'wego.here.co' in url: return _geocoords_from_wego_link(url) return None, None, None def html_open_street_map(url: str, bounding_box_degrees: float, translate: {}, width: str = "725", height: str = "650") -> str: """Returns embed html for an OSM link """ osm_domain = 'openstreetmap.org' zoom, latitude, longitude = geocoords_from_map_link(url, osm_domain) if not latitude: return '' if not longitude: return '' if not zoom: return '' html_str = \ '' + \ '
' + translate['View Larger Map'] + '\n' return html_str def set_map_preferences_url(base_dir: str, nickname: str, domain: str, maps_website_url: str) -> None: """Sets the preferred maps website for an account """ maps_filename = \ acct_dir(base_dir, nickname, domain) + '/map_preferences.json' if os.path.isfile(maps_filename): maps_json = load_json(maps_filename) maps_json['url'] = maps_website_url else: maps_json = { 'url': maps_website_url } save_json(maps_json, maps_filename) def get_map_preferences_url(base_dir: str, nickname: str, domain: str) -> str: """Gets the preferred maps website for an account """ maps_filename = \ acct_dir(base_dir, nickname, domain) + '/map_preferences.json' if os.path.isfile(maps_filename): maps_json = load_json(maps_filename) if maps_json.get('url'): return maps_json['url'] return None def set_map_preferences_coords(base_dir: str, nickname: str, domain: str, latitude: float, longitude: float, zoom: int) -> None: """Sets the preferred maps website coordinates for an account """ maps_filename = \ acct_dir(base_dir, nickname, domain) + '/map_preferences.json' if os.path.isfile(maps_filename): maps_json = load_json(maps_filename) maps_json['latitude'] = latitude maps_json['longitude'] = longitude maps_json['zoom'] = zoom else: maps_json = { 'latitude': latitude, 'longitude': longitude, 'zoom': zoom } save_json(maps_json, maps_filename) def get_map_preferences_coords(base_dir: str, nickname: str, domain: str) -> (float, float, int): """Gets the preferred maps website coordinates for an account """ maps_filename = \ acct_dir(base_dir, nickname, domain) + '/map_preferences.json' if os.path.isfile(maps_filename): maps_json = load_json(maps_filename) if maps_json.get('latitude') and \ maps_json.get('longitude') and \ maps_json.get('zoom'): return maps_json['latitude'], \ maps_json['longitude'], \ maps_json['zoom'] return None, None, None