[Mapserver-users] [PHP/MapScript] Search for attribute in a shapefile

Frank Broniewski Frank.Broniewski at mnha.etat.lu
Thu Jun 17 08:13:19 EDT 2004


Dear List

With the help from some of you I managed to solve my problems on
querying an shapefile and zoom to the found shape (polygon, point etc.).
For solving my problems I have browsed the mailing list archives and the
docs alot but found only little help in those. Therefore I want to
contribute my code for others with similar problems, so they get some
help in coding their programs. The most difficult thing to understand
for me was the interaction of the queryByAttribute method and the zoom
and draw methods and how I get finally some results from that query.
I'm not a programmer by nature, only geographer, so the objectoriented
stuff is sometimes hard to understand for me; all those methods and
members and what is returnd by what method :-)

I've put my code in two parts, mainly a function and the call of the
function in the main script:

Call of the function:
________________________________________________________________________
__________________
/*
This is where I start searching for a Location
which in my case means: I have location names stored in a point
shapefile
I query an attribute field (called toponyme) and get one (or possibly
more) matches,
then I zoom to the found match
variables and names are partly german, but for theory the code should be
understandable :-)
*/
// if the user entered a string in the queryfield
if ($_POST['suche'] != "") {
  // write the querystring into the variable $SuchOrt
  $SuchOrt = $_POST['suche'];
  // call the function Searchbyname and forward the Querystring and the
mapobj
  // returns wether a string or an array
  // the string will contain an errormsg -> nothing found or an array
with 4 coordinates
  // grouped around the the matching shape of the query
  $extent = SearchByName($SuchOrt,$map);
// here I test what was returned by the function Searchbyname
  if (is_array($extent)) {
  // if it is an array set the mapextent to the new coordinates ...
    $map->setextent($extent[0], $extent[1], $extent[2], $extent[3]);
  } else {
  // otherwise get the current extent
  // which is stored in a hidden field in my form
    $extent_to_set = explode(" ",$_POST['extent']);
  // set the extent to the current extent
  // I'm not sure if necessary, but I don't want to test
    $map->setextent($extent_to_set[0], $extent_to_set[1],
$extent_to_set[2], $extent_to_set[3]);
  // print out the errormsg generated by the function
    echo "<div id=\"error\">"
    ."<p>Fehler:</p><p>"
    .$extent
    ."</p></div>";
  }
}
________________________________________________________________________
__________________

Here comes my function:

________________________________________________________________________
__________________
// gets 2 parameters, the mapobj as reference and the location to search
for as string
function SearchByName($SuchOrt,&$MapObj) {
  // set to maximum extent of map for searching whole map and not only
the visible extent
  $MapObj->setextent(42000, 53000, 111000, 141000);
  // get the Layer which should be queried
  $mySearchLayer = $MapObj->getLayerByName("Bezeichnung");
  // set the Layer to active, in case it isnt (I'm not sure if
necessary)
  $mySearchLayer->set("status", 1);
  // query the layer for the searchclause and return only 1 find (if
more than one)
  $mySearchLayer->queryByAttributes("Toponyme", $SuchOrt,"MS_SINGLE");
  // multiple finds are more difficult to implement, as one needs to
calculate a boundingbox around all finds
  // maybe later :-)
/*  $numberofresults = $mySearchLayer->getNumResults();
  for ($i = 1; $i <= $numberofresults; $i++ ) {
     $myLoc = $mySearchLayer->getResult($i);
  }
*/
  // if we found something, start ...
  // should maybe be tested earlier like:
  // if ($mySearchLayer->queryByAttributes("Toponyme",
$SuchOrt,"MS_SINGLE"); == "MS_SUCCESS") { ...
  if ($mySearchLayer->getNumResults() > 0) {
    // get the first result of the querybyattributes
    // which selects afaik the shapes in a shapefile which meet the
searchcriterium
    // ??? comparable to sql-query in arc 8.x ???
    $myResult = $mySearchLayer->getResult(0);
    // open the layer for getting the shapefile in it
    $mySearchLayer->open();
    // gets the shapefile as Obj with the parameters tileindex and
shapeindex
    // which returns me the selected shape
    $myShape = $mySearchLayer->getShape($myResult->tileindex,
$myResult->shapeindex);
    // get the outer limits of the shape as rectangle
    $myShapeExtent = $myShape->bounds;
    // here I extract the boundary coordinates for adding some buffer
around
    // which also helps, if your query is on a point shapefile
    // because afaik minx and maxx have to be of different value
    // the other thing is, that you get some kind of close overview of
your found shape
    $minx = $myShapeExtent->minx;
    $minx -= 500;
    $maxx = $myShapeExtent->maxx;
    $maxx += 500;
    $miny = $myShapeExtent->miny;
    $miny -= 500;
    $maxy = $myShapeExtent->maxy;
    $maxy += 500;
    // write the stuff into an array for returning to the main script
    $arr_extent = array(
      $minx,
      $miny,
      $maxx,
      $maxy
    );
    // return the extent in array
    return $arr_extent;
  // otherwise ...
  } else {
    // nothing was found, so create error msg
    $fehler = "Kein Objekt mit Namen <b></b>".$SuchOrt."</b> im
Kartenausschnitt gefunden!";
    // return the error to the main script
    return $fehler;
  }
}
________________________________________________________________________
__________________

And again thanks for your help! But be prepared, I might come back ;-)

Greetings from Luxembourg
                                                      
Frank Broniewski
Musée National d'Histoire et d'Art





More information about the mapserver-users mailing list