Issue #121: add show overlapped feature.

This commit is contained in:
Sergey Vartanov 2022-04-06 03:12:39 +03:00
parent 7c99d828f4
commit 360ca3f600
4 changed files with 40 additions and 11 deletions

View file

@ -451,7 +451,10 @@ class Constructor:
color = get_time_color(node.timestamp, self.osm_data.time) color = get_time_color(node.timestamp, self.osm_data.time)
dot: Shape = self.extractor.get_shape(DEFAULT_SMALL_SHAPE_ID) dot: Shape = self.extractor.get_shape(DEFAULT_SMALL_SHAPE_ID)
icon_set: IconSet = IconSet( icon_set: IconSet = IconSet(
Icon([ShapeSpecification(dot, color)]), [], set() Icon([ShapeSpecification(dot, color)]),
[],
Icon([ShapeSpecification(dot, color)]),
set(),
) )
point: Point = Point( point: Point = Point(
icon_set, icon_set,

View file

@ -584,6 +584,10 @@ class IconSet:
main_icon: Icon main_icon: Icon
extra_icons: list[Icon] extra_icons: list[Icon]
# Icon to use if the point is hidden by overlapped icons but still need to
# be shown.
default_icon: Optional[Icon]
# Tag keys that were processed to create icon set (other tag keys should be # Tag keys that were processed to create icon set (other tag keys should be
# displayed by text or ignored) # displayed by text or ignored)
processed: set[str] processed: set[str]

View file

@ -105,7 +105,12 @@ class Point(Tagged):
self.tags if self.add_tooltips else None self.tags if self.add_tooltips else None
) )
self.main_icon_painted: bool = self.draw_point_shape( self.main_icon_painted: bool = self.draw_point_shape(
svg, self.icon_set.main_icon, position, occupied, tags=tags svg,
self.icon_set.main_icon,
self.icon_set.default_icon,
position,
occupied,
tags=tags,
) )
if self.main_icon_painted: if self.main_icon_painted:
self.y += 16.0 self.y += 16.0
@ -133,7 +138,7 @@ class Point(Tagged):
left: float = -(len(self.icon_set.extra_icons) - 1.0) * 8.0 left: float = -(len(self.icon_set.extra_icons) - 1.0) * 8.0
for icon in self.icon_set.extra_icons: for icon in self.icon_set.extra_icons:
point: np.ndarray = self.point + np.array((left, self.y)) point: np.ndarray = self.point + np.array((left, self.y))
self.draw_point_shape(svg, icon, point, occupied=occupied) self.draw_point_shape(svg, icon, None, point, occupied=occupied)
left += 16.0 left += 16.0
if self.icon_set.extra_icons: if self.icon_set.extra_icons:
self.y += 16.0 self.y += 16.0
@ -142,21 +147,27 @@ class Point(Tagged):
self, self,
svg: svgwrite.Drawing, svg: svgwrite.Drawing,
icon: Icon, icon: Icon,
default_icon: Optional[Icon],
position: np.ndarray, position: np.ndarray,
occupied: Occupied, occupied: Optional[Occupied],
tags: Optional[dict[str, str]] = None, tags: Optional[dict[str, str]] = None,
) -> bool: ) -> bool:
"""Draw one combined icon and its outline.""" """Draw one combined icon and its outline."""
# Down-cast floats to integers to make icons pixel-perfect. # Down-cast floats to integers to make icons pixel-perfect.
position: np.ndarray = np.array((int(position[0]), int(position[1]))) position: np.ndarray = np.array((int(position[0]), int(position[1])))
icon_to_draw: Icon = icon
if occupied and occupied.check(position): if occupied and occupied.check(position):
return False if default_icon:
icon_to_draw = default_icon
else:
return False
if self.draw_outline: if self.draw_outline:
icon.draw(svg, position, outline=True) icon_to_draw.draw(svg, position, outline=True)
icon.draw(svg, position, tags=tags) icon_to_draw.draw(svg, position, tags=tags)
if occupied: if occupied:
overlap: int = occupied.overlap overlap: int = occupied.overlap

View file

@ -22,6 +22,7 @@ from map_machine.pictogram.icon import (
Shape, Shape,
ShapeExtractor, ShapeExtractor,
ShapeSpecification, ShapeSpecification,
DEFAULT_SMALL_SHAPE_ID,
) )
from map_machine.text import Label, TextConstructor from map_machine.text import Label, TextConstructor
@ -559,13 +560,23 @@ class Scheme:
if main_icon and color: if main_icon and color:
main_icon.recolor(color) main_icon.recolor(color)
default_shape = extractor.get_shape(DEFAULT_SHAPE_ID)
if not main_icon: if not main_icon:
main_icon = Icon( dot_spec: ShapeSpecification = ShapeSpecification(
[ShapeSpecification(default_shape, self.get_color("default"))] extractor.get_shape(DEFAULT_SHAPE_ID), self.get_color("default")
) )
main_icon: Icon = Icon([dot_spec])
returned: IconSet = IconSet(main_icon, extra_icons, processed) default_icon: Optional[Icon] = None
if configuration.show_overlapped:
small_dot_spec: ShapeSpecification = ShapeSpecification(
extractor.get_shape(DEFAULT_SMALL_SHAPE_ID),
self.get_color("default"),
)
default_icon = Icon([small_dot_spec])
returned: IconSet = IconSet(
main_icon, extra_icons, default_icon, processed
)
self.cache[tags_hash] = returned, priority self.cache[tags_hash] = returned, priority
for key in "direction", "camera:direction": for key in "direction", "camera:direction":