When learning to use mapserver and mapscript, the first steps have been to display, zoom and pan. Zooming and panning is quite easy, it is just a line like
$map->zoompoint($zoomfactor,$clickpoint,$map->width,$map->height,$mapextent);
where $map is a mapboject, $zoomfactor is a number telling how many times to zoom in or out, positive for zoom in, negative for zoom out, $clickpoint is a pointobject of the location of the click in image coordinates.
Then enter the urge to do a query as well – but not much luck. I reused the same $clickpoint and tried
$map->queryByPoint($clickpoint, MS_SINGLE, 1);
(after doing some adjustments in the map file) but to no luck. Digging into the kmap source code, I understood after a while that the coordinates needed to be in map coordinates and not image coordinates. That is just a simple linear transformation, just with the little snag that the y-coordinates go the opposite direction in the image than in the map. Kmap called the transformation function twice, once for each koordinate, I preferred to make one function for the two-dimentional transformation:
function pix2geo($mapx,$mapy,$minx,$miny,$maxx,$maxy,$sizex,$sizey) // $mapx and $mapy: image coordinates of point of interest // $minx, $maxx,$miny, $maxy map extent in map coordinates // $sizex and $sizey, width and height of image { list($miny,$maxy)=array($maxy,$miny); // swaps miny and max y since the coordinates acsends upwards in the map, downwards in the picture $geopoint=array(); foreach( array('x','y') as $dim){ $p=array(); foreach(array('map','min','max','size') as $par){ $name="$par$dim"; $p[$par]=$$name; } $geowidth=$p['max']-$p['min']; $geopoint[$dim]=$p['map']/$p['size']*$geowidth+$p['min']; } return(array($geopoint['x'],$geopoint['y'])); }
This can be used like:
list($geoX,$geoY)=pix2geo($_GET['MAP_x']*1,$_GET['MAP_y']*1,$minx,$miny,$maxx,$maxy,$map->width,$map->height); $geopoint=ms_newpointObj(); $geopoint->setXY( $geoX,$geoY); $map->queryByPoint($geopoint, MS_SINGLE, 1);
followed by getNumResults for each layer, getResult, getShape and finally getting the relevant values out of the shape.
I have to admit, I simplified things a bit at the beginning. The point needs to be in the projection of the queried data set. As I have the queried dataset in geographical projection and want to have the map in utm, I still have a problem there..