Fix floating point numbers.

This commit is contained in:
Sergey Vartanov 2021-11-11 23:52:46 +03:00
parent 6e20668e24
commit ed0e0384b7
23 changed files with 358 additions and 332 deletions

View file

@ -35,7 +35,7 @@ def get_gradient_color(
scale: list[Color] = colors + [Color("black")]
range_coefficient: float = (
0 if bounds.is_empty() else (value - bounds.min_) / bounds.delta()
0.0 if bounds.is_empty() else (value - bounds.min_) / bounds.delta()
)
# If value is out of range, set it to boundary value.
range_coefficient = min(1.0, max(0.0, range_coefficient))

View file

@ -189,7 +189,7 @@ class Constructor:
self.craters: list[Crater] = []
self.direction_sectors: list[DirectionSector] = []
self.heights: set[float] = {2, 4}
self.heights: set[float] = {2.0, 4.0}
def add_building(self, building: Building) -> None:
"""Add building and update levels."""
@ -327,10 +327,10 @@ class Constructor:
style: dict[str, Any] = {
"fill": "none",
"stroke": Color("red").hex,
"stroke-width": 1,
"stroke-width": 1.0,
}
figure: StyledFigure = StyledFigure(
line.tags, inners, outers, LineStyle(style, 1000)
line.tags, inners, outers, LineStyle(style, 1000.0)
)
self.figures.append(figure)
@ -453,6 +453,7 @@ class Constructor:
)
if icon_set is None:
return
labels: list[Label] = self.scheme.construct_text(
tags, processed, self.configuration.label_mode
)
@ -498,7 +499,7 @@ def check_level_overground(tags: Tags) -> bool:
if "level" in tags:
try:
for level in map(float, tags["level"].replace(",", ".").split(";")):
if level < 0:
if level < 0.0:
return False
except ValueError:
pass

View file

@ -206,7 +206,7 @@ class MapMachineHTML(MapMachineMoire, DefaultHTML):
def icon(self, arg: Arguments) -> str:
"""Image with Röntgen icon."""
size: str = self.clear(arg[1]) if len(arg) > 1 else 16
size: str = self.clear(arg[1]) if len(arg) > 1 else "16"
return (
f'<img class="icon" style="width: {size}px; height: {size}px;" '
f'src="out/icons_by_id/{self.clear(arg[0])}.svg" />'
@ -261,7 +261,7 @@ class MapMachineOSMWiki(MapMachineMoire, DefaultWiki):
def icon(self, arg: Arguments) -> str:
"""Image with Röntgen icon."""
size: str = self.clear(arg[1]) if len(arg) > 1 else 16
size: str = self.clear(arg[1]) if len(arg) > 1 else "16"
shape_id: str = self.clear(arg[0])
name: str = self.extractor.get_shape(shape_id).name
return f"[[File:Röntgen {name}.svg|{size}px]]"

View file

@ -27,7 +27,7 @@ class Style:
fill: Optional[Color] = None
stroke: Optional[Color] = None
width: float = 1
width: float = 1.0
def update_svg_element(self, element: BaseElement) -> None:
"""Set style for SVG element."""
@ -41,7 +41,7 @@ class Style:
def draw_png_fill(self, context: Context) -> None:
"""Set style for context and draw fill."""
context.set_source_rgba(
self.fill.get_red(), self.fill.get_green(), self.fill.get_blue(), 1
self.fill.get_red(), self.fill.get_green(), self.fill.get_blue()
)
context.fill()
@ -51,7 +51,6 @@ class Style:
self.stroke.get_red(),
self.stroke.get_green(),
self.stroke.get_blue(),
1,
)
context.set_line_width(self.width)
context.stroke()
@ -176,7 +175,7 @@ class PNGDrawing(Drawing):
def _do_path(self, commands: PathCommands) -> None:
"""Draw path."""
current: np.ndarray = np.array((0, 0))
current: np.ndarray = np.array((0.0, 0.0))
start_point: Optional[np.ndarray] = None
command: str = "M"
is_absolute: bool = True
@ -231,14 +230,14 @@ class PNGDrawing(Drawing):
point: np.ndarray
if is_absolute:
if command == "v":
point = np.array((0, commands[index]))
point = np.array((0.0, commands[index]))
else:
point = np.array((commands[index], 0))
point = np.array((commands[index], 0.0))
else:
if command == "v":
point = current + np.array((0, commands[index]))
point = current + np.array((0.0, commands[index]))
else:
point = current + np.array((commands[index], 0))
point = current + np.array((commands[index], 0.0))
current = point
self.context.line_to(point[0], point[1])
if start_point is None:

