mapnav.icn: Procedures for navigating a map interactively

procedure mapinit:         initialize navigator
procedure mapgen:          invoke callback to redraw the map
procedure mapproj:         compute map projection
procedure mapevent:        navigate map as directed by action e

link mapnav
May 7, 2002; Gregg M. Townsend
This file is in the public domain.

These procedures implement a user interface for browsing a map
that is drawn using a simple rectangular projection.  The
following interface actions are provided, if not overridden
by the calling program:
   The arrow keys pan the display.
   Shifted arrows pan by a smaller amount.
   The + and - keys zoom in and out.
   The 0, 1, or HOME key resets the original display.
   The q key causes an immediate exit.
   Sweeping a region with the mouse zooms the display.
   Resizing the window causes it to be redrawn.

The calling program provides the main loop and a drawing
procedure; this module handles the interface and computes
the output transformation.

mapinit(win, proc, arg, xleft, xright, ytop, ybottom, m) initializes.
mapgen(win, proc, arg) generates the map by invoking the callback.
mapevent(win, e) handles a window event, possibly invoking a callback.
mapproj(win) returns the projection used in the window.

The win argument is optional in all procedures but can be used
to supply the correct graphics context.  The window argument is
always supplied to the callback procedure.
____________________________________________________________

Typical use is like this:

procedure main(...)
   ... initialize ...
   ... load data ...
   ... open window ...
   mapinit(draw, ...)
   mapgen()
   case e := Event() of {
      ... handle custom events ...
      default: mapevent(e)
      }
end

procedure draw(win, p, arg)
   ... create list of coordinates ...
   ... L2 := project(p, L1) ...
   ... draw map ...
end
____________________________________________________________

mapinit(win, proc, arg, xleft, xright, ytop, ybottom, m) configures
the navigator.  proc is a drawing procedure to be called whenever
the window needs to be redrawn.  arg is an arbitrary value to be
passed to proc along with the transformation parameters.

xleft, xright, ytop, and ybottom specify the range of coordinates
for the data that is to be displayed.  For both the x and y pairs,
the values must differ but either can be the greater.

The value of m (default 1.0) specifies the aspect ratio of the
input units.  If the input data is in units of latitude and
longitude, choose a central latitude for projection and pass
the cosine of that latitude as m.
____________________________________________________________

mapgen(win, proc, arg) calls the drawing procedure proc to draw a
map.  win is optional, and proc and arg default to the values
registered by the last mapinit() call.

The drawing procedure is called as
   proc(win, pj, arg)
where pj the projection returned by mapproj(win).

The drawing procedure should project and display its data.
It must ensure that the resulting coordinates lie inside
the range -32768 <= v <=32767 before passing them to Icon
drawing functions.  (See also clipping.icn.)
____________________________________________________________

mapevent(win, e) handles a window event.  If e is recognized as
an interface action, the map parameters are altered and mapgen()
is called, resulting in a call to the drawing procedure.  For
a panning action, the window contents are first shifted;
otherwise, the window is first erased.  mapevent() fails if
e is not recognized.

The calling program can intercept and override any action it does
not want handled by the navigator.  This can be used to customize
the interface -- for example, to use "0" for something other than
"reset zooming".  However, any &resize event, even if handled by
the caller, should be passed to the navigator to allow it to
properly adjust its view of the world.
____________________________________________________________

mapproj(win) returns a rectangular projection (see cartog.icn)
that maximizes the display of the currently selected data range
for viewing in the center of window win.  The "selected data range"
is that passed to mapinit() and subsequently modified by any
zooming or panning actions.

Source code | Program Library Page | Icon Home Page