[GRASS5] embedding GRASS display into my app

Glynn Clements glynn.clements at virgin.net
Thu Apr 8 22:15:26 EDT 2004


David Piasecki wrote:

> I started thinking about writing my own d.where that doesn't require 
> the interaction with the GRASS monitor. I took a look at the current 
> d.where, and it has a function that accepts screen (x,y) pixel 
> coordinates, and you can convert to Lat/Lon. I was thinking I could 
> remove a good chunk of code that interacts with the user and simply 
> have my program pass in the screen coords. That doesn't seem too bad to 
> me. I'm just nervous about getting it to compile since I haven't 
> actually been able to compile GRASS on my Mac yet (I only have the 
> binary). What do you think?

The core functionality of d.where is its use of the D_* functions from
setup.c and cnversions.c (both in src/libes/display). D_setup()
(called from main) reads the region and display boundaries from the
monitor, and passes them D_do_conversions() to set up the
transformation coeffecients. The various D_?_to_?_{row,col} functions
then convert between map coordinates, screen coordinates and raster
indices.

Much of the complexity derives from two factors:

1. The ability to create "frames" within the monitor means that the
map may be positioned and scaled to fit an arbitrary rectangle, not
necessarily the entire "screen".

2. The map is scaled so that one dimension exactly fits the current
frame. The other dimension is determined by the need to preserve the
aspect ratio, and will be smaller than the corresponding dimension of
the frame. The image will be centred in that dimension.

E.g. if you display a square region in a frame whose width is greater
than its height, the image will fill the frame vertically and be
centred horizontally.

> Yes, my PNG image was created with the PNG driver. Basically, I want to 
> be able to get Lat/Lon values for locations clicked on, and I want to 
> be able to zoom, create a new PNG map, and reload.
> 
> It sounds like you're telling me that once I write the PNG file, it 
> will no longer be present on the monitor, so I won't be able to get geo 
> coords from it.

The PNG file is only written when the monitor is terminated. You can't
do anything with the monitor after that (except re-start it).

> So I should grab the corners before creating the PNG 
> and interpolate the rest.

The obvious sequence is:

1. d.mon start=PNG
2. d.vect ... (or other drawing commands)
3. Obtain map coordinates of top-left/bottom-right pixels (similar to
   d.where)
4. d.mon stop=PNG
5. Read PNG file

> What happens when I want to display a larger 
> map? If I had a map the size of the U.S. or the world, then I imagine 
> the results of standard linear interpolation will vary depending on 
> which projection I choose to use.

The correspondence between map coordinates (whether UTM metres,
lat/lon degrees etc) and screen coordinates is limited to uniform
scaling plus an offset, i.e.:

	screen_x = (map_x - x0) * scale
	screen_y = (map_y - y0) * scale

where x0, y0 and scale are constant for any given d.vect/d.rast/etc
operation.

The conversion between projected (e.g. UTM) coordinates and Lat/Lon is
a separate issue. d.vect, d.rast etc don't perform projections; you
have to do that separately (with r.proj, v.proj etc).

> Expanding on that idea, perhaps before doing a stop=PNG (which I assume 
> closes the display), I can get a small number of geo coordinates at 
> intervals in the image (say 100x100 points). I imagine that wouldn't 
> add too much time. Then I could close the monitor and interpolate 
> between the various points. I might get a little better accuracy with 
> the bigger maps that way. What do you think?

If you want to display lat/lon coordinates as well as map coordinates
(assuming that the map isn't itself lat/lon), use the pj_* functions
from the proj library. d.where provides an example of this.

IOW, you only need to two samples for the map <-> screen projection. 
Any map <-> lat/lon projections can be done afterwards, and don't
involve the monitor.

-- 
Glynn Clements <glynn.clements at virgin.net>




More information about the grass-dev mailing list