mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-22 21:46:24 +02:00
Fix code style.
This commit is contained in:
parent
669f6712c4
commit
c098f39e46
4 changed files with 169 additions and 100 deletions
|
@ -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)
|
||||
|
|
|
@ -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<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)
|
||||
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)
|
||||
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
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ class SVG:
|
|||
self.index = 0
|
||||
|
||||
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(
|
||||
f'''<svg version="1.1" baseProfile="full"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -66,8 +67,11 @@ class SVG:
|
|||
self.file.write('stroke-dashoffset:' + str(dashoffset) + '; ')
|
||||
self.file.write('" />\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('<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(' <path d = "M ' + str(x1) + ',' + str(y1) + ' ' + str(x2) + ',' + str(y2) + '" ')
|
||||
if id:
|
||||
self.file.write('id = "' + id + '" ')
|
||||
self.file.write('style = "')
|
||||
self.file.write(
|
||||
f'<defs><linearGradient id="grad{str(self.index)}" '
|
||||
f'x1="{str(gx1)}" y1="{str(gy1)}" x2="{str(gx2)}" '
|
||||
f'y2="{str(gy2)}" gradientUnits="userSpaceOnUse">\n'
|
||||
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:
|
||||
self.file.write('stroke:' + self.get_color(color) + '; ')
|
||||
self.file.write(f'stroke:{self.get_color(color)}; ')
|
||||
else:
|
||||
self.file.write('stroke:url(#grad' + str(self.index) + '); ')
|
||||
self.file.write('stroke-width:' + str(width) + '; ')
|
||||
self.file.write('stroke-linecap:' + end + '; ')
|
||||
self.file.write(f'stroke:url(#grad{self.index}); ')
|
||||
self.file.write(f'stroke-width:{width}; ')
|
||||
self.file.write(f'stroke-linecap:{end}; ')
|
||||
if dash:
|
||||
self.file.write('stroke-dasharray:' + dash + '; ')
|
||||
if dashoffset:
|
||||
|
@ -97,8 +110,10 @@ class SVG:
|
|||
self.file.write('opacity: ' + str(opacity) + '; ')
|
||||
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',
|
||||
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(' <rect x = "' + str(x) + '" y = "' + str(y) + '" rx = "' + str(rx) + '" ry = "' + str(ry) +
|
||||
'" ')
|
||||
self.file.write(' width = "' + str(width) + '" height = "' + str(height) + '" ')
|
||||
|
@ -132,25 +147,32 @@ class SVG:
|
|||
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('''<defs>
|
||||
<radialGradient id="grad''' + str(self.index) + '" cx="' + str(gx) + '%" cy="' + str(gy) + '%" r="' + str(gr) + '%" fx="' + str(fx) + '%" fy="' + str(fy) + '''%">
|
||||
<stop offset="0%" style="stop-color:rgb(255,255,255);
|
||||
stop-opacity:0" />
|
||||
<stop offset="100%" style="stop-color:''' + self.get_color(color) + ''';stop-opacity:1" />
|
||||
</radialGradient>
|
||||
</defs>''')
|
||||
self.file.write(
|
||||
f'<defs><radialGradient id="grad{str(self.index)}" '
|
||||
f'cx="{gx}%" cy="{gy}%" r="{gr}%" fx="{fx}%" fy="{fy}%">'
|
||||
f'<stop offset="0%" style="stop-color:rgb(255,255,255);'
|
||||
f'stop-opacity:0" /><stop offset="100%" '
|
||||
f'style="stop-color:{self.get_color(color)};stop-opacity:1" />'
|
||||
f'</radialGradient></defs>\n')
|
||||
c = 0.577
|
||||
self.file.write(
|
||||
f''' <path d = "M {x: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} {x - d * c:5.1f} {y - d:5.1f} {x: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}
|
||||
{x + d * c:5.1f} {y + d:5.1f} {x:5.1f} {y + d:5.1f}" ''')
|
||||
if id:
|
||||
self.file.write('id = "' + id + '" ')
|
||||
f' <path d = "'
|
||||
f'M {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} '
|
||||
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 = "')
|
||||
if is_grad:
|
||||
self.file.write('fill:url(#grad' + str(self.index) + '); ')
|
||||
|
|
|
@ -11,8 +11,7 @@ def parse_options(args):
|
|||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('-i', '--input', dest='input_file_name',
|
||||
required=True)
|
||||
parser.add_argument('-i', '--input', dest='input_file_name')
|
||||
parser.add_argument('-o', '--output', dest='output_file_name',
|
||||
required=True)
|
||||
parser.add_argument('-bbox', '--boundary-box', dest='boundary_box',
|
||||
|
@ -39,9 +38,6 @@ def parse_options(args):
|
|||
|
||||
arguments = parser.parse_args(args[1:])
|
||||
|
||||
arguments.boundary_box = \
|
||||
list(map(lambda x: float(x.replace('m', '-')), arguments.boundary_box.split(',')))
|
||||
|
||||
return arguments
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue