[mapserver-users] QuerybyPoint blues
Hankley, Chip
Chip.Hankley at gasai.com
Wed Oct 2 07:17:41 PDT 2002
Guys...
The query function that I use is below... the mapfile definition is quite
simple... note the TEMPLATE line.
LAYER
NAME "ZIP"
DATA "Vector\Rock_ZIP"
TEMPLATE "ttt_query.html" #Important Line!
STATUS OFF
TYPE POINT
CLASS
COLOR 255 0 0
END
END
The variables being passed are:
$map - the map object
$coords - the coordinates (image coordinates) of the click
$Last_Extent - the map extent (map coordinates)
$lyr_name - the name of the layer in the mapfile
There are several things to note about this function.
1) You don't have to specify RESULT FIELDS in the metadata.
It returns everything from the dbase record.
2) One thing I found w/ querybypoint was that if I wanted
to query a layer that was lower in the drawing order (i.e.
it was on the bottom), I would often get the "no records
returned" error... even when I was OBVIOUSLY clicking right
on the object. What this function does is turn all of the
layers that you are not querying off before doing the query
then turns them back on at the end. The result is that I get
much more consistent query results. The end user never sees
the "on" and "off" of the layers... it just happens on either
side of the query.
Use the print_r function in PHP to examine the results of the function. The
variable $result is a multi-dimensional array. The code now does MS_SINGLE,
but it could just as easily do MS_MULTIPLE. You could also change this
easily to do a querybypoint or rectangle, depending on what $coords look
like when they are passed.
Cheers!
Chip Hankley
function query_map($map, $coords, $Last_Extent, $lyr_name) {
//First, loop through all the layers, making an associative
// array of how they are currently set. We are going to then
// turn all of the layers off. Later (a few lines down) we
// will turn the query layer on. At the end of the function,
// we will turn the ON layers back on.
$onLayers = array();
foreach ($map->getAllLayerNames() as $a) {
$Layer = $map->GetLayerByName($a);
if ($Layer->status) {
array_push($onLayers, $a);
$Layer->set("status",0);
}
}
//Get the Layer being queried
$Layer = $map->GetLayerByName("$lyr_name");
$data_nm = $Layer->data;
$data_pth = $map->shapepath;
$shpPath = $data_pth . $data_nm;
//Set the layers status ON (b/c it might not be...)
$Layer->set("status", 1);
//Convert Image Coords to Map Coords
$rect_coords = explode(";", $coords);
$ll_coord = explode(",", $rect_coords[0]);
$ImgWidth = $map->width;
$ImgHeight = $map->height;
$x = (($ll_coord[0] / $ImgWidth) * ($Last_Extent[2] - $Last_Extent[0])) +
$Last_Extent[0];
$y = $Last_Extent[3] - (($ll_coord[1] / $ImgHeight) * ($Last_Extent[3] -
$Last_Extent[1]));
$click_pt = ms_newPointObj();
$click_pt->setXY($x, $y);
//Query the Map at the point clicked
@$map->queryByPoint($click_pt, MS_SINGLE, -1);
$count_results = $Layer->getNumResults();
if ($count_results > 0) {
$Layer->open($map->shapepath);
$result=array();
//create a dynamic layer in which to display the selectd record
$qryLyr = ms_newLayerObj($map);
$qryLyr->set("status", MS_ON);
$qryLyr->set("name", "Temporary Query Layer");
$qryLyr->set("type", $Layer->type);
$qryLyrClass = ms_newClassObj($qryLyr);
$qryLyrClass->set("color", $map->addColor(255, 0 ,0));
//set the type and size
if ($Layer->type==0) { //Point
$qryLyrClass->set("symbol", 7);
$qryLyrClass->set("size", 18);
}
elseif ($Layer->type==1) { //Line
$qryLyrClass->set("symbol", 2);
$qryLyrClass->set("size", 3);
}
elseif ($Layer->type==2) { //Polygon
$qryLyrClass->set("symbol", 1);
$qryLyrClass->set("size", 2);
}
//get the names of the fields in the shapefile
if ($dbi = dbase_open($shpPath . ".dbf", 0)) {
$db_fields = array_keys(dbase_get_record_with_names ($dbi, 1));
dbase_close($dbi);
//the SHAPE field is returned as 'delelted', so use
// a callback function to remove it.
$db_fields = array_filter($db_fields, "ResultFieldFilter");
}
for ($i=0; $i<= $count_results-1; $i++) {
$oRes = $Layer->getResult($i);
$oShape = $Layer->getShape($oRes->tileindex,$oRes->shapeindex);
$temp=array();
foreach($db_fields as $a) {
$tRes = $oShape->values[$a];
if ($tRes == "") {
$tRes = " ";
}
$temp[$a] = $tRes;
}
$result[$i] = $temp;
unset ($temp);
//Move the $oShape and $qryLyr variable to
// global scope to be called before drawing
// the map
$GLOBALS["oShape"] = $oShape;
$GLOBALS["qryLyr"] = $qryLyr;
}
}
else $result = "No records returned";
//Turn the query layer off, then turn all of
// the layers that were on, back on
$Layer->set("status", 0);
foreach ($onLayers as $a) {
$Layer = $map->GetLayerByName($a);
$Layer->set("status",1);
}
return $result;
}
//Callback function to remove the 'deleted' value that
// is returned for the SHAPE field
function ResultFieldFilter($var) {
return($var <> 'deleted');
}
More information about the MapServer-users
mailing list