Fix code style.

This commit is contained in:
Sergey Vartanov 2020-08-23 11:17:23 +03:00
parent 669f6712c4
commit c098f39e46
4 changed files with 169 additions and 100 deletions

View file

@ -8,11 +8,18 @@ import math
import numpy as np 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): class Flinger(object):
""" """
Flinger. Coordinates repositioning. 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.minimum = minimum
self.maximum = maximum self.maximum = maximum
@ -24,19 +31,27 @@ class Flinger(object):
space = [0, 0] space = [0, 0]
if ratio: if ratio:
if ratio == 'geo': if ratio == "geo":
ratio = math.sin((90.0 - ((self.maximum[1] + self.minimum[1]) / 2.0)) / 180.0 * math.pi) 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]) current_ratio = get_ratio(self.maximum, self.minimum, ratio)
target_ratio = (target_maximum[0] - target_minimum[0]) / (target_maximum[1] - target_minimum[1]) target_ratio = get_ratio(target_maximum, target_minimum)
if current_ratio >= target_ratio: if current_ratio >= target_ratio:
n = (target_maximum[0] - target_minimum[0]) / (maximum[0] - minimum[0]) / ratio n = (target_maximum[0] - target_minimum[0]) / \
space[1] = ((target_maximum[1] - target_minimum[1]) - (maximum[1] - minimum[1]) * n) / 2.0 (maximum[0] - minimum[0]) / ratio
space[1] = \
((target_maximum[1] - target_minimum[1]) -
(maximum[1] - minimum[1]) * n) / 2.0
space[0] = 0 space[0] = 0
else: else:
n = (target_maximum[1] - target_minimum[1]) / (maximum[1] - minimum[1]) n = (target_maximum[1] - target_minimum[1]) / \
space[0] = ((target_maximum[0] - target_minimum[0]) - (maximum[0] - minimum[0]) * n) / 2.0 (maximum[1] - minimum[1])
space[0] = \
((target_maximum[0] - target_minimum[0]) -
(maximum[0] - minimum[0]) * n) / 2.0
space[1] = 0 space[1] = 0
target_minimum[0] += space target_minimum[0] += space
@ -49,8 +64,12 @@ class Flinger(object):
""" """
Fling current point to the surface. Fling current point to the surface.
""" """
x = map_(current[0], self.minimum[0], self.maximum[0], self.target_minimum[0], self.target_maximum[0]) x = map_(
y = map_(current[1], self.minimum[1], self.maximum[1], self.target_minimum[1], self.target_maximum[1]) 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] return [x, y]
@ -59,6 +78,12 @@ class Geo:
self.lat = lat self.lat = lat
self.lon = lon self.lon = lon
def __getitem__(self, item):
if item == 0:
return self.lon
if item == 1:
return self.lat
def __add__(self, other): def __add__(self, other):
return Geo(self.lat + other.lat, self.lon + other.lon) return Geo(self.lat + other.lat, self.lon + other.lon)
@ -70,15 +95,19 @@ class Geo:
class GeoFlinger: 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.minimum = minimum
self.maximum = maximum self.maximum = maximum
# Ratio is depended of latitude. It is always <= 1. # Ratio is depended of latitude. It is always <= 1. In one latitude
# In one latitude degree is always 40 000 / 360 km. # degree is always 40 000 / 360 km. In one current longitude degree is
# In one current longitude degree is about 40 000 / 360 * ratio km. # 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. # Longitude displayed as x.
# Latitude displayed as y. # Latitude displayed as y.
@ -86,16 +115,22 @@ class GeoFlinger:
# Ratio is x / y. # Ratio is x / y.
space = [0, 0] space = [0, 0]
current_ratio = (self.maximum.lon - self.minimum.lon) * ratio / (self.maximum.lat - self.minimum.lat) current_ratio = get_ratio(self.maximum, self.minimum, ratio)
target_ratio = (target_maximum[0] - target_minimum[0]) / (target_maximum[1] - target_minimum[1]) target_ratio = get_ratio(target_maximum, target_minimum)
if current_ratio >= target_ratio: if current_ratio >= target_ratio:
n = (target_maximum[0] - target_minimum[0]) / (maximum.lon - minimum.lon) / ratio n = (target_maximum[0] - target_minimum[0]) / \
space[1] = ((target_maximum[1] - target_minimum[1]) - (maximum.lat - minimum.lat) * n) / 2.0 (maximum.lon - minimum.lon) / ratio
space[1] = \
((target_maximum[1] - target_minimum[1]) -
(maximum.lat - minimum.lat) * n) / 2.0
space[0] = 0 space[0] = 0
else: else:
n = (target_maximum[1] - target_minimum[1]) / (maximum.lat - minimum.lat) * ratio n = (target_maximum[1] - target_minimum[1]) / \
space[0] = ((target_maximum[0] - target_minimum[0]) - (maximum.lon - minimum.lon) * n) / 2.0 (maximum.lat - minimum.lat) * ratio
space[0] = \
((target_maximum[0] - target_minimum[0]) -
(maximum.lon - minimum.lon) * n) / 2.0
space[1] = 0 space[1] = 0
self.target_minimum = np.add(target_minimum, space) self.target_minimum = np.add(target_minimum, space)
@ -104,16 +139,23 @@ class GeoFlinger:
self.space = space self.space = space
def fling(self, current): def fling(self, current):
x = map_(current.lon, self.minimum.lon, self.maximum.lon, x = map_(
self.target_minimum[0], self.target_maximum[0]) current.lon, self.minimum.lon, self.maximum.lon,
y = map_(self.maximum.lat + self.minimum.lat - current.lat, self.target_minimum[0], self.target_maximum[0])
self.minimum.lat, self.maximum.lat, y = map_(
self.target_minimum[1], self.target_maximum[1]) 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] 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)

