Some interest was shown in how I was calculating frame scale. I'll post the
code in a separate message.
As I said in my previous message, all methods are convoluted and
inaccurate. Perhaps too inaccurate to meet anyone's needs.
That ObjectInfo() or ObjectGeography() call for a frame window would be very
nice to have. Pretty Please?
All methods must deal with the fact that MapInfo makes a best fit for a
Map window within a layout frame. If the aspect ratio of the frame is
different from the aspect ratio of the map view, then there is dead space
outside the area the map window covers.
Although fill frame with contents will cause MapINfo to fill in a frame's
dead space with an extended map view, it's still dead space with respect to
measuring the scale.
IF the frame is wider than the map view is, the dead space is on the left
and right. If the frame is narrower than the window, the dead space is on
the top and bottom.
So, all methods have to measure the layout view and the map view and compare
their aspect ratios, and use horizontal or vertical measurements to avoid
the dead space. But measuring the map view is problematical because of some
quirks in the way maps work. There are a couple of ways to do it.
Method 1:
Define the Map View by measuring the (Earth) distance between the top edge
and bottom edge, as well as the left edge and right edge. I take the map
extent MBR (e.g. MapperInfo (MAPPER_INFO_MINX) etc. ) and use the Distance
function to calculate north-south and east-west edistances, using the
minimum and maximum coordinates of the axis being measured and the average
coordinate of the other axis. If the frame is wider than the map, the scale
is the north-south distance over the frame height, otherwise it's the
East-west distance over the frame width.
This is a very good method if the map is oriented with north up, and the map
view isn't too wide, and the map projection's scale distortions don't add up
unreasonably in the east-west direction. It's horrible otherwise.
Method 2:
Define the Map view by using a Windows API call (GetClientRect) to get the
Map Window's client area extents. If the frame is wider than the map,
scale up the map's Zoom based upon the difference in aspect ratios.
Divide the final zoom by the frame width.
This is very accurate at close-in scales but as you zoom out, the accuracy
varies in a complicated way.But its accuracy is more consistent with
projection and zoom changes than Method 1.
There's also a big problem when the map has scrollbars. Although the
window client area ignores the scrollbars, the map's zoom and the map view
in the frame do not! I can't get GetScrollbarInfo() to return anything but
gibberish (perhaps they're not really MDI child window scrollbars), so only
use this without scrollbars.
Unfortunately, GetClientRect returns a rectangle of zero size when a window
is minimized. And when it's maximized, MapInfo's menus and docked toolbars
are part of the client area, similar to the scrollbar problem.
Method 3:
Similar to method 2, the Map widnow's scale (MapperInfo (MAPPER_INFO_SCALE))
is altered based upon the relative paper sizes of frame and map view. You
need the inside dimensions (GetClientRect()) as well as the outside
(GetWindowRect()) because you need the map's view in paper units.
This is generally less accurate than Method 2 (accumulated rounding errors,
I guess) and suffers from all of that method's other drawbacks as well.
Hope this helps
Spencer
___
MapInfo-L mailing list
MapInfo-L@lists.directionsmag.com
http://www.directionsmag.com/mailman/listinfo/mapinfo-l