legend scale dependency issues

percy percyd at PDX.EDU
Wed Feb 14 15:39:27 PST 2007


I've stripped the code down to the bare minimum. The errant behavior 
persists!

Geologic faults turn on in the map (and show up in the DIV resulting 
from a map->draw()) at a scale of 500000. If I then zoom in sort of 
slowly, drawing a zoom rectangle just slightly smaller than the screen 
each time, they'll show up the legend at around 250000. The legend gets 
redrawn on every zoom.

If I use our pre-defined zoom levels, the faults don't show up at 
250000, but they do show up at 100000. It sometimes seems like the 
legend is a step behind.

Same behavior if I use a normal legend instead of legend template.

Just for fun (!) I tried turning on legend items (naming the classes) 
for all of the other layers to see how they behaved. I had legend items 
coming and going at just weird times. This was what led me to think that 
it might be known bug in MapServer version 4.8.0-rc2

Below is the stripped down code, it get's called by a little AJAX-y 
javascript function that stuffs the results into the innerhtml on a 
popup tab. Hmmmmmmm, I wonder if the AJAX-y stuff is interfering 
somehow... :-)

<?php // legend.php
// set error reporting
ini_set("display_errors", 1);
ini_set("display_startup_errors", 1);
error_reporting (E_ALL);

header("Content-type: text/html charset=utf-8");

if (isSet ($_REQUEST['extent']) &&
     isSet ($_REQUEST['mapfile']) &&
     isset($_REQUEST['layers'])
   ) {
	$extent = $_REQUEST['extent'];
	$mymap = './map/' . $_REQUEST['mapfile'];
	$layers=$_REQUEST['layers'];
} else {
	print "<p>Invalid query string: ".$_SERVER['QUERY_STRING']."</p>";
	exit;
}
//first set the exyent, this should take care of the scale dependencies
$map = ms_newMapObj($mymap);
	if ($extent['x1'] && $extent['y1'] &&
	    $extent['x2'] && $extent['y2']) {
		// set the extent
		$map->setExtent($extent['x1'], $extent['y1'], $extent['x2'], 
$extent['y2']);
	}
//now handle turning the layers on or off
if (count($layers)>0) {
   for ($i=0; $i<$map->numlayers; ++$i) {
     $oLayer=$map->getLayer($i);
     if (in_array($oLayer->name,$layers)) {
       $oLayer->set("status",MS_ON);
     } else {
       $oLayer->set("status",MS_OFF);
     }
   }
}
$my_html=$map->processLegendTemplate(null);
echo $my_html;
?>

Daniel Morissette wrote:
> The code that you included in your last email seems to be missing the 
> stuff that handles the zoom. i.e. a comment suggests that you create a 
> $extent_obj for this, which is either initialized from the values in the 
> $extent[] array, or from the $map->extents which have just been set from 
> the contents of the $extent[] array, so in both case you get more or 
> less the same result minus the width/height ratio adjustment that 
> MapServer does automatically on $map->setExtent()... and there is 
> nothing to adjust the extents to reflect the last zoom operation and 
> pass that to $map->setExtents().
> 
> What does the $extent[] array contain when this code starts being 
> executed? Is it the extents before or after applying the zoom?
> 
> Daniel
> 
> percy wrote:
>> Thanks Daniel, but I've been testing this pretty hard as you can see 
>> from the code snippet below (testing parts are commented out). The 
>> layers are getting turned on and off correctly in the section right 
>> before the call to processlegendtemplate...
>>
>> $map = ms_newMapObj($mymap);
>>     if ($extent['x1'] && $extent['y1'] &&
>>         $extent['x2'] && $extent['y2']) {
>>         // set the extent
>>         $map->setExtent($extent['x1'], $extent['y1'], $extent['x2'], 
>> $extent['y2']);
>>
>>         // set up extent object for use in zoom (!?!?)
>>         $extent_obj = ms_newRectObj();
>>         $extent_obj->setExtent($extent['x1'], $extent['y1'], 
>> $extent['x2'], $extent['y2']);
>>     } else {
>>         $extent_obj = ms_newRectObj();
>>
>> $extent_obj->setExtent ($map->extent->minx, $map->extent->miny, 
>> $map->extent->maxx, $map->extent->maxy);
>>     }
>> //now handle turning the layers on or off
>> if (count($layers)>0) {
>> //echo "I see more than 0 layers\n";
>>   for ($i=0; $i<$map->numlayers; ++$i) {
>>     $oLayer=$map->getLayer($i);
>> //    echo "got layer number".$i;
>>     if (in_array($oLayer->name,$layers)) {
>>       $oLayer->set("status",MS_ON);
>> //      echo "turning on layer  ".$oLayer->name;
>> //      echo $oLayer->status;
>>     } else {
>>       $oLayer->set("status",MS_OFF);
>> //      echo "turning OFF layer  ".$oLayer->name;
>>     }
>>   }
>> }
>> $my_html=$map->processLegendTemplate(null);
>> //echo $_SERVER['QUERY_STRING'];
>> echo $my_html;
>>
>>
>>
>> Daniel Morissette wrote:
>>> percy wrote:
>>>>
>>>> When you zoom in on the map, the scale dependencies all work great 
>>>> for the map, but the legend is always out of whack. I am using 
>>>> php/mapscript to generate a processlegendtemplate() request. For 
>>>> debugging this issue, I have also tried just a straight drawlegend() 
>>>> request and I get similarly odd behavior. The geologic faults, which 
>>>> are set to show up at a scale of 1:500,000 don't show up in the 
>>>> legend until zoomed in to around 1:100,000. (though sometimes if I 
>>>> zoom in small increments, they'll show up sooner...)
>>>>
>>>
>>> The problem could be related to the order in which you make calls in 
>>> your PHP script. The legend object uses the last calculated scale in 
>>> its tests to decide which layer/classes to include in the legend, so 
>>> if you call processlegendtemplate() before the extents and scale have 
>>> been updated to reflect the last zoom operation then you could get 
>>> this kind of behavior.
>>>
>>> I just did a quick check in the code and $map->setExtent() does 
>>> update the scale value, so if you call that with the right extents 
>>> before processing the legend then you should be fine.
>>>
>>> Daniel
>>
> 
> 

-- 
David Percy
Geospatial Data Manager
Geology Department
Portland State University
http://gisgeek.pdx.edu
503-725-3373



More information about the MapServer-users mailing list