View file

@ -1,67 +1,75 @@
import copy import copy
import re import re
from typing import Any, Dict
def get_color(color, scheme):
if color in scheme['colors']: STANDARD_COLOR: str = "444444"
return scheme['colors'][color]
def get_color(color: str, scheme: Dict[str, Any]):
if color in scheme["colors"]: # type: str
return scheme["colors"][color]
else: else:
m = re.match('^(\\#)?(?P<color1>[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])' + m = re.match("^#?(?P<color1>[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])" +
'(?P<color2>[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])?$', color) "(?P<color2>[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])?$", color)
if m: if m:
if 'color2' in m.groups(): if "color2" in m.groups():
return m.group('color1') + m.group('color2') return m.group("color1") + m.group("color2")
else: else:
return ''.join(map(lambda x: x + x, m.group('color1'))) return "".join(map(lambda x: x + x, m.group("color1")))
return '444444' return STANDARD_COLOR
def get_icon(tags, scheme, fill='444444'): def get_icon(
tags_hash = ','.join(tags.keys()) + ':' + \ tags: Dict[str, Any], scheme: Dict[str, Any],
','.join(map(lambda x: str(x), tags.values())) fill: str = STANDARD_COLOR):
if tags_hash in scheme['cache']:
return scheme['cache'][tags_hash] 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 main_icon = None
extra_icons = [] extra_icons = []
processed = set() processed = set()
for matcher in scheme['tags']: for matcher in scheme["tags"]:
matched = True matched = True
for key in matcher['tags']: for key in matcher["tags"]:
if not key in tags: if key not in tags:
matched = False matched = False
break break
if matcher['tags'][key] != '*' and matcher['tags'][key] != tags[key]: if matcher["tags"][key] != "*" and matcher["tags"][key] != tags[key]:
matched = False matched = False
break break
if 'no_tags' in matcher: if "no_tags" in matcher:
for no_tag in matcher['no_tags']: for no_tag in matcher["no_tags"]:
if no_tag in tags.keys(): if no_tag in tags.keys():
matched = False matched = False
break break
if matched: if matched:
if 'draw' in matcher and not matcher['draw']: if "draw" in matcher and not matcher["draw"]:
processed |= set(matcher['tags'].keys()) processed |= set(matcher["tags"].keys())
if 'icon' in matcher: if "icon" in matcher:
main_icon = copy.deepcopy(matcher['icon']) main_icon = copy.deepcopy(matcher["icon"])
processed |= set(matcher['tags'].keys()) processed |= set(matcher["tags"].keys())
if 'over_icon' in matcher: if "over_icon" in matcher:
if main_icon: # TODO: check main icon in under icons if main_icon: # TODO: check main icon in under icons
main_icon += matcher['over_icon'] main_icon += matcher["over_icon"]
for key in matcher['tags'].keys(): for key in matcher["tags"].keys():
processed.add(key) processed.add(key)
if 'add_icon' in matcher: if "add_icon" in matcher:
extra_icons += matcher['add_icon'] extra_icons += matcher["add_icon"]
for key in matcher['tags'].keys(): for key in matcher["tags"].keys():
processed.add(key) processed.add(key)
if 'color' in matcher: if "color" in matcher:
fill = scheme['colors'][matcher['color']] fill = scheme["colors"][matcher["color"]]
for key in matcher['tags'].keys(): for key in matcher["tags"].keys():
processed.add(key) processed.add(key)
for color_name in ['color', 'colour', 'building:colour']: for color_name in ["color", "colour", "building:colour"]:
if color_name in tags: if color_name in tags:
fill = get_color(tags[color_name], scheme) fill = get_color(tags[color_name], scheme)
if fill != '444444': if fill != STANDARD_COLOR:
processed.add(color_name) processed.add(color_name)
else: else:
print(f"No color {tags[color_name]}.") print(f"No color {tags[color_name]}.")
@ -71,6 +79,7 @@ def get_icon(tags, scheme, fill='444444'):
else: else:
returned = extra_icons, fill, processed returned = extra_icons, fill, processed
scheme['cache'][tags_hash] = returned scheme["cache"][tags_hash] = returned
return returned return returned

