Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I've noticed in a current project that MapServer seems to get the map scale wrong, or then I'm wrong, but don't see how.

My mapfile contains the following definitions:

RESOLUTION 72   # this is the default, but I set it explicitly, just to make sure

PROJECTION
    "init=epsg:21781"  # = CH1903 LV 03, which uses meters as coordinate units
END

LAYER
    NAME "one"
    MAXSCALEDENOM 7500
    ...
END

LAYER
    NAME "two"
    MINSCALEDENOM 7502
    ...
END

If I only display these two layers, I should definitely be able to get an empty map at scale 1:7,501.

I have written a simple map viewer application to verify this. My viewer also assumes a screen resolution of 72 DPI, just like MapServer. However, it turns out that both layers are invisible around map scale 1:5,803. I would have to adjust my viewer to 93.062 DPI to get the empty map at 1:7,501. Why is this?

Just for reference, this is how I calculate the map scale in my viewer:

double imageWidthInPixels = ...;   // passed to mapserv.exe (via 'map_size' arg.)
double extentWidthInMeters = ...;  // = extent's xmax-xmin (via 'mapext' arg.)

// constants:
const double dpi = 72.0;
const double inchesPerPixel = 1.0 / dpi;
const double inchesPerMeter = 1.0 / 0.0254;

double inchesOnScreen = inchesPerPixel * imageWidthInPixels;
double inchesInReality = inchesPerMeter * extentWidthInMeters;

double scaleDenominator = 1 / (inchesOnScreen / inchesInReality);

How could this go wrong?

P.S.: I am quite certain that I have the right extentWidthInMeters since I can easily derive it from the extent. (I'm using the Swiss projected coordinate system CH1903 LV03, which already uses meters as coordinate units.)


UPDATE: It seems as if the inaccuracy was partly caused by differing aspect ratios of the map image control in my viewer and the extent sent to MapServer. I've now made sure that only map extents are passed to MapServer that have the same aspect ratio as my map image control. But some small error still remains: The map is now empty around scale 1:7'489 instead of 1:7'501.

share|improve this question
    
The difference between 1:7489 and 1:7501 is explainable by rounding to whole pixel coordinates on any display that is up to 625 pixels wide. If there's another error (perhaps due to multiple stages of rounding or from rounding in the shorter vertical direction) of just one more pixel, then this difference would not be unexpected on a display even twice as wide. Moreover, the ratio of meridian scales to horizontal scales in this projection alone could explain a discrepancy of this size. Altogether then, you should be satisfied with what you're getting. –  whuber Oct 29 '10 at 19:03
    
@Mapperz, why do you ask this? What's wrong with this question? –  stakx Oct 29 '10 at 19:57
    
@whuber, if you post this as an answer, I'll accept it. Your explanation of rounding to integer pixel coordinates seems perfectly believable. –  stakx Oct 29 '10 at 20:04
add comment

2 Answers 2

up vote 3 down vote accepted

I was happy to see @mwalker's answer but the comments that follow it indicate it did not end up addressing the OP's problem (as later modified). As it turns out in the updated version, we're actually talking about a much smaller discrepancy: the difference between 1:7489 and 1:7501 (0.16%). This amount is explainable by rounding to whole pixel coordinates on any display that is up to 1/(0.16%) = 625 pixels wide. If there's another error (perhaps due to multiple stages of rounding or from rounding in the shorter vertical direction) of just one more pixel, then this difference would not be unexpected on a display even twice as wide. Moreover, the ratio of meridian scales to horizontal scales in this projection could by itself explain a discrepancy of this size. Altogether then, a transition of image control at 1:7489 where 1:7501 is desired should be considered to be perfectly accurate.

share|improve this answer
add comment

Your screen is probably running at 96 DPI, not 72.

Computing scale as a ratio of 1:n is a risky business at best with a web map. If your map is being displayed on an average monitor, you can assume 96DPI. But that will be wrong on (say) a mobile device, or a projector, or a 19" LCD running at 640x480 resolution, etc.

It is better to produce a scale bar of a known width and then label its width.

Your loss of precision is likely due to the conversion factor - try:

const double inchesPerMeter = 1.0 / 0.0254000508;
share|improve this answer
    
I'm aware that my display has a resolution much higher than 72 DPI, and that on-screen distances will be wrong when I tell MapServer that it should assume my screen is 72 DPI. But that's not the issue here. The real problem here is that both MapServer and my viewer arrive at their map scales purely by computation, and they end up with different results for an unknown reason. This is the problem, not correct distances on the screen. Those will eventually be taken care of by telling MapServer the correct DPI value, but first, I must be confident that MapServer does what I expect it to. –  stakx Oct 29 '10 at 19:20
    
Also, note that I'm not going to display the map scale in any way -- not in numeric form, not as a scale bar. The only reason I'm interested in scale is for scale-dependent visibility of layers. –  stakx Oct 29 '10 at 19:25
    
@stakx It's probably worthwhile to delve into the MapServer code and find out which constants they use for conversion, then. Once all the constants are matched up you should see the expected results. –  mwalker Oct 29 '10 at 19:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.