Come realizzare una query sugli attributi su layer di tipo POSTGIS e SHAPEFILE con mapscript 4.6

Un esempio:

< ?php
/**
* Mapscript query example, with both POSTGIS and SHAPEFILE
* in this example we want to query all the map
*/

$layername    = $_REQUEST['layername'];
$searchfield  = $_REQUEST['searchfield'];
$searchstring = $_REQUEST['searchstring'];


if (!extension_loaded('MapScript'))
{
    dl( 'php_mapscript.so');
}

  $map = ms_newMapObj('/map/mapfile.map');
  // Set to max extent (query all the map)
  $map->setextent(1581106.5300398634,4852151.5,1624260.5949601366, 4881342.0);

  $results = array();

  $layer=$map->getLayerByName($layername);
  if($layer->connectiontype == MS_POSTGIS){
    $searchstring = $searchfield . ' ~* \'' . $searchstring .'\'  ';
  } else {  // Shapefile
    $numclasses = $layer->numclasses;
    // HACK: Remove all classes except one: otherwise only first class is queryied
    // If anybody knows a better way... please let me know
    for($i = 1 ; $i < $numclasses; $i++){
       // This produces a fatal: Call to undefined method ms_layer_obj::removeClass()
       // $layer->removeClass();
    }
    // Second HACK: it works
    if($numclasses > 1){
      $class = $layer->getClass(0);
      // Match all
      $class->setExpression('/.*/');
    }
    $searchstring = "/$searchstring/";
  }
  if($layer->queryByAttributes($searchfield, $searchstring, MS_MULTIPLE) == MS_SUCCESS){
    $layer->open();
    // Add element to results array for each result row
    for ($j=0; $j < $layer->getNumResults(); $j++)
    {
        // get next shape row
        $result = $layer->getResult($j);
        $shape  = $layer->getShape($result->tileindex, $result->shapeindex);
        //var_dump($shape);
        // push the row array onto the results array
        $aTmp = $shape->values;
        //Calculate centroid
        $x = ($shape->bounds->minx + $shape->bounds->maxx) / 2;
        $y = ($shape->bounds->miny + $shape->bounds->maxy) / 2;
        $aTmp = array_merge( $aTmp ,  array('x' => $x,'y' => $y, 'id' => $result->shapeindex));
        $results[$layername][] =  $aTmp;
    // end for loop
    }
  } else {
    print('No results' . "\n");
  }
  $layer->close();
  var_dump($results);
?>

Il problema è stato capire come eseguire la query sui diversi tipi di layer (postgis e shapefile), c’è probabilmente un baco o un errore nella documentazione: la chiamata al metodo $layer->removeClass() provoca un errore fatale, mentre dalla documentazione sembra che il metodo sia corretto.

Il tutto si è reso necessario perchè nel caso siano state definite più classi per un singolo layer di tipo shapefile, i risultati vengono filtrati sollo sulla prima classe, e questo spesso è un comportamento indesiderato.

2 Responses to “Query by Attributes with php mapscript”

  • Gianluca

    Ciao, ho visto i tuoi esempi, molto interessanti… vedo comunque che hai molta esperienza su mapscript. Ti vorrei chiedere se sai qualcosa sulla generazione degli swf fatta da mapscript e perchè non funziona con i risultati delle query.

    Grazie, ciao.

    Gianluca

  • luca

    Ciao, vista la tua dimestichezza con mapscript credo tu sia la persona giusta per alcune domande:
    devo realizzare un box all’interno del quale digitare una serie di toponimi e se presenti nel dbf (dello shape toponimi) dovrei individuare il record selezionato. Ho realizzato fino ad ora la query nquery, ma non riesco a capire come funziona ad esempio ithemquery.

    Scusa il disturbo e grazie.
    Ciao