Skip to content

Commit

Permalink
Add Info Window, Remove fudge factor. (#57)
Browse files Browse the repository at this point in the history
Added the info window functionality.
Finally found the way to convert between display coordinates and
point positions with out using fudge factors.
Fixed up minor issues with marker display.

d_rats/map/mapdraw.py:
  remove unused get_map_base method.
  Move calculating map to display offset to MapTile class.
  In draw_image_at method, center icon over point.
  in draw_marker method, use Map.Tile.deg2display() instead of latlon2xy.
  In draw_marker method, remove fudge factor usage.
  in draw_text_marker_at method, Make sure text is centered on point.
  In expose_map method, refactor to use MapTile methods to reduce
  code duplication in other methods.

d_rats/map/maptile.py:
  Add _set_x_origin method to calculate and store display origin as
  a class variable.
  Add get_display_center as a class method, as a common method of getting
  the center tile offset.
  Add get_display_limits to return number of display pixels for each axis.
  Add get_display_tile_limits to return number of tiles for each axis.
  Add get_display_origin to return the offset of the display from the
  map tile numbers.
  Add set_center method to store the center position of the map.
  In the set_map_widget method store the the requested tile limits for
  each axis as class variables
  In the set_zoom method, calculate and store the maximum number of tiles
  to avoid doing that calculation for every coordinate to or from degree
  method called.
  Removed unused deg2pixel method.
  Add deg2display method to replace latlon2xy method and eliminate
  fudge factors.
  Add display2deg method to replace xy2latlon method and eliminate fudge
  factors.

d_rats/map/mapwidget.py:
  Simplify calculate_bounds method, remove fudge factor calculation.
  Remove latlon2xy and xy2latlon methods.

d_rats/map/mapwindow.py:
  Implement the Info Window mouse popup for points.
  Shorten the mouse movement timer from 10 to 5 to be more responsive.

Co-authored-by: John E. Malmberg <wb8tyw@gmail.com>
  • Loading branch information
wb8tyw and JohnMalmberg committed Sep 5, 2022
1 parent 3352dcd commit 519651b
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 216 deletions.
142 changes: 34 additions & 108 deletions d_rats/map/mapdraw.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@ class MapDraw():
__center = None
__center_changed = False
__zoom_changed = False
center_tile = None
x_base = 0.0
y_base = 0.0

def __init__(self, map_widget, cairo_ctx):
self.map_widget = map_widget
Expand Down Expand Up @@ -122,16 +119,6 @@ def set_zoom_changed(cls):
'''
cls.__zoom_changed = True

@classmethod
def get_map_base(cls):
'''
Get the map base coordinates.
:returns: Map coordinates for the top left tile
:rtype: tuple of (float, float)
'''
return cls.x_base, cls.y_base

# pylint wants a max of 15 local variables in a method.
# pylint: disable=too-many-locals
@classmethod
Expand Down Expand Up @@ -180,28 +167,14 @@ def handler(cls, map_widget, cairo_ctx):
if cls.__zoom_changed or cls.__center_changed:
map_widget.calculate_bounds()

# if cls.__center != cls.__old_center:
# We do not know the page size of the scrollbars until we get
# here, so a self._center change is used to let us know when
# here, so self._center change is used to let us know when
# we need to have the program adjust the scrollbars to the new
# center.
if cls.__center:
cls.center_tile = Map.Tile(cls.__center)

# Map dimmensions in Tile Pixels
width = self.map_widget.width
map_width = width * self.map_widget.tilesize
delta_x = map_width / 2
height = self.map_widget.height
map_height = height * self.map_widget.tilesize
delta_y = map_height / 2

base = cls.center_tile + (-delta_x, -delta_y)
cls.x_base = base.x_tile
cls.y_base = base.y_tile

hadj.set_value(delta_x - (h_page_size / 2))
vadj.set_value(delta_y - (v_page_size / 2))
display_width, display_height = Map.Tile.get_display_limits()
hadj.set_value((display_width - h_page_size) / 2)
vadj.set_value((display_height - v_page_size) / 2)

self.expose_map()
self.scale()
Expand Down Expand Up @@ -269,11 +242,16 @@ def draw_image_at(self, x_coord, y_coord, pixbuf):
:rtype: int
'''
self.cairo_ctx.save()
Gdk.cairo_set_source_pixbuf(self.cairo_ctx, pixbuf, x_coord, y_coord)
half_width = pixbuf.get_width() / 2
height = pixbuf.get_height()
half_height = height / 2
Gdk.cairo_set_source_pixbuf(self.cairo_ctx, pixbuf,
x_coord - half_width,
y_coord - half_height)
self.cairo_ctx.paint()
self.cairo_ctx.restore()

return pixbuf.get_height()
return height

# pylint wants a max of 12 branches and 50 statements for a method.
# pylint: disable=too-many-branches, too-many-statements
Expand All @@ -284,67 +262,9 @@ def draw_marker(self, point):
:param point: point to draw
:type point: :class:`MapPoint`
'''
color = "yellow"

position = Map.Position(point.get_latitude(), point.get_longitude())
try:
x_coord1, y_coord1 = self.map_widget.latlon2xy(position)
zoom = self.map_widget.map_window.mapcontrols.zoom_control.level

# This is the only way that I can get my position to plot
# correctly from zoom levels 4-18.
# This is based on looking up the position of my house with a
# Meridian Marine GPS.
# I am hoping that someone can find a better solution in the
# future.
x_fudge1 = 9
y_fudge1 = 6
if zoom == 5:
x_fudge1 = 8
y_fudge1 = 5
elif zoom == 6:
x_fudge1 = 5
y_fudge1 = 5
elif zoom == 7:
x_fudge1 = 8
y_fudge1 = 10
elif zoom == 8:
x_fudge1 = 10
y_fudge1 = 13
elif zoom == 9:
x_fudge1 = 10
y_fudge1 = 13
elif zoom == 10:
x_fudge1 = 10
y_fudge1 = 10
elif zoom == 11:
x_fudge1 = 10
y_fudge1 = 10
elif zoom == 12:
x_fudge1 = 14
y_fudge1 = 10
elif zoom == 13:
x_fudge1 = 30
y_fudge1 = 18
elif zoom == 14:
x_fudge1 = 50
y_fudge1 = 10
elif zoom == 15:
x_fudge1 = 80
y_fudge1 = 0
elif zoom == 16:
x_fudge1 = 150
y_fudge1 = -20
elif zoom == 17:
x_fudge1 = 295
y_fudge1 = -40
elif zoom == 18:
x_fudge1 = 580
y_fudge1 = -105

x_coord = x_coord1 - x_fudge1
y_coord = y_coord1 - y_fudge1

x_coord, y_coord = Map.Tile.deg2display(position)
except ZeroDivisionError:
return

Expand All @@ -353,9 +273,10 @@ def draw_marker(self, point):
self.draw_cross_marker_at(x_coord, y_coord)
else:
img = point.get_icon()
offset = 0
if img:
y_coord += (4 + self.draw_image_at(x_coord, y_coord, img))
self.draw_text_marker_at(x_coord, y_coord, label, color)
offset = self.draw_image_at(x_coord, y_coord, img)
self.draw_text_marker_at(x_coord, y_coord, offset, label)

def draw_markers(self):
'''
Expand All @@ -369,20 +290,25 @@ def draw_markers(self):
for point in self.map_widget.map_window.points_visible:
self.draw_marker(point)

def draw_text_marker_at(self, x_coord, y_coord, text, color="yellow"):
def draw_text_marker_at(self, x_coord, y_coord, icon_height, text):
'''
Draw Text Marker At Location on Map.
:param x_coord: X position for tile
:type x_coord: float
:param y_coord: y position for tile
:type y_coord: float
:param icon_height: icon height
:type icon_height: int
:param text: Text for marker
:type text: str
:param color: Color of text, default 'yellow'
:type color str
'''
color = "yellow"
# setting the size for the text marker
y_offset = 0
if icon_height:
# Position text just below icon
y_offset = icon_height / 2 + 1
zoom = Map.ZoomControls.get_level()
if zoom < 12:
size = 'size="x-small"'
Expand All @@ -395,8 +321,13 @@ def draw_text_marker_at(self, x_coord, y_coord, text, color="yellow"):
pango_layout = self.map_widget.create_pango_layout("")
markup = '<span %s background="%s">%s</span>' % (size, color, text)
pango_layout.set_markup(markup)
width, height = pango_layout.get_pixel_size()
self.cairo_ctx.save()
self.cairo_ctx.move_to(x_coord, y_coord)
# make sure to center the text under the point
if not y_offset:
# If no icon center text over position
y_offset = -height / 2
self.cairo_ctx.move_to(x_coord - width/2, y_coord + y_offset)
PangoCairo.show_layout(self.cairo_ctx, pango_layout)
self.cairo_ctx.stroke()
self.cairo_ctx.restore()
Expand Down Expand Up @@ -450,16 +381,12 @@ def expose_map(self):
'''
Expose the Map.
'''
width = self.map_widget.width
height = self.map_widget.height
width, height = Map.Tile.get_display_tile_limits()
self.load_ctx = LoadContext(0, (width * height))
center = Map.Tile(self.map_widget.position)

# python2 delta_h is 4, python3 4.5
delta_h = int(height / 2)
delta_w = int(width / 2)
center = Map.Tile.center
delta_w, delta_h = Map.Tile.get_display_center()

tilesize = self.map_widget.tilesize
tilesize = Map.Tile.get_tilesize()
self.map_widget.map_tiles = []
for i in range(0, width):
for j in range(0, height):
Expand Down Expand Up @@ -494,11 +421,10 @@ def scale(self):
:param pixels: Tile size in pixels, default=128
:type pixels: int
'''
# Need to find out about magic number 128 for pixels.
pango_layout = self.map_widget.map_scale_pango_layout()
pango_width, pango_height = pango_layout.get_pixel_size()

pixels = self.map_widget.pixels
pixels = Map.Tile.get_tilesize() / 2
self.cairo_ctx.save()

self.cairo_ctx.set_source_rgba(0.0, 0.0, 0.0) # default for black
Expand Down

0 comments on commit 519651b

Please sign in to comment.