TomSchimansky / TomSchimansky/TkinterMapView

Labels in map

Open
#162 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
743
Forks
110
PR merge metrics
No merged PRs in 30d

Description

if you chanage a icon=False you can make lables
map.set_marker(center_lat, center_lon,icon=False,text=label_text,font=label_font,text_angle=text_angle)
and original code will be like this:::

class CanvasPositionMarker:
def init(self,
map_widget: "TkinterMapView",
position: tuple,
text: str = None,
text_color: str = "#652A22",
text_anchor: str = "center",
text_angle: int=0,
font=None,
marker_color_circle: str = "#9B261E",
marker_color_outside: str = "#C5542D",
command: Callable = None,
command_right: Callable = None,
image: tkinter.PhotoImage = None,
icon: tkinter.PhotoImage = None,
icon_anchor: str = "center",
image_zoom_visibility: tuple = (0, float("inf")),
data: any = None):

    self.map_widget = map_widget
    self.position = position
    self.text_color = text_color
    self.marker_color_circle = marker_color_circle
    self.marker_color_outside = marker_color_outside
    self.text = text
    self.text_y_offset = 0  # vertical offset pf text from marker position in px
    self.text_anchor=text_anchor
    self.text_angle=text_angle
    self.image = image
    self.icon = icon
    self.icon_anchor = icon_anchor  # can be center, n, nw, w, sw, s, ew, e, ne
    self.image_hidden = False
    self.image_zoom_visibility = image_zoom_visibility
    self.deleted = False
    self.command = command
    self.command_right=command_right
    self.data = data

    self.polygon = None
    self.big_circle = None
    self.canvas_text = None
    self.canvas_image = None
    self.canvas_icon = None

    if font is None:
        if sys.platform == "darwin":
            self.font = "Tahoma 13 bold"
        else:
            self.font = "Tahoma 11 bold"
    else:
        self.font = font

    self.calculate_text_y_offset()

def calculate_text_y_offset(self):
    if self.icon is False:
               self.text_y_offset=-5
    elif self.icon is not None:
        if self.icon_anchor in ("center", "e", "w"):
            self.text_y_offset = -round(self.icon.height() / 2) - 5
        elif self.icon_anchor in ("nw", "n", "ne"):
            self.text_y_offset = -5
        elif self.icon_anchor in ("sw", "s", "se"):
            self.text_y_offset = -self.icon.height() - 5
        else:
            raise ValueError(f"CanvasPositionMarker: wring anchor value: {self.icon_anchor}")

    else:
        self.text_y_offset = -56

def delete(self):
    if self in self.map_widget.canvas_marker_list:
        self.map_widget.canvas_marker_list.remove(self)

    self.map_widget.canvas.delete(self.polygon)
    self.map_widget.canvas.delete(self.big_circle)
    self.map_widget.canvas.delete(self.canvas_text)
    self.map_widget.canvas.delete(self.canvas_icon)
    self.map_widget.canvas.delete(self.canvas_image)

    self.polygon, self.big_circle, self.canvas_text, self.canvas_image, self.canvas_icon = None, None, None, None, None
    self.deleted = True
    self.map_widget.canvas.update()

def set_position(self, deg_x, deg_y):
    self.position = (deg_x, deg_y)
    self.draw()

def set_text(self, text):
    self.text = text
    self.draw()

def change_icon(self, new_icon: tkinter.PhotoImage):
    if self.icon is None:
        raise AttributeError("CanvasPositionMarker: marker needs icon image in constructor to change icon image later")
    else:
        self.icon = new_icon
        self.calculate_text_y_offset()
        self.map_widget.canvas.itemconfigure(self.canvas_icon, image=self.icon)

def hide_image(self, image_hidden: bool):
    self.image_hidden = image_hidden
    self.draw()

def mouse_enter(self, event=None):
    if sys.platform == "darwin":
        self.map_widget.canvas.config(cursor="pointinghand")
    elif sys.platform.startswith("win"):
        self.map_widget.canvas.config(cursor="hand2")
    else:
        self.map_widget.canvas.config(cursor="hand2")  # not tested what it looks like on Linux!

def mouse_leave(self, event=None):
    self.map_widget.canvas.config(cursor="arrow")

def click(self, event=None):
    if self.command is not None:
        self.command(self)
def clickright(self, event=None):
    if self.command_right is not None:
        self.command_right(self)
def get_canvas_pos(self, position):
    tile_position = decimal_to_osm(*position, round(self.map_widget.zoom))

    widget_tile_width = self.map_widget.lower_right_tile_pos[0] - self.map_widget.upper_left_tile_pos[0]
    widget_tile_height = self.map_widget.lower_right_tile_pos[1] - self.map_widget.upper_left_tile_pos[1]

    canvas_pos_x = ((tile_position[0] - self.map_widget.upper_left_tile_pos[0]) / widget_tile_width) * self.map_widget.width
    canvas_pos_y = ((tile_position[1] - self.map_widget.upper_left_tile_pos[1]) / widget_tile_height) * self.map_widget.height

    return canvas_pos_x, canvas_pos_y

