diff --git a/roentgen/flinger.py b/roentgen/flinger.py index f39d3c4..713b83e 100644 --- a/roentgen/flinger.py +++ b/roentgen/flinger.py @@ -8,11 +8,18 @@ import math import numpy as np +def get_ratio(maximum: float, minimum: float, ratio: float = 1): + return (maximum[0] - minimum[0]) * ratio / (maximum[1] - minimum[1]) + + class Flinger(object): """ Flinger. Coordinates repositioning. """ - def __init__(self, minimum, maximum, target_minimum=None, target_maximum=None, ratio=None): + def __init__( + self, minimum, maximum, target_minimum=None, target_maximum=None, + ratio=None): + self.minimum = minimum self.maximum = maximum @@ -24,19 +31,27 @@ class Flinger(object): space = [0, 0] if ratio: - if ratio == 'geo': - ratio = math.sin((90.0 - ((self.maximum[1] + self.minimum[1]) / 2.0)) / 180.0 * math.pi) + if ratio == "geo": + ratio = math.sin( + (90.0 - ((self.maximum[1] + self.minimum[1]) / 2.0)) + / 180.0 * math.pi) - current_ratio = (self.maximum[0] - self.minimum[0]) * ratio / (self.maximum[1] - self.minimum[1]) - target_ratio = (target_maximum[0] - target_minimum[0]) / (target_maximum[1] - target_minimum[1]) + current_ratio = get_ratio(self.maximum, self.minimum, ratio) + target_ratio = get_ratio(target_maximum, target_minimum) if current_ratio >= target_ratio: - n = (target_maximum[0] - target_minimum[0]) / (maximum[0] - minimum[0]) / ratio - space[1] = ((target_maximum[1] - target_minimum[1]) - (maximum[1] - minimum[1]) * n) / 2.0 + n = (target_maximum[0] - target_minimum[0]) / \ + (maximum[0] - minimum[0]) / ratio + space[1] = \ + ((target_maximum[1] - target_minimum[1]) - + (maximum[1] - minimum[1]) * n) / 2.0 space[0] = 0 else: - n = (target_maximum[1] - target_minimum[1]) / (maximum[1] - minimum[1]) - space[0] = ((target_maximum[0] - target_minimum[0]) - (maximum[0] - minimum[0]) * n) / 2.0 + n = (target_maximum[1] - target_minimum[1]) / \ + (maximum[1] - minimum[1]) + space[0] = \ + ((target_maximum[0] - target_minimum[0]) - + (maximum[0] - minimum[0]) * n) / 2.0 space[1] = 0 target_minimum[0] += space @@ -49,8 +64,12 @@ class Flinger(object): """ Fling current point to the surface. """ - x = map_(current[0], self.minimum[0], self.maximum[0], self.target_minimum[0], self.target_maximum[0]) - y = map_(current[1], self.minimum[1], self.maximum[1], self.target_minimum[1], self.target_maximum[1]) + x = map_( + current[0], self.minimum[0], self.maximum[0], + self.target_minimum[0], self.target_maximum[0]) + y = map_( + current[1], self.minimum[1], self.maximum[1], + self.target_minimum[1], self.target_maximum[1]) return [x, y] @@ -59,6 +78,12 @@ class Geo: self.lat = lat self.lon = lon + def __getitem__(self, item): + if item == 0: + return self.lon + if item == 1: + return self.lat + def __add__(self, other): return Geo(self.lat + other.lat, self.lon + other.lon) @@ -70,15 +95,19 @@ class Geo: class GeoFlinger: - def __init__(self, minimum, maximum, target_minimum=None, target_maximum=None): + def __init__( + self, minimum, maximum, target_minimum=None, target_maximum=None): + self.minimum = minimum self.maximum = maximum - # Ratio is depended of latitude. It is always <= 1. - # In one latitude degree is always 40 000 / 360 km. - # In one current longitude degree is about 40 000 / 360 * ratio km. + # Ratio is depended of latitude. It is always <= 1. In one latitude + # degree is always 40 000 / 360 km. In one current longitude degree is + # about 40 000 / 360 * ratio km. - ratio = math.sin((90.0 - ((self.maximum.lat + self.minimum.lat) / 2.0)) / 180.0 * math.pi) + ratio = math.sin( + (90.0 - ((self.maximum.lat + self.minimum.lat) / 2.0)) + / 180.0 * math.pi) # Longitude displayed as x. # Latitude displayed as y. @@ -86,16 +115,22 @@ class GeoFlinger: # Ratio is x / y. space = [0, 0] - current_ratio = (self.maximum.lon - self.minimum.lon) * ratio / (self.maximum.lat - self.minimum.lat) - target_ratio = (target_maximum[0] - target_minimum[0]) / (target_maximum[1] - target_minimum[1]) + current_ratio = get_ratio(self.maximum, self.minimum, ratio) + target_ratio = get_ratio(target_maximum, target_minimum) if current_ratio >= target_ratio: - n = (target_maximum[0] - target_minimum[0]) / (maximum.lon - minimum.lon) / ratio - space[1] = ((target_maximum[1] - target_minimum[1]) - (maximum.lat - minimum.lat) * n) / 2.0 + n = (target_maximum[0] - target_minimum[0]) / \ + (maximum.lon - minimum.lon) / ratio + space[1] = \ + ((target_maximum[1] - target_minimum[1]) - + (maximum.lat - minimum.lat) * n) / 2.0 space[0] = 0 else: - n = (target_maximum[1] - target_minimum[1]) / (maximum.lat - minimum.lat) * ratio - space[0] = ((target_maximum[0] - target_minimum[0]) - (maximum.lon - minimum.lon) * n) / 2.0 + n = (target_maximum[1] - target_minimum[1]) / \ + (maximum.lat - minimum.lat) * ratio + space[0] = \ + ((target_maximum[0] - target_minimum[0]) - + (maximum.lon - minimum.lon) * n) / 2.0 space[1] = 0 self.target_minimum = np.add(target_minimum, space) @@ -104,16 +139,23 @@ class GeoFlinger: self.space = space def fling(self, current): - x = map_(current.lon, self.minimum.lon, self.maximum.lon, - self.target_minimum[0], self.target_maximum[0]) - y = map_(self.maximum.lat + self.minimum.lat - current.lat, - self.minimum.lat, self.maximum.lat, - self.target_minimum[1], self.target_maximum[1]) + x = map_( + current.lon, self.minimum.lon, self.maximum.lon, + self.target_minimum[0], self.target_maximum[0]) + y = map_( + self.maximum.lat + self.minimum.lat - current.lat, + self.minimum.lat, self.maximum.lat, + self.target_minimum[1], self.target_maximum[1]) return [x, y] -def map_(value, current_min, current_max, target_min, target_max): +def map_( + value: float, current_min: float, current_max: float, target_min: float, + target_max: float): """ - Map current value in bounds of current_min and current_max to bounds of target_min and target_max. + Map current value in bounds of current_min and current_max to bounds of + target_min and target_max. """ - return target_min + (value - current_min) / (current_max - current_min) * (target_max - target_min) + return \ + target_min + (value - current_min) / (current_max - current_min) * \ + (target_max - target_min) diff --git a/roentgen/process.py b/roentgen/process.py index 9c34248..c7473d8 100644 --- a/roentgen/process.py +++ b/roentgen/process.py @@ -1,67 +1,75 @@ import copy import re +from typing import Any, Dict -def get_color(color, scheme): - if color in scheme['colors']: - return scheme['colors'][color] + +STANDARD_COLOR: str = "444444" + + +def get_color(color: str, scheme: Dict[str, Any]): + if color in scheme["colors"]: # type: str + return scheme["colors"][color] else: - m = re.match('^(\\#)?(?P[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])' + - '(?P[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])?$', color) + m = re.match("^#?(?P[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])" + + "(?P[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])?$", color) if m: - if 'color2' in m.groups(): - return m.group('color1') + m.group('color2') + if "color2" in m.groups(): + return m.group("color1") + m.group("color2") else: - return ''.join(map(lambda x: x + x, m.group('color1'))) - return '444444' + return "".join(map(lambda x: x + x, m.group("color1"))) + return STANDARD_COLOR -def get_icon(tags, scheme, fill='444444'): - tags_hash = ','.join(tags.keys()) + ':' + \ - ','.join(map(lambda x: str(x), tags.values())) - if tags_hash in scheme['cache']: - return scheme['cache'][tags_hash] +def get_icon( + tags: Dict[str, Any], scheme: Dict[str, Any], + fill: str = STANDARD_COLOR): + + tags_hash = ",".join(tags.keys()) + ":" + \ + ",".join(map(lambda x: str(x), tags.values())) + if tags_hash in scheme["cache"]: + return scheme["cache"][tags_hash] main_icon = None extra_icons = [] processed = set() - for matcher in scheme['tags']: + for matcher in scheme["tags"]: matched = True - for key in matcher['tags']: - if not key in tags: + for key in matcher["tags"]: + if key not in tags: matched = False break - if matcher['tags'][key] != '*' and matcher['tags'][key] != tags[key]: + if matcher["tags"][key] != "*" and matcher["tags"][key] != tags[key]: matched = False break - if 'no_tags' in matcher: - for no_tag in matcher['no_tags']: + if "no_tags" in matcher: + for no_tag in matcher["no_tags"]: if no_tag in tags.keys(): matched = False break if matched: - if 'draw' in matcher and not matcher['draw']: - processed |= set(matcher['tags'].keys()) - if 'icon' in matcher: - main_icon = copy.deepcopy(matcher['icon']) - processed |= set(matcher['tags'].keys()) - if 'over_icon' in matcher: + if "draw" in matcher and not matcher["draw"]: + processed |= set(matcher["tags"].keys()) + if "icon" in matcher: + main_icon = copy.deepcopy(matcher["icon"]) + processed |= set(matcher["tags"].keys()) + if "over_icon" in matcher: if main_icon: # TODO: check main icon in under icons - main_icon += matcher['over_icon'] - for key in matcher['tags'].keys(): + main_icon += matcher["over_icon"] + for key in matcher["tags"].keys(): processed.add(key) - if 'add_icon' in matcher: - extra_icons += matcher['add_icon'] - for key in matcher['tags'].keys(): + if "add_icon" in matcher: + extra_icons += matcher["add_icon"] + for key in matcher["tags"].keys(): processed.add(key) - if 'color' in matcher: - fill = scheme['colors'][matcher['color']] - for key in matcher['tags'].keys(): + if "color" in matcher: + fill = scheme["colors"][matcher["color"]] + for key in matcher["tags"].keys(): processed.add(key) - for color_name in ['color', 'colour', 'building:colour']: + for color_name in ["color", "colour", "building:colour"]: if color_name in tags: fill = get_color(tags[color_name], scheme) - if fill != '444444': + if fill != STANDARD_COLOR: processed.add(color_name) else: print(f"No color {tags[color_name]}.") @@ -71,6 +79,7 @@ def get_icon(tags, scheme, fill='444444'): else: returned = extra_icons, fill, processed - scheme['cache'][tags_hash] = returned + scheme["cache"][tags_hash] = returned + return returned diff --git a/roentgen/svg.py b/roentgen/svg.py index 9954eb4..7de4957 100644 --- a/roentgen/svg.py +++ b/roentgen/svg.py @@ -13,7 +13,8 @@ class SVG: self.index = 0 def begin(self, width, height): - self.file.write('\n\n') + self.file.write( + '\n\n') self.file.write( f'''\n') - def line(self, x1, y1, x2, y2, width=1, color='black', end='butt', id=None, color2=None, - gx1=None, gy1=None, gx2=None, gy2=None, dash=None, dashoffset=None, opacity=None): + def line( + self, x1, y1, x2, y2, width=1, color='black', end='butt', id_=None, + color2=None, gx1=None, gy1=None, gx2=None, gy2=None, dash=None, + dashoffset=None, opacity=None): + if color2: if not gx1: gx1 = x1 @@ -78,17 +82,26 @@ class SVG: if not gy2: gy2 = y2 self.index += 1 - self.file.write('\n\n\n') - self.file.write(' \n' + f'' + f'' + f'\n') + self.file.write( + f' \n') - def rect(self, x, y, width, height, color='black', id=None, rx=0, ry=0, opacity=1.0, stroke_color='none', - stroke_width=1.0): + def rect( + self, x, y, width, height, color='black', id=None, rx=0, ry=0, + opacity=1.0, stroke_color='none', stroke_width=1.0): + self.file.write(' \n') def circle(self, x, y, d, color='black', color2='white', fill='none', - opacity=None, width=1, id=None, gx=0, gy=0, gr=0, fx=0, fy=0): + opacity=None, width=1, id_=None, gx=0, gy=0, gr=0, fx=0, fy=0): is_grad = gx != 0 or gy != 0 or gr != 0 if is_grad: self.index += 1 - self.file.write(''' - - - - - ''') + self.file.write( + f'' + f'' + f'\n') c = 0.577 self.file.write( - f'''