[mapserver-users] Query by attributes with PHP/MapScript

Hankley, Chip Chip.Hankley at gasai.com
Wed Oct 2 10:30:38 EDT 2002


Armin,

Here's how I do it. This is an example using a zipcode, and a layer called
"ZIP." The key thing here is that a shapefiles records are base 1, whereas
mapscript views them as base 0. So, if you wanted to retrieve the first
record in your shapefile, you would refer to it as 'record 1' in dbase, and
'row 0' in mapscript.

You're right, there is no SQL like syntax. Basically what we are doing here
is VERY inefficient... we are looping through the records in the dbase doc
'til we get a match (also a logic problem in some cases... what if there are
two matches?).

One solution to this, if you want better performance, is to store your
attribute data in a database (MySQL for instance), with one of the fields
being row-id. You can then perform a real SQL query, return the row-id's,
then use the ->getExtent(<row-id>) method in MapScript.

If you don't care about performance, or your recordset is small, you could
always rework the conditional statement in this function to:

  1) Not break; on success
  2) Query more than one field...

Basically you'd just be writing a really complex conditional statement
(mimicking SQL) that would be applied to each record.

Another option, of course, if you have really large datasets and want to do
heavy duty SQL queries is to use PostGIS.

Chip Hankley

======================================

function zip_zoom($map, $zipcode) {
  $lyr = $map->getlayerbyname('ZIP');
  $src = $lyr->data;
  $path = $map->shapepath;
  $shp_path = $path . $src;
  $db_path = $shp_path . ".dbf";

  $nShpFile = ms_newShapefileObj($shp_path, -1);
  $zip_fail = 1;

  //open the dbase file for the shapefile
  if ($dbi = dbase_open($db_path, 0)) {
     $nr = dbase_numrecords ($dbi);
     $q_result = array();
     $x = 0;
     for ($i=1; $i <= $nr; $i++) {
       $cur_row = dbase_get_record_with_names ($dbi, $i);
       if (trim($zipcode) == trim($cur_row[ZIP])) {
          $row_id = $i;
          $zip_fail = 0;
          break;
      }
     }
  }
  
  if ($zip_fail)
    echo "<script>javascript:alert('No Zip Code Match Found!');</script>";

  $row_id = $row_id - 1;
  $shapeExtObj = $nShpFile->getExtent($row_id);
  $minx = $shapeExtObj->minx;
  $miny = $shapeExtObj->miny;
  $maxx = $shapeExtObj->maxx;
  $maxy = $shapeExtObj->maxy;

  $border = 10000;

  $minx = $minx - $border;
  $miny = $miny - $border;
  $maxx = $maxx + $border;
  $maxy = $maxy + $border;

  $map->setExtent($minx, $miny, $maxx, $maxy);

}




More information about the mapserver-users mailing list