def draw(self, event=None):
    canvas_pos_x, canvas_pos_y = self.get_canvas_pos(self.position)

    if not self.deleted:
        if 0 - 50 < canvas_pos_x < self.map_widget.width + 50 and 0 < canvas_pos_y < self.map_widget.height + 70:

            # draw icon image for marker
            if self.icon is False:
                pass
            elif self.icon is not None:
                if self.canvas_icon is None:
                    self.canvas_icon = self.map_widget.canvas.create_image(canvas_pos_x, canvas_pos_y,
                                                                           anchor=self.icon_anchor,
                                                                           image=self.icon,
                                                                           tag="marker")
                    if self.command is not None:
                        self.map_widget.canvas.tag_bind(self.canvas_icon, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.canvas_icon, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.canvas_icon, "<Button-1>", self.click)
                    if self.command_right is not None:
                        self.map_widget.canvas.tag_bind(self.canvas_icon, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.canvas_icon, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.canvas_icon, "<Button-3>", self.clickright)
                else:
                    self.map_widget.canvas.coords(self.canvas_icon, canvas_pos_x, canvas_pos_y)

                
            # draw standard icon shape
            else:
                if self.polygon is None:
                    self.polygon = self.map_widget.canvas.create_polygon(canvas_pos_x - 14, canvas_pos_y - 23,
                                                                         canvas_pos_x, canvas_pos_y,
                                                                         canvas_pos_x + 14, canvas_pos_y - 23,
                                                                         fill=self.marker_color_outside, width=2,
                                                                         outline=self.marker_color_outside, tag="marker")
                    if self.command is not None:
                        self.map_widget.canvas.tag_bind(self.polygon, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.polygon, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.polygon, "<Button-1>", self.click)
                    if self.command_right is not None:
                        self.map_widget.canvas.tag_bind(self.polygon, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.polygon, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.polygon, "<Button-3>", self.clickright)
                else:
                    self.map_widget.canvas.coords(self.polygon,
                                                  canvas_pos_x - 14, canvas_pos_y - 23,
                                                  canvas_pos_x, canvas_pos_y,
                                                  canvas_pos_x + 14, canvas_pos_y - 23)
                if self.big_circle is None:
                    self.big_circle = self.map_widget.canvas.create_oval(canvas_pos_x - 14, canvas_pos_y - 45,
                                                                         canvas_pos_x + 14, canvas_pos_y - 17,
                                                                         fill=self.marker_color_circle, width=6,
                                                                         outline=self.marker_color_outside, tag="marker")
                    if self.command is not None:
                        self.map_widget.canvas.tag_bind(self.big_circle, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.big_circle, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.big_circle, "<Button-1>", self.click)
                    if self.command_right is not None:
                        self.map_widget.canvas.tag_bind(self.big_circle, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.big_circle, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.big_circle, "<Button-3>", self.clickright)
                else:
                    self.map_widget.canvas.coords(self.big_circle,
                                                  canvas_pos_x - 14, canvas_pos_y - 45,
                                                  canvas_pos_x + 14, canvas_pos_y - 17)

            if self.text is not None:
                if self.canvas_text is None:
                    self.canvas_text = self.map_widget.canvas.create_text(canvas_pos_x, canvas_pos_y + self.text_y_offset,
                                                                          anchor=self.text_anchor,
                                                                          text=self.text,
                                                                          fill=self.text_color,
                                                                          font=self.font,
                                                                          tag=("marker", "marker_text"),
                                                                          angle=self.text_angle
                                                                          )
                    if self.command is not None:
                        self.map_widget.canvas.tag_bind(self.canvas_text, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.canvas_text, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.canvas_text, "<Button-1>", self.click)
                    if self.command_right is not None:
                        self.map_widget.canvas.tag_bind(self.canvas_text, "<Enter>", self.mouse_enter)
                        self.map_widget.canvas.tag_bind(self.canvas_text, "<Leave>", self.mouse_leave)
                        self.map_widget.canvas.tag_bind(self.canvas_text, "<Button-3>", self.clickright)
                else:
                    self.map_widget.canvas.coords(self.canvas_text, canvas_pos_x, canvas_pos_y + self.text_y_offset)
                    self.map_widget.canvas.itemconfig(self.canvas_text, text=self.text)
            else:
                if self.canvas_text is not None:
                    self.map_widget.canvas.delete(self.canvas_text)

            if self.image is not None and self.image_zoom_visibility[0] <= self.map_widget.zoom <= self.image_zoom_visibility[1]\
                    and not self.image_hidden:

                if self.canvas_image is None:
                    self.canvas_image = self.map_widget.canvas.create_image(canvas_pos_x, canvas_pos_y + (self.text_y_offset - 30),
                                                                            anchor=tkinter.S,
                                                                            image=self.image,
                                                                            tag=("marker", "marker_image"))
                else:
                    self.map_widget.canvas.coords(self.canvas_image, canvas_pos_x, canvas_pos_y + (self.text_y_offset - 30))
            else:
                if self.canvas_image is not None:
                    self.map_widget.canvas.delete(self.canvas_image)
                    self.canvas_image = None
        else:
            self.map_widget.canvas.delete(self.canvas_icon)
            self.map_widget.canvas.delete(self.canvas_text)
            self.map_widget.canvas.delete(self.polygon)
            self.map_widget.canvas.delete(self.big_circle)
            self.map_widget.canvas.delete(self.canvas_image)
            self.canvas_text, self.polygon, self.big_circle, self.canvas_image, self.canvas_icon = None, None, None, None, None

        self.map_widget.manage_z_order()

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with CanvasPositionMarker and the map.set_marker call shown in the issue, then trace how icon, text, font, and text_angle are handled by calculate_text_y_offset and draw. Done means markers created with icon=False can render labels with the requested text, font, and angle without an icon.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
desktop
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.