View file

@ -13,7 +13,8 @@ class SVG:
self.index = 0 self.index = 0
def begin(self, width, height): def begin(self, width, height):
self.file.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n\n') self.file.write(
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n\n')
self.file.write( self.file.write(
f'''<svg version="1.1" baseProfile="full" f'''<svg version="1.1" baseProfile="full"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -66,8 +67,11 @@ class SVG:
self.file.write('stroke-dashoffset:' + str(dashoffset) + '; ') self.file.write('stroke-dashoffset:' + str(dashoffset) + '; ')
self.file.write('" />\n') self.file.write('" />\n')
def line(self, x1, y1, x2, y2, width=1, color='black', end='butt', id=None, color2=None, def line(
gx1=None, gy1=None, gx2=None, gy2=None, dash=None, dashoffset=None, opacity=None): 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 color2:
if not gx1: if not gx1:
gx1 = x1 gx1 = x1
@ -78,17 +82,26 @@ class SVG:
if not gy2: if not gy2:
gy2 = y2 gy2 = y2
self.index += 1 self.index += 1
self.file.write('<defs><linearGradient id = "grad' + str(self.index) + '" x1 = "' + str(gx1) + '" y1 = "' + str(gy1) + '" x2 = "' + str(gx2) + '" y2 = "' + str(gy2) + '" gradientUnits="userSpaceOnUse">\n<stop\nstyle="stop-color:#' + str(color) + ';stop-opacity:1;"\noffset="0"\n /><stop\nstyle="stop-color:#' + str(color2) + ';stop-opacity:1;"\noffset="1"\n /></linearGradient>\n</defs>\n') self.file.write(
self.file.write(' <path d = "M ' + str(x1) + ',' + str(y1) + ' ' + str(x2) + ',' + str(y2) + '" ') f'<defs><linearGradient id="grad{str(self.index)}" '
if id: f'x1="{str(gx1)}" y1="{str(gy1)}" x2="{str(gx2)}" '
self.file.write('id = "' + id + '" ') f'y2="{str(gy2)}" gradientUnits="userSpaceOnUse">\n'
self.file.write('style = "') f'<stop style="stop-color:#{str(color)};stop-opacity:1;" '
f'offset="0" />'
f'<stop style=\"stop-color:#{str(color2)};stop-opacity:1;" '
f'offset="1" />'
f'</linearGradient></defs>\n')
self.file.write(
f' <path d = "M {str(x1)},{str(y1)} {str(x2)},{str(y2)}" ')
if id_:
self.file.write(f'id="{id_}" ')
self.file.write('style="')
if not color2: if not color2:
self.file.write('stroke:' + self.get_color(color) + '; ') self.file.write(f'stroke:{self.get_color(color)}; ')
else: else:
self.file.write('stroke:url(#grad' + str(self.index) + '); ') self.file.write(f'stroke:url(#grad{self.index}); ')
self.file.write('stroke-width:' + str(width) + '; ') self.file.write(f'stroke-width:{width}; ')
self.file.write('stroke-linecap:' + end + '; ') self.file.write(f'stroke-linecap:{end}; ')
if dash: if dash:
self.file.write('stroke-dasharray:' + dash + '; ') self.file.write('stroke-dasharray:' + dash + '; ')
if dashoffset: if dashoffset:
@ -97,8 +110,10 @@ class SVG:
self.file.write('opacity: ' + str(opacity) + '; ') self.file.write('opacity: ' + str(opacity) + '; ')
self.file.write('" />\n') self.file.write('" />\n')
def rect(self, x, y, width, height, color='black', id=None, rx=0, ry=0, opacity=1.0, stroke_color='none', def rect(
stroke_width=1.0): 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(' <rect x = "' + str(x) + '" y = "' + str(y) + '" rx = "' + str(rx) + '" ry = "' + str(ry) + self.file.write(' <rect x = "' + str(x) + '" y = "' + str(y) + '" rx = "' + str(rx) + '" ry = "' + str(ry) +
'" ') '" ')
self.file.write(' width = "' + str(width) + '" height = "' + str(height) + '" ') self.file.write(' width = "' + str(width) + '" height = "' + str(height) + '" ')
@ -132,25 +147,32 @@ class SVG:
self.file.write('" />\n') self.file.write('" />\n')
def circle(self, x, y, d, color='black', color2='white', fill='none', 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 is_grad = gx != 0 or gy != 0 or gr != 0
if is_grad: if is_grad:
self.index += 1 self.index += 1
self.file.write('''<defs> self.file.write(
<radialGradient id="grad''' + str(self.index) + '" cx="' + str(gx) + '%" cy="' + str(gy) + '%" r="' + str(gr) + '%" fx="' + str(fx) + '%" fy="' + str(fy) + '''%"> f'<defs><radialGradient id="grad{str(self.index)}" '
<stop offset="0%" style="stop-color:rgb(255,255,255); f'cx="{gx}%" cy="{gy}%" r="{gr}%" fx="{fx}%" fy="{fy}%">'
stop-opacity:0" /> f'<stop offset="0%" style="stop-color:rgb(255,255,255);'
<stop offset="100%" style="stop-color:''' + self.get_color(color) + ''';stop-opacity:1" /> f'stop-opacity:0" /><stop offset="100%" '
</radialGradient> f'style="stop-color:{self.get_color(color)};stop-opacity:1" />'
</defs>''') f'</radialGradient></defs>\n')
c = 0.577 c = 0.577
self.file.write( self.file.write(
f''' <path d = "M {x:5.1f} {y + d:5.1f} C {x - d * c:5.1f} {y + d:5.1f} f' <path d = "'
{x - d:5.1f} {y + d * c:5.1f} {x - d:5.1f} {y:5.1f} C {x - d:5.1f} {y - d * c:5.1f} {x - d * c:5.1f} {y - d:5.1f} {x:5.1f} f'M {x:5.1f} {y + d:5.1f} '
{y - d:5.1f} C {x + d * c:5.1f} {y - d:5.1f} {x + d:5.1f} {y - d * c:5.1f} {x + d:5.1f} {y:5.1f} C {x + d:5.1f} {y + d * c:5.1f} f'C {x - d * c:5.1f} {y + d:5.1f} {x - d:5.1f} {y + d * c:5.1f} '
{x + d * c:5.1f} {y + d:5.1f} {x:5.1f} {y + d:5.1f}" ''') f'{x - d:5.1f} {y:5.1f} '
if id: f'C {x - d:5.1f} {y - d * c:5.1f} {x - d * c:5.1f} {y - d:5.1f} '
self.file.write('id = "' + id + '" ') f'{x:5.1f} {y - d:5.1f} '
f'C {x + d * c:5.1f} {y - d:5.1f} {x + d:5.1f} {y - d * c:5.1f} '
f'{x + d:5.1f} {y:5.1f} '
f'C {x + d:5.1f} {y + d * c:5.1f} {x + d * c:5.1f} {y + d:5.1f} '
f'{x:5.1f} {y + d:5.1f}" ')
if id_:
self.file.write('id = "' + id_ + '" ')
self.file.write('style = "') self.file.write('style = "')
if is_grad: if is_grad:
self.file.write('fill:url(#grad' + str(self.index) + '); ') self.file.write('fill:url(#grad' + str(self.index) + '); ')

View file

@ -11,8 +11,7 @@ def parse_options(args):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', dest='input_file_name', parser.add_argument('-i', '--input', dest='input_file_name')
required=True)
parser.add_argument('-o', '--output', dest='output_file_name', parser.add_argument('-o', '--output', dest='output_file_name',
required=True) required=True)
parser.add_argument('-bbox', '--boundary-box', dest='boundary_box', parser.add_argument('-bbox', '--boundary-box', dest='boundary_box',
@ -39,9 +38,6 @@ def parse_options(args):
arguments = parser.parse_args(args[1:]) arguments = parser.parse_args(args[1:])
arguments.boundary_box = \
list(map(lambda x: float(x.replace('m', '-')), arguments.boundary_box.split(',')))
return arguments return arguments