Opened 17 years ago
Last modified 16 years ago
#2166 reopened defect
MAXSCALE bug
Reported by: | woodbri | Owned by: | sdlime |
---|---|---|---|
Priority: | normal | Milestone: | 5.0 release |
Component: | MapServer C Library | Version: | 5.0 |
Severity: | normal | Keywords: | |
Cc: | woodbri@…, dmorissette |
Description
I have found a problem with the MAXSCALE computation in mapserver. This showed up while looking at the AGG code, but might not have anything to do with that per say.
The layer (see below) has the MAXSCALE 4000100.0 but when I request a map at scale=4000000 the cities do not show up.
http://imaptools.com/cgi-bin/mapserv-4.99?mode=map&layers=all&scale=4000000&map=/u/data/maps/google-agg.map&mapxy=-87.65+41.85&map_size=450+350 http://imaptools.com/cgi-bin/mapserv-4.99?mode=map&layers=all&scale=3997555&map=/u/data/maps/google-agg.map&mapxy=-87.65+41.85&map_size=450+350
this one finally works:
This mapfile works fine in 4.10, here is a comparison of 4.10 and trunk with AGG.
Here is the layer in question:
LAYER NAME "US_Places" STATUS DEFAULT DATA "us/placenames2" TYPE ANNOTATION FILTER ([POP] >= 5000) MAXSCALE 4000100.0 CLASSITEM "POP" LABELITEM "NAME" CLASS NAME "Mega Cities" EXPRESSION ([POP] > 100000) SYMBOL "target-1" COLOR 0 0 0 LABEL TYPE TRUETYPE FONT "arial-bold" SIZE 9 POSITION AUTO BUFFER 5 COLOR 0 0 0 OUTLINECOLOR 245 245 231 #ANTIALIAS TRUE PARTIALS FALSE END END CLASS NAME "Major Cities" EXPRESSION ([POP] >= 25000 && [POP] < 99999) SYMBOL "target-2" COLOR 0 0 0 LABEL TYPE TRUETYPE FONT "arial-bold" SIZE 8 POSITION AUTO BUFFER 5 COLOR 0 0 0 OUTLINECOLOR 245 245 231 #ANTIALIAS TRUE PARTIALS FALSE END END CLASS NAME "Cities" EXPRESSION ([POP] >= 5000 && [POP] < 24999) SYMBOL "circle" COLOR 255 255 255 OUTLINECOLOR 0 0 0 SIZE 5 LABEL TYPE TRUETYPE FONT "arial-bold" SIZE 7 POSITION AUTO BUFFER 5 COLOR 0 0 0 OUTLINECOLOR 245 245 231 #ANTIALIAS TRUE PARTIALS FALSE END END END
Change History (24)
comment:1 by , 17 years ago
Status: | new → assigned |
---|
comment:2 by , 17 years ago
Yes, AGG and GD behave the same:
This compares AGG to GD both using current SVN http://imaptools.com/maps/compare-maps2.php?loc=99&ll=34.0011238+-118.3511872&address=&city=le+paso&state=tx&zipcode=&country=&asrv=1&amf=%2Fu%2Fdata%2Fmaps%2Fgoogle-aa2.map&msa=mapserv-4.99&bsrv=1&bmf=%2Fu%2Fdata%2Fmaps%2Fgoogle-agg.map&msb=mapserv-4.99&submit=Show
This compares GD to GD left on 4.10, right on SVN http://imaptools.com/maps/compare-maps2.php?loc=99&ll=34.0011238+-118.3511872&address=&city=le+paso&state=tx&zipcode=&country=&asrv=1&amf=%2Fu%2Fdata%2Fmaps%2Fgoogle-aa2.map&msa=mapserv-4.10&bsrv=1&bmf=%2Fu%2Fdata%2Fmaps%2Fgoogle-aa2.map&msb=mapserv-4.99&submit=Show
comment:3 by , 17 years ago
Cc: | added |
---|
comment:4 by , 17 years ago
Note that #2193 is a duplicate of this, there's some discussion there.
Steve
comment:5 by , 17 years ago
Steve: Can you share the US_Places, or at least a small subset? I want to be able to test that layer snippet and your URLs to see what the computations (in mapserv.c) really are. I think it's likely that's where the problem is.
Steve
comment:6 by , 17 years ago
Cc: | added |
---|
Steve: I believe I fixed it. The inconsistency in extent models caused this problem. The code in maptemplate.c should be using width/height minus 1 when building the extent from a point and a scale value, and then msCalculateScale should also use width-1 when figuring the map distance. When I made those changes the scale and cellsize were identical before and after msAdjustExtent as I would expect.
cc'ing Dan...
Dan: Does this have any impact on the MapScript zoomScale method? I admit I don't quite get that method mostly because it requires a current extent and I don't know why that is necessary. The code in maptemplate.c (used by mapserv.c) just uses a point and a scale value and doesn't need the existing extent. (as an aside I'd like to get all the zoom code for both the CGI and MapScript ported to C and popped in a mapzoom.c)
An easy test would be to zoom to a scale in PHP/MapScript and have MapServer compute the scale. If they aren't the same then I suspect the off by 1 error.
Changes are in r6529 if anyone'd care to test and report back.
Steve
comment:7 by , 17 years ago
Oh, I see that zoomScale uses a image coordinate for point input so that's why you need the existing extent, to do the conversion to map units. Still should test scale before and after, they should be the same. Again, check the change set...
Steve
comment:8 by , 17 years ago
I just rebuilt from SVN and it looks great! http://imaptools.com/maps/compare-maps2.php?loc=99&ll=34.0011238+-118.3511872&address=&city=le+paso&state=tx&zipcode=&country=&asrv=1&amf=%2Fu%2Fdata%2Fmaps%2Fgoogle-aa2.map&msa=mapserv-4.10&bsrv=1&bmf=%2Fu%2Fdata%2Fmaps%2Fgoogle-agg.map&msb=mapserv-4.99&submit=Show I think this can be closed from my perspective. Thank You.
comment:9 by , 17 years ago
Python MapScript tests now reporting this failure:
====================================================================== FAIL: MapExtentTestCase.testSetExtent: test the setting of a mapObj's extent ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/maptest.py", line 73, in testSetExtent self.assertAlmostEqual(test_map.scaledenom, 14.173236) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 71, in assertAlmostEqual raise AssertionError, \ AssertionError: 14.244458291457285 != 14.173235999999999 within 7 places
comment:10 by , 17 years ago
Howard: I guess that confirms my worry. At lines 423 and 424 in mapscript/swiginc/mapzoom.i can you try changing width and height to (width-1) and (height-1) and re-run the test?
Steve
comment:11 by , 17 years ago
I guess my question is does the test need to be updated because we were wrong all that time before, or does the test demonstrate we broke something?
Changing that to (width-1) results in three failures:
====================================================================== FAIL: ZoomScaleTestCase.testRecenter: recentering map returns proper extent ---------------------------------------------------------------------- Traceback (most recent call last): File "zoomtest.py", line 137, in testRecenter self.assertRectsEqual(new_extent, mapscript.rectObj(-50,-50,50,50)) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 137, in assertRectsEqual self.assertAlmostEqual(first.minx, second.minx) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 71, in assertAlmostEqual raise AssertionError, \ AssertionError: -49.494949494949495 != -50.0 within 7 places ====================================================================== FAIL: ZoomScaleTestCase.testZoomInScale: zooming in to a specified scale returns proper extent ---------------------------------------------------------------------- Traceback (most recent call last): File "zoomtest.py", line 147, in testZoomInScale self.assertRectsEqual(new_extent, mapscript.rectObj(-25,-25,25,25)) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 137, in assertRectsEqual self.assertAlmostEqual(first.minx, second.minx) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 71, in assertAlmostEqual raise AssertionError, \ AssertionError: -24.494949494949495 != -25.0 within 7 places ====================================================================== FAIL: ZoomScaleTestCase.testZoomOutScale: zooming out to a specified scale returns proper extent ---------------------------------------------------------------------- Traceback (most recent call last): File "zoomtest.py", line 157, in testZoomOutScale self.assertRectsEqual(new_extent, mapscript.rectObj(-100,-100,100,100)) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 137, in assertRectsEqual self.assertAlmostEqual(first.minx, second.minx) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 71, in assertAlmostEqual raise AssertionError, \ AssertionError: -99.494949494949495 != -100.0 within 7 places ----------------------------------------------------------------------
comment:12 by , 17 years ago
You did hight-1 too correct? What does 4.10 output, nothing I assume.
Steve
comment:13 by , 17 years ago
It looks like:
dX = dfDeltaX/((double)width-1); dY = dfDeltaY/((double)height-1);
There were no failures in mapzoom in 4.10 AFAIK
comment:14 by , 17 years ago
I don't understand that code very well (zoomScale) do there may be another place to change. The code at lines 423/4 is only for converting from image to map coordinates. At line 437 there is another block using width/height for actually doing the extent computation. Try changing width/height there too.
Steve
comment:16 by , 17 years ago
I don't see how that could affect things, so yes, wierd. I also see that the test isn't testing what I'd thought. I think we need a test of the scale before and after zooming. For example, if the requested scale is 50,000 in the call to zoomScale then that's what the computed scale should be after an extent is computed.
Testing the extent just tells us if things are consistent (e.g. I bet it works with width/height minus one in those couple of places), but not if they are correct.
Steve
comment:17 by , 17 years ago
I have updated one mapscript test that was complaining about a different scaledenom
====================================================================== FAIL: MapExtentTestCase.testSetExtent: test the setting of a mapObj's extent ---------------------------------------------------------------------- Traceback (most recent call last): File "maptest.py", line 73, in testSetExtent self.assertAlmostEqual(test_map.scaledenom, 14.244458) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 71, in assertAlmostEqual raise AssertionError, \ AssertionError: 14.244458291457285 != 14.244458 within 7 places
Updated in r6726.
comment:18 by , 17 years ago
Actually, the old failure was:
====================================================================== FAIL: MapExtentTestCase.testSetExtent: test the setting of a mapObj's extent ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/maptest.py", line 73, in testSetExtent self.assertAlmostEqual(test_map.scaledenom, 14.173236) File "/Users/hobu/svn/mapserver/mapscript/python/tests/cases/testing.py", line 71, in assertAlmostEqual raise AssertionError, \ AssertionError: 14.244458291457285 != 14.173235999999999 within 7 places
comment:21 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Declaring it dead (for now :)
comment:22 by , 17 years ago
Cc: | added; removed |
---|
comment:23 by , 16 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
comment:24 by , 16 years ago
I've recently updated from 4.8.6 to 5.0.2 and fallen foul of this defect, where layers are not visible when I would expect them to be.
I'm in OSGB Projection (epsg:27700) but I didn't include this information in my sample mapfiles, in case it was a projection related issue. My implementation uses mapscript rather than the cgi mapserv process, but I have been testing using shp2img.
4.8.3 Mapfile
MAP EXTENT 200000 200000 266145 266145 IMAGECOLOR 255 255 255 IMAGETYPE png RESOLUTION 96.000000 SIZE 500 500 STATUS ON TRANSPARENT TRUE UNITS METERS NAME "Base" IMAGEQUALITY 75 LEGEND IMAGECOLOR 255 255 255 KEYSIZE 20 10 KEYSPACING 5 5 LABEL SIZE MEDIUM TYPE BITMAP BUFFER 0 COLOR 0 0 0 FORCE FALSE MINDISTANCE -1 MINFEATURESIZE -1 OFFSET 0 0 PARTIALS TRUE END POSITION LL STATUS OFF END WEB IMAGEPATH "c:\tmp\" IMAGEURL "/" QUERYFORMAT text/html LEGENDFORMAT text/html BROWSEFORMAT text/html END LAYER MAXSCALE 500000 MINSCALE 0 NAME "Land" STATUS ON TRANSPARENCY 100 TYPE RASTER UNITS METERS DATA "C:\Documents and Settings\Administrator\Desktop\gb\gbpng.tif" END END
5.0.2 Mapfile
MAP EXTENT 200000 200000 266145 266145 IMAGECOLOR 255 255 255 IMAGETYPE png RESOLUTION 96.000000 SIZE 500 500 STATUS ON TRANSPARENT TRUE UNITS METERS NAME "Base" OUTPUTFORMAT NAME "png" MIMETYPE "image/png" DRIVER "GD/PNG" EXTENSION "png" IMAGEMODE "PC256" TRANSPARENT TRUE END PROJECTION "init=epsg:27700" END LEGEND IMAGECOLOR 255 255 255 KEYSIZE 20 10 KEYSPACING 5 5 LABEL SIZE MEDIUM TYPE BITMAP BUFFER 0 COLOR 0 0 0 FORCE FALSE MINDISTANCE -1 MINFEATURESIZE -1 OFFSET 0 0 PARTIALS TRUE END POSITION LL STATUS OFF END WEB IMAGEPATH "c:\tmp\" IMAGEURL "/" QUERYFORMAT text/html LEGENDFORMAT text/html BROWSEFORMAT text/html END LAYER DEBUG 5 MAXSCALEDENOM 500000 MINSCALEDENOM 0 NAME "Land" STATUS ON TRANSPARENCY 100 TYPE RASTER UNITS METERS DATA "C:\Documents and Settings\Administrator\Desktop\gb\gbpng.tif" END END
GBPNG.TFW
333.333333333 0.000 0.000 -333.333333333 166.66666666 649833.33333333
Any 1000x1000 image should work.
Running shp2img against 4.8.3 will produce a valid image. Running shp2img against 5.0.2 does not.
Code is currently
center_y = (extent.miny+extent.maxy)/2.0; md = (width-1)/(resolution*msInchesPerUnit(units, center_y)); /* remember, we use a pixel-center to pixel-center extent, hence the width-1 */ gd = extent.maxx - extent.minx; *scale = gd/md;
For the extents in the mapfiles, this gives a scale of 500997
Previously, using (width) instead of (width-1), we would have had 499993
My desktop GIS product seems to agree with the calculation to result in 499993, judging by the bbox it requests when zooming to 1:500,000
Full mapserver-users conversation is here - http://www.nabble.com/Problems-calculating-MAXSCALES-td18926188.html
Do AGG and GD behave the same or not? If not I can't see how this is a scale bug... Hard to debug otherwise.
Steve