epicyon/maps.py

239 lines
6.9 KiB
Python

__filename__ = "maps.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.3.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
from utils import is_float
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]
if ',' not in coords_str:
return None, None, None
coords = coords_str.split(',')
if len(coords) != 3:
return None, None, None
zoom = coords[2].replace('z', '')
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) -> (int, float, float):
"""Returns geocoordinates from a map link url
"""
if osm_domain in url:
return _geocoords_from_osm_link(url, osm_domain)
elif '.google.co' in url:
return _geocoords_from_gmaps_link(url)
elif '.bing.co' in url:
return _geocoords_from_bmaps_link(url)
elif '.waze.co' in url:
return _geocoords_from_waze_link(url)
elif '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: {}) -> 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 = \
'<iframe width="425" height="350" frameborder="0" ' + \
'scrolling="no" marginheight="0" marginwidth="0" ' + \
'src="https://www.' + osm_domain + '/export/embed.html?' + \
'bbox=' + str(longitude - bounding_box_degrees) + \
'%2C' + \
str(latitude - bounding_box_degrees) + \
'%2C' + \
str(longitude + bounding_box_degrees) + \
'%2C' + \
str(latitude + bounding_box_degrees) + \
'&amp;layer=mapnik" style="border: 1px solid black"></iframe>' + \
'<br/><small><a href="https://www.' + osm_domain + '/#map=' + \
zoom + '/' + latitude + '/' + longitude + \
'">' + translate['View Larger Map'] + '</a></small>\n'
return html_str