View file

@ -51,13 +51,13 @@ def draw_element(options: argparse.Namespace) -> None:
labels,
tags,
processed,
np.array((32, 32)),
np.array((32.0, 32.0)),
is_for_node=is_for_node,
draw_outline=is_for_node,
)
border: np.ndarray = np.array((16, 16))
border: np.ndarray = np.array((16.0, 16.0))
size: np.ndarray = point.get_size() + border
point.point = np.array((size[0] / 2, 16 / 2 + border[1] / 2))
point.point = np.array((size[0] / 2.0, 16.0 / 2.0 + border[1] / 2.0))
output_file_path: Path = workspace.output_path / "element.svg"
svg: svgwrite.Drawing = svgwrite.Drawing(

View file

@ -11,9 +11,9 @@ from map_machine.drawing import PathCommands
__author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru"
SHIFT: float = -np.pi / 2
SMALLEST_ANGLE: float = np.pi / 15
DEFAULT_ANGLE: float = np.pi / 30
SHIFT: float = -np.pi / 2.0
SMALLEST_ANGLE: float = np.pi / 15.0
DEFAULT_ANGLE: float = np.pi / 30.0
def parse_vector(text: str) -> Optional[np.ndarray]:
@ -66,13 +66,13 @@ class Sector:
parts: list[str] = text.split("-")
self.start = parse_vector(parts[0])
self.end = parse_vector(parts[1])
self.main_direction = (self.start + self.end) / 2
self.main_direction = (self.start + self.end) / 2.0
else:
result_angle: float
if angle is None:
result_angle = DEFAULT_ANGLE
else:
result_angle = max(SMALLEST_ANGLE, np.radians(angle) / 2)
result_angle = max(SMALLEST_ANGLE, np.radians(angle) / 2.0)
vector: Optional[np.ndarray] = parse_vector(text)
self.main_direction = vector
@ -105,9 +105,9 @@ class Sector:
None otherwise.
"""
if self.main_direction is not None:
if np.allclose(self.main_direction[0], 0):
if np.allclose(self.main_direction[0], 0.0):
return None
if self.main_direction[0] > 0:
if self.main_direction[0] > 0.0:
return True
return False

View file

@ -435,7 +435,7 @@ class Road(Tagged):
lane.get_width(self.scale)
for lane in self.lanes[: lane_number - 1]
)
- self.width * self.scale / 2
- self.width * self.scale / 2.0
)
if place == "left_of":
pass
@ -525,7 +525,7 @@ class Road(Tagged):
"""Get road main color."""
color: Color = self.matcher.color
if self.tags.get("tunnel") == "yes":
color = Color(color, luminance=min(1, color.luminance + 0.2))
color = Color(color, luminance=min(1.0, color.luminance + 0.2))
return color
def get_border_color(self) -> Color:
@ -546,7 +546,7 @@ class Road(Tagged):
for index in range(1, len(self.lanes)):
lane_offset: float = self.scale * (
-self.width / 2 + index * self.width / len(self.lanes)
-self.width / 2.0 + index * self.width / len(self.lanes)
)
path: Path = Path(
d=self.line.get_path(self.placement_offset + lane_offset)
@ -555,7 +555,7 @@ class Road(Tagged):
"fill": "none",
"stroke": color.hex,
"stroke-linejoin": "round",
"stroke-width": 1,
"stroke-width": 1.0,
"opacity": 0.5,
}
path.update(style)
@ -568,7 +568,7 @@ class Road(Tagged):
return
path: Path = svg.path(
d=self.line.get_path(self.placement_offset + 3), fill="none"
d=self.line.get_path(self.placement_offset + 3.0), fill="none"
)
svg.add(path)
@ -580,7 +580,7 @@ class Road(Tagged):
method="align",
spacing="exact",
font_family="Roboto",
font_size=10,
font_size=10.0,
)
text.add(text_path)
@ -668,7 +668,7 @@ class SimpleConnector(Connector):
"""Draw connection fill."""
circle: Circle = svg.circle(
self.point,
self.road_1.width * self.scale / 2,
self.road_1.width * self.scale / 2.0,
fill=self.road_1.get_color().hex,
)
svg.add(circle)
@ -677,7 +677,7 @@ class SimpleConnector(Connector):
"""Draw connection outline."""
circle: Circle = svg.circle(
self.point,
self.road_1.width * self.scale / 2 + 1,
self.road_1.width * self.scale / 2.0 + 1.0,
fill=self.road_1.matcher.border_color.hex,
)
svg.add(circle)
@ -706,7 +706,7 @@ class ComplexConnector(Connector):
point_1: np.ndarray = flinger.fling(node_1.coordinates)
node_2: OSMNode = self.road_2.nodes[self.index_2]
point_2: np.ndarray = flinger.fling(node_2.coordinates)
point = (point_1 + point_2) / 2
point = (point_1 + point_2) / 2.0
points_1: list[np.ndarray] = get_curve_points(
self.road_1,
@ -765,7 +765,9 @@ class SimpleIntersection(Connector):
node: OSMNode = self.road_1.nodes[self.index_1]
point: np.ndarray = self.flinger.fling(node.coordinates)
circle: Circle = svg.circle(
point, road.width * self.scale / 2, fill=road.matcher.color.hex
point,
road.width * self.scale / 2.0,
fill=road.matcher.color.hex,
)
svg.add(circle)
@ -776,7 +778,7 @@ class SimpleIntersection(Connector):
point: np.ndarray = self.flinger.fling(node.coordinates)
circle: Circle = svg.circle(
point,
road.width * self.scale / 2 + 1,
road.width * self.scale / 2.0 + 1.0,
fill=road.matcher.border_color.hex,
)
svg.add(circle)

View file

@ -42,7 +42,7 @@ class Figure(Tagged):
)
def get_path(
self, flinger: Flinger, offset: np.ndarray = np.array((0, 0))
self, flinger: Flinger, offset: np.ndarray = np.array((0.0, 0.0))
) -> str:
"""
Get SVG path commands.
@ -365,13 +365,13 @@ def is_clockwise(polygon: list[OSMNode]) -> bool:
:param polygon: list of OpenStreetMap nodes
"""
count: float = 0
count: float = 0.0
for index, node in enumerate(polygon):
next_index: int = 0 if index == len(polygon) - 1 else index + 1
count += (polygon[next_index].coordinates[0] - node.coordinates[0]) * (
polygon[next_index].coordinates[1] + node.coordinates[1]
)
return count >= 0
return count >= 0.0
def make_clockwise(polygon: list[OSMNode]) -> list[OSMNode]:

View file

@ -95,15 +95,15 @@ class BoundaryBox:
n: float = 2.0 ** (zoom_level + 8.0)
x: int = int((coordinates[1] + 180.0) / 360.0 * n)
left: float = (x - width / 2) / n * 360.0 - 180.0
right: float = (x + width / 2) / n * 360.0 - 180.0
left: float = (x - width / 2.0) / n * 360.0 - 180.0
right: float = (x + width / 2.0) / n * 360.0 - 180.0
y: int = (1.0 - np.arcsinh(np.tan(lat_rad)) / np.pi) / 2.0 * n
bottom_radians = np.arctan(
np.sinh((1.0 - (y + height / 2) * 2.0 / n) * np.pi)
np.sinh((1.0 - (y + height / 2.0) * 2.0 / n) * np.pi)
)
top_radians = np.arctan(
np.sinh((1.0 - (y - height / 2) * 2.0 / n) * np.pi)
np.sinh((1.0 - (y - height / 2.0) * 2.0 / n) * np.pi)
)
return cls(
@ -131,17 +131,17 @@ class BoundaryBox:
def round(self) -> "BoundaryBox":
"""Round boundary box."""
self.left = round(self.left * 1000) / 1000 - 0.001
self.bottom = round(self.bottom * 1000) / 1000 - 0.001
self.right = round(self.right * 1000) / 1000 + 0.001
self.top = round(self.top * 1000) / 1000 + 0.001
self.left = round(self.left * 1000.0) / 1000.0 - 0.001
self.bottom = round(self.bottom * 1000.0) / 1000.0 - 0.001
self.right = round(self.right * 1000.0) / 1000.0 + 0.001
self.top = round(self.top * 1000.0) / 1000.0 + 0.001
return self
def center(self) -> np.ndarray:
"""Return center point of boundary box."""
return np.array(
((self.top + self.bottom) / 2, (self.left + self.right) / 2)
((self.top + self.bottom) / 2.0, (self.left + self.right) / 2.0)
)
def get_format(self) -> str:
@ -150,10 +150,10 @@ class BoundaryBox:
<longitude 1>,<latitude 1>,<longitude 2>,<latitude 2>. Coordinates are
rounded to three digits after comma.
"""
left: float = np.floor(self.left * 1000) / 1000
bottom: float = np.floor(self.bottom * 1000) / 1000
right: float = np.ceil(self.right * 1000) / 1000
top: float = np.ceil(self.top * 1000) / 1000
left: float = np.floor(self.left * 1000.0) / 1000.0
bottom: float = np.floor(self.bottom * 1000.0) / 1000.0
right: float = np.ceil(self.right * 1000.0) / 1000.0
top: float = np.ceil(self.top * 1000.0) / 1000.0
return f"{left:.3f},{bottom:.3f},{right:.3f},{top:.3f}"

View file

@ -20,7 +20,9 @@ def pseudo_mercator(coordinates: np.ndarray) -> np.ndarray:
:return: position on the plane in the form of (x, y)
"""
y: float = (
180 / np.pi * np.log(np.tan(np.pi / 4 + coordinates[0] * np.pi / 360))
180.0
/ np.pi
* np.log(np.tan(np.pi / 4.0 + coordinates[0] * np.pi / 360.0))
)
return np.array((coordinates[1], y))
@ -36,7 +38,7 @@ def osm_zoom_level_to_pixels_per_meter(
function allows any non-negative float value
:param equator_length: celestial body equator length in meters
"""
return 2 ** zoom_level / equator_length * 256
return 2.0 ** zoom_level / equator_length * 256.0
class Flinger:
@ -54,7 +56,7 @@ class Flinger:
:param equator_length: celestial body equator length in meters
"""
self.geo_boundaries: BoundaryBox = geo_boundaries
self.ratio: float = 2 ** zoom_level * 256 / 360
self.ratio: float = 2.0 ** zoom_level * 256.0 / 360.0
self.size: np.ndarray = self.ratio * (
pseudo_mercator(self.geo_boundaries.max_())
- pseudo_mercator(self.geo_boundaries.min_())
@ -90,5 +92,5 @@ class Flinger:
# Get pixels per meter ratio for the center of the boundary box.
coordinates = self.geo_boundaries.center()
scale_factor: float = abs(1 / np.cos(coordinates[0] / 180 * np.pi))
scale_factor: float = abs(1.0 / np.cos(coordinates[0] / 180.0 * np.pi))
return self.pixels_per_meter * scale_factor

View file

@ -14,14 +14,14 @@ def compute_angle(vector: np.ndarray) -> float:
For the given vector compute an angle between it and (1, 0) vector. The
result is in [0, 2π].
"""
if vector[0] == 0:
if vector[1] > 0:
return np.pi / 2
return np.pi + np.pi / 2
if vector[0] < 0:
if vector[0] == 0.0:
if vector[1] > 0.0:
return np.pi / 2.0
return np.pi + np.pi / 2.0
if vector[0] < 0.0:
return np.arctan(vector[1] / vector[0]) + np.pi
if vector[1] < 0:
return np.arctan(vector[1] / vector[0]) + 2 * np.pi
if vector[1] < 0.0:
return np.arctan(vector[1] / vector[0]) + 2.0 * np.pi
return np.arctan(vector[1] / vector[0])
@ -46,10 +46,10 @@ class Polyline:
def __init__(self, points: list[np.ndarray]) -> None:
self.points: list[np.ndarray] = points
def get_path(self, parallel_offset: float = 0) -> str:
def get_path(self, parallel_offset: float = 0.0) -> str:
"""Construct SVG path commands."""
points: list[np.ndarray]
if np.allclose(parallel_offset, 0):
if np.allclose(parallel_offset, 0.0):
points = self.points
else:
try:
@ -98,12 +98,12 @@ class Line:
def is_parallel(self, other: "Line") -> bool:
"""If lines are parallel or equal."""
return np.allclose(other.a * self.b - self.a * other.b, 0)
return np.allclose(other.a * self.b - self.a * other.b, 0.0)
def get_intersection_point(self, other: "Line") -> np.ndarray:
"""Get point of intersection current line with other."""
if other.a * self.b - self.a * other.b == 0:
return np.array((0, 0))
if other.a * self.b - self.a * other.b == 0.0:
return np.array((0.0, 0.0))
x: float = -(self.b * other.c - other.b * self.c) / (
other.a * self.b - self.a * other.b

View file

@ -166,7 +166,7 @@ class MapCSSWriter:
return
for index, stage_of_decay in enumerate(STAGES_OF_DECAY):
opacity: float = 0.6 - 0.4 * index / (len(STAGES_OF_DECAY) - 1)
opacity: float = 0.6 - 0.4 * index / (len(STAGES_OF_DECAY) - 1.0)
for matcher in self.point_matchers:
if len(matcher.tags) > 1:
continue

View file

@ -54,7 +54,7 @@ class Map:
def draw(self, constructor: Constructor) -> None:
"""Draw map."""
self.svg.add(
Rect((0, 0), self.flinger.size, fill=self.background_color)
Rect((0.0, 0.0), self.flinger.size, fill=self.background_color)
)
ways: list[StyledFigure] = sorted(
constructor.figures, key=lambda x: x.line_style.priority
@ -130,7 +130,7 @@ class Map:
building.draw_shade(building_shade, self.flinger)
self.svg.add(building_shade)
previous_height: float = 0
previous_height: float = 0.0
for height in sorted(constructor.heights):
for building in constructor.buildings:
if building.height < height or building.min_height > height:

View file

@ -93,8 +93,8 @@ class Shape:
def get_path(
self,
point: np.ndarray,
offset: np.ndarray = np.array((0, 0)),
scale: np.ndarray = np.array((1, 1)),
offset: np.ndarray = np.array((0.0, 0.0)),
scale: np.ndarray = np.array((1.0, 1.0)),
) -> SVGPath:
"""
Draw icon into SVG file.
@ -108,7 +108,7 @@ class Shape:
transformations.append(f"translate({shift[0]},{shift[1]})")
if not np.allclose(scale, np.array((1, 1))):
if not np.allclose(scale, np.array((1.0, 1.0))):
transformations.append(f"scale({scale[0]},{scale[1]})")
transformations.append(f"translate({self.offset[0]},{self.offset[1]})")
@ -221,7 +221,7 @@ class ShapeExtractor:
def get_offset(value: str) -> float:
"""Get negated icon offset from the origin."""
return (
-int(float(value) / GRID_STEP) * GRID_STEP - GRID_STEP / 2
-int(float(value) / GRID_STEP) * GRID_STEP - GRID_STEP / 2.0
)
point: np.ndarray = np.array(
@ -259,7 +259,7 @@ class ShapeSpecification:
shape: Shape
color: Color = DEFAULT_COLOR
offset: np.ndarray = np.array((0, 0))
offset: np.ndarray = np.array((0.0, 0.0))
flip_horizontally: bool = False
flip_vertically: bool = False
use_outline: bool = True
@ -401,7 +401,7 @@ class Icon:
shape_specification.color = color
shape_specification.draw(
svg,
np.array((8, 8)),
np.array((8.0, 8.0)),
outline=outline,
outline_opacity=outline_opacity,
)
@ -409,7 +409,7 @@ class Icon:
for shape_specification in self.shape_specifications:
if color:
shape_specification.color = color
shape_specification.draw(svg, np.array((8, 8)))
shape_specification.draw(svg, np.array((8.0, 8.0)))
with file_name.open("w", encoding="utf-8") as output_file:
svg.write(output_file)

View file

@ -161,7 +161,7 @@ class IconCollection:
self,
file_name: Path,
columns: int = 16,
step: float = 24,
step: float = 24.0,
background_color: Color = Color("white"),
scale: float = 1.0,
) -> None:
@ -174,19 +174,19 @@ class IconCollection:
:param background_color: background color
:param scale: scale icon by the magnitude
"""
point: np.ndarray = np.array((step / 2 * scale, step / 2 * scale))
point: np.ndarray = np.array((step / 2.0 * scale, step / 2.0 * scale))
width: float = step * columns * scale
height: int = int(int(len(self.icons) / columns + 1) * step * scale)
height: int = int(int(len(self.icons) / columns + 1.0) * step * scale)
svg: Drawing = Drawing(str(file_name), (width, height))
svg.add(svg.rect((0, 0), (width, height), fill=background_color.hex))
for icon in self.icons:
icon.draw(svg, point, scale=scale)
point += np.array((step * scale, 0))
if point[0] > width - 8:
point[0] = step / 2 * scale
point += np.array((0, step * scale))
point += np.array((step * scale, 0.0))
if point[0] > width - 8.0:
point[0] = step / 2.0 * scale
point += np.array((0.0, step * scale))
height += step * scale
with file_name.open("w", encoding="utf-8") as output_file:

View file

@ -32,13 +32,13 @@ class Occupied:
def check(self, point: np.ndarray) -> bool:
"""Check whether point is already occupied by other elements."""
if 0 <= point[0] < self.width and 0 <= point[1] < self.height:
if 0.0 <= point[0] < self.width and 0.0 <= point[1] < self.height:
return self.matrix[point[0], point[1]]
return True
def register(self, point: np.ndarray) -> None:
"""Register that point is occupied by an element."""
if 0 <= point[0] < self.width and 0 <= point[1] < self.height:
if 0.0 <= point[0] < self.width and 0.0 <= point[1] < self.height:
self.matrix[point[0], point[1]] = True
assert self.matrix[point[0], point[1]]
@ -57,7 +57,7 @@ class Point(Tagged):
tags: dict[str, str],
processed: set[str],
point: np.ndarray,
priority: float = 0,
priority: float = 0.0,
is_for_node: bool = True,
draw_outline: bool = True,
add_tooltips: bool = False,
@ -71,12 +71,12 @@ class Point(Tagged):
self.processed: set[str] = processed
self.point: np.ndarray = point
self.priority: float = priority
self.layer: float = 0
self.layer: float = 0.0
self.is_for_node: bool = is_for_node
self.draw_outline: bool = draw_outline
self.add_tooltips: bool = add_tooltips
self.y = 0
self.y: float = 0.0
self.main_icon_painted: bool = False
def draw_main_shapes(
@ -91,7 +91,7 @@ class Point(Tagged):
):
return
position: np.ndarray = self.point + np.array((0, self.y))
position: np.ndarray = self.point + np.array((0.0, self.y))
tags: Optional[dict[str, str]] = (
self.tags if self.add_tooltips else None
)
@ -99,7 +99,7 @@ class Point(Tagged):
svg, self.icon_set.main_icon, position, occupied, tags=tags
)
if self.main_icon_painted:
self.y += 16
self.y += 16.0
def draw_extra_shapes(
self, svg: svgwrite.Drawing, occupied: Optional[Occupied] = None
@ -110,7 +110,7 @@ class Point(Tagged):
is_place_for_extra: bool = True
if occupied:
left: float = -(len(self.icon_set.extra_icons) - 1) * 8
left: float = -(len(self.icon_set.extra_icons) - 1.0) * 8.0
for _ in self.icon_set.extra_icons:
point: np.ndarray = np.array(
(int(self.point[0] + left), int(self.point[1] + self.y))
@ -118,16 +118,16 @@ class Point(Tagged):
if occupied.check(point):
is_place_for_extra = False
break
left += 16
left += 16.0
if is_place_for_extra:
left: float = -(len(self.icon_set.extra_icons) - 1) * 8
left: float = -(len(self.icon_set.extra_icons) - 1.0) * 8.0
for icon in self.icon_set.extra_icons:
point: np.ndarray = self.point + np.array((left, self.y))
self.draw_point_shape(svg, icon, point, occupied=occupied)
left += 16
left += 16.0
if self.icon_set.extra_icons:
self.y += 16
self.y += 16.0
def draw_point_shape(
self,
@ -180,7 +180,7 @@ class Point(Tagged):
text = text.replace("&quot;", '"')
text = text.replace("&amp;", "&")
text = text[:26] + ("..." if len(text) > 26 else "")
point = self.point + np.array((0, self.y + 2))
point = self.point + np.array((0.0, self.y + 2.0))
self.draw_text(
svg, text, point, occupied, label.fill, size=label.size
)
@ -212,9 +212,9 @@ class Point(Tagged):
if occupied:
is_occupied: bool = False
for i in range(-int(length / 2), int(length / 2)):
for i in range(-int(length / 2.0), int(length / 2.0)):
text_position: np.ndarray = np.array(
(int(point[0] + i), int(point[1] - 4))
(int(point[0] + i), int(point[1] - 4.0))
)
if occupied.check(text_position):
is_occupied = True
@ -223,7 +223,7 @@ class Point(Tagged):
if is_occupied:
return
for i in range(-int(length / 2), int(length / 2)):
for i in range(-int(length / 2.0), int(length / 2.0)):
for j in range(-12, 5):
occupied.register(
np.array((int(point[0] + i), int(point[1] + j)))
@ -233,24 +233,40 @@ class Point(Tagged):
if out_fill_2:
text_element = svg.text(
text, point, font_size=size, text_anchor="middle",
font_family=DEFAULT_FONT, fill=out_fill_2.hex,
stroke_linejoin="round", stroke_width=5, stroke=out_fill_2.hex,
opacity=out_opacity_2
) # fmt: skip
text,
point,
font_size=size,
text_anchor="middle",
font_family=DEFAULT_FONT,
fill=out_fill_2.hex,
stroke_linejoin="round",
stroke_width=5.0,
stroke=out_fill_2.hex,
opacity=out_opacity_2,
)
svg.add(text_element)
if out_fill:
text_element = svg.text(
text, point, font_size=size, text_anchor="middle",
font_family=DEFAULT_FONT, fill=out_fill.hex,
stroke_linejoin="round", stroke_width=3, stroke=out_fill.hex,
text,
point,
font_size=size,
text_anchor="middle",
font_family=DEFAULT_FONT,
fill=out_fill.hex,
stroke_linejoin="round",
stroke_width=3.0,
stroke=out_fill.hex,
opacity=out_opacity,
) # fmt: skip
)
svg.add(text_element)
text_element = svg.text(
text, point, font_size=size, text_anchor="middle",
font_family=DEFAULT_FONT, fill=fill.hex,
) # fmt: skip
text,
point,
font_size=size,
text_anchor="middle",
font_family=DEFAULT_FONT,
fill=fill.hex,
)
svg.add(text_element)
self.y += 11
@ -264,7 +280,9 @@ class Point(Tagged):
width: int = icon_size * (
1 + max(2, len(self.icon_set.extra_icons) - 1)
)
height: int = icon_size * (1 + int(len(self.icon_set.extra_icons) / 3))
height: int = icon_size * (
1 + np.ceil(len(self.icon_set.extra_icons) / 3.0)
)
if len(self.labels):
height += 4 + 11 * len(self.labels)
return np.array((width, height))

View file

@ -289,16 +289,16 @@ class RoadMatcher(Matcher):
if "color" in structure:
self.color = Color(scheme.get_color(structure["color"]))
self.default_width: float = structure["default_width"]
self.priority: float = 0
self.priority: float = 0.0
if "priority" in structure:
self.priority = structure["priority"]
def get_priority(self, tags: Tags) -> float:
"""Get priority for drawing order."""
layer: float = 0
layer: float = 0.0
if "layer" in tags:
layer = float(tags.get("layer"))
return 1000 * layer + self.priority
return 1000.0 * layer + self.priority
class Scheme:
@ -598,7 +598,7 @@ class Scheme:
"""
shape: Shape = extractor.get_shape(DEFAULT_SHAPE_ID)
color: Color = color
offset: np.ndarray = np.array((0, 0))
offset: np.ndarray = np.array((0.0, 0.0))
flip_horizontally: bool = False
flip_vertically: bool = False
use_outline: bool = True

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@ from typing import Optional
import cairosvg
from map_configuration import MapConfiguration
from map_machine.map_configuration import MapConfiguration
from map_machine.slippy.tile import Tile
from map_machine.workspace import workspace

View file

@ -151,7 +151,7 @@ def construct_text(
processed.add("route_ref")
if "cladr:code" in tags:
texts.append(Label(tags["cladr:code"], size=7))
texts.append(Label(tags["cladr:code"], size=7.0))
processed.add("cladr:code")
if "website" in tags:

View file

@ -293,7 +293,7 @@ def add_render_arguments(parser: argparse.ArgumentParser) -> None:
type=float,
metavar="<float>",
help="OSM zoom level",
default=18,
default=18.0,
)
parser.add_argument(
"-c",
@ -354,6 +354,7 @@ def progress_bar(
fill_length: int = int(parts / BOXES_LENGTH)
box: str = BOXES[int(parts - fill_length * BOXES_LENGTH)]
sys.stdout.write(
f"{str(int(int(ratio * 1000) / 10)):>3} % {fill_length * ''}{box}"
f"{str(int(int(ratio * 1000.0) / 10.0)):>3} % "
f"{fill_length * ''}{box}"
f"{int(length - fill_length - 1) * ' '}{text}\n\033[F"
)

View file

@ -26,7 +26,7 @@ class MinMax:
def center(self) -> Any:
"""Get middle point between minimum and maximum."""
return (self.min_ + self.max_) / 2
return (self.min_ + self.max_) / 2.0
def is_empty(self) -> bool:
"""Check if interval is empty."""

View file

@ -5,5 +5,6 @@ from map_machine.ui.completion import completion_commands
def test_completion() -> None:
"""Test Fish shell completion generation."""
commands: str = completion_commands()
assert commands.startswith("